updated argc before calling MPI_Init in case argc and argv do not agree.
[charm.git] / src / arch / template / machine.c
1 /** @file
2  * Templated machine layer
3  * @ingroup Machine
4  *
5  * This file explains what the machine layer has to provide (which functions
6  * need to be implemented). Depending on the flags set in the files
7  * conv-common.h, conv-mach.h and the possible other suboption file
8  * conv-mach-suboption.h, some additional functions may be needed to be
9  * implemented.
10
11  * Throughout the file, "#if CMK_VARIABLE" means it was set to 1 in the .h
12  * files, "#if ! CMK_VARIABLE" means it was set to 0.
13
14 /*@{*/
15
16 /*==========================================================*/
17 /*==========================================================*/
18 /*==========================================================*/
19
20 /** FUNCTIONS ALWAYS TO BE IMPLEMENTED
21
22  * This first section of the file reports which methods must always be
23  * implemented inside the machine layer.
24  */ 
25
26 void ConverseInit(int, char**, CmiStartFn, int, int);
27 void ConverseExit(void);
28
29 void CmiAbort(const char *);
30
31 void          CmiSyncSendFn(int, int, char *);
32 void          CmiFreeSendFn(int, int, char *);
33
34 void          CmiSyncBroadcastFn(int, char *);
35 void          CmiFreeBroadcastFn(int, char *);
36
37 void          CmiSyncBroadcastAllFn(int, char *);
38 void          CmiFreeBroadcastAllFn(int, char *);
39
40 /* Poll the network for messages */
41 //Different machine layers have different names for this function  
42
43 /* Poll the network and when a message arrives and insert this arrived
44    message into the local queue. For SMP this message would have to be
45    inserted into the thread's queue with the correct rank **/
46 //Pump messages is called when the processor goes idle
47 void PumpMessages();  
48
49 /* Free network resources when the messages have been sent out. Also
50 called when machine goes idle and at other places depending on the
51 implementation *********/
52 void CmiReleaseSentMessages(); 
53
54 //Called when the processor goes idle. Typically calls pump messages
55 //and releaseSentMessages. The idle handler has to be explicitly
56 //registered in ConverseInit through a call to CcdCallOnConditionKeep
57 void CmiNotifyIdle();
58
59
60 /*==========================================================*/
61 /*==========================================================*/
62 /*==========================================================*/
63
64 /************ Recommended routines ***********************/
65 /************ You dont have to implement these but they are supported
66  in the converse syntax and some rare programs may crash. But most
67  programs dont need them. *************/
68
69 CmiCommHandle CmiAsyncSendFn(int, int, char *);
70 CmiCommHandle CmiAsyncBroadcastFn(int, char *);
71 CmiCommHandle CmiAsyncBroadcastAllFn(int, char *);
72
73 int           CmiAsyncMsgSent(CmiCommHandle handle);
74 void          CmiReleaseCommHandle(CmiCommHandle handle);
75
76
77 /*==========================================================*/
78 /*==========================================================*/
79 /*==========================================================*/
80
81 //Optional routines which could use common code which is shared with
82 //other machine layer implementations.
83
84 /* MULTICAST/VECTOR SENDING FUNCTIONS
85
86  * In relations to some flags, some other delivery functions may be needed.
87  */
88
89 #if ! CMK_MULTICAST_LIST_USE_COMMON_CODE
90 void          CmiSyncListSendFn(int, int *, int, char*);
91 CmiCommHandle CmiAsyncListSendFn(int, int *, int, char*);
92 void          CmiFreeListSendFn(int, int *, int, char*);
93 #endif
94
95 #if ! CMK_MULTICAST_GROUP_USE_COMMON_CODE
96 void          CmiSyncMulticastFn(CmiGroup, int, char*);
97 CmiCommHandle CmiAsyncMulticastFn(CmiGroup, int, char*);
98 void          CmiFreeMulticastFn(CmiGroup, int, char*);
99 #endif
100
101 #if ! CMK_VECTOR_SEND_USES_COMMON_CODE
102 void          CmiSyncVectorSend(int, int, int *, char **);
103 CmiCommHandle CmiAsyncVectorSend(int, int, int *, char **);
104 void          CmiSyncVectorSendAndFree(int, int, int *, char **);
105 #endif
106
107
108 /** NODE SENDING FUNCTIONS
109
110  * If there is a node queue, and we consider also nodes as entity (tipically in
111  * SMP versions), these functions are needed.
112  */
113
114 #if CMK_NODE_QUEUE_AVAILABLE
115
116 void          CmiSyncNodeSendFn(int, int, char *);
117 CmiCommHandle CmiAsyncNodeSendFn(int, int, char *);
118 void          CmiFreeNodeSendFn(int, int, char *);
119
120 void          CmiSyncNodeBroadcastFn(int, char *);
121 CmiCommHandle CmiAsyncNodeBroadcastFn(int, char *);
122 void          CmiFreeNodeBroadcastFn(int, char *);
123
124 void          CmiSyncNodeBroadcastAllFn(int, char *);
125 CmiCommHandle CmiAsyncNodeBroadcastAllFn(int, char *);
126 void          CmiFreeNodeBroadcastAllFn(int, char *);
127
128 #endif
129
130
131 /** GROUPS DEFINITION
132
133  * For groups of processors (establishing and managing) some more functions are
134  * needed, they also con be found in common code (convcore.c) or here.
135  */
136
137 #if ! CMK_MULTICAST_DEF_USE_COMMON_CODE
138 void     CmiGroupInit();
139 CmiGroup CmiEstablishGroup(int npes, int *pes);
140 void     CmiLookupGroup(CmiGroup grp, int *npes, int **pes);
141 #endif
142
143
144 /** MESSAGE DELIVERY FUNCTIONS
145
146  * In order to deliver the messages to objects (either converse register
147  * handlers, or charm objects), a scheduler is needed. The one implemented in
148  * convcore.c can be used, or a new one can be implemented here. At present, all
149  * machines use the default one, exept sim-linux.
150
151  * If the one in convcore.c is used, still one function is needed.
152  */
153
154 #if CMK_CMIDELIVERS_USE_COMMON_CODE /* use the default one */
155
156 CpvDeclare(void*, CmiLocalQueue);
157 void *CmiGetNonLocal();
158
159 #elif /* reimplement the scheduler and delivery */
160
161 void CsdSchedulerState_new(CsdSchedulerState_t *state);
162 void *CsdNextMessage(CsdSchedulerState_t *state);
163 int  CsdScheduler(int maxmsgs);
164
165 void CmiDeliversInit();
166 int  CmiDeliverMsgs(int maxmsgs);
167 void CmiDeliverSpecificMsg(int handler);
168
169 #endif
170
171
172 /** SHARED VARIABLES DEFINITIONS
173
174  * In relation to which CMK_SHARED_VARS_ flag is set, different
175  * functions/variables need to be defined and initialized correctly.
176  */
177
178 #if CMK_SHARED_VARS_UNAVAILABLE /* Non-SMP version of shared vars. */
179
180 int _Cmi_mype;
181 int _Cmi_numpes;
182 int _Cmi_myrank; /* Normally zero; only 1 during SIGIO handling */
183
184 void CmiMemLock();
185 void CmiMemUnlock();
186
187 #endif
188
189 #if CMK_SHARED_VARS_POSIX_THREADS_SMP /*Used by the net-*-smp versions*/
190
191 int _Cmi_numpes;
192 int _Cmi_mynodesize;
193 int _Cmi_mynode;
194 int _Cmi_numnodes;
195
196 int CmiMyPe();
197 int CmiMyRank();
198 int CmiNodeFirst(int node);
199 int CmiNodeSize(int node);
200 int CmiNodeOf(int pe);
201 int CmiRankOf(int pe);
202
203 /* optional, these functions are implemented in "machine-smp.c", so including
204    this file avoid the necessity to reimplement them.
205  */
206 void CmiNodeBarrier(void);
207 void CmiNodeAllBarrier(void);
208 CmiNodeLock CmiCreateLock();
209 void CmiDestroyLock(CmiNodeLock lock);
210
211 #endif
212
213 /* NOT VERY USEFUL */
214 #if CMK_SHARED_VARS_UNIPROCESSOR /*Used only by uth- and sim- versions*/
215
216 int _Cmi_mype;
217 int _Cmi_numpes;
218
219 void         CmiLock(CmiNodeLock lock);
220 void         CmiUnlock(CmiNodeLock lock);
221 int          CmiTryLock(CmiNodeLock lock);
222
223 /* optional, these functions are implemented in "machine-smp.c", so including
224    this file avoid the necessity to reimplement them.
225  */
226 void CmiNodeBarrier();
227 void CmiNodeAllBarrier();
228 CmiNodeLock  CmiCreateLock(void);
229 void         CmiDestroyLock(CmiNodeLock lock);
230
231 #endif
232
233 /* NOT VERY USEFUL */
234 #if CMK_SHARED_VARS_PTHREADS /*Used only by origin-pthreads*/
235
236 int CmiMyPe();
237 int _Cmi_numpes;
238
239 void CmiMemLock();
240 void CmiMemUnlock();
241
242 void         CmiLock(CmiNodeLock lock);
243 void         CmiUnlock(CmiNodeLock lock);
244 int          CmiTryLock(CmiNodeLock lock);
245
246 /* optional, these functions are implemented in "machine-smp.c", so including
247    this file avoid the necessity to reimplement them.
248  */
249 void CmiNodeBarrier();
250 void CmiNodeAllBarrier();
251 CmiNodeLock  CmiCreateLock(void);
252 void         CmiDestroyLock(CmiNodeLock lock);
253
254 #endif
255
256 /* NOT VERY USEFUL */
257 #if CMK_SHARED_VARS_NT_THREADS /*Used only by win32 versions*/
258
259 int _Cmi_numpes;
260 int _Cmi_mynodesize;
261 int _Cmi_mynode;
262 int _Cmi_numnodes;
263
264 int CmiMyPe();
265 int CmiMyRank();
266 int CmiNodeFirst(int node);
267 int CmiNodeSize(int node);
268 int CmiNodeOf(int pe);
269 int CmiRankOf(int pe);
270
271 /* optional, these functions are implemented in "machine-smp.c", so including
272    this file avoid the necessity to reimplement them.
273  */
274 void CmiNodeBarrier(void);
275 void CmiNodeAllBarrier(void);
276 CmiNodeLock CmiCreateLock(void);
277 void CmiDestroyLock(CmiNodeLock lock);
278
279 #endif
280
281
282 /** TIMERS DEFINITIONS
283
284  * In relation to what CMK_TIMER_USE_ is selected, some * functions may need to
285  * be implemented.
286  */
287
288 /* If all the CMK_TIMER_USE_ are set to 0, the following timer functions are
289    needed. */
290
291 void   CmiTimerInit(char **argv);
292 double CmiTimer();
293 double CmiWallTimer();
294 double CmiCpuTimer();
295 int    CmiTimerIsSynchronized();
296
297 /* If one of the following is set to 1, barriers are needed:
298    CMK_TIMER_USE_GETRUSAGE
299    CMK_TIMER_USE_RDTSC
300    CMK_TIMER_USE_BLUEGENEL
301 */
302
303 int CmiBarrier();
304 int CmiBarrierZero();
305
306
307 /** PRINTF FUNCTIONS
308
309  * Default code is provided in convcore.c but for particular architectures they
310  * can be reimplemented. At present only net- versions reimplement them.
311
312  */
313
314 #if CMK_CMIPRINTF_IS_A_BUILTIN
315
316 void CmiPrintf(const char *, ...);
317 void CmiError(const char *, ...);
318 int  CmiScanf(const char *, ...);
319
320 #endif
321
322
323 /** SPANNING TREE
324
325  * During some working operations (such as quiescence detection), spanning trees
326  * are used. Default code in convcore.c can be used, or a new definition can be
327  * implemented here.
328  */
329
330 #if ! CMK_SPANTREE_USE_COMMON_CODE
331
332 int      CmiNumSpanTreeChildren(int) ;
333 int      CmiSpanTreeParent(int) ;
334 void     CmiSpanTreeChildren(int node, int *children);
335
336 int      CmiNumNodeSpanTreeChildren(int);
337 int      CmiNodeSpanTreeParent(int) ;
338 void     CmiNodeSpanTreeChildren(int node, int *children) ;
339
340 #endif
341
342
343
344 /** IMMEDIATE MESSAGES
345
346  * If immediate messages are supported, the following function is needed. There
347  * is an exeption if the machine progress is also defined (see later for this).
348
349  * Moreover, the file "immediate.c" should be included, otherwise all its
350  * functions and variables have to be redefined.
351 */
352
353 #if CMK_CCS_AVAILABLE
354
355 #include "immediate.c"
356
357 #if ! CMK_MACHINE_PROGRESS_DEFINED /* Hack for some machines */
358 void CmiProbeImmediateMsg();
359 #endif
360
361 #endif
362
363
364 /** MACHINE PROGRESS DEFINED
365
366  * Some machines (like BlueGene/L) do not have coprocessors, and messages need
367  * to be pulled out of the network manually. For this reason the following
368  * functions are needed. Notice that the function "CmiProbeImmediateMsg" must
369  * not be defined anymore.
370  */
371
372 #if CMK_MACHINE_PROGRESS_DEFINED
373
374 CpvDeclare(unsigned, networkProgressCount);
375 int  networkProgressPeriod;
376
377 void CmiMachineProgressImpl();
378
379 #endif