5
/* ---------------------------------------------------------------------------------------------- *\
6
portals_cp.c -- compute process portals calls
9
\* ---------------------------------------------------------------------------------------------- */
16
/* ---------------------------------------------------------------------------------------------- *\
17
\* ---------------------------------------------------------------------------------------------- */
18
static ptl_handle_ni_t cp_nih;
19
static ptl_handle_eq_t cp_eqh;
20
static ptl_handle_eq_t cp_tx_eqh;
22
static void *portals_eager_send_buffer = NULL;
23
static size_t portals_unique_msg_counter = 373;
25
static int portals_smp_sem = -1;
26
static int *active_requests_by_node = NULL;
28
/* ---------------------------------------------------------------------------------------------- *\
29
\* ---------------------------------------------------------------------------------------------- */
30
int portals_cp_finished = 0;
33
/* ---------------------------------------------------------------------------------------------- *\
35
\* ---------------------------------------------------------------------------------------------- */
44
rc = portals_init(&cp_nih);
46
printf("error in portals_init: err %d\n",rc);
50
rc = portals_create_eq(cp_nih,10*PORTALS_MAX_DESCRIPTORS,&cp_eqh);
52
printf("failed to create cp event queue; err %d\n",rc);
56
rc = portals_create_eq(cp_nih,30,&cp_tx_eqh);
58
printf("failed to create cp_tx event queue; err %d\n",rc);
62
rc = portals_cp_getid(&id);
64
printf("failed to get the portals id; err %d\n",rc);
68
/* creating an smp/intra-node communicator */
69
MPI_Comm_rank(ARMCI_COMM_WORLD,&me);
70
MPI_Comm_split(ARMCI_COMM_WORLD,id.nid,me,&portals_smp_comm);
73
# ifdef PORTALS_AFFINITY
76
unsigned int len = sizeof(mask);
78
unsigned int nsockets, siblings;
79
int cores_per_socket, cps_per_socket;
82
MPI_Comm_size(portals_smp_comm,&smp_np);
83
MPI_Comm_rank(portals_smp_comm,&smp_me);
86
if((ncpus = sysconf(_SC_NPROCESSORS_ONLN)) < 0) {
87
printf("%d [cp] sysconf(_SC_NPROCESSORS_ONLN) failed; err=%d\n", ncpus);
88
armci_die("sysconf in init_throttle",911);
92
if(sched_getaffinity(0, len, &mask) < 0) {
93
perror("sched_getaffinity");
94
armci_die("getaffinity error in ds_init",911);
97
if(armci_clus_me == 0 && /* verbose */ 0 ) {
98
printf("%d [cp]: old affinity = 0x%x, ncpus = %d\n", armci_me, mask, ncpus);
102
mask = 1 << (ncpus-1);
103
if(sched_setaffinity(0, len, (cpu_set_t *) &mask) < 0) {
104
perror("sched_setaffinity to probe the socket count");
105
armci_die("setaffinity error in ds_init",911);
107
siblings = cpuid_ebx(1) >>16 & 0xff;
108
nsockets = ncpus / siblings;
110
MPI_Bcast(&nsockets,1,MPI_INT,0,portals_smp_comm);
112
cores_per_socket = ncpus/nsockets;
113
cps_per_socket = (smp_np / nsockets);
114
cps_per_socket += (smp_np % nsockets);
116
armci_die("nsockets > 2 not supported",911);
118
if(smp_me < cps_per_socket) {
121
mask = 1 << (smp_me + (cores_per_socket - cps_per_socket));
124
if(sched_setaffinity(0, len, (cpu_set_t *) &mask) < 0) {
125
perror("sched_setaffinity");
126
armci_die("setaffinity error in ds_init",911);
129
if(sched_getaffinity(0, len, &mask) < 0) {
130
perror("sched_getaffinity");
131
armci_die("getaffinity error (#2) in ds_init",911);
134
if(armci_clus_me == 0 && verbose) {
135
printf("%d [cp]: new affinity = 0x%x, ncpus = %d\n", armci_me, mask, ncpus);
144
portals_cp_finalize()
148
# ifdef PORTALS_LIMIT_REMOTE_REQUESTS_BY_NODE
149
armci_semrm(portals_smp_sem);
152
rc = portals_free_eq(cp_eqh);
154
printf("error freeing cp_eqh; err %d\n",rc);
157
MPI_Barrier(ARMCI_COMM_WORLD);
160
portals_cp_finished = 1;
164
// return portals_finalize(cp_nih);
169
portals_cp_getid(ptl_process_id_t *id)
171
return portals_getid(cp_nih, id);
176
portals_get_unique_msg_id(void) {
177
size_t val = armci_me*1000;
178
portals_unique_msg_counter++;
179
if(portals_unique_msg_counter == 1000) portals_unique_msg_counter=1;
180
val += portals_unique_msg_counter;
186
portals_req_clear(portals_ds_req_t *req)
189
req->unique_msg_id = 0;
191
req->req_desc.done = 1;
192
req->req_desc.state = 0;
193
req->req_desc.eqh = cp_tx_eqh;
195
req->ack_desc.done = 1;
196
req->ack_desc.state = 0;
197
req->ack_desc.eqh = cp_eqh;
199
req->data_desc.done = 1;
200
req->data_desc.state = 0;
201
req->data_desc.eqh = cp_eqh;
203
req->remote_node = -1;
207
static ptl_process_id_t
208
portals_get_dsid_from_node(int remote_node)
210
int rank = armci_clus_info[remote_node].master;
211
if(portals_cloned_id_map) return portals_cloned_id_map[rank];
212
else return portals_id_map[rank];
216
static ptl_process_id_t
217
portals_get_dsid_from_rank(int remote_id)
219
if(portals_cloned_id_map) return portals_cloned_id_map[remote_id];
220
else return portals_id_map[remote_id];
224
portals_req_nbsend(void *buffer, size_t size, portals_ds_req_t *req)
227
portals_desc_t *desc = &req->req_desc;
229
assert(req->unique_msg_id);
230
assert(size < portalsMaxEagerMessageSize);
231
assert(req->remote_node >= 0);
233
/* ---------------------------------------------------------------------------- *\
234
if we get here, we can guarantee that where are no outstanding requests from
235
this PE to the remote node; however, we can not guarantee that other PEs on
236
this node aren't talking to the intended data server ... so now we wait on
237
value in the "shared" array.
238
\* ---------------------------------------------------------------------------- */
239
# ifdef PORTALS_LIMIT_REMOTE_REQUESTS_BY_NODE
242
portalsSpinLockOnInt(&active_requests_by_node[req->remote_node],0,1000);
243
semaphoreAcquire(portals_smp_sem,1,PORTALS_WRITE_ACCESS);
244
if(active_requests_by_node[req->remote_node] == 0) {
245
active_requests_by_node[req->remote_node] = 1;
248
semaphoreRelease(portals_smp_sem,1,PORTALS_WRITE_ACCESS);
252
desc->buffer = buffer;
254
desc->id = req->dsid;
255
desc->mbits = MATCH_ALL_MBITS;
256
desc->hdr = req->unique_msg_id;
258
desc->eqh = cp_tx_eqh;
261
rc = portals_put(desc);
263
printf("portals_put err %d\n",rc);
269
portals_req_send(void *buffer, size_t size, portals_ds_req_t *req)
272
portals_desc_t *desc = &req->req_desc;
274
portals_req_nbsend(buffer,size,req);
276
rc = portals_wait(desc);
278
printf("portals_wait err %d\n",rc);
285
portals_req_wait(portals_ds_req_t *req)
289
if(req->req_desc.state) {
290
rc = portals_wait( &(req->req_desc) );
292
printf("portals wait error on req_desc in req_wait; err=%d\n",rc);
297
if(req->ack_desc.state) {
298
rc = portals_wait( &(req->ack_desc) );
300
printf("portals wait error on ack_desc in req_wait; err=%d\n",rc);
304
if(req->data_desc.state) {
305
rc = portals_wait( &(req->data_desc) );
307
printf("portals wait error on data_desc in req_wait; err=%d\n",rc);
318
portalsWaitOnRequest(portals_ds_req_t *req) {
319
portals_req_wait(req);
324
portals_prepost_ack_from_ds(portals_ds_req_t *req)
328
portals_desc_t *desc = &req->ack_desc;
329
unsigned long mbits = req->unique_msg_id;
331
assert(req->unique_msg_id);
332
assert(req->remote_node >= 0);
334
# ifdef PORTALS_LIMIT_REMOTE_REQUESTS_BY_NODE
335
desc->buffer = &active_requests_by_node[req->remote_node];
336
desc->length = sizeof(int);
341
desc->id = req->dsid;
342
desc->mbits = mbits | DS_RESPONSE_ACK;
346
rc = portals_me_attach(cp_nih,desc->id,desc->mbits,0,&desc->meh);
348
printf("me failed in prepost ack\n");
352
md.start = desc->buffer;
353
md.length = desc->length;
355
md.options = PTL_MD_OP_PUT | PTL_MD_EVENT_START_DISABLE;
357
md.eq_handle = cp_eqh;
359
rc = portals_md_attach(desc->meh,md,PTL_UNLINK,&desc->mdh);
361
printf("md failed in prepost ack\n");
365
// desc->state = STATE_PUT_END;
366
// |= needed for rendez-vous gets; put and get using the same descriptor
367
desc->state |= STATE_PUT_END;
373
portals_prepost_put_from_ds(void *buffer, size_t size, portals_ds_req_t *req)
378
portals_desc_t *desc = &req->data_desc;
379
unsigned long mbits = req->unique_msg_id;
381
assert(req->unique_msg_id);
383
desc->buffer = buffer;
385
desc->id = req->dsid;
386
desc->mbits = mbits | DS_RESPONSE_PUT;
390
rc = portals_me_attach(cp_nih,desc->id,desc->mbits,0,&desc->meh);
392
printf("me failed in prepost put\n");
398
md.threshold = desc->noperations;
399
md.options = PTL_MD_OP_PUT
400
| PTL_MD_EVENT_AUTO_UNLINK_ENABLE
401
| PTL_MD_EVENT_START_DISABLE
402
| PTL_MD_EVENT_END_DISABLE;
403
md.user_ptr = (void *) desc;
404
md.eq_handle = cp_eqh;
406
rc = portals_md_attach(desc->meh,md,PTL_UNLINK,&desc->mdh);
408
printf("md failed in prepost put\n");
412
// desc->state = STATE_UNLINK;
413
// |= needed for rendez-vous gets; put and get using the same descriptor
414
desc->state |= STATE_UNLINK;
420
portals_prepost_get_from_ds(void *buffer, size_t size, portals_ds_req_t *req) {
424
portals_desc_t *desc = &req->data_desc;
425
unsigned long mbits = req->unique_msg_id;
427
assert(req->unique_msg_id);
429
desc->buffer = buffer;
431
desc->id = req->dsid;
432
desc->mbits = mbits | DS_RESPONSE_GET;
436
rc = portals_me_attach(cp_nih,desc->id,desc->mbits,0,&desc->meh);
438
printf("me failed in prepost get\n");
444
md.threshold = desc->noperations;
445
md.options = PTL_MD_OP_GET
446
| PTL_MD_EVENT_START_DISABLE;
447
// | PTL_MD_EVENT_AUTO_UNLINK_ENABLE
448
// | PTL_MD_EVENT_START_DISABLE
449
// | PTL_MD_EVENT_END_DISABLE;
450
md.user_ptr = (void *) desc;
451
md.eq_handle = cp_eqh;
453
rc = portals_md_attach(desc->meh,md,PTL_UNLINK,&desc->mdh);
455
printf("md failed in prepost get\n");
459
// printf("%d: preposted get of lenght=%ld\n",armci_me,size);
460
// desc->state = STATE_UNLINK;
461
// desc->state = STATE_GET_END;
462
// |= needed for rendez-vous gets; put and get using the same descriptor
463
desc->state |= STATE_GET_END;
468
void portalsBlockingRemoteOperationToNode(void *buffer, size_t length, int remote_node) {
469
portals_ds_req_t req;
470
portals_req_clear(&req);
471
portalsRemoteOperationToNode(buffer,length,remote_node,&req);
472
portalsWaitOnRequest(&req);
476
void portalsRemoteOperationToNode(void *buffer, size_t length, int remote_node, portals_ds_req_t *req)
478
ptl_process_id_t id = portals_get_dsid_from_node(remote_node);
479
req->remote_node = remote_node;
480
portalsRemoteOperation(buffer,length,id,req);
485
void portalsRemoteOperationToRank(void *buffer, size_t length, int remote_rank, portals_ds_req_t *req) {
486
ptl_process_id_t id = portals_get_dsid_from_rank(remote_rank);
487
portalsRemoteOperation(buffer,length,id,req);
493
portalsRemoteOperation(void *buffer, size_t length, ptl_process_id_t dsid, portals_ds_req_t *req)
495
/* --------------------------------------------------------------------- *\
496
initialize the data server request
497
\* --------------------------------------------------------------------- */
498
// portals_req_clear(req);
500
req->unique_msg_id = portals_get_unique_msg_id();
503
/* --------------------------------------------------------------------- *\
504
the only response from the ds will be a 0-byte ack coming in as a put
505
\* --------------------------------------------------------------------- */
506
portals_prepost_ack_from_ds(req);
508
/* --------------------------------------------------------------------- *\
509
send data request; this is a completely blocking req
510
\* --------------------------------------------------------------------- */
511
portals_req_send(buffer,length,req);
516
portals_send_oper(int remote_node,int val, portals_ds_req_t *req)
519
request_header_t msg;
521
/* --------------------------------------------------------------------- *\
522
initialize the data server request
523
\* --------------------------------------------------------------------- */
524
portals_req_clear(req);
526
req->unique_msg_id = portals_get_unique_msg_id();
527
req->dsid = portals_get_dsid_from_node(remote_node);
528
req->remote_node = remote_node;
530
/* --------------------------------------------------------------------- *\
531
the only response from the ds will be a 0-byte ack coming in as a put
532
\* --------------------------------------------------------------------- */
533
portals_prepost_ack_from_ds(req);
535
/* --------------------------------------------------------------------- *\
536
prepare data request and send it; this is a completely blocking req
537
\* --------------------------------------------------------------------- */
539
portals_req_send(&msg,sizeof(request_header_t),req);
545
portals_send_QUIT(int remote_node)
547
portals_ds_req_t req;
548
portals_send_oper(remote_node,QUIT,&req);
549
portals_req_wait(&req);
554
portals_determine_remote_op_count(request_header_t *msg)
558
int datatype_extent = sizeof(double);
560
/* --------------------------------------------------------------------- *\
561
previously we have worked with words, but to provide support for
562
other data types, we must work with bytes. note to developers:
563
datatype_extent = the size in bytes of the stored datatype
564
\* --------------------------------------------------------------------- */
565
if(msg->size*datatype_extent <= MAX_DS_MSG_SIZE) return 1;
567
/* --------------------------------------------------------------------- *\
568
the data must be moved in segments; determine patch dimensions
569
\* --------------------------------------------------------------------- */
570
nr = msg->ihi - msg->ilo + 1;
571
nc = msg->jhi - msg->jlo + 1;
573
/* --------------------------------------------------------------------- *\
574
each column individually is too long to fit in the buffer
575
\* --------------------------------------------------------------------- */
576
if(nr*datatype_extent < MAX_DS_MSG_SIZE) {
578
/* ------------------------------------------------------------------ *\
579
np the number of "evenly" sized passed needed to send a column
580
\* ------------------------------------------------------------------ */
582
while(((nr/np)+((nr%np)?1:0)*datatype_extent)>MAX_DS_MSG_SIZE) np++;
584
/* ------------------------------------------------------------------ *\
585
noperations is np times the number of columns to be sent
586
\* ------------------------------------------------------------------ */
591
/* --------------------------------------------------------------------- *\
592
determine the number of full columns that can be sent in one pass
593
break down the subpatch on this metric
594
\* --------------------------------------------------------------------- */
597
/* ------------------------------------------------------------------ *\
598
np is the number of passes needed to send the full patch which
599
is broken down into "evenly" sized sets of columns that fit in
600
the allocated buffer region
601
\* ------------------------------------------------------------------ */
603
while(nr*((nc/np)+((nc%np)?1:0))*datatype_extent>MAX_DS_MSG_SIZE) np++;
605
/* ------------------------------------------------------------------ *\
607
\* ------------------------------------------------------------------ */
612
assert(0); // should not happen
620
portals_remote_rmw(void *buffer, request_header_t *msginfo, int remote_node, portals_ds_req_t *req)
624
/* --------------------------------------------------------------------- *\
625
initialize the data server request
626
\* --------------------------------------------------------------------- */
627
portals_req_clear(req);
629
req->unique_msg_id = portals_get_unique_msg_id();
630
req->dsid = portals_get_dsid_from_node(remote_node);
631
req->remote_node = remote_node;
633
/* --------------------------------------------------------------------- *\
634
prepare the buffer into which the ds will put data
635
\* --------------------------------------------------------------------- */
636
req->data_desc.noperations=portals_determine_remote_op_count(msginfo);
637
portals_prepost_put_from_ds(buffer,msginfo->datalen,req);
639
# ifdef PORTALS_LIMIT_REMOTE_REQUESTS_BY_NODE
640
portals_prepost_ack_from_ds(req);
643
/* --------------------------------------------------------------------- *\
645
note: from armci_send_req - if get, the value of bytes (local: length)
646
is msginfo->dscrlen + (hdrlen=sizeof(request_header_t) ... this is
647
the size of the "data server request message" to be sent
648
\* --------------------------------------------------------------------- */
649
length = sizeof(request_header_t) + msginfo->dscrlen + msginfo->datalen;
650
portals_req_send(msginfo,length,req);
654
portals_remote_get(void *buffer, request_header_t *msginfo, int remote_node)
656
portals_ds_req_t req;
657
portals_remote_nbget(buffer,msginfo,remote_node,&req);
658
portals_req_wait(&req);
662
portals_remote_nbget(void *buffer, request_header_t *msginfo, int remote_node, portals_ds_req_t *req)
666
/* --------------------------------------------------------------------- *\
667
initialize the data server request
668
\* --------------------------------------------------------------------- */
669
portals_req_clear(req);
671
req->unique_msg_id = portals_get_unique_msg_id();
672
req->dsid = portals_get_dsid_from_node(remote_node);
673
req->remote_node = remote_node;
675
/* --------------------------------------------------------------------- *\
676
prepare the buffer into which the ds will put data
677
\* --------------------------------------------------------------------- */
678
req->data_desc.noperations=portals_determine_remote_op_count(msginfo);
679
portals_prepost_put_from_ds(buffer,msginfo->datalen,req);
681
# ifdef PORTALS_LIMIT_REMOTE_REQUESTS_BY_NODE
682
portals_prepost_ack_from_ds(req);
685
/* --------------------------------------------------------------------- *\
687
note: from armci_send_req - if get, the value of bytes (local: length)
688
is msginfo->dscrlen + (hdrlen=sizeof(request_header_t) ... this is
689
the size of the "data server request message" to be sent
690
\* --------------------------------------------------------------------- */
691
length = sizeof(request_header_t) + msginfo->dscrlen;
693
# if defined(PORTALS_USE_RENDEZ_VOUS)
694
if(length < portalsMaxEagerMessageSize) portals_req_send(msginfo,length,req);
696
req->data_desc.noperations = 1;
697
portals_prepost_get_from_ds(msginfo,length,req);
699
/* ------------------------------------------------------------------ *\
700
send data request: branch here for eager vs. rendez-vous
701
\* ------------------------------------------------------------------ */
702
assert(length <= PORTALS_BUF_SIZE);
703
portals_req_send(msginfo,sizeof(request_header_t),req);
706
portals_req_send(msginfo,length,req);
712
portals_remote_put(void *buffer, request_header_t *msginfo, int remote_node)
714
portals_ds_req_t req;
715
portals_remote_nbput(buffer,msginfo,remote_node,&req);
716
portals_req_wait(&req);
721
portals_remote_nbput(void *buffer, request_header_t *msginfo, int remote_node, portals_ds_req_t *req)
723
char *eagerBuffer = NULL;
724
size_t eagerSendSize = 0;
726
/* --------------------------------------------------------------------- *\
727
initialize the data server request
728
\* --------------------------------------------------------------------- */
729
portals_req_clear(req);
731
req->unique_msg_id = portals_get_unique_msg_id();
732
req->dsid = portals_get_dsid_from_node(remote_node);
733
req->remote_node = remote_node;
735
/* --------------------------------------------------------------------- *\
736
prepost ack response from the data server
737
\* --------------------------------------------------------------------- */
738
portals_prepost_ack_from_ds(req);
740
/* --------------------------------------------------------------------- *\
741
eager vs. rendez-vous messaging
742
eager: pack and send the message immediate (only for small messages)
743
developers note: since portals_eager_send_buffer only exists once,
744
this has to be a blocking send (ie the data is on the wire when
745
req_send has finished and the buffer can be reused. for greater
746
overlap, create a set of eager send buffers ... however they have to
747
be managed ... probably best to do it in a ring.
749
note: armci put/acc buffer is prepacked.
750
\* --------------------------------------------------------------------- */
751
eagerSendSize = sizeof(request_header_t) + msginfo->dscrlen + msginfo->datalen;
752
if(eagerSendSize < portalsMaxEagerMessageSize) {
753
// printf("sending eager message\n");
754
# if 0 /* armci prepacked */
755
eagerBuffer = (char *) portals_eager_send_buffer;
756
memcpy(eagerBuffer,msginfo,sizeof(request_header_t));
757
eagerBuffer += sizeof(request_header_t);
758
memcpy(eagerBuffer,buffer,msginfo->bytes);
760
eagerBuffer = (char *) msginfo; /* buffer == msginfo for armci */
761
portals_req_send(eagerBuffer,eagerSendSize,req);
764
/* --------------------------------------------------------------------- *\
765
rendez-vous: send the ds a request; ds will "get/pull" data
766
\* --------------------------------------------------------------------- */
768
# ifdef PORTALS_USE_RENDEZ_VOUS
769
/* ------------------------------------------------------------------ *\
770
prepare the buffer into which the ds will put data
771
\* ------------------------------------------------------------------ */
772
// req->data_desc.noperations=portals_determine_remote_op_count(msginfo);
773
req->data_desc.noperations = 1;
774
portals_prepost_get_from_ds(msginfo,eagerSendSize,req);
776
/* ------------------------------------------------------------------ *\
777
send data request: branch here for eager vs. rendez-vous
778
\* ------------------------------------------------------------------ */
779
assert(eagerSendSize <= PORTALS_BUF_SIZE);
780
portals_req_send(msginfo,sizeof(request_header_t),req);
783
printf("%d [cp]: rendez-vous messaging not supported\n",armci_me);
794
portals_remote_acc(void *buffer, request_header_t *msginfo, int remote_node)
796
portals_ds_req_t req;
797
portals_remote_nbacc(buffer,msginfo,remote_node,&req);
798
portals_req_wait(&req);
803
portals_remote_nbacc(void *buffer, request_header_t *msginfo, int remote_node, portals_ds_req_t *req)
805
char *eagerBuffer = NULL;
806
size_t eagerSendSize = 0;
808
assert(msginfo->bytes);
810
/* --------------------------------------------------------------------- *\
811
initialize the data server request
812
\* --------------------------------------------------------------------- */
813
portals_req_clear(req);
815
req->unique_msg_id = portals_get_unique_msg_id();
816
req->dsid = portals_get_dsid_from_node(remote_node);
818
/* --------------------------------------------------------------------- *\
819
eager vs. rendez-vous messaging
820
eager: pack and send the message immediate (only for small messages)
821
\* --------------------------------------------------------------------- */
822
eagerSendSize = msginfo->bytes + sizeof(request_header_t);
823
if(eagerSendSize < portalsMaxEagerMessageSize) {
825
/* ------------------------------------------------------------------ *\
826
prepost ack response from the data server
827
developers note: if you globally fence an array with a collective
828
operation prior to a section of code and defence it after, then you
829
don't need to micro manage the fence on a per request basis in that
830
section; this eliminates the need for a DS ack
831
\* ------------------------------------------------------------------ */
832
portals_prepost_ack_from_ds(req);
834
/* ------------------------------------------------------------------ *\
835
pack and send eager data request
836
blocking for now, since portals_eager_send_buffer only exists once
837
create multiple eager buffers for greater overlap
838
\* ------------------------------------------------------------------ */
839
eagerBuffer = (char *) portals_eager_send_buffer;
840
memcpy(eagerBuffer,msginfo,sizeof(request_header_t));
841
eagerBuffer += sizeof(request_header_t);
842
memcpy(eagerBuffer,buffer,msginfo->bytes);
843
eagerBuffer = (char *) portals_eager_send_buffer;
844
portals_req_send(eagerBuffer,eagerSendSize,req);
847
/* --------------------------------------------------------------------- *\
848
rendez-vous: send the ds a request; ds will "get/pull" data
849
developers note: a ds ack is not required for a rendez-vous pull,
850
this is because the ds will not start the pull until a local fence
851
has been raised (if needed - see note above)
852
\* --------------------------------------------------------------------- */
854
/* ------------------------------------------------------------------ *\
855
prepare the buffer from which the ds will pull data
856
\* ------------------------------------------------------------------ */
857
req->data_desc.noperations=portals_determine_remote_op_count(msginfo);
858
portals_prepost_get_from_ds(buffer,msginfo->bytes,req);
860
/* ------------------------------------------------------------------ *\
862
\* ------------------------------------------------------------------ */
863
portals_req_send(msginfo,sizeof(request_header_t),req);
864
portalsWaitOnRequest(req);
869
extern int armci_shmget(size_t,char*);
870
extern int armci_semget(int);
871
extern void *shmat(int,int,int);
874
portals_cp_init_throttle(int nnodes)
876
int i, shmid, smp_np, smp_me;
877
size_t size = nnodes*sizeof(int);
880
MPI_Comm_size(portals_smp_comm,&smp_np);
881
MPI_Comm_rank(portals_smp_comm,&smp_me);
884
# ifdef PORTALS_LIMIT_REMOTE_REQUESTS_BY_NODE
885
if(armci_me == armci_master) {
886
if(smp_me != 0) armci_die("smp_me and armci_master are different",911);
890
shmid = armci_shmget(size,"portals_cp_init_throttle");
891
active_requests_by_node = (int *) shmat(shmid,0,0);
892
if(active_requests_by_node == (void *) -1) {
893
printf("%d [cp] shmat failed for shmid %d\n",armci_me,shmid);
894
armci_die("badness",911);
897
for(i=0; i<nnodes; i++) active_requests_by_node[i] = 0;
898
portals_smp_sem = armci_semget(2);
899
semaphoreOperation(portals_smp_sem,1,PORTALS_WRITE_ACCESS);
902
MPI_Bcast(&shmid,1,MPI_INT,0,portals_smp_comm);
903
MPI_Bcast(&portals_smp_sem,1,MPI_INT,0,portals_smp_comm);
906
active_requests_by_node = (int *) shmat(shmid,0,0);
910
MPI_Barrier(portals_smp_comm);