idle callback should call generic AdvanceCommunication() instead of only LrtSAdvanceC...
[charm.git] / src / arch / gemini_gni / machine.c
1 /*****************************************************************************
2  * $Source$
3  * $Author$  Yanhua Sun
4  * $Date$  07-01-2011
5  * $Revision$ 
6  *****************************************************************************/
7
8 /** @file
9  * Gemini GNI machine layer
10  */
11 /*@{*/
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <stdint.h>
16 #include <errno.h>
17 #include <malloc.h>
18
19 #include "gni_pub.h"
20 #include "pmi.h"
21
22 #include "converse.h"
23
24 /*Support for ++debug: */
25 #if defined(_WIN32) && ! defined(__CYGWIN__)
26 #include <windows.h>
27 #include <wincon.h>
28 #include <sys/types.h>
29 #include <sys/timeb.h>
30
31 static void sleep(int secs) {
32     Sleep(1000*secs);
33 }
34 #else
35 #include <unistd.h> /*For getpid()*/
36 #endif
37
38
39 #define REMOTE_EVENT         0
40 #define USE_LRTS_MEMPOOL   1
41
42 #if USE_LRTS_MEMPOOL
43 static CmiInt8 _mempool_size = 1024ll*1024*32;
44 #endif
45
46 #define PRINT_SYH  0
47
48 int         rdma_id = 0;
49 #if PRINT_SYH
50 int         lrts_smsg_success = 0;
51 int         lrts_send_msg_id = 0;
52 int         lrts_send_rdma_success = 0;
53 int         lrts_received_msg = 0;
54 int         lrts_local_done_msg = 0;
55 #endif
56
57 #include "machine.h"
58
59 #include "pcqueue.h"
60
61 #if CMK_PERSISTENT_COMM
62 #include "machine-persistent.h"
63 #endif
64
65 //#define  USE_ONESIDED 1
66 #ifdef USE_ONESIDED
67 //onesided implementation is wrong, since no place to restore omdh
68 #include "onesided.h"
69 onesided_hnd_t   onesided_hnd;
70 onesided_md_t    omdh;
71 #define MEMORY_REGISTER(handler, nic_hndl, msg, size, mem_hndl, myomdh)  omdh. onesided_mem_register(handler, (uint64_t)msg, size, 0, myomdh) 
72
73 #define MEMORY_DEREGISTER(handler, nic_hndl, mem_hndl, myomdh) onesided_mem_deregister(handler, myomdh)
74
75 #else
76 uint8_t   onesided_hnd, omdh;
77 #if REMOTE_EVENT
78 #define  MEMORY_REGISTER(handler, nic_hndl, msg, size, mem_hndl, myomdh) GNI_MemRegister(nic_hndl, (uint64_t)msg,  (uint64_t)size, smsg_rx_cqh,  GNI_MEM_READWRITE, -1, mem_hndl)
79 #else
80 #define  MEMORY_REGISTER(handler, nic_hndl, msg, size, mem_hndl, myomdh) GNI_MemRegister(nic_hndl, (uint64_t)msg,  (uint64_t)size, NULL,  GNI_MEM_READWRITE, -1, mem_hndl)
81 #endif
82 #define  MEMORY_DEREGISTER(handler, nic_hndl, mem_hndl, myomdh)  GNI_MemDeregister(nic_hndl, (mem_hndl))
83 #endif
84
85 #define CmiGetMsgSize(m)  ((CmiMsgHeaderExt*)m)->size
86 #define CmiSetMsgSize(m,s)  ((((CmiMsgHeaderExt*)m)->size)=(s))
87
88 #define ALIGNBUF                64
89
90 /* =======Beginning of Definitions of Performance-Specific Macros =======*/
91 /* If SMSG is not used */
92 #define FMA_PER_CORE  1024
93 #define FMA_BUFFER_SIZE 1024
94 /* If SMSG is used */
95 static int  SMSG_MAX_MSG;
96 //static int  log2_SMSG_MAX_MSG;
97 #define SMSG_MAX_CREDIT  36
98
99 #define MSGQ_MAXSIZE       2048
100 /* large message transfer with FMA or BTE */
101 #define LRTS_GNI_RDMA_THRESHOLD  2048
102 #define LRTS_GNI_RDMA_PUT_THRESHOLD  2048
103
104 #define REMOTE_QUEUE_ENTRIES  2048 
105 #define LOCAL_QUEUE_ENTRIES   64 
106
107 #define PUT_DONE_TAG      0x29
108 #define ACK_TAG           0x30
109 /* SMSG is data message */
110 #define SMALL_DATA_TAG          0x31
111 /* SMSG is a control message to initialize a BTE */
112 #define MEDIUM_HEAD_TAG         0x32
113 #define MEDIUM_DATA_TAG         0x33
114 #define LMSG_INIT_TAG     0x39 
115
116 #define DEBUG
117 #ifdef GNI_RC_CHECK
118 #undef GNI_RC_CHECK
119 #endif
120 #ifdef DEBUG
121 #define GNI_RC_CHECK(msg,rc) do { if(rc != GNI_RC_SUCCESS) {           CmiPrintf("[%d] %s; err=%s\n",CmiMyPe(),msg,gni_err_str[rc]); CmiAbort("GNI_RC_CHECK"); } } while(0)
122 #else
123 #define GNI_RC_CHECK(msg,rc)
124 #endif
125
126 #define ALIGN64(x)       (size_t)((~63)&((x)+63))
127 #define ALIGN4(x)        (size_t)((~3)&((x)+3)) 
128
129 static int Mempool_MaxSize = 1024*1024*128;
130
131 #define     useDynamicSMSG    0
132 //static int useDynamicSMSG   = 1;
133 static int useStaticMSGQ = 0;
134 static int useStaticFMA = 0;
135 static int mysize, myrank;
136 static gni_nic_handle_t      nic_hndl;
137
138 typedef struct {
139     gni_mem_handle_t mdh;
140     uint64_t addr;
141 } mdh_addr_t ;
142 // this is related to dynamic SMSG
143
144 typedef struct mdh_addr_list{
145     gni_mem_handle_t mdh;
146    void *addr;
147     struct mdh_addr_list *next;
148 }mdh_addr_list_t;
149
150 static unsigned int         smsg_memlen;
151 #define     SMSG_CONN_SIZE     sizeof(gni_smsg_attr_t)
152 gni_smsg_attr_t    **smsg_local_attr_vec = 0;
153 int                 *smsg_connected_flag= 0;
154 char                *smsg_connection_addr = 0;
155 mdh_addr_t          setup_mem;
156 mdh_addr_t          *smsg_connection_vec = 0;
157 gni_mem_handle_t    smsg_connection_memhndl;
158 static int          smsg_expand_slots = 10;
159 static int          smsg_available_slot = 0;
160 static void         *smsg_mailbox_mempool = 0;
161 mdh_addr_list_t     *smsg_dynamic_list = 0;
162
163 static void             *smsg_mailbox_base;
164 gni_msgq_attr_t         msgq_attrs;
165 gni_msgq_handle_t       msgq_handle;
166 gni_msgq_ep_attr_t      msgq_ep_attrs;
167 gni_msgq_ep_attr_t      msgq_ep_attrs_size;
168
169
170
171 /* preallocated DMA buffer */
172 int                     DMA_slots;
173 uint64_t                DMA_avail_tag = 0;
174 uint32_t                DMA_incoming_avail_tag = 0;
175 uint32_t                DMA_outgoing_avail_tag = 0;
176 void                    *DMA_incoming_base_addr;
177 void                    *DMA_outgoing_base_addr;
178 mdh_addr_t              DMA_buffer_base_mdh_addr;
179 mdh_addr_t              *DMA_buffer_base_mdh_addr_vec;
180 int                     DMA_buffer_size;
181 int                     DMA_max_single_msg = 131072;//524288 ;
182
183 #define                 DMA_SIZE_PER_SLOT       8192
184
185
186 typedef struct dma_msgid_map
187 {
188     uint64_t     msg_id;
189     int     msg_subid
190 } dma_msgid_map_t;
191
192 dma_msgid_map_t         *dma_map_list;
193
194 typedef struct msg_trace
195 {
196     uint64_t    msg_id;
197     int         done_num;
198 }msg_trace_t;
199
200 msg_trace_t             *pending_msg_list;
201 /* =====Beginning of Declarations of Machine Specific Variables===== */
202 static int cookie;
203 static int modes = 0;
204 static gni_cq_handle_t       smsg_rx_cqh = NULL;
205 static gni_cq_handle_t       smsg_tx_cqh = NULL;
206 static gni_cq_handle_t       post_rx_cqh = NULL;
207 static gni_cq_handle_t       post_tx_cqh = NULL;
208 static gni_ep_handle_t       *ep_hndl_array;
209
210 typedef    struct  pending_smg
211 {
212     int     inst_id;
213     struct  pending_smg *next;
214 } PENDING_GETNEXT;
215
216
217 typedef struct msg_list
218 {
219     uint32_t destNode;
220     uint32_t size;
221     void *msg;
222     struct msg_list *next;
223     struct msg_list *pehead_next;
224     uint8_t tag;
225 }MSG_LIST;
226
227 typedef struct medium_msg_list
228 {
229     uint32_t destNode;
230     uint32_t msg_id;
231     uint32_t msg_subid;
232     uint32_t remain_size;
233     void *msg;
234     struct medium_msg_list *next;
235 }MEDIUM_MSG_LIST;
236
237
238 typedef struct control_msg
239 {
240     uint64_t            source_addr;
241     int                 source;               /* source rank */
242     int                 length;
243     gni_mem_handle_t    source_mem_hndl;
244     struct control_msg *next;
245 }CONTROL_MSG;
246
247 typedef struct medium_msg_control
248 {
249     uint64_t            dma_offset;     //the dma_buffer for this block of msg
250     int                 msg_id;         //Id for the total index
251     int                 msg_subid;      //offset inside the message id 
252 }MEDIUM_MSG_CONTROL;
253
254 typedef struct  rmda_msg
255 {
256     int                   destNode;
257     gni_post_descriptor_t *pd;
258     struct  rmda_msg      *next;
259 }RDMA_REQUEST;
260
261 typedef struct  msg_list_index
262 {
263     int         next;
264     MSG_LIST    *head;
265     MSG_LIST    *tail;
266 } MSG_LIST_INDEX;
267
268 /* reuse PendingMsg memory */
269 static CONTROL_MSG          *control_freelist=0;
270 static MSG_LIST             *msglist_freelist=0;
271 static int                  smsg_head_index;
272 static MSG_LIST_INDEX       *smsg_msglist_index= 0;
273 static MSG_LIST             *smsg_free_head=0;
274 static MSG_LIST             *smsg_free_tail=0;
275
276 /*
277 #define FreeMsgList(msg_head, msg_tail, free_head, free_tail)       \
278     if(free_head == 0)  free_head = free_tail = msg_head;    \
279     else   free_tail = free_tail->next;    \
280     if( msg_head->next == msg_tail) msg_head =0;   \
281     else msg_head= msg_head->next;    
282
283 #define MallocMsgList(d, msg_head, msg_tail, free_head, free_tail, msgsize) \
284     if(free_head == 0) {d= malloc(msgsize);  \
285         if(msg_head == 0)   msg_head =msg_tail = msg_head->next = msg_tail->next = d; \
286         else { msg_tail->next = d; d->next = msg_head; msg_tail=d;} \
287     }else {d = free_head; free_head = free_head->next; if(free_tail->next == free_head) free_head =0;} \
288 */
289
290 #define FreeMsgList(d)  \
291   (d)->next = msglist_freelist;\
292   msglist_freelist = d;
293
294
295
296 #define MallocMsgList(d) \
297   d = msglist_freelist;\
298   if (d==0) {d = ((MSG_LIST*)malloc(sizeof(MSG_LIST)));\
299              _MEMCHECK(d);\
300   } else msglist_freelist = d->next;
301
302
303 #define FreeControlMsg(d)       \
304   (d)->next = control_freelist;\
305   control_freelist = d;
306
307 #define MallocControlMsg(d) \
308   d = control_freelist;\
309   if (d==0) {d = ((CONTROL_MSG*)malloc(sizeof(CONTROL_MSG)));\
310              _MEMCHECK(d);\
311   } else control_freelist = d->next;
312
313
314 static RDMA_REQUEST         *rdma_freelist = NULL;
315
316 #define FreeControlMsg(d)       \
317   (d)->next = control_freelist;\
318   control_freelist = d;
319
320 #define MallocControlMsg(d) \
321   d = control_freelist;\
322   if (d==0) {d = ((CONTROL_MSG*)malloc(sizeof(CONTROL_MSG)));\
323              _MEMCHECK(d);\
324   } else control_freelist = d->next;
325
326 #define FreeMediumControlMsg(d)       \
327   (d)->next = medium_control_freelist;\
328   medium_control_freelist = d;
329
330
331 #define MallocMediumControlMsg(d) \
332     d = medium_control_freelist;\
333     if (d==0) {d = ((MEDIUM_MSG_CONTROL*)malloc(sizeof(MEDIUM_MSG_CONTROL)));\
334     _MEMCHECK(d);\
335 } else mediumcontrol_freelist = d->next;
336
337 #define FreeRdmaRequest(d)       \
338   (d)->next = rdma_freelist;\
339   rdma_freelist = d;
340
341 #define MallocRdmaRequest(d) \
342   d = rdma_freelist;\
343   if (d==0) {d = ((RDMA_REQUEST*)malloc(sizeof(RDMA_REQUEST)));\
344              _MEMCHECK(d);\
345   } else rdma_freelist = d->next;
346
347 /* reuse gni_post_descriptor_t */
348 static gni_post_descriptor_t *post_freelist=0;
349
350 #if 1
351 #define FreePostDesc(d)       \
352     (d)->next_descr = post_freelist;\
353     post_freelist = d;
354
355 #define MallocPostDesc(d) \
356   d = post_freelist;\
357   if (d==0) { \
358      d = ((gni_post_descriptor_t*)malloc(sizeof(gni_post_descriptor_t)));\
359      _MEMCHECK(d);\
360   } else post_freelist = d->next_descr;
361 #else
362
363 #define FreePostDesc(d)     free(d);
364 #define MallocPostDesc(d)   d = ((gni_post_descriptor_t*)malloc(sizeof(gni_post_descriptor_t))); _MEMCHECK(d);
365
366 #endif
367
368 static PENDING_GETNEXT     *pending_smsg_head = 0;
369 static PENDING_GETNEXT     *pending_smsg_tail = 0;
370
371 /* LrtsSent is called but message can not be sent by SMSGSend because of mailbox full or no credit */
372 static int      buffered_smsg_counter = 0;
373
374 /* SmsgSend return success but message sent is not confirmed by remote side */
375 static RDMA_REQUEST  *pending_smsg_conn_head = 0;
376 static RDMA_REQUEST  *pending_smsg_conn_tail = 0;
377
378 static RDMA_REQUEST  *pending_rdma_head = 0;
379 static RDMA_REQUEST  *pending_rdma_tail = 0;
380 static MSG_LIST *buffered_fma_head = 0;
381 static MSG_LIST *buffered_fma_tail = 0;
382
383 /* functions  */
384 #define IsFree(a,ind)  !( a& (1<<(ind) ))
385 #define SET_BITS(a,ind) a = ( a | (1<<(ind )) )
386 #define Reset(a,ind) a = ( a & (~(1<<(ind))) )
387
388 #include "mempool.c"
389
390 /* get the upper bound of log 2 */
391 int mylog2(int size)
392 {
393     int op = size;
394     unsigned int ret=0;
395     unsigned int mask = 0;
396     int i;
397     while(op>0)
398     {
399         op = op >> 1;
400         ret++;
401
402     }
403     for(i=1; i<ret; i++)
404     {
405         mask = mask << 1;
406         mask +=1;
407     }
408
409     ret -= ((size &mask) ? 0:1);
410     return ret;
411 }
412
413 static void
414 allgather(void *in,void *out, int len)
415 {
416     static int *ivec_ptr=NULL,already_called=0,job_size=0;
417     int i,rc;
418     int my_rank;
419     char *tmp_buf,*out_ptr;
420
421     if(!already_called) {
422
423         rc = PMI_Get_size(&job_size);
424         CmiAssert(rc == PMI_SUCCESS);
425         rc = PMI_Get_rank(&my_rank);
426         CmiAssert(rc == PMI_SUCCESS);
427
428         ivec_ptr = (int *)malloc(sizeof(int) * job_size);
429         CmiAssert(ivec_ptr != NULL);
430
431         rc = PMI_Allgather(&my_rank,ivec_ptr,sizeof(int));
432         CmiAssert(rc == PMI_SUCCESS);
433
434         already_called = 1;
435
436     }
437
438     tmp_buf = (char *)malloc(job_size * len);
439     CmiAssert(tmp_buf);
440
441     rc = PMI_Allgather(in,tmp_buf,len);
442     CmiAssert(rc == PMI_SUCCESS);
443
444     out_ptr = out;
445
446     for(i=0;i<job_size;i++) {
447
448         memcpy(&out_ptr[len * ivec_ptr[i]],&tmp_buf[i * len],len);
449
450     }
451
452     free(tmp_buf);
453 }
454 static void
455 allgather_2(void *in,void *out, int len)
456 {
457     //PMI_Allgather is out of order
458     int i,rc, extend_len;
459     int  rank_index;
460     char *out_ptr, *out_ref;
461     char *in2;
462
463     extend_len = sizeof(int) + len;
464     in2 = (char*)malloc(extend_len);
465
466     memcpy(in2, &myrank, sizeof(int));
467     memcpy(in2+sizeof(int), in, len);
468
469     out_ptr = (char*)malloc(mysize*extend_len);
470
471     rc = PMI_Allgather(in2, out_ptr, extend_len);
472     GNI_RC_CHECK("allgather", rc);
473
474     out_ref = out;
475
476     for(i=0;i<mysize;i++) {
477         //rank index 
478         memcpy(&rank_index, &(out_ptr[extend_len*i]), sizeof(int));
479         //copy to the rank index slot
480         memcpy(&out_ref[rank_index*len], &out_ptr[extend_len*i+sizeof(int)], len);
481     }
482
483     free(out_ptr);
484     free(in2);
485
486 }
487
488 static unsigned int get_gni_nic_address(int device_id)
489 {
490     unsigned int address, cpu_id;
491     gni_return_t status;
492     int i, alps_dev_id=-1,alps_address=-1;
493     char *token, *p_ptr;
494
495     p_ptr = getenv("PMI_GNI_DEV_ID");
496     if (!p_ptr) {
497         status = GNI_CdmGetNicAddress(device_id, &address, &cpu_id);
498        
499         GNI_RC_CHECK("GNI_CdmGetNicAddress", status);
500     } else {
501         while ((token = strtok(p_ptr,":")) != NULL) {
502             alps_dev_id = atoi(token);
503             if (alps_dev_id == device_id) {
504                 break;
505             }
506             p_ptr = NULL;
507         }
508         CmiAssert(alps_dev_id != -1);
509         p_ptr = getenv("PMI_GNI_LOC_ADDR");
510         CmiAssert(p_ptr != NULL);
511         i = 0;
512         while ((token = strtok(p_ptr,":")) != NULL) {
513             if (i == alps_dev_id) {
514                 alps_address = atoi(token);
515                 break;
516             }
517             p_ptr = NULL;
518             ++i;
519         }
520         CmiAssert(alps_address != -1);
521         address = alps_address;
522     }
523     return address;
524 }
525
526 static uint8_t get_ptag(void)
527 {
528     char *p_ptr, *token;
529     uint8_t ptag;
530
531     p_ptr = getenv("PMI_GNI_PTAG");
532     CmiAssert(p_ptr != NULL);
533     token = strtok(p_ptr, ":");
534     ptag = (uint8_t)atoi(token);
535     return ptag;
536         
537 }
538
539 static uint32_t get_cookie(void)
540 {
541     uint32_t cookie;
542     char *p_ptr, *token;
543
544     p_ptr = getenv("PMI_GNI_COOKIE");
545     CmiAssert(p_ptr != NULL);
546     token = strtok(p_ptr, ":");
547     cookie = (uint32_t)atoi(token);
548
549     return cookie;
550 }
551
552 /* =====Beginning of Definitions of Message-Corruption Related Macros=====*/
553 /* TODO: add any that are related */
554 /* =====End of Definitions of Message-Corruption Related Macros=====*/
555
556
557 #include "machine-lrts.h"
558 #include "machine-common-core.c"
559
560 /* Network progress function is used to poll the network when for
561    messages. This flushes receive buffers on some  implementations*/
562 #if CMK_MACHINE_PROGRESS_DEFINED
563 void CmiMachineProgressImpl() {
564 }
565 #endif
566
567 inline
568 static void delay_send_small_msg(void *msg, int size, int destNode, uint8_t tag)
569 {
570     MSG_LIST        *msg_tmp;
571     MallocMsgList(msg_tmp);
572     msg_tmp->destNode = destNode;
573     msg_tmp->size   = size;
574     msg_tmp->msg    = msg;
575     msg_tmp->tag    = tag;
576     msg_tmp->next   = 0;
577     if (smsg_msglist_index[destNode].head == 0 ) {
578         smsg_msglist_index[destNode].head = msg_tmp;
579         smsg_msglist_index[destNode].next = smsg_head_index;
580         smsg_head_index = destNode;
581     }
582     else {
583       (smsg_msglist_index[destNode].tail)->next    = msg_tmp;
584     }
585     smsg_msglist_index[destNode].tail          = msg_tmp;
586 #if PRINT_SYH
587     buffered_smsg_counter++;
588 #endif
589 }
590
591 inline static void print_smsg_attr(gni_smsg_attr_t     *a)
592 {
593     CmiPrintf("type=%d\n, credit=%d\n, size=%d\n, buf=%p, offset=%d\n", a->msg_type, a->mbox_maxcredit, a->buff_size, a->msg_buffer, a->mbox_offset);
594 }
595
596 inline
597 static void setup_smsg_connection(int destNode)
598 {
599     mdh_addr_list_t  *new_entry = 0;
600     gni_post_descriptor_t *pd;
601     gni_smsg_attr_t      *smsg_attr;
602     gni_return_t status = GNI_RC_NOT_DONE;
603     RDMA_REQUEST        *rdma_request_msg;
604     
605     if(smsg_available_slot == smsg_expand_slots)
606     {
607         new_entry = (mdh_addr_list_t*)malloc(sizeof(mdh_addr_list_t));
608         new_entry->addr = memalign(64, smsg_memlen*smsg_expand_slots);
609         bzero(new_entry->addr, smsg_memlen*smsg_expand_slots);
610
611         status = GNI_MemRegister(nic_hndl, (uint64_t)new_entry->addr,
612             smsg_memlen*smsg_expand_slots, smsg_rx_cqh,
613             GNI_MEM_READWRITE,   
614             -1,
615             &(new_entry->mdh));
616         smsg_available_slot = 0; 
617         new_entry->next = smsg_dynamic_list;
618         smsg_dynamic_list = new_entry;
619     }
620     smsg_attr = (gni_smsg_attr_t*) malloc (sizeof(gni_smsg_attr_t));
621     smsg_attr->msg_type = GNI_SMSG_TYPE_MBOX_AUTO_RETRANSMIT;
622     smsg_attr->mbox_maxcredit = SMSG_MAX_CREDIT;
623     smsg_attr->msg_maxsize = SMSG_MAX_MSG;
624     smsg_attr->mbox_offset = smsg_available_slot * smsg_memlen;
625     smsg_attr->buff_size = smsg_memlen;
626     smsg_attr->msg_buffer = smsg_dynamic_list->addr;
627     smsg_attr->mem_hndl = smsg_dynamic_list->mdh;
628     smsg_local_attr_vec[destNode] = smsg_attr;
629     smsg_available_slot++;
630     MallocPostDesc(pd);
631     pd->type            = GNI_POST_FMA_PUT;
632     pd->cq_mode         = GNI_CQMODE_GLOBAL_EVENT |  GNI_CQMODE_REMOTE_EVENT;
633     pd->dlvr_mode       = GNI_DLVMODE_PERFORMANCE;
634     pd->length          = sizeof(gni_smsg_attr_t);
635     pd->local_addr      = (uint64_t) smsg_attr;
636     pd->remote_addr     = (uint64_t)&((((gni_smsg_attr_t*)(smsg_connection_vec[destNode].addr))[myrank]));
637     pd->remote_mem_hndl = smsg_connection_vec[destNode].mdh;
638     pd->src_cq_hndl     = 0;
639     pd->rdma_mode       = 0;
640     status = GNI_PostFma(ep_hndl_array[destNode],  pd);
641     print_smsg_attr(smsg_attr);
642     if(status == GNI_RC_ERROR_RESOURCE )
643     {
644         MallocRdmaRequest(rdma_request_msg);
645         rdma_request_msg->next = 0;
646         rdma_request_msg->destNode = destNode;
647         rdma_request_msg->pd = pd;
648         if(pending_smsg_conn_head== 0)
649         {
650             pending_smsg_conn_head  = rdma_request_msg;
651         }else
652         {
653             pending_smsg_conn_tail->next = rdma_request_msg;
654         }
655         pending_smsg_conn_tail = rdma_request_msg;
656
657     }
658     if(status != GNI_RC_SUCCESS)
659        CmiPrintf("[%d=%d] send post FMA %s\n", myrank, destNode, gni_err_str[status]);
660     else
661         CmiPrintf("[%d=%d]OK send post FMA \n", myrank, destNode);
662     //GNI_RC_CHECK("SMSG Dynamic link", status);
663 }
664
665 inline 
666 static gni_return_t send_smsg_message(int destNode, void *header, int size_header, void *msg, int size, uint8_t tag, int inbuff )
667 {
668     gni_return_t status = GNI_RC_NOT_DONE;
669     gni_smsg_attr_t      *smsg_attr;
670     gni_post_descriptor_t *pd;
671  
672 #if useDynamicSMSG
673     //if(useDynamicSMSG == 1)
674     {
675         if(smsg_connected_flag[destNode] == 0)
676         {
677             //CmiPrintf("[%d]Init smsg connection\n", CmiMyPe());
678             setup_smsg_connection(destNode);
679             delay_send_small_msg(msg, size, destNode, tag);
680             smsg_connected_flag[destNode] =10;
681             return status;
682         }
683         else  if(smsg_connected_flag[destNode] <20)
684         {
685             if(inbuff == 0)
686                 delay_send_small_msg(msg, size, destNode, tag);
687             return status;
688         }
689     }
690 #endif
691     //CmiPrintf("[%d] reach send\n", myrank);
692     if(smsg_msglist_index[destNode].head == 0 || inbuff==1)
693     {
694         status = GNI_SmsgSendWTag(ep_hndl_array[destNode], header, size_header, msg, size, 0, tag);
695         if(status == GNI_RC_SUCCESS)
696         {
697 #if PRINT_SYH
698             lrts_smsg_success++;
699             if(lrts_smsg_success == lrts_send_msg_id)
700                 CmiPrintf("GOOD [%d==>%d] sent done%d (msgs=%d)\n", myrank, destNode, lrts_smsg_success, lrts_send_msg_id);
701             else
702                 CmiPrintf("BAD [%d==>%d] sent done%d (msgs=%d)\n", myrank, destNode, lrts_smsg_success, lrts_send_msg_id);
703 #endif
704             return status;
705         }
706     }
707     if(inbuff ==0)
708         delay_send_small_msg(msg, size, destNode, tag);
709     return status;
710 }
711
712 // Get first 0 in DMA_tags starting from index
713 static int get_first_avail_bit(uint64_t DMA_tags, int start_index)
714 {
715
716     uint64_t         mask = 0x1;
717     register    int     i=0;
718     while((DMA_tags & mask) && i<DMA_slots) {mask << 1; i++;}
719
720 }
721
722 static int send_medium_messages(int destNode, int size, char *msg)
723 {
724 #if 0
725     gni_return_t status = GNI_RC_SUCCESS;
726     int first_avail_bit=0;
727     uint64_t mask = 0x1;
728     MEDIUM_MSG_CONTROL  *medium_msg_control_tmp;
729     MEDIUM_MSG_LIST        *msg_tmp;
730     int blocksize, remain_size, pos;
731     int sub_id = 0;
732     remain_size = size;
733     pos = 0;  //offset before which data are sent
734     /* copy blocks of the message to DMA preallocated buffer and send SMSG */
735     //Check whether there is any available DMA buffer
736     
737     do{
738         while((DMA_avail_tag & mask) && first_avail_bit<DMA_slots) {mask << 1; first_avail_bit++;}
739         if(first_avail_bit == DMA_slots) //No available DMA, buffer this message
740         {
741             MallocMediumMsgList(msg_tmp);
742             msg_tmp->destNode = destNode;
743             msg_tmp->msg_id   = lrts_send_msg_id;
744             msg_tmp->msg_subid   = sub_id;
745             msg_tmp->size   = remain_size;
746             msg_tmp->msg    = msg+pos;
747             msg_tmp->next   = NULL;
748             break;
749         }else
750         {
751             //copy this part of the message into this DMA buffer
752             //TODO optimize here, some data can go with this SMSG
753             blocksize = (remain_size>DMA_SIZE_PER_SLOT)?DMA_SIZE_PER_SLOT: remain_size;
754             memcpy(DMA_buffer_base_mdh_addr.addr[first_avail_bit], msg+pos, blocksize);
755             pos += blocksize;
756             remain_size -= blocksize;
757             SET_BITS(DMA_avail_tag, first_avail_bit);
758            
759             MallocMediumControlMsg(medium_msg_control_tmp);
760             medium_msg_control_tmp->msg_id = lrts_send_msg_id;
761             medium_msg_control_tmp->msg_subid = sub_id;
762             if(status == GNI_RC_SUCCESS)
763             {
764                 if(sub_id==0)
765                     status = GNI_SmsgSendWTag(ep_hndl_array[destNode], NULL, 0, medium_msg_tmp, sizeof(MEDIUM_MSG_CONTROL), 0, MEDIUM_HEAD_TAG);
766                 else
767                     status = GNI_SmsgSendWTag(ep_hndl_array[destNode], NULL, 0, medium_msg_tmp, sizeof(MEDIUM_MSG_CONTROL), 0, MEDIUM_DATA_TAG);
768             }
769             //buffer this smsg
770             if(status != GNI_RC_SUCCESS)
771             {
772                 delay_send_small_msg(medium_msg_tmp, sizeof(MEDIUM_MSG_CONTROL), destNode, MEDIUM_HEAD_TAG);
773             }
774             sub_id++;
775         }while(remain_size > 0 );
776
777         }
778     }
779 #endif
780 }
781
782 // Large message, send control to receiver, receiver register memory and do a GET 
783 inline
784 static void send_large_messages(int destNode, int size, char *msg)
785 {
786 #if     USE_LRTS_MEMPOOL
787     gni_return_t        status  =   GNI_RC_SUCCESS;
788     CONTROL_MSG         *control_msg_tmp;
789     uint32_t            vmdh_index  = -1;
790     /* construct a control message and send */
791     MallocControlMsg(control_msg_tmp);
792     control_msg_tmp->source_addr    = (uint64_t)msg;
793     control_msg_tmp->source         = myrank;
794     control_msg_tmp->length         =ALIGN4(size); //for GET 4 bytes aligned 
795     //memcpy( &(control_msg_tmp->source_mem_hndl), GetMemHndl(msg), sizeof(gni_mem_handle_t)) ;
796     control_msg_tmp->source_mem_hndl = GetMemHndl(msg);
797 #if PRINT_SYH
798     lrts_send_msg_id++;
799     CmiPrintf("Large LrtsSend PE:%d==>%d, size=%d, messageid:%d LMSG\n", myrank, destNode, size, lrts_send_msg_id);
800 #endif
801     status = send_smsg_message( destNode, 0, 0, control_msg_tmp, sizeof(CONTROL_MSG), LMSG_INIT_TAG, 0);  
802     if(status == GNI_RC_SUCCESS)
803     {
804         FreeControlMsg(control_msg_tmp);
805     }
806 // NOT use mempool, should slow 
807 #else
808     gni_return_t        status  =   GNI_RC_SUCCESS;
809     CONTROL_MSG         *control_msg_tmp;
810     uint32_t            vmdh_index  = -1;
811     /* construct a control message and send */
812     MallocControlMsg(control_msg_tmp);
813     control_msg_tmp->source_addr    = (uint64_t)msg;
814     control_msg_tmp->source         = myrank;
815     control_msg_tmp->length         =ALIGN4(size); //for GET 4 bytes aligned 
816     control_msg_tmp->source_mem_hndl.qword1 = 0;
817     control_msg_tmp->source_mem_hndl.qword2 = 0;
818 #if PRINT_SYH
819     lrts_send_msg_id++;
820     CmiPrintf("Large LrtsSend PE:%d==>%d, size=%d, messageid:%d LMSG\n", myrank, destNode, size, lrts_send_msg_id);
821 #endif
822     status = MEMORY_REGISTER(onesided_hnd, nic_hndl,msg, ALIGN4(size), &(control_msg_tmp->source_mem_hndl), &omdh);
823     if(status == GNI_RC_SUCCESS)
824     {
825         status = send_smsg_message( destNode, 0, 0, control_msg_tmp, sizeof(CONTROL_MSG), LMSG_INIT_TAG, 0);  
826         if(status == GNI_RC_SUCCESS)
827         {
828             FreeControlMsg(control_msg_tmp);
829         }
830     } else if (status == GNI_RC_INVALID_PARAM || status == GNI_RC_PERMISSION_ERROR)
831     {
832         CmiAbort("Memory registor for large msg\n");
833     }else 
834     {
835         delay_send_small_msg(control_msg_tmp, sizeof(CONTROL_MSG), destNode, LMSG_INIT_TAG);
836     }
837 #endif
838 }
839
840 inline void LrtsPrepareEnvelope(char *msg, int size)
841 {
842     CmiSetMsgSize(msg, size);
843 }
844
845 static CmiCommHandle LrtsSendFunc(int destNode, int size, char *msg, int mode)
846 {
847     gni_return_t        status  =   GNI_RC_SUCCESS;
848     LrtsPrepareEnvelope(msg, size);
849
850     if(size <= SMSG_MAX_MSG)
851     {
852 #if PRINT_SYH
853         lrts_send_msg_id++;
854         CmiPrintf("SMSG LrtsSend PE:%d==>%d, size=%d, messageid:%d\n", myrank, destNode, size, lrts_send_msg_id);
855 #endif
856         status = send_smsg_message( destNode, 0, 0, msg, size, SMALL_DATA_TAG, 0);  
857         if(status == GNI_RC_SUCCESS)
858         {
859             CmiFree(msg);
860         }
861     }
862     else
863     {
864         send_large_messages(destNode, size, msg);
865     }
866     return 0;
867 }
868
869 static void LrtsPreCommonInit(int everReturn){}
870
871 /* Idle-state related functions: called in non-smp mode */
872 void CmiNotifyIdleForGemini(void) {
873     AdvanceCommunication();
874     //LrtsAdvanceCommunication();
875 }
876
877 static void LrtsPostCommonInit(int everReturn)
878 {
879 #if CMK_SMP
880     CmiIdleState *s=CmiNotifyGetState();
881     CcdCallOnConditionKeep(CcdPROCESSOR_BEGIN_IDLE,(CcdVoidFn)CmiNotifyBeginIdle,(void *)s);
882     CcdCallOnConditionKeep(CcdPROCESSOR_STILL_IDLE,(CcdVoidFn)CmiNotifyStillIdle,(void *)s);
883 #else
884     CcdCallOnConditionKeep(CcdPROCESSOR_STILL_IDLE,(CcdVoidFn)CmiNotifyIdleForGemini,NULL);
885 #endif
886
887 }
888
889
890 void LrtsPostNonLocal(){}
891 /* pooling CQ to receive network message */
892 static void PumpNetworkRdmaMsgs()
893 {
894     gni_cq_entry_t      event_data;
895     gni_return_t        status;
896     while( (status = GNI_CqGetEvent(post_rx_cqh, &event_data)) == GNI_RC_SUCCESS);
897 }
898
899 static void SendRdmaMsg();
900 static void getLargeMsgRequest(void* header, uint64_t inst_id);
901 static void PumpNetworkSmsg()
902 {
903     uint64_t            inst_id;
904     PENDING_GETNEXT     *pending_next;
905     int                 ret;
906     gni_cq_entry_t      event_data;
907     gni_return_t        status;
908     void                *header;
909     uint8_t             msg_tag;
910     int                 msg_nbytes;
911     void                *msg_data;
912     gni_mem_handle_t    msg_mem_hndl;
913     gni_smsg_attr_t     *smsg_attr;
914     gni_smsg_attr_t     *remote_smsg_attr;
915     int                 init_flag;
916     while ((status =GNI_CqGetEvent(smsg_rx_cqh, &event_data)) == GNI_RC_SUCCESS)
917     {
918         inst_id = GNI_CQ_GET_INST_ID(event_data);
919         // GetEvent returns success but GetNext return not_done. caused by Smsg out-of-order transfer
920 #if PRINT_SYH
921         CmiPrintf("[%d] PumpNetworkMsgs small msgs is received from PE: %d,  status=%s\n", myrank, inst_id,  gni_err_str[status]);
922 #endif
923 #if     useDynamicSMSG
924         rdma_id++;
925      //   if(useDynamicSMSG == 1)
926         {
927             init_flag = smsg_connected_flag[inst_id];
928             //CmiPrintf("[%d] initflag=%d\n", myrank, init_flag);
929             if(init_flag == 0 )
930             {
931                 CmiPrintf("setup[%d==%d]pump Init smsg connection id=%d\n", myrank, inst_id, rdma_id);
932                 smsg_connected_flag[inst_id] =20;
933                 setup_smsg_connection(inst_id);
934                 remote_smsg_attr = &(((gni_smsg_attr_t*)(setup_mem.addr))[inst_id]);
935                 status = GNI_SmsgInit(ep_hndl_array[inst_id], smsg_local_attr_vec[inst_id],  remote_smsg_attr);
936                 GNI_RC_CHECK("no send SmsgInit", status);
937                 continue;
938             } else if (init_flag <20) 
939             {
940                 CmiPrintf("setup[%d==%d]pump setup smsg connection id=%d\n", myrank, inst_id, rdma_id);
941                 smsg_connected_flag[inst_id] = 20;
942                 remote_smsg_attr = &(((gni_smsg_attr_t*)(setup_mem.addr))[inst_id]);
943                 status = GNI_SmsgInit(ep_hndl_array[inst_id], smsg_local_attr_vec[inst_id],  remote_smsg_attr);
944                 print_smsg_attr(remote_smsg_attr);
945                 GNI_RC_CHECK("send once SmsgInit", status);
946                 continue;
947             }
948         }
949 #endif
950         msg_tag = GNI_SMSG_ANY_TAG;
951         while( (status = GNI_SmsgGetNextWTag(ep_hndl_array[inst_id], &header, &msg_tag)) == GNI_RC_SUCCESS)
952         {
953 #if PRINT_SYH
954             lrts_received_msg++;
955             CmiPrintf("+++[%d] PumpNetwork msg is received, messageid:%d tag=%d\n", myrank, lrts_received_msg, msg_tag);
956 #endif
957             /* copy msg out and then put into queue (small message) */
958             switch (msg_tag) {
959             case SMALL_DATA_TAG:
960             {
961                 msg_nbytes = CmiGetMsgSize(header);
962                 msg_data    = CmiAlloc(msg_nbytes);
963                 memcpy(msg_data, (char*)header, msg_nbytes);
964                 handleOneRecvedMsg(msg_nbytes, msg_data);
965                 break;
966             }
967             case LMSG_INIT_TAG:
968             {
969 #if PRINT_SYH
970                 CmiPrintf("+++[%d] from %d PumpNetwork Rdma Request msg is received, messageid:%d tag=%d\n", myrank, inst_id, lrts_received_msg, msg_tag);
971 #endif
972                 getLargeMsgRequest(header, inst_id);
973                 break;
974             }
975             case ACK_TAG:
976             {
977                 /* Get is done, release message . Now put is not used yet*/
978 #if         !USE_LRTS_MEMPOOL
979                 MEMORY_DEREGISTER(onesided_hnd, nic_hndl, &(((CONTROL_MSG *)header)->source_mem_hndl), &omdh);
980 #endif
981                 CmiFree((void*)((CONTROL_MSG *) header)->source_addr);
982                 SendRdmaMsg();
983                 break;
984             }
985 #if CMK_PERSISTENT_COMM
986             case PUT_DONE_TAG: //persistent message
987             {
988                 void *msg = (void *)((CONTROL_MSG *) header)->source_addr;
989                 int size = ((CONTROL_MSG *) header)->length;
990 #if 0
991                 void *dupmsg;
992                 dupmsg = CmiAlloc(size);
993                 _MEMCHECK(dupmsg);
994                 memcpy(dupmsg, msg, size);
995                 msg = dupmsg;
996
997 #else
998                 CmiReference(msg);
999 #endif
1000                 handleOneRecvedMsg(size, msg); 
1001                 break;
1002             }
1003 #endif
1004             default: {
1005                 CmiPrintf("weird tag problem\n");
1006                 CmiAbort("Unknown tag\n");
1007             }
1008             }
1009             GNI_SmsgRelease(ep_hndl_array[inst_id]);
1010             msg_tag = GNI_SMSG_ANY_TAG;
1011         } //endwhile getNext
1012     }   //end while GetEvent
1013     if(status == GNI_RC_ERROR_RESOURCE)
1014     {
1015         GNI_RC_CHECK("Smsg_rx_cq full", status);
1016     }
1017 }
1018
1019 static void getLargeMsgRequest(void* header, uint64_t inst_id)
1020 {
1021 #if     USE_LRTS_MEMPOOL
1022     CONTROL_MSG         *request_msg;
1023     gni_return_t        status;
1024     void                *msg_data;
1025     gni_post_descriptor_t *pd;
1026     RDMA_REQUEST        *rdma_request_msg;
1027     gni_mem_handle_t    msg_mem_hndl;
1028     int source;
1029     // initial a get to transfer data from the sender side */
1030     request_msg = (CONTROL_MSG *) header;
1031     source = request_msg->source;
1032     msg_data = CmiAlloc(request_msg->length);
1033     _MEMCHECK(msg_data);
1034     //memcpy(&msg_mem_hndl, GetMemHndl(msg_data), sizeof(gni_mem_handle_t));
1035     msg_mem_hndl = GetMemHndl(msg_data);
1036
1037     MallocPostDesc(pd);
1038     if(request_msg->length < LRTS_GNI_RDMA_THRESHOLD) 
1039         pd->type            = GNI_POST_FMA_GET;
1040     else
1041         pd->type            = GNI_POST_RDMA_GET;
1042 #if REMOTE_EVENT
1043     pd->cq_mode         = GNI_CQMODE_GLOBAL_EVENT |  GNI_CQMODE_REMOTE_EVENT;
1044 #else
1045     pd->cq_mode         = GNI_CQMODE_GLOBAL_EVENT;
1046 #endif
1047     pd->dlvr_mode       = GNI_DLVMODE_PERFORMANCE;
1048     pd->length          = ALIGN4(request_msg->length);
1049     pd->local_addr      = (uint64_t) msg_data;
1050     pd->local_mem_hndl  = msg_mem_hndl;
1051     pd->remote_addr     = request_msg->source_addr;
1052     pd->remote_mem_hndl = request_msg->source_mem_hndl;
1053     pd->src_cq_hndl     = 0;//post_tx_cqh;     /* smsg_tx_cqh;  */
1054     pd->rdma_mode       = 0;
1055
1056     if(pd->type == GNI_POST_RDMA_GET) 
1057         status = GNI_PostRdma(ep_hndl_array[source], pd);
1058     else
1059         status = GNI_PostFma(ep_hndl_array[source],  pd);
1060     if(status == GNI_RC_ERROR_RESOURCE|| status == GNI_RC_ERROR_NOMEM )
1061     {
1062         MallocRdmaRequest(rdma_request_msg);
1063         rdma_request_msg->next = 0;
1064         rdma_request_msg->destNode = inst_id;
1065         rdma_request_msg->pd = pd;
1066         if(pending_rdma_head == 0)
1067         {
1068             pending_rdma_head = rdma_request_msg;
1069         }else
1070         {
1071             pending_rdma_tail->next = rdma_request_msg;
1072         }
1073         pending_rdma_tail = rdma_request_msg;
1074     }else
1075         GNI_RC_CHECK("AFter posting", status);
1076
1077 #else
1078     CONTROL_MSG         *request_msg;
1079     gni_return_t        status;
1080     void                *msg_data;
1081     gni_post_descriptor_t *pd;
1082     RDMA_REQUEST        *rdma_request_msg;
1083     gni_mem_handle_t    msg_mem_hndl;
1084     int source;
1085     // initial a get to transfer data from the sender side */
1086     request_msg = (CONTROL_MSG *) header;
1087     source = request_msg->source;
1088     msg_data = CmiAlloc(request_msg->length);
1089     _MEMCHECK(msg_data);
1090
1091     status = MEMORY_REGISTER(onesided_hnd, nic_hndl, msg_data, request_msg->length, &msg_mem_hndl, &omdh);
1092
1093     if (status == GNI_RC_INVALID_PARAM || status == GNI_RC_PERMISSION_ERROR) 
1094     {
1095         GNI_RC_CHECK("Mem Register before post", status);
1096     }
1097
1098     MallocPostDesc(pd);
1099     if(request_msg->length < LRTS_GNI_RDMA_THRESHOLD) 
1100         pd->type            = GNI_POST_FMA_GET;
1101     else
1102         pd->type            = GNI_POST_RDMA_GET;
1103 #if REMOTE_EVENT
1104     pd->cq_mode         = GNI_CQMODE_GLOBAL_EVENT |  GNI_CQMODE_REMOTE_EVENT;
1105 #else
1106     pd->cq_mode         = GNI_CQMODE_GLOBAL_EVENT;
1107 #endif
1108     pd->dlvr_mode       = GNI_DLVMODE_PERFORMANCE;
1109     pd->length          = ALIGN4(request_msg->length);
1110     pd->local_addr      = (uint64_t) msg_data;
1111     pd->remote_addr     = request_msg->source_addr;
1112     pd->remote_mem_hndl = request_msg->source_mem_hndl;
1113     pd->src_cq_hndl     = 0;//post_tx_cqh;     /* smsg_tx_cqh;  */
1114     pd->rdma_mode       = 0;
1115
1116     //memory registration successful
1117     if(status == GNI_RC_SUCCESS)
1118     {
1119         pd->local_mem_hndl  = msg_mem_hndl;
1120         if(pd->type == GNI_POST_RDMA_GET) 
1121             status = GNI_PostRdma(ep_hndl_array[source], pd);
1122         else
1123             status = GNI_PostFma(ep_hndl_array[source],  pd);
1124     }else
1125     {
1126         pd->local_mem_hndl.qword1  = 0; 
1127         pd->local_mem_hndl.qword1  = 0; 
1128     }
1129     if(status == GNI_RC_ERROR_RESOURCE|| status == GNI_RC_ERROR_NOMEM )
1130     {
1131         MallocRdmaRequest(rdma_request_msg);
1132         rdma_request_msg->next = 0;
1133         rdma_request_msg->destNode = inst_id;
1134         rdma_request_msg->pd = pd;
1135         if(pending_rdma_head == 0)
1136         {
1137             pending_rdma_head = rdma_request_msg;
1138         }else
1139         {
1140             pending_rdma_tail->next = rdma_request_msg;
1141         }
1142         pending_rdma_tail = rdma_request_msg;
1143     }else
1144         GNI_RC_CHECK("AFter posting", status);
1145 #endif
1146 }
1147
1148 /* Check whether message send or get is confirmed by remote */
1149 static void PumpLocalSmsgTransactions()
1150 {
1151     gni_return_t            status;
1152     gni_cq_entry_t          ev;
1153     while ((status = GNI_CqGetEvent(smsg_tx_cqh, &ev)) == GNI_RC_SUCCESS)
1154     {
1155 #if PRINT_SYH
1156         lrts_local_done_msg++;
1157         //CmiPrintf("*[%d]  PumpLocalSmsgTransactions GNI_CQ_GET_TYPE %d. Localdone=%d\n", myrank, GNI_CQ_GET_TYPE(ev), lrts_local_done_msg);
1158 #endif
1159         if(GNI_CQ_OVERRUN(ev))
1160         {
1161             CmiPrintf("Overrun detected in local CQ");
1162             CmiAbort("Overrun in TX");
1163         }
1164     }
1165     if(status == GNI_RC_ERROR_RESOURCE)
1166     {
1167         GNI_RC_CHECK("Smsg_tx_cq full", status);
1168     }
1169 }
1170
1171 static void SendSmsgConnectMsg();
1172 static void PumpLocalRdmaTransactions()
1173 {
1174     gni_cq_entry_t          ev;
1175     gni_return_t            status;
1176     uint64_t                type, inst_id;
1177     gni_post_descriptor_t   *tmp_pd;
1178     MSG_LIST                *ptr;
1179     CONTROL_MSG             *ack_msg_tmp;
1180     uint8_t             msg_tag;
1181
1182    // while ( (status = GNI_CqGetEvent(post_tx_cqh, &ev)) == GNI_RC_SUCCESS) 
1183     while ( (status = GNI_CqGetEvent(smsg_tx_cqh, &ev)) == GNI_RC_SUCCESS) 
1184     {
1185         type        = GNI_CQ_GET_TYPE(ev);
1186 #if PRINT_SYH
1187         //lrts_local_done_msg++;
1188         CmiPrintf("**[%d] SMSGPumpLocalTransactions (type=%d)\n", myrank, type);
1189 #endif
1190         if (type == GNI_CQ_EVENT_TYPE_POST)
1191         {
1192             inst_id     = GNI_CQ_GET_INST_ID(ev);
1193 #if PRINT_SYH
1194             CmiPrintf("**[%d] SMSGPumpLocalTransactions localdone=%d, %d\n", myrank,  lrts_local_done_msg, smsg_connected_flag[inst_id]);
1195 #endif
1196             //status = GNI_GetCompleted(post_tx_cqh, ev, &tmp_pd);
1197             status = GNI_GetCompleted(smsg_tx_cqh, ev, &tmp_pd);
1198             ////Message is sent, free message , put is not used now
1199             switch (tmp_pd->type) {
1200 #if CMK_PERSISTENT_COMM
1201             case GNI_POST_RDMA_PUT:
1202             case GNI_POST_FMA_PUT:
1203 #if useDynamicSMSG
1204                 SendSmsgConnectMsg();
1205                 if(tmp_pd->length == sizeof(gni_smsg_attr_t))
1206                     continue;
1207 #endif
1208                 CmiFree((void *)tmp_pd->local_addr);
1209                 msg_tag = PUT_DONE_TAG;
1210                 break;
1211 #endif
1212             case GNI_POST_RDMA_GET:
1213             case GNI_POST_FMA_GET:
1214                 msg_tag = ACK_TAG;  
1215                 break;
1216             default:
1217                 CmiAbort("PumpLocalRdmaTransactions: unknown type!");
1218             }
1219
1220             MallocControlMsg(ack_msg_tmp);
1221             ack_msg_tmp->source             = myrank;
1222             ack_msg_tmp->source_addr        = tmp_pd->remote_addr;
1223             ack_msg_tmp->length             = tmp_pd->length; 
1224             ack_msg_tmp->source_mem_hndl    = tmp_pd->remote_mem_hndl;
1225 #if PRINT_SYH
1226             lrts_send_msg_id++;
1227             CmiPrintf("ACK LrtsSend PE:%d==>%d, size=%d, messageid:%d ACK\n", myrank, inst_id, sizeof(CONTROL_MSG), lrts_send_msg_id);
1228 #endif
1229             status = send_smsg_message(inst_id, 0, 0, ack_msg_tmp, sizeof(CONTROL_MSG), msg_tag, 0);  
1230             if(status == GNI_RC_SUCCESS)
1231             {
1232                 FreeControlMsg(ack_msg_tmp);
1233             }
1234 #if     !USE_LRTS_MEMPOOL
1235             MEMORY_DEREGISTER(onesided_hnd, nic_hndl, &tmp_pd->local_mem_hndl, &omdh);
1236 #endif
1237 #if CMK_PERSISTENT_COMM
1238             if (tmp_pd->type == GNI_POST_RDMA_GET || tmp_pd->type == GNI_POST_FMA_GET)
1239 #endif
1240             {
1241               CmiAssert(SIZEFIELD((void*)(tmp_pd->local_addr)) <= tmp_pd->length);
1242               handleOneRecvedMsg(tmp_pd->length, (void*)tmp_pd->local_addr); 
1243               SendRdmaMsg(); 
1244             }
1245             FreePostDesc(tmp_pd);
1246         }
1247     } //end while
1248 }
1249
1250 static void SendSmsgConnectMsg()
1251 {
1252     gni_return_t            status = GNI_RC_SUCCESS;
1253     gni_mem_handle_t        msg_mem_hndl;
1254
1255     RDMA_REQUEST *ptr = pending_smsg_conn_head;
1256     RDMA_REQUEST *prev = NULL;
1257
1258     while (ptr != NULL)
1259     {
1260         gni_post_descriptor_t *pd = ptr->pd;
1261         status = GNI_RC_SUCCESS;
1262         status = GNI_PostFma(ep_hndl_array[ptr->destNode], pd);
1263         if(status == GNI_RC_SUCCESS)
1264         {
1265             RDMA_REQUEST *tmp = ptr;
1266             if (prev)
1267                 prev->next = ptr->next;
1268             else
1269                 pending_smsg_conn_head = ptr->next;
1270             CmiPrintf("[%d=%d]OK send post FMA resend\n", myrank, ptr->destNode);
1271             ptr = ptr->next;
1272             FreeRdmaRequest(tmp);
1273             continue;
1274         }
1275         prev = ptr;
1276         ptr = ptr->next;
1277     } //end while
1278 }
1279
1280 static void  SendRdmaMsg()
1281 {
1282     gni_return_t            status = GNI_RC_SUCCESS;
1283     gni_mem_handle_t        msg_mem_hndl;
1284
1285     RDMA_REQUEST *ptr = pending_rdma_head;
1286     RDMA_REQUEST *prev = NULL;
1287
1288     while (ptr != NULL)
1289     {
1290         gni_post_descriptor_t *pd = ptr->pd;
1291         status = GNI_RC_SUCCESS;
1292         // register memory first
1293         if( pd->local_mem_hndl.qword1 == 0 && pd->local_mem_hndl.qword2 == 0)
1294         {
1295             status = MEMORY_REGISTER(onesided_hnd, nic_hndl, pd->local_addr, pd->length, &(pd->local_mem_hndl), &omdh);
1296         }
1297         if(status == GNI_RC_SUCCESS)
1298         {
1299             if(pd->type == GNI_POST_RDMA_GET || pd->type == GNI_POST_RDMA_PUT) 
1300                 status = GNI_PostRdma(ep_hndl_array[ptr->destNode], pd);
1301             else
1302                 status = GNI_PostFma(ep_hndl_array[ptr->destNode],  pd);
1303             if(status == GNI_RC_SUCCESS)
1304             {
1305                 RDMA_REQUEST *tmp = ptr;
1306                 if (prev)
1307                   prev->next = ptr->next;
1308                 else
1309                   pending_rdma_head = ptr->next;
1310                 ptr = ptr->next;
1311                 FreeRdmaRequest(tmp);
1312                 continue;
1313             }
1314         }
1315         prev = ptr;
1316         ptr = ptr->next;
1317     } //end while
1318 }
1319
1320 // return 1 if all messages are sent
1321 static int SendBufferMsg()
1322 {
1323     MSG_LIST            *ptr, *previous_head, *current_head;
1324     CONTROL_MSG         *control_msg_tmp;
1325     gni_return_t        status;
1326     int done = 1;
1327     register    int     i;
1328     int                 index_previous = -1;
1329     int                 index = smsg_head_index;
1330     //if( smsg_msglist_head == 0 && buffered_smsg_counter!= 0 ) {CmiPrintf("WRONGWRONG on rank%d, buffermsg=%d, (msgid-succ:%d)\n", myrank, buffered_smsg_counter, (lrts_send_msg_id-lrts_smsg_success)); CmiAbort("sendbuf");}
1331     /* can add flow control here to control the number of messages sent before handle message */
1332     while(index != -1)
1333     {
1334         ptr = smsg_msglist_index[index].head;
1335        
1336         while(ptr!=0)
1337         {
1338             CmiAssert(ptr!=NULL);
1339             if(ptr->tag == SMALL_DATA_TAG)
1340             {
1341                 status = send_smsg_message( ptr->destNode, 0, 0, ptr->msg, ptr->size, SMALL_DATA_TAG, 1);  
1342                 if(status == GNI_RC_SUCCESS)
1343                 {
1344                     CmiFree(ptr->msg);
1345                 }
1346             }
1347             else if(ptr->tag == LMSG_INIT_TAG)
1348             {
1349                 control_msg_tmp = (CONTROL_MSG*)ptr->msg;
1350 #if PRINT_SYH
1351                 CmiPrintf("[%d==>%d] LMSG buffer send call(%d)%s\n", myrank, ptr->destNode, lrts_smsg_success, gni_err_str[status] );
1352 #endif
1353                 if(control_msg_tmp->source_mem_hndl.qword1 == 0 && control_msg_tmp->source_mem_hndl.qword2 == 0)
1354                 {
1355                     MEMORY_REGISTER(onesided_hnd, nic_hndl, control_msg_tmp->source_addr, control_msg_tmp->length, &(control_msg_tmp->source_mem_hndl), &omdh);
1356                     if(status != GNI_RC_SUCCESS) {
1357                         done = 0;
1358                         break;
1359                     }
1360                 }
1361                 
1362                 status = send_smsg_message( ptr->destNode, 0, 0, ptr->msg, sizeof(CONTROL_MSG), LMSG_INIT_TAG, 1);  
1363                 if(status == GNI_RC_SUCCESS)
1364                 {
1365                     FreeControlMsg((CONTROL_MSG*)(ptr->msg));
1366                 }
1367             }else if (ptr->tag == ACK_TAG)
1368             {
1369                 status = send_smsg_message( ptr->destNode, 0, 0, ptr->msg, sizeof(CONTROL_MSG), ACK_TAG, 1);  
1370                 if(status == GNI_RC_SUCCESS)
1371                 {
1372                     FreeControlMsg((CONTROL_MSG*)ptr->msg);
1373                 }
1374             }else
1375             {
1376                 CmiPrintf("Weird tag\n");
1377                 CmiAbort("should not happen\n");
1378             }
1379             if(status == GNI_RC_SUCCESS)
1380             {
1381 #if PRINT_SYH
1382                 buffered_smsg_counter--;
1383                 if(lrts_smsg_success == lrts_send_msg_id)
1384                     CmiPrintf("GOOD send buff [%d==>%d] send buffer sent done%d (msgs=%d)\n", myrank, ptr->destNode, lrts_smsg_success, lrts_send_msg_id);
1385                 else
1386                     CmiPrintf("BAD send buff [%d==>%d] sent done%d (msgs=%d)\n", myrank, ptr->destNode, lrts_smsg_success, lrts_send_msg_id);
1387 #endif
1388                 smsg_msglist_index[index].head = smsg_msglist_index[index].head->next;
1389                 FreeMsgList(ptr);
1390                 ptr= smsg_msglist_index[index].head;
1391
1392             }else {
1393                 done = 0;
1394                 break;
1395             } 
1396         
1397         } //end while
1398         if(ptr == 0)
1399         {
1400             if(index_previous != -1)
1401                 smsg_msglist_index[index_previous].next = smsg_msglist_index[index].next;
1402             else
1403                 smsg_head_index = smsg_msglist_index[index].next;
1404         }else
1405         {
1406             index_previous = index;
1407         }
1408         index = smsg_msglist_index[index].next;
1409     }   // end pooling for all cores
1410     return done;
1411 }
1412
1413 static void LrtsAdvanceCommunication()
1414 {
1415     /*  Receive Msg first */
1416 #if 0
1417     if(myrank == 0)
1418     CmiPrintf("Calling Lrts Pump Msg PE:%d\n", myrank);
1419 #endif
1420     PumpNetworkSmsg();
1421     //CmiPrintf("Calling Lrts Pump RdmaMsg PE:%d\n", CmiMyPe());
1422     //PumpNetworkRdmaMsgs();
1423     /* Release Sent Msg */
1424     //CmiPrintf("Calling Lrts Rlease Msg PE:%d\n", CmiMyPe());
1425 #if 0
1426     ////PumpLocalSmsgTransactions();
1427     if(myrank == 0)
1428     CmiPrintf("Calling Lrts Rlease RdmaMsg PE:%d\n", myrank);
1429 #endif
1430     PumpLocalRdmaTransactions();
1431 #if 0
1432     if(myrank == 0)
1433     CmiPrintf("Calling Lrts Send Buffmsg PE:%d\n", myrank);
1434 #endif
1435     /* Send buffered Message */
1436     SendBufferMsg();
1437 #if 0
1438     if(myrank == 0)
1439     CmiPrintf("Calling Lrts rdma PE:%d\n", myrank);
1440 #endif
1441     SendRdmaMsg();
1442 #if 0
1443     if(myrank == 0)
1444     CmiPrintf("done PE:%d\n", myrank);
1445 #endif
1446 }
1447
1448 static void _init_dynamic_smsg()
1449 {
1450     gni_smsg_attr_t smsg_attr;
1451     gni_return_t status;
1452     smsg_connected_flag = (int*)malloc(sizeof(int)*mysize);
1453     memset(smsg_connected_flag, 0, mysize*sizeof(int));
1454
1455     smsg_local_attr_vec = (gni_smsg_attr_t**) malloc(sizeof(gni_smsg_attr_t*) *mysize);
1456     
1457     setup_mem.addr = (uint64_t)malloc(mysize * sizeof(gni_smsg_attr_t));
1458     status = GNI_MemRegister(nic_hndl, setup_mem.addr,  mysize * sizeof(gni_smsg_attr_t), smsg_rx_cqh,  GNI_MEM_READWRITE, -1,  &(setup_mem.mdh));
1459    
1460     GNI_RC_CHECK("Smsg dynamic allocation \n", status);
1461     smsg_connection_vec = (mdh_addr_t*) malloc(mysize*sizeof(mdh_addr_t)); 
1462     allgather(&setup_mem, smsg_connection_vec, sizeof(mdh_addr_t));
1463     
1464     //pre-allocate some memory as mailbox for dynamic connection
1465     if(mysize <=4096)
1466     {
1467         SMSG_MAX_MSG = 1024;
1468     }else if (mysize > 4096 && mysize <= 16384)
1469     {
1470         SMSG_MAX_MSG = 512;
1471     }else {
1472         SMSG_MAX_MSG = 256;
1473     }
1474     
1475     smsg_attr.msg_type = GNI_SMSG_TYPE_MBOX_AUTO_RETRANSMIT;
1476     smsg_attr.mbox_maxcredit = SMSG_MAX_CREDIT;
1477     smsg_attr.msg_maxsize = SMSG_MAX_MSG;
1478     status = GNI_SmsgBufferSizeNeeded(&smsg_attr, &smsg_memlen);
1479     GNI_RC_CHECK("GNI_GNI_MemRegister mem buffer", status);
1480     
1481     smsg_dynamic_list = (mdh_addr_list_t*)malloc(sizeof(mdh_addr_list_t));
1482
1483     smsg_dynamic_list->addr = memalign(64, smsg_memlen*smsg_expand_slots);
1484     bzero(smsg_dynamic_list->addr, smsg_memlen*smsg_expand_slots);
1485     
1486     status = GNI_MemRegister(nic_hndl, (uint64_t)smsg_dynamic_list->addr,
1487             smsg_memlen*smsg_expand_slots, smsg_rx_cqh,
1488             GNI_MEM_READWRITE,   
1489             -1,
1490             &(smsg_dynamic_list->mdh));
1491    smsg_available_slot = 0;  
1492 }
1493
1494 static void _init_static_smsg()
1495 {
1496     gni_smsg_attr_t      *smsg_attr;
1497     gni_smsg_attr_t      remote_smsg_attr;
1498     gni_smsg_attr_t      *smsg_attr_vec;
1499     gni_mem_handle_t     my_smsg_mdh_mailbox;
1500     int      i;
1501     gni_return_t status;
1502     uint32_t              vmdh_index = -1;
1503     mdh_addr_t            base_infor;
1504     mdh_addr_t            *base_addr_vec;
1505     if(mysize <=4096)
1506     {
1507         SMSG_MAX_MSG = 1024;
1508         //log2_SMSG_MAX_MSG = 10;
1509     }else if (mysize > 4096 && mysize <= 16384)
1510     {
1511         SMSG_MAX_MSG = 512;
1512         //log2_SMSG_MAX_MSG = 9;
1513
1514     }else {
1515         SMSG_MAX_MSG = 256;
1516         //log2_SMSG_MAX_MSG = 8;
1517     }
1518     
1519     smsg_attr = malloc(mysize * sizeof(gni_smsg_attr_t));
1520     
1521     smsg_attr[0].msg_type = GNI_SMSG_TYPE_MBOX_AUTO_RETRANSMIT;
1522     smsg_attr[0].mbox_maxcredit = SMSG_MAX_CREDIT;
1523     smsg_attr[0].msg_maxsize = SMSG_MAX_MSG;
1524     status = GNI_SmsgBufferSizeNeeded(&smsg_attr[0], &smsg_memlen);
1525     GNI_RC_CHECK("GNI_GNI_MemRegister mem buffer", status);
1526     smsg_mailbox_base = memalign(64, smsg_memlen*(mysize));
1527     _MEMCHECK(smsg_mailbox_base);
1528     bzero(smsg_mailbox_base, smsg_memlen*(mysize));
1529     //if (myrank == 0) CmiPrintf("Charm++> allocates %.2fMB for SMSG. \n", smsg_memlen*mysize/1e6);
1530     
1531     status = GNI_MemRegister(nic_hndl, (uint64_t)smsg_mailbox_base,
1532             smsg_memlen*(mysize), smsg_rx_cqh,
1533             GNI_MEM_READWRITE,   
1534             vmdh_index,
1535             &my_smsg_mdh_mailbox);
1536
1537     GNI_RC_CHECK("GNI_GNI_MemRegister mem buffer", status);
1538
1539     base_infor.addr =  (uint64_t)smsg_mailbox_base;
1540     base_infor.mdh =  my_smsg_mdh_mailbox;
1541     base_addr_vec = malloc(mysize * sizeof(mdh_addr_t));
1542
1543     allgather(&base_infor, base_addr_vec,  sizeof(mdh_addr_t));
1544  
1545     for(i=0; i<mysize; i++)
1546     {
1547         if(i==myrank)
1548             continue;
1549         smsg_attr[i].msg_type = GNI_SMSG_TYPE_MBOX_AUTO_RETRANSMIT;
1550         smsg_attr[i].mbox_maxcredit = SMSG_MAX_CREDIT;
1551         smsg_attr[i].msg_maxsize = SMSG_MAX_MSG;
1552         smsg_attr[i].mbox_offset = i*smsg_memlen;
1553         smsg_attr[i].buff_size = smsg_memlen;
1554         smsg_attr[i].msg_buffer = smsg_mailbox_base ;
1555         smsg_attr[i].mem_hndl = my_smsg_mdh_mailbox;
1556     }
1557
1558     for(i=0; i<mysize; i++)
1559     {
1560         if (myrank == i) continue;
1561
1562         remote_smsg_attr.msg_type = GNI_SMSG_TYPE_MBOX_AUTO_RETRANSMIT;
1563         remote_smsg_attr.mbox_maxcredit = SMSG_MAX_CREDIT;
1564         remote_smsg_attr.msg_maxsize = SMSG_MAX_MSG;
1565         remote_smsg_attr.mbox_offset = myrank*smsg_memlen;
1566         remote_smsg_attr.buff_size = smsg_memlen;
1567         remote_smsg_attr.msg_buffer = (void*)base_addr_vec[i].addr;
1568         remote_smsg_attr.mem_hndl = base_addr_vec[i].mdh;
1569
1570         /* initialize the smsg channel */
1571         status = GNI_SmsgInit(ep_hndl_array[i], &smsg_attr[i], &remote_smsg_attr);
1572         GNI_RC_CHECK("SMSG Init", status);
1573     } //end initialization
1574
1575     free(base_addr_vec);
1576
1577     free(smsg_attr);
1578     status = GNI_SmsgSetMaxRetrans(nic_hndl, 4096);
1579      GNI_RC_CHECK("SmsgSetMaxRetrans Init", status);
1580
1581
1582 inline
1583 static void _init_smsg()
1584 {
1585     int i;
1586
1587      smsg_msglist_index = (MSG_LIST_INDEX*)malloc(mysize*sizeof(MSG_LIST_INDEX));
1588      for(i =0; i<mysize; i++)
1589      {
1590         smsg_msglist_index[i].next = -1;
1591         smsg_msglist_index[i].head = 0;
1592         smsg_msglist_index[i].tail = 0;
1593      }
1594      smsg_head_index = -1;
1595 }
1596
1597 static void _init_static_msgq()
1598 {
1599     gni_return_t status;
1600     /* MSGQ is to send and receive short messages for large jobs (exceeding 200,000 ranks). The          performance scales by the node count rather than rank count */
1601     msgq_attrs.max_msg_sz = MSGQ_MAXSIZE;
1602     msgq_attrs.smsg_q_sz = 1;
1603     msgq_attrs.rcv_pool_sz = 1;
1604     msgq_attrs.num_msgq_eps = 2;
1605     msgq_attrs.nloc_insts = 8;
1606     msgq_attrs.modes = 0;
1607     msgq_attrs.rcv_cq_sz = REMOTE_QUEUE_ENTRIES ;
1608
1609     status = GNI_MsgqInit(nic_hndl, NULL, NULL, NULL, &msgq_attrs, &msgq_handle);
1610     GNI_RC_CHECK("MSGQ Init", status);
1611
1612
1613 }
1614
1615 static void _init_DMA_buffer()
1616 {
1617     gni_return_t            status = GNI_RC_SUCCESS;
1618     /*AUTO tuning */
1619     /* suppose max_smsg is 1024, DMA buffer is split into 2048, 4096, 8192, ... */
1620     /*  This method might be better for SMP, but it is bad for Nonsmp since msgs are sharing same slots */
1621     /*
1622      * DMA_slots = 19-log2_SMSG_MAX_MSG;
1623     DMA_incoming_avail_tag = malloc(DMA_slots);
1624     DMA_buffer_size = 2*(DMA_max_single_msg - SMSG_MAX_MSG); 
1625     DMA_incoming_base_addr =  memalign(ALIGNBUF, DMA_buffer_size);
1626     DMA_outgoing_base_addr =  memalign(ALIGNBUF, DMA_buffer_size);
1627     
1628     status = GNI_MemRegister(nic_hndl, (uint64_t)DMA_incoming_base_addr,
1629             DMA_buffer_size, smsg_rx_cqh,
1630             GNI_MEM_READWRITE ,   
1631             vmdh_index,
1632             &);
1633             */
1634     // one is reserved to avoid deadlock
1635     DMA_slots           = 17; // each one is 8K  16*8K + 1 slot reserved to avoid deadlock
1636     DMA_buffer_size     = DMA_max_single_msg + 8192;
1637     DMA_buffer_base_mdh_addr.addr = (uint64_t)memalign(ALIGNBUF, DMA_buffer_size);
1638     status = GNI_MemRegister(nic_hndl, DMA_buffer_base_mdh_addr.addr,
1639         DMA_buffer_size, smsg_rx_cqh,
1640         GNI_MEM_READWRITE ,   
1641         -1,
1642         &(DMA_buffer_base_mdh_addr.mdh));
1643     GNI_RC_CHECK("GNI_MemRegister", status);
1644     DMA_buffer_base_mdh_addr_vec = (mdh_addr_t*) malloc(sizeof(mdh_addr_t) * mysize);
1645
1646     allgather(&DMA_buffer_base_mdh_addr, DMA_buffer_base_mdh_addr_vec, sizeof(mdh_addr_t) );
1647 }
1648
1649 static void LrtsInit(int *argc, char ***argv, int *numNodes, int *myNodeID)
1650 {
1651     register int            i;
1652     int                     rc;
1653     int                     device_id = 0;
1654     unsigned int            remote_addr;
1655     gni_cdm_handle_t        cdm_hndl;
1656     gni_return_t            status = GNI_RC_SUCCESS;
1657     uint32_t                vmdh_index = -1;
1658     uint8_t                 ptag;
1659     unsigned int            local_addr, *MPID_UGNI_AllAddr;
1660     int                     first_spawned;
1661     int                     physicalID;
1662     //void (*local_event_handler)(gni_cq_entry_t *, void *)       = &LocalEventHandle;
1663     //void (*remote_smsg_event_handler)(gni_cq_entry_t *, void *) = &RemoteSmsgEventHandle;
1664     //void (*remote_bte_event_handler)(gni_cq_entry_t *, void *)  = &RemoteBteEventHandle;
1665    
1666     //Mempool_MaxSize = CmiGetArgFlag(*argv, "+useMemorypoolSize");
1667     //useDynamicSMSG = CmiGetArgFlag(*argv, "+useDynamicSmsg");
1668        //useStaticMSGQ = CmiGetArgFlag(*argv, "+useStaticMsgQ");
1669     
1670     status = PMI_Init(&first_spawned);
1671     GNI_RC_CHECK("PMI_Init", status);
1672
1673     status = PMI_Get_size(&mysize);
1674     GNI_RC_CHECK("PMI_Getsize", status);
1675
1676     status = PMI_Get_rank(&myrank);
1677     GNI_RC_CHECK("PMI_getrank", status);
1678
1679     //physicalID = CmiPhysicalNodeID(myrank);
1680     
1681     //printf("Pysical Node ID:%d for PE:%d\n", physicalID, myrank);
1682
1683     *myNodeID = myrank;
1684     *numNodes = mysize;
1685   
1686     if(myrank == 0)
1687     {
1688 #if useDynamicSMSG
1689         printf("Charm++> use Dynamic SMSG\n");
1690 #else
1691         printf("Charm++> use Static SMSG\n");
1692 #endif
1693         printf("Charm++> Running on Gemini (GNI) using %d  cores\n", mysize);
1694     }
1695 #ifdef USE_ONESIDED
1696     onesided_init(NULL, &onesided_hnd);
1697
1698     // this is a GNI test, so use the libonesided bypass functionality
1699     onesided_gni_bypass_get_nih(onesided_hnd, &nic_hndl);
1700     local_addr = gniGetNicAddress();
1701 #else
1702     ptag = get_ptag();
1703     cookie = get_cookie();
1704 #if 0
1705     modes = GNI_CDM_MODE_CQ_NIC_LOCAL_PLACEMENT;
1706 #endif
1707     //Create and attach to the communication  domain */
1708     status = GNI_CdmCreate(myrank, ptag, cookie, modes, &cdm_hndl);
1709     GNI_RC_CHECK("GNI_CdmCreate", status);
1710     //* device id The device id is the minor number for the device
1711     //that is assigned to the device by the system when the device is created.
1712     //To determine the device number, look in the /dev directory, which contains a list of devices. For a NIC, the device is listed as kgniX
1713     //where X is the device number 0 default 
1714     status = GNI_CdmAttach(cdm_hndl, device_id, &local_addr, &nic_hndl);
1715     GNI_RC_CHECK("GNI_CdmAttach", status);
1716     local_addr = get_gni_nic_address(0);
1717 #endif
1718     MPID_UGNI_AllAddr = (unsigned int *)malloc(sizeof(unsigned int) * mysize);
1719     _MEMCHECK(MPID_UGNI_AllAddr);
1720     allgather(&local_addr, MPID_UGNI_AllAddr, sizeof(unsigned int));
1721     /* create the local completion queue */
1722     /* the third parameter : The number of events the NIC allows before generating an interrupt. Setting this parameter to zero results in interrupt delivery with every event. When using this parameter, the mode parameter must be set to GNI_CQ_BLOCKING*/
1723     status = GNI_CqCreate(nic_hndl, LOCAL_QUEUE_ENTRIES, 0, GNI_CQ_NOBLOCK, NULL, NULL, &smsg_tx_cqh);
1724     GNI_RC_CHECK("GNI_CqCreate (tx)", status);
1725     
1726     //status = GNI_CqCreate(nic_hndl, LOCAL_QUEUE_ENTRIES, 0, GNI_CQ_NOBLOCK, NULL, NULL, &post_tx_cqh);
1727     //GNI_RC_CHECK("GNI_CqCreate post (tx)", status);
1728     /* create the destination completion queue for receiving micro-messages, make this queue considerably larger than the number of transfers */
1729
1730     status = GNI_CqCreate(nic_hndl, REMOTE_QUEUE_ENTRIES, 0, GNI_CQ_NOBLOCK, NULL, NULL, &smsg_rx_cqh);
1731     GNI_RC_CHECK("Create CQ (rx)", status);
1732     
1733     //status = GNI_CqCreate(nic_hndl, REMOTE_QUEUE_ENTRIES, 0, GNI_CQ_NOBLOCK, NULL, NULL, &post_rx_cqh);
1734     //GNI_RC_CHECK("Create Post CQ (rx)", status);
1735     
1736     //status = GNI_CqCreate(nic_hndl, REMOTE_QUEUE_ENTRIES, 0, GNI_CQ_NOBLOCK, NULL, NULL, &rdma_cqh);
1737     //GNI_RC_CHECK("Create BTE CQ", status);
1738
1739     /* create the endpoints. they need to be bound to allow later CQWrites to them */
1740     ep_hndl_array = (gni_ep_handle_t*)malloc(mysize * sizeof(gni_ep_handle_t));
1741     _MEMCHECK(ep_hndl_array);
1742
1743     for (i=0; i<mysize; i++) {
1744         if(i == myrank) continue;
1745         status = GNI_EpCreate(nic_hndl, smsg_tx_cqh, &ep_hndl_array[i]);
1746         GNI_RC_CHECK("GNI_EpCreate ", status);   
1747         remote_addr = MPID_UGNI_AllAddr[i];
1748         status = GNI_EpBind(ep_hndl_array[i], remote_addr, i);
1749         GNI_RC_CHECK("GNI_EpBind ", status);   
1750     }
1751     /* Depending on the number of cores in the job, decide different method */
1752     /* SMSG is fastest but not scale; Msgq is scalable, FMA is own implementation for small message */
1753     if(mysize > 1)
1754     {
1755 #if useDynamicSMSG
1756             _init_dynamic_smsg();
1757 #else
1758             _init_static_smsg();
1759 #endif
1760         _init_smsg();
1761         CmiBarrier();
1762     }
1763 #if     USE_LRTS_MEMPOOL
1764     CmiGetArgLong(*argv, "+useMemorypoolSize", &_mempool_size);
1765     if (myrank==0) printf("Charm++> use memorypool size: %1.fMB\n", _mempool_size/1024.0/1024);
1766     init_mempool(_mempool_size);
1767     //init_mempool(Mempool_MaxSize);
1768 #endif
1769
1770     /* init DMA buffer for medium message */
1771
1772     //_init_DMA_buffer();
1773     
1774     free(MPID_UGNI_AllAddr);
1775 }
1776
1777
1778 void* LrtsAlloc(int n_bytes, int header)
1779 {
1780     void *ptr;
1781 #if 0
1782     CmiPrintf("\n[PE:%d]Alloc Lrts for bytes=%d, head=%d\n", CmiMyPe(), n_bytes, header);
1783 #endif
1784     if(n_bytes <= SMSG_MAX_MSG)
1785     {
1786         int totalsize = n_bytes+header;
1787         ptr = malloc(totalsize);
1788     }else 
1789     {
1790
1791         CmiAssert(header <= ALIGNBUF);
1792 #if     USE_LRTS_MEMPOOL
1793         n_bytes = ALIGN64(n_bytes);
1794         char *res = syh_mempool_malloc(ALIGNBUF+n_bytes);
1795 #else
1796         n_bytes = ALIGN4(n_bytes);           /* make sure size if 4 aligned */
1797         char *res = memalign(ALIGNBUF, n_bytes+ALIGNBUF);
1798 #endif
1799         ptr = res + ALIGNBUF - header;
1800     }
1801 #if 0 
1802     CmiPrintf("Done Alloc Lrts for bytes=%d, head=%d\n", n_bytes, header);
1803 #endif
1804     return ptr;
1805 }
1806
1807 void  LrtsFree(void *msg)
1808 {
1809     int size = SIZEFIELD((char*)msg+sizeof(CmiChunkHeader));
1810     if (size <= SMSG_MAX_MSG)
1811       free(msg);
1812     else
1813     {
1814 #if 0
1815         CmiPrintf("[PE:%d] Free lrts for bytes=%d, ptr=%p\n", CmiMyPe(), size, (char*)msg + sizeof(CmiChunkHeader) - ALIGNBUF);
1816 #endif
1817 #if     USE_LRTS_MEMPOOL
1818         syh_mempool_free((char*)msg + sizeof(CmiChunkHeader) - ALIGNBUF);
1819 #else
1820         free((char*)msg + sizeof(CmiChunkHeader) - ALIGNBUF);
1821 #endif
1822     }
1823 #if 0 
1824     CmiPrintf("Done Free lrts for bytes=%d\n", size);
1825 #endif
1826 }
1827
1828 static void LrtsExit()
1829 {
1830     /* free memory ? */
1831 #if     USE_LRTS_MEMPOOL
1832     kill_allmempool();
1833 #endif
1834     PMI_Finalize();
1835     exit(0);
1836 }
1837
1838 static void LrtsDrainResources()
1839 {
1840     while (!SendBufferMsg()) {
1841         PumpNetworkSmsg();
1842         PumpNetworkRdmaMsgs();
1843         PumpLocalSmsgTransactions();
1844         PumpLocalRdmaTransactions();
1845     }
1846     PMI_Barrier();
1847 }
1848
1849 void CmiAbort(const char *message) {
1850
1851     CmiPrintf("CmiAbort is calling on PE:%d\n", myrank);
1852     PMI_Abort(-1, message);
1853 }
1854
1855 /**************************  TIMER FUNCTIONS **************************/
1856 #if CMK_TIMER_USE_SPECIAL
1857 /* MPI calls are not threadsafe, even the timer on some machines */
1858 static CmiNodeLock  timerLock = 0;
1859 static int _absoluteTime = 0;
1860 static int _is_global = 0;
1861 static struct timespec start_ns;
1862
1863 inline int CmiTimerIsSynchronized() {
1864     return 1;
1865 }
1866
1867 inline int CmiTimerAbsolute() {
1868     return _absoluteTime;
1869 }
1870
1871 double CmiStartTimer() {
1872     return 0.0;
1873 }
1874
1875 double CmiInitTime() {
1876     return (double)(start_ts.tv_sec)+(double)start_ts.tv_nsec/1000000000.0;
1877 }
1878
1879 void CmiTimerInit(char **argv) {
1880     _absoluteTime = CmiGetArgFlagDesc(argv,"+useAbsoluteTime", "Use system's absolute time as wallclock time.");
1881     if (_absoluteTime && CmiMyPe() == 0)
1882         printf("Charm++> absolute  timer is used\n");
1883     
1884     _is_global = CmiTimerIsSynchronized();
1885
1886
1887     if (_is_global) {
1888         if (CmiMyRank() == 0) {
1889             clock_gettime(CLOCK_MONOTONIC, &start_ts)
1890         }
1891     } else { /* we don't have a synchronous timer, set our own start time */
1892         CmiBarrier();
1893         CmiBarrier();
1894         CmiBarrier();
1895         clock_gettime(CLOCK_MONOTONIC, &start_ts)
1896     }
1897     CmiNodeAllBarrier();          /* for smp */
1898 }
1899
1900 /**
1901  * Since the timerLock is never created, and is
1902  * always NULL, then all the if-condition inside
1903  * the timer functions could be disabled right
1904  * now in the case of SMP.
1905  */
1906 double CmiTimer(void) {
1907     struct timespec now_ts;
1908     clock_gettime(CLOCK_MONOTONIC, &now_ts)
1909     return _absoluteTime?((double)(now_ts.tv_sec)+(double)now_ts.tv_nsec/1000000000.0)
1910         : (double)( now_ts.tv_sec - start_ts.tv_sec ) + (((double) now_ts.tv_nsec - (double) start_ts.tv_nsec)  / 1000000000.0);
1911 }
1912
1913 double CmiWallTimer(void) {
1914     struct timespec now_ts;
1915     clock_gettime(CLOCK_MONOTONIC, &now_ts)
1916     return _absoluteTime?((double)(now_ts.tv_sec)+(double)now_ts.tv_nsec/1000000000.0)
1917         : (double)( now_ts.tv_sec - start_ts.tv_sec ) + (((double) now_ts.tv_nsec - (double) start_ts.tv_nsec)  / 1000000000.0);
1918 }
1919
1920 double CmiCpuTimer(void) {
1921     struct timespec now_ts;
1922     clock_gettime(CLOCK_MONOTONIC, &now_ts)
1923     return _absoluteTime?((double)(now_ts.tv_sec)+(double)now_ts.tv_nsec/1000000000.0)
1924         : (double)( now_ts.tv_sec - start_ts.tv_sec ) + (((double) now_ts.tv_nsec - (double) start_ts.tv_nsec)  / 1000000000.0);
1925 }
1926
1927 #endif
1928 /************Barrier Related Functions****************/
1929
1930 int CmiBarrier()
1931 {
1932     int status;
1933     status = PMI_Barrier();
1934     return status;
1935
1936 }
1937
1938
1939 #if CMK_PERSISTENT_COMM
1940 #include "machine-persistent.c"
1941 #endif
1942
1943