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