fix in infi_CmiFree the case in standalone mode for SMP.
[charm.git] / src / arch / vmi / machine.h
1 /**************************************************************************
2 ** Greg Koenig (koenig@uiuc.edu)
3 */
4
5 /** @file
6  * VMI machine layer
7  * @ingroup Machine
8  * @{
9  */
10
11 #include <ctype.h>
12 #include <errno.h>
13 #include <fcntl.h>
14 #include <limits.h>
15 #include <signal.h>
16 #include <stdarg.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <sys/time.h>
21
22 #include "converse.h"
23
24 #define VMI_DEVICENAME "converse"
25 #undef PACKAGE_BUGREPORT
26 #undef PACKAGE_NAME
27 #undef PACKAGE_STRING
28 #undef PACKAGE_TARNAME
29 #undef PACKAGE_VERSION
30
31 #include "vmi.h"
32
33 /* These settings can only be changed at compile time. */
34 #define CMI_VMI_OPTIMIZE 0
35
36 /*
37   These settings are defaults that can be overridden at runtime by
38   setting environment variables of the same name.
39 */
40 #define CMI_VMI_WAN_LATENCY                      1000      /* microseconds */
41 #define CMI_VMI_PROBE_CLUSTERS                   0         /* Boolean */
42 #define CMI_VMI_GRID_QUEUE                       0         /* Boolean */
43 #define CMI_VMI_GRID_QUEUE_MAXIMUM               100
44 #define CMI_VMI_GRID_QUEUE_INTERVAL              0
45 #define CMI_VMI_GRID_QUEUE_THRESHOLD             0
46 #define CMI_VMI_MEMORY_POOL                      1         /* Boolean */
47 #define CMI_VMI_TERMINATE_VMI_HACK               1         /* Boolean */
48 #define CMI_VMI_CONNECTION_TIMEOUT               300       /* seconds */
49 #define CMI_VMI_MAXIMUM_HANDLES                  10000
50 #define CMI_VMI_SMALL_MESSAGE_BOUNDARY           2048      /* bytes */
51 #define CMI_VMI_MEDIUM_MESSAGE_BOUNDARY          16384     /* bytes */
52 #define CMI_VMI_EAGER_PROTOCOL                   0         /* Boolean */
53 #define CMI_VMI_EAGER_INTERVAL                   10000
54 #define CMI_VMI_EAGER_THRESHOLD                  1000
55 #define CMI_VMI_EAGER_SHORT_POLLSET_SIZE_MAXIMUM 32
56 #define CMI_VMI_EAGER_SHORT_SLOTS                16
57 #define CMI_VMI_EAGER_SHORT_MESSAGE_BOUNDARY     16384     /* bytes */
58 #define CMI_VMI_EAGER_LONG_BUFFERS               3
59 #define CMI_VMI_EAGER_LONG_BUFFER_SIZE           1048576   /* bytes */
60
61 /*
62   If CMI_VMI_OPTIMIZE is defined, all of the checks for success for
63   calls to VMI are removed by the use of the following macro.  The
64   performance improvements seen by this are probably not worth the
65   headaches caused when error conditions within VMI are not immediately
66   discovered, however most of the code from NCSA that uses VMI skips
67   checking VMI return codes, so we provide the same option here.
68 */
69 #if CMI_VMI_OPTIMIZE
70 #define CMI_VMI_CHECK_SUCCESS(status,message)
71 #else
72 #define CMI_VMI_CHECK_SUCCESS(status,message)   \
73           if (!VMI_SUCCESS (status)) {          \
74             VMI_perror (message, status);       \
75           }
76 #endif
77
78
79 /*
80   The VMI versions of CmiAlloc() and CmiFree() prepend additional information
81   onto each memory allocation, similar to what Converse already does.  This
82   information holds a context associated with the memory chunk.  Normally
83   this context is NULL, but in the case of eager message buffers the
84   context points to the handle associated with the message buffer.  When the
85   application calls CmiFree() on this message buffer, the call is intercepted
86   and the message buffer is marked as free rather than deallocating the
87   memory.
88 */
89 #define CONTEXTFIELD(m) (((CMI_VMI_Memory_Chunk_T *)(m))[-1].context)
90
91 typedef struct
92 {
93   void           *context;
94   CmiChunkHeader  chunk_header;
95 } CMI_VMI_Memory_Chunk_T;
96
97 #define CMI_VMI_EAGER_SHORT_SENTINEL_READY    0
98 #define CMI_VMI_EAGER_SHORT_SENTINEL_DATA     1
99 #define CMI_VMI_EAGER_SHORT_SENTINEL_RECEIVED 2
100 #define CMI_VMI_EAGER_SHORT_SENTINEL_FREE     3
101
102 typedef struct
103 {
104   unsigned short msgsize;
105   unsigned short sentinel;
106 } CMI_VMI_Eager_Short_Slot_Footer_T;
107
108
109 /*
110   If the memory pool is enabled, the following settings determine the
111   sizes of the memory pool buckets as well as the number of entries in
112   each bucket to pre-define and by which to grow.  The memory pool
113   provides an efficient method of allocating and deallocating memory
114   that does not need to call malloc() and free() repeatedly.
115 */
116 #define CMI_VMI_BUCKET1_SIZE 1024
117 #define CMI_VMI_BUCKET2_SIZE 2048
118 #define CMI_VMI_BUCKET3_SIZE 4096
119 #define CMI_VMI_BUCKET4_SIZE 8192
120 #define CMI_VMI_BUCKET5_SIZE 16384
121
122 #define CMI_VMI_BUCKET1_PREALLOCATE 128
123 #define CMI_VMI_BUCKET1_GROW        128
124
125 #define CMI_VMI_BUCKET2_PREALLOCATE 128
126 #define CMI_VMI_BUCKET2_GROW        128
127
128 #define CMI_VMI_BUCKET3_PREALLOCATE 128
129 #define CMI_VMI_BUCKET3_GROW        128
130
131 #define CMI_VMI_BUCKET4_PREALLOCATE 128
132 #define CMI_VMI_BUCKET4_GROW        128
133
134 #define CMI_VMI_BUCKET5_PREALLOCATE 128
135 #define CMI_VMI_BUCKET5_GROW        128
136
137
138 /*
139   The following settings are used to describe the startup methods that
140   may be used to assign an ordering to the processes in the computation.
141   (So far, only startup via the Charm++ Resource Manager (CRM) is possible.)
142 */
143 #define CMI_VMI_STARTUP_TYPE_UNKNOWN  0
144 #define CMI_VMI_STARTUP_TYPE_CRM      1
145 #define CMI_VMI_STARTUP_TYPE_CHARMRUN 2
146
147 /*
148   The following settings and message structures are used for communicating with
149   the CRM.  These are only needed for startup CMI_VMI_STARTUP_TYPE_CRM.
150 */
151 #define CMI_VMI_CRM_PORT 7777
152
153 #define CMI_VMI_CRM_MESSAGE_SUCCESS  0
154 #define CMI_VMI_CRM_MESSAGE_FAILURE  1
155 #define CMI_VMI_CRM_MESSAGE_REGISTER 2
156
157 #define CMI_VMI_CRM_ERROR_CONFLICT 0
158 #define CMI_VMI_CRM_ERROR_TIMEOUT  1
159
160 typedef struct CMI_VMI_CRM_Register_Message_T
161 {
162   int numpes;
163   int cluster;
164   int node_context;
165   int key_length;
166   char key[1024];
167 } CMI_VMI_CRM_Register_Message_T;
168
169 typedef struct CMI_VMI_CRM_Nodeblock_Message_T
170 {
171   int node_IP;
172   int node_context;
173   int cluster;
174 } CMI_VMI_CRM_Nodeblock_Message_T;
175
176 /*
177   The following message structures are used for communicating with
178   Charmrun.  These are only needed for startup CMI_VMI_STARTUP_TYPE_CHARMRUN.
179 */
180 typedef struct CMI_VMI_Charmrun_Message_Header_T
181 {
182   int  msg_len;
183   char msg_type[12];
184 } CMI_VMI_Charmrun_Message_Header_T;
185
186 typedef struct CMI_VMI_Charmrun_Register_Message_T
187 {
188   int node_number;
189   int numpes;
190   int dataport;
191   int mach_id;
192   int node_IP;
193 } CMI_VMI_Charmrun_Register_Message_T;
194
195 typedef struct CMI_VMI_Charmrun_Nodeblock_Message_T
196 {
197   int numpes;
198   int dataport;
199   int mach_id;
200   int node_IP;
201 } CMI_VMI_Charmrun_Nodeblock_Message_T;
202
203
204 /*
205   Sometimes vmi-linux needs to determine information about processes
206   within a Grid environment.  Such information may include the latency
207   between two processes or the cluster that a process belongs to.
208   Because it is quite costly (and usually unnecessary) to distribute
209   this information to all processes in a computation, some processes
210   may have "unknown" entries for these values.
211 */
212 #define CMI_VMI_LATENCY_UNKNOWN LONG_MAX
213 #define CMI_VMI_CLUSTER_UNKNOWN -1
214
215
216 /*
217   Messages sent from one process to another using the VMI machine layer
218   are tagged with a "type" field which is part of the Converse message
219   header.
220
221   "Standard" messages are simply placed into the Converse remote message
222   queue when they received.
223
224   "Barrier" messages are used to organize a barrier of all processes in
225   the computation.  These have to be handled out-of-band at a lower
226   layer than Converse to avoid race conditions.
227
228   "Persistent Request" messages are used by the persistent handle setup
229   function CmiCreatePersistent() to signal the receiver that a particular
230   sender thinks it will be sending many messages to the receiver.  The
231   receiver can use this hint to decide whether to set up an eager channel.
232
233   "Credit" messages are used to replentish eager short credits on a sender.
234   Normally credit replentishes are sent in the message headers of other
235   messages ("piggyback") but if a process does not communicate frequently
236   with its eager sender, no opportunities to piggyback credits may happen.
237   In these cases, a separate message is sent.
238
239   "Latency Vector Request" messages are used to request a vector of
240   latencies from a given node to all other nodes in the computation.
241   The node responding to the message replies with a "Latency Vector Reply"
242   message.
243
244   "Cluster Mapping" messages are used to distribute a mapping of processes
245   to clusters computed in process 0.  The user may specify that the cluster
246   mapping should be probed at startup, and this message type distributes the
247   results of this probe to all processes.
248 */
249 #define CMI_VMI_MESSAGE_TYPE(msg) ((CmiMsgHeaderBasic *)msg)->vmitype
250 #define CMI_VMI_MESSAGE_CREDITS(msg) ((CmiMsgHeaderBasic *)msg)->vmicredits
251
252 #define CMI_VMI_MESSAGE_TYPE_UNKNOWN                0
253 #define CMI_VMI_MESSAGE_TYPE_STANDARD               1
254 #define CMI_VMI_MESSAGE_TYPE_BARRIER                2
255 #define CMI_VMI_MESSAGE_TYPE_PERSISTENT_REQUEST     3
256 #define CMI_VMI_MESSAGE_TYPE_CREDIT                 4
257 #define CMI_VMI_MESSAGE_TYPE_LATENCY_VECTOR_REQUEST 5
258 #define CMI_VMI_MESSAGE_TYPE_LATENCY_VECTOR_REPLY   6
259 #define CMI_VMI_MESSAGE_TYPE_CLUSTER_MAPPING        7
260
261
262 /*
263   The following structures define messages that are sent within the VMI
264   machine layer.
265
266   CMI_VMI_Connect_Message_T are connect messages that are only sent during
267   the connection setup phase.
268
269   CMI_VMI_Barrier_Message_T are used to signal barrier operations.
270
271   CMI_VMI_Persistent_Request_Message_T are used to indicate to a receiver
272   that the sender will likely perform a lot of send operations, thus if
273   the receiver has resources it is a good idea to set up eager channels.
274
275   CMI_VMI_Credit_Message_T are used to send eager credit replentish messages
276   when no opportunity to piggyback credits has happened.
277
278   CMI_VMI_Latency_Vector_Request_Message_T are used to request a latency vector
279   from a specified process to all other processes in the computation.
280
281   CMI_VMI_Latency_Vector_Reply_Message_T are used to reply to the above message.
282
283   CMI_VMI_Cluster_Mapping_Message_T are used to distribute process-to-cluster
284   mappings (computed by process 0) to all processes in a computation.  This is
285   used when the user requests that the cluster mapping be probed during startup.
286 */
287 typedef struct
288 {
289   int rank;
290 } CMI_VMI_Connect_Message_T;
291
292 typedef struct
293 {
294   char header[CmiMsgHeaderSizeBytes];
295 } CMI_VMI_Barrier_Message_T;
296
297 typedef struct
298
299   char header[CmiMsgHeaderSizeBytes];
300   int  maxsize;
301 } CMI_VMI_Persistent_Request_Message_T;
302
303 typedef struct
304 {
305   char header[CmiMsgHeaderSizeBytes];
306 } CMI_VMI_Credit_Message_T;
307
308 typedef struct
309 {
310   char header[CmiMsgHeaderSizeBytes];
311 } CMI_VMI_Latency_Vector_Request_Message_T;
312
313 typedef struct
314 {
315   char header[CmiMsgHeaderSizeBytes];
316   unsigned long latency[1];
317 } CMI_VMI_Latency_Vector_Reply_Message_T;
318
319 typedef struct
320 {
321   char header[CmiMsgHeaderSizeBytes];
322   int cluster[1];
323 } CMI_VMI_Cluster_Mapping_Message_T;
324
325
326 /* Publish messages (sent as payload with VMI_RDMA_Publish_Buffer() call). */
327 typedef enum
328 {
329   CMI_VMI_PUBLISH_TYPE_GET,
330   CMI_VMI_PUBLISH_TYPE_EAGER_SHORT,
331   CMI_VMI_PUBLISH_TYPE_EAGER_LONG
332 } CMI_VMI_Publish_Type_T;
333
334 typedef struct
335 {
336   CMI_VMI_Publish_Type_T type;
337 } CMI_VMI_Publish_Message_T;
338
339
340 /*
341   Send and receive operations which cannot be completed immediately need
342   to have some amount of state associated with them.  The following data
343   structures are used to hold state for these operations in Send and
344   Receive handles.
345 */
346 typedef enum
347 {
348   CMI_VMI_HANDLE_TYPE_SEND,
349   CMI_VMI_HANDLE_TYPE_RECEIVE
350 } CMI_VMI_Handle_Type_T;
351
352 typedef enum
353 {
354   CMI_VMI_SEND_HANDLE_TYPE_STREAM,
355   CMI_VMI_SEND_HANDLE_TYPE_RDMAGET,
356   CMI_VMI_SEND_HANDLE_TYPE_RDMABROADCAST,
357   CMI_VMI_SEND_HANDLE_TYPE_EAGER_SHORT,
358   CMI_VMI_SEND_HANDLE_TYPE_EAGER_LONG
359 } CMI_VMI_Send_Handle_Type_T;
360
361 typedef enum
362 {
363   CMI_VMI_MESSAGE_DISPOSITION_NONE,
364   CMI_VMI_MESSAGE_DISPOSITION_FREE,
365   CMI_VMI_MESSAGE_DISPOSITION_ENQUEUE
366 } CMI_VMI_Message_Disposition_T;
367
368 typedef struct
369 {
370   PVMI_CACHE_ENTRY cacheentry;
371 } CMI_VMI_Send_Handle_Stream_T;
372
373 typedef struct
374 {
375   PVMI_CACHE_ENTRY cacheentry;
376   int              publishes_pending;
377 } CMI_VMI_Send_Handle_RDMAGet_T;
378
379 typedef struct
380 {
381   PVMI_CACHE_ENTRY cacheentry;
382   int              publishes_pending;
383 } CMI_VMI_Send_Handle_RDMABroadcast_T;
384
385 typedef struct
386 {
387   PVMI_REMOTE_BUFFER remote_buffer;
388   int                offset;
389   PVMI_CACHE_ENTRY   cacheentry;
390   PVMI_RDMA_OP       rdmaop;
391 } CMI_VMI_Send_Handle_Eager_Short_T;
392
393 typedef struct
394 {
395   int                maxsize;
396   PVMI_REMOTE_BUFFER remote_buffer;
397   PVMI_CACHE_ENTRY   cacheentry;
398 } CMI_VMI_Send_Handle_Eager_Long_T;
399
400 typedef struct
401 {
402   CMI_VMI_Send_Handle_Type_T    send_handle_type;
403   CMI_VMI_Message_Disposition_T message_disposition;
404
405   union
406   {
407     CMI_VMI_Send_Handle_Stream_T        stream;
408     CMI_VMI_Send_Handle_RDMAGet_T       rdmaget;
409     CMI_VMI_Send_Handle_RDMABroadcast_T rdmabroadcast;
410     CMI_VMI_Send_Handle_Eager_Short_T   eager_short;
411     CMI_VMI_Send_Handle_Eager_Long_T    eager_long;
412   } data;
413 } CMI_VMI_Send_Handle_T;
414
415 typedef enum
416 {
417   CMI_VMI_RECEIVE_HANDLE_TYPE_RDMAGET,
418   CMI_VMI_RECEIVE_HANDLE_TYPE_EAGER_SHORT,
419   CMI_VMI_RECEIVE_HANDLE_TYPE_EAGER_LONG
420 } CMI_VMI_Receive_Handle_Type_T;
421
422 typedef struct
423 {
424   PVMI_CACHE_ENTRY  cacheentry;
425   void             *process;
426 } CMI_VMI_Receive_Handle_RDMAGet_T;
427
428 typedef struct
429 {
430   int                                sender_rank;
431   char                              *publish_buffer;
432   PVMI_CACHE_ENTRY                   cacheentry;
433   char                              *eager_buffer;
434   CMI_VMI_Eager_Short_Slot_Footer_T *footer;
435   int                                publishes_pending;
436 } CMI_VMI_Receive_Handle_Eager_Short_T;
437
438 typedef struct
439 {
440   int              sender_rank;
441   int              maxsize;
442   PVMI_CACHE_ENTRY cacheentry;
443   int              publishes_pending;
444 } CMI_VMI_Receive_Handle_Eager_Long_T;
445
446 typedef struct
447 {
448   CMI_VMI_Receive_Handle_Type_T receive_handle_type;
449
450   union
451   {
452     CMI_VMI_Receive_Handle_RDMAGet_T     rdmaget;
453     CMI_VMI_Receive_Handle_Eager_Short_T eager_short;
454     CMI_VMI_Receive_Handle_Eager_Long_T  eager_long;
455   } data;
456 } CMI_VMI_Receive_Handle_T;
457
458 typedef struct
459 {
460   int                    index;
461   int                    refcount;
462   char                  *msg;
463   int                    msgsize;
464   CMI_VMI_Handle_Type_T  handle_type;
465
466   union
467   {
468     CMI_VMI_Send_Handle_T    send;
469     CMI_VMI_Receive_Handle_T receive;
470   } data;
471 } CMI_VMI_Handle_T;
472
473
474 /*
475   The following data structure holds per-process state information for
476   each process in the computation.  The machine layer determines the
477   total number of processes in the computation during startup and then
478   creates an array of CMI_VMI_Process_T structures.
479 */
480 typedef enum
481 {
482   CMI_VMI_CONNECTION_CONNECTING,
483   CMI_VMI_CONNECTION_CONNECTED,
484   CMI_VMI_CONNECTION_DISCONNECTING,
485   CMI_VMI_CONNECTION_DISCONNECTED,
486   CMI_VMI_CONNECTION_ERROR
487 } CMI_VMI_Connection_State_T;
488
489 typedef struct
490 {
491   int                        rank;
492   int                        node_IP;
493   PVMI_CONNECT               connection;
494   CMI_VMI_Connection_State_T connection_state;
495   int                        cluster;
496
497   unsigned long *latency_vector;
498
499   int normal_short_count;
500   int normal_long_count;
501   int eager_short_count;
502   int eager_long_count;
503
504   CMI_VMI_Handle_T *eager_short_send_handles[CMI_VMI_EAGER_SHORT_SLOTS];
505   int               eager_short_send_size;
506   int               eager_short_send_index;
507   int               eager_short_send_credits_available;
508
509   CMI_VMI_Handle_T *eager_short_receive_handles[CMI_VMI_EAGER_SHORT_SLOTS];
510   int               eager_short_receive_size;
511   int               eager_short_receive_index;
512   int               eager_short_receive_dirty;
513   int               eager_short_receive_credits_replentish;
514
515   CMI_VMI_Handle_T *eager_long_send_handles[CMI_VMI_EAGER_LONG_BUFFERS];
516   int               eager_long_send_size;
517
518   CMI_VMI_Handle_T *eager_long_receive_handles[CMI_VMI_EAGER_LONG_BUFFERS];
519   int               eager_long_receive_size;
520 } CMI_VMI_Process_T;
521
522
523 /*
524   If CMK_BROADCAST_SPANNING_TREE is defined, broadcasts are done via a
525   spanning tree.  (Otherwise, broadcasts are done by iterating through
526   each process in the process list and sending a separate message.)
527 */
528 #if CMK_BROADCAST_SPANNING_TREE
529 #ifndef CMI_VMI_BROADCAST_SPANNING_FACTOR
530 #define CMI_VMI_BROADCAST_SPANNING_FACTOR 4
531 #endif
532
533 #define CMI_BROADCAST_ROOT(msg)   ((CmiMsgHeaderBasic *)msg)->tree_root
534 #define CMI_DEST_RANK(msg)        ((CmiMsgHeaderBasic *)msg)->tree_rank
535
536 #define CMI_SET_BROADCAST_ROOT(msg,tree_root) CMI_BROADCAST_ROOT(msg) = (tree_root);
537 #endif
538
539
540 #if CMK_GRID_QUEUE_AVAILABLE
541 typedef struct
542 {
543   int gid;
544   int nInts;
545   int index1;
546   int index2;
547   int index3;
548 } CMI_VMI_Grid_Object_T;
549
550 #define CkMsgAlignmentMask  (sizeof(double)-1)
551 #define CkMsgAlignLength(x) (((x)+CkMsgAlignmentMask)&(~(CkMsgAlignmentMask)))
552 #define CkMsgAlignOffset(x) (CkMsgAlignLength(x)-(x))
553
554 typedef union
555 {
556   struct s_chare
557   {
558     void *ptr;
559     unsigned int forAnyPe;
560   } chare;
561
562   struct s_group
563   {
564     int g;
565     int rednMgr;
566     int epoch;
567     unsigned short arrayEp;
568   } group;
569
570   struct s_array
571   {
572     struct
573     {
574       int nInts;
575       int index[3];
576     } index;
577     int listenerData[3];
578     int arr;
579     unsigned char hopCount;
580     unsigned char ifNotThere;
581   } array;
582
583   struct s_roData
584   {
585     unsigned int count;
586   } roData;
587
588   struct s_roMsg
589   {
590     unsigned int roIdx;
591   } roMsg;
592 } CMI_VMI_Envelope_utype;
593
594 typedef struct
595 {
596   unsigned char msgIdx;
597   unsigned char mtype;
598   unsigned char queueing:4;
599   unsigned char isPacked:1;
600   unsigned char isUsed:1;
601 } CMI_VMI_Envelope_sattribs;
602
603 typedef struct
604 {
605   char core[CmiReservedHeaderSize];
606   CMI_VMI_Envelope_utype u_type;
607   unsigned short ref;
608   CMI_VMI_Envelope_sattribs s_attribs;
609
610   unsigned char align[CkMsgAlignOffset(CmiReservedHeaderSize+sizeof(CMI_VMI_Envelope_utype)+sizeof(unsigned short)+sizeof(CMI_VMI_Envelope_sattribs))];
611
612   /* The remaining fields in this struct are now aligned to (void *). */
613
614   unsigned short priobits;
615   unsigned short epIdx;
616   unsigned int pe;
617   unsigned int event;
618   unsigned int totalsize;
619 } CMI_VMI_Envelope;
620 #endif
621
622
623
624
625
626 /***********************/
627 /* FUNCTION PROTOTYPES */
628 /***********************/
629
630 /* Externally-visible API functions */
631 void ConverseInit (int argc, char **argv, CmiStartFn start_function, int user_calls_scheduler, int init_returns);
632 void ConverseExit ();
633 void CmiAbort (const char *message);
634
635 void CmiNotifyIdle ();
636
637 void CmiMemLock ();
638 void CmiMemUnlock ();
639
640 void CmiPrintf (const char *format, ...);
641 void CmiError (const char *format, ...);
642 int CmiScanf (const char *format, ...);
643
644 int CmiBarrier ();
645 int CmiBarrierZero ();
646
647 void CmiSyncSendFn (int destrank, int msgsize, char *msg);
648 CmiCommHandle CmiAsyncSendFn (int destrank, int msgsize, char *msg);
649 void CmiFreeSendFn (int destrank, int msgsize, char *msg);
650
651 void CmiSyncBroadcastFn (int msgsize, char *msg);
652 CmiCommHandle CmiAsyncBroadcastFn (int msgsize, char *msg);
653 void CmiFreeBroadcastFn (int msgsize, char *msg);
654
655 void CmiSyncBroadcastAllFn (int msgsize, char *msg);
656 CmiCommHandle CmiAsyncBroadcastAllFn (int msgsize, char *msg);
657 void CmiFreeBroadcastAllFn (int msgsize, char *msg);
658
659 int CmiAsyncMsgSent (CmiCommHandle commhandle);
660 int CmiAllAsyncMsgsSent ();
661 void CmiReleaseCommHandle (CmiCommHandle commhandle);
662
663 void *CmiGetNonLocal ();
664
665 void CmiProbeLatencies ();
666 unsigned long CmiGetLatency (int process1, int process2);
667 int CmiGetCluster (int process);
668
669 /* Grid object prioritization functions */
670 #if CMK_GRID_QUEUE_AVAILABLE
671 int CmiGridQueueGetInterval ();
672 int CmiGridQueueGetThreshold ();
673 void CmiGridQueueRegister (int gid, int nInts, int index1, int index2, int index3);
674 void CmiGridQueueDeregister (int gid, int nInts, int index1, int index2, int index3);
675 void CmiGridQueueDeregisterAll ();
676 int CmiGridQueueLookup (int gid, int nInts, int index1, int index2, int index3);
677 int CmiGridQueueLookupMsg (char *msg);
678 int CMI_VMI_Grid_Objects_Compare (const void *ptr1, const void *ptr2);
679 #endif
680
681 #if CMK_PERSISTENT_COMM
682 void CmiPersistentInit ();
683 PersistentHandle CmiCreatePersistent (int destrank, int maxsize);
684 void CmiUsePersistentHandle (PersistentHandle *handle_array, int array_size);
685 void CmiDestroyPersistent (PersistentHandle phandle);
686 void CmiDestroyAllPersistent ();
687 PersistentReq CmiCreateReceiverPersistent (int maxsize);
688 PersistentHandle CmiRegisterReceivePersistent (PersistentReq request);
689 #endif
690
691
692 /* Startup and shutdown functions */
693 void CMI_VMI_Read_Environment ();
694
695 int CMI_VMI_Startup_CRM ();
696
697 int CMI_VMI_Startup_Charmrun ();
698
699 int CMI_VMI_Initialize_VMI ();
700
701 int CMI_VMI_Terminate_VMI ();
702
703
704 /* Socket send and receive functions */
705 int CMI_VMI_Socket_Send (int sockfd, const void *msg, int size);
706 int CMI_VMI_Socket_Receive (int sockfd, void *msg, int size);
707
708
709 /* Connection open and close functions */
710 int CMI_VMI_Open_Connections ();
711 int CMI_VMI_Open_Connection (int remote_rank, char *remote_key, PVMI_BUFFER connect_message_buffer);
712 VMI_CONNECT_RESPONSE CMI_VMI_Connection_Handler (PVMI_CONNECT connection, PVMI_SLAB slab, ULONG data_size);
713 void CMI_VMI_Connection_Response_Handler (PVOID context, PVOID response, USHORT size, PVOID handle, VMI_CONNECT_RESPONSE remote_status);
714
715 int CMI_VMI_Close_Connections ();
716 void CMI_VMI_Disconnection_Handler (PVMI_CONNECT connection);
717 void CMI_VMI_Disconnection_Response_Handler (PVMI_CONNECT connection, PVOID context, VMI_STATUS remote_status);
718
719
720 /* Latency and cluster mapping functions */
721 void CMI_VMI_Reply_Latencies (int sourcerank);
722 void CMI_VMI_Compute_Cluster_Mapping ();
723 void CMI_VMI_Distribute_Cluster_Mapping ();
724 void CMI_VMI_Wait_Cluster_Mapping ();
725
726
727 /* Memory allocation and deallocation functions */
728 void *CMI_VMI_CmiAlloc (int request_size);
729 void CMI_VMI_CmiFree (void *ptr);
730
731 PVMI_CACHE_ENTRY CMI_VMI_CacheEntry_From_Context (void *context);
732
733
734 /* Handle allocation and deallocation functions */
735 CMI_VMI_Handle_T *CMI_VMI_Handle_Allocate ();
736 void CMI_VMI_Handle_Deallocate (CMI_VMI_Handle_T *handle);
737
738
739 /* Eager communication setup functions */
740 void CMI_VMI_Eager_Short_Setup (int sender_rank);
741 void CMI_VMI_Eager_Long_Setup (int sender_rank, int maxsize);
742
743
744 /* Send and receive handler functions */
745 VMI_RECV_STATUS CMI_VMI_Stream_Notification_Handler (PVMI_CONNECT connection, PVMI_STREAM_RECV stream, VMI_STREAM_COMMAND command, PVOID context, PVMI_SLAB slab);
746 void CMI_VMI_Stream_Completion_Handler (PVOID context, VMI_STATUS remote_status);
747
748 void CMI_VMI_RDMA_Publish_Notification_Handler (PVMI_CONNECT connection, PVMI_REMOTE_BUFFER remote_buffer, PVMI_SLAB publish_data, ULONG publish_data_size);
749 void CMI_VMI_RDMA_Publish_Completion_Handler (PVOID context, VMI_STATUS remote_status);
750
751 void CMI_VMI_RDMA_Put_Notification_Handler (PVMI_CONNECT connection, UINT32 rdma_size, UINT32 context, VMI_STATUS remote_status);
752 void CMI_VMI_RDMA_Put_Completion_Handler (PVMI_RDMA_OP rdmaop, PVOID context, VMI_STATUS remote_status);
753
754 void CMI_VMI_RDMA_Get_Notification_Handler (PVMI_CONNECT connection, UINT32 context, VMI_STATUS remote_status);
755 void CMI_VMI_RDMA_Get_Completion_Handler (PVMI_RDMA_OP rdmaop, PVOID context, VMI_STATUS remote_status);
756
757
758 /* Spanning tree send functions */
759 #if CMK_BROADCAST_SPANNING_TREE
760 int CMI_VMI_Spanning_Children_Count (char *msg);
761 void CMI_VMI_Send_Spanning_Children (int msgsize, char *msg);
762 #endif
763
764
765 /* Receive functions */
766 void CMI_VMI_Common_Receive ();
767
768 /*@}*/