ROSS
network-mpi.c
Go to the documentation of this file.
1 #include <ross.h>
2 #include <mpi.h>
3 
4 MPI_Comm MPI_COMM_ROSS = MPI_COMM_WORLD;
6 
7 /**
8  * @struct act_q
9  * @brief Keeps track of posted send or recv operations.
10  *
11  * This list structure is used *only* by the network mpi layer (this
12  * file). Within this file, two lists are used, for MPI Irecv and
13  * Isend requests. The MPI requests and statusus are linked with an
14  * event buffer through this struct.
15  */
16 struct act_q
17 {
18  const char *name; /**< name of the list, used in error printouts */
19 
20  tw_event **event_list; /**< list of event pointers in this queue */
21  MPI_Request *req_list; /**< list of MPI request handles */
22  int *idx_list; /**< indices in this queue of finished operations */
23  MPI_Status *status_list; /**< list of MPI_Status handles */
24  unsigned int cur; /**< index of first open spot in the queue */
25 };
26 
27 #define EVENT_TAG 1
28 
29 #define EVENT_SIZE(e) g_tw_event_msg_sz
30 
31 static struct act_q posted_sends;
32 static struct act_q posted_recvs;
33 static tw_eventq outq;
34 
35 static unsigned int read_buffer = 16; /**< Number of Irecv's to buffer, length of posted_recvs queue */
36 static unsigned int send_buffer = 1024; /**< Number of Isend's to buffer, length of posted_sends queue */
37 static int world_size = 1;
38 
39 static const tw_optdef mpi_opts[] = {
40  TWOPT_GROUP("ROSS MPI Kernel"),
41  TWOPT_UINT(
42  "read-buffer",
44  "network read buffer size in # of events"),
45  TWOPT_UINT(
46  "send-buffer",
48  "network send buffer size in # of events"),
49  TWOPT_END()
50 };
51 
52 // Forward declarations of functions used in MPI network message processing
53 static int recv_begin(tw_pe *me);
54 static void recv_finish(tw_pe *me, tw_event *e, char * buffer);
55 static int send_begin(tw_pe *me);
56 static void send_finish(tw_pe *me, tw_event *e, char * buffer);
57 
58 // Start of implmentation of network processing routines/functions
59 void tw_comm_set(MPI_Comm comm)
60 {
61  MPI_COMM_ROSS = comm;
63 }
64 
65 const tw_optdef *
66 tw_net_init(int *argc, char ***argv)
67 {
68  int my_rank;
69  int initialized;
70  MPI_Initialized(&initialized);
71 
72  if (!initialized) {
73  if (MPI_Init(argc, argv) != MPI_SUCCESS)
74  tw_error(TW_LOC, "MPI_Init failed.");
75  }
76 
77  if (MPI_Comm_rank(MPI_COMM_ROSS, &my_rank) != MPI_SUCCESS)
78  tw_error(TW_LOC, "Cannot get MPI_Comm_rank(MPI_COMM_ROSS)");
79 
80  g_tw_masternode = 0;
81  g_tw_mynode = my_rank;
82 
83  return mpi_opts;
84 }
85 
86 /**
87  * @brief Initializes queues used for posted sends and receives
88  *
89  * @param[in] q pointer to the queue to be initialized
90  * @param[in] name name of the queue
91  */
92 static void
93 init_q(struct act_q *q, const char *name, unsigned int size)
94 {
95  q->name = name;
96  q->event_list = (tw_event **) tw_calloc(TW_LOC, name, sizeof(tw_event *), size);
97  q->req_list = (MPI_Request *) tw_calloc(TW_LOC, name, sizeof(MPI_Request), size);
98  q->idx_list = (int *) tw_calloc(TW_LOC, name, sizeof(int), size);
99  q->status_list = (MPI_Status *) tw_calloc(TW_LOC, name, sizeof(MPI_Status), size);
100 }
101 
102 unsigned int
104 {
105  return world_size;
106 }
107 
108 void
110 {
111  // sets value of tw_nnodes
112  if (MPI_Comm_size(MPI_COMM_ROSS, &world_size) != MPI_SUCCESS)
113  tw_error(TW_LOC, "Cannot get MPI_Comm_size(MPI_COMM_ROSS)");
114 
115  if( g_tw_mynode == 0)
116  {
117  printf("tw_net_start: Found world size to be %d \n", world_size );
118  }
119 
120  // Check after tw_nnodes is defined
121  if(tw_nnodes() == 1) {
122  // force the setting of SEQUENTIAL protocol
127  fprintf(stderr, "Warning: Defaulting to Sequential Simulation, not enough PEs defined.\n");
128  }
129  }
130 
131  tw_pe_init();
132 
133  // these values are command line options
134  if (send_buffer < 1) tw_error(TW_LOC, "network send buffer must be >= 1");
135  if (read_buffer < 1) tw_error(TW_LOC, "network read buffer must be >= 1");
136 
137  init_q(&posted_sends, "MPI send queue", send_buffer);
138  init_q(&posted_recvs, "MPI recv queue", read_buffer);
139 
141 
142  // pre-post all the Irecv operations
144 }
145 
146 void
148 {
149  MPI_Abort(MPI_COMM_ROSS, 1);
150  exit(1);
151 }
152 
153 void
155 {
156 #ifdef USE_DAMARIS
157  if (g_st_damaris_enabled)
158  st_damaris_ross_finalize();
159  else
160  {
161  if (!custom_communicator) {
162  if (MPI_Finalize() != MPI_SUCCESS)
163  tw_error(TW_LOC, "Failed to finalize MPI");
164  }
165  }
166 #else
167  if (!custom_communicator) {
168  if (MPI_Finalize() != MPI_SUCCESS)
169  tw_error(TW_LOC, "Failed to finalize MPI");
170  }
171 #endif
172 }
173 
174 void
176 {
177  if (MPI_Barrier(MPI_COMM_ROSS) != MPI_SUCCESS)
178  tw_error(TW_LOC, "Failed to wait for MPI_Barrier");
179 }
180 
181 tw_stime
183 {
185  tw_event *e;
186  unsigned int i;
187 
188  e = outq.head;
189  while (e) {
190  if (TW_STIME_CMP(m, e->recv_ts) > 0)
191  m = e->recv_ts;
192  e = e->next;
193  }
194 
195  for (i = 0; i < posted_sends.cur; i++) {
196  e = posted_sends.event_list[i];
197  if (TW_STIME_CMP(m, e->recv_ts) > 0)
198  m = e->recv_ts;
199  }
200 
201  return m;
202 }
203 
204 /**
205  * @brief Calls MPI_Testsome on the provided queue, to check for finished operations.
206  *
207  * @param[in] q queue to check
208  * @param[in] me pointer to the PE
209  * @param[in] finish pointer to function that will perform the appropriate send/recv
210  * finish functionality
211  *
212  * @return 0 if MPI_Testsome did not return any finished operations, 1 otherwise.
213  */
214 static int
216  struct act_q *q,
217  tw_pe *me,
218  void (*finish)(tw_pe *, tw_event *, char *))
219 {
220  int ready, i, n;
221 
222  if (!q->cur)
223  return 0;
224 
225  if (MPI_Testsome(
226  q->cur,
227  q->req_list,
228  &ready,
229  q->idx_list,
230  q->status_list) != MPI_SUCCESS) {
231  tw_error(
232  TW_LOC,
233  "MPI_testsome failed with %u items in %s",
234  q->cur,
235  q->name);
236  }
237 
238  if (1 > ready)
239  return 0;
240 
241  for (i = 0; i < ready; i++)
242  {
243  tw_event *e;
244 
245  n = q->idx_list[i];
246  e = q->event_list[n];
247  q->event_list[n] = NULL;
248 
249  finish(me, e, NULL);
250  }
251 
252  /* Collapse the lists to remove any holes we left. */
253  for (i = 0, n = 0; (unsigned int)i < q->cur; i++)
254  {
255  if (q->event_list[i])
256  {
257  if (i != n)
258  {
259  // swap the event pointers
260  q->event_list[n] = q->event_list[i];
261 
262  // copy the request handles
263  memcpy(
264  &q->req_list[n],
265  &q->req_list[i],
266  sizeof(q->req_list[0]));
267 
268  } // endif (i != n)
269  n++;
270  } // endif (q->event_list[i])
271  }
272  q->cur -= ready;
273 
274  return 1;
275 }
276 
277 /**
278  * @brief If there are any openings in the posted_recvs queue, post more Irecvs.
279  *
280  * @param[in] me pointer to the PE
281  * @return 0 if no changes are made to the queue, 1 otherwise.
282  */
283 static int
285 {
286  tw_event *e = NULL;
287 
288  int changed = 0;
289 
290  while (posted_recvs.cur < read_buffer)
291  {
292  unsigned id = posted_recvs.cur;
293 
294  if(!(e = tw_event_grab(me)))
295  {
296  if(tw_gvt_inprogress(me))
297  tw_error(TW_LOC, "Out of events in GVT! Consider increasing --extramem");
298  return changed;
299  }
300 
301  if( MPI_Irecv(e,
302  (int)EVENT_SIZE(e),
303  MPI_BYTE,
304  MPI_ANY_SOURCE,
305  EVENT_TAG,
307  &posted_recvs.req_list[id]) != MPI_SUCCESS)
308  {
309  tw_event_free(me, e);
310  return changed;
311  }
312 
313  posted_recvs.event_list[id] = e;
314  posted_recvs.cur++;
315  changed = 1;
316  }
317 
318  return changed;
319 }
320 
321 /**
322  * @brief Determines how to handle the newly received event.
323  *
324  * @param[in] me pointer to PE
325  * @param[in] e pointer to event that we just received
326  * @param[in] buffer not currently used
327  */
328 static void
329 recv_finish(tw_pe *me, tw_event *e, char * buffer)
330 {
331  (void) buffer;
332  tw_pe *dest_pe;
333  tw_clock start;
334 
335  me->stats.s_nread_network++;
336  me->s_nwhite_recv++;
337 
338  // printf("recv_finish: remote event [cancel %u] FROM: LP %lu, PE %lu, TO: LP %lu, PE %lu at TS %lf \n",
339  // e->state.cancel_q, (tw_lpid)e->src_lp, e->send_pe, (tw_lpid)e->dest_lp, me->id, e->recv_ts);
340 
342  dest_pe = e->dest_lp->pe;
343  // instrumentation
346 
347  if(e->send_pe > tw_nnodes()-1)
348  tw_error(TW_LOC, "bad sendpe_id: %d", e->send_pe);
349 
350  e->cancel_next = NULL;
351  e->caused_by_me = NULL;
352  e->cause_next = NULL;
353 
354 
355 
356  if(TW_STIME_CMP(e->recv_ts, me->GVT) < 0)
357  tw_error(TW_LOC, "%d: Received straggler from %d: %lf (%d)",
358  me->id, e->send_pe, e->recv_ts, e->state.cancel_q);
359 
360  if(tw_gvt_inprogress(me))
361  me->trans_msg_ts = (TW_STIME_CMP(me->trans_msg_ts, e->recv_ts) < 0) ? me->trans_msg_ts : e->recv_ts;
362 
363  // if cancel event, retrieve and flush
364  // else, store in hash table
365  if(e->state.cancel_q)
366  {
367  tw_event *cancel = tw_hash_remove(me->hash_t, e, e->send_pe);
368 
369  // NOTE: it is possible to cancel the event we
370  // are currently processing at this PE since this
371  // MPI module lets me read cancel events during
372  // event sends over the network.
373 
374  cancel->state.cancel_q = 1;
375  cancel->state.remote = 0;
376 
377  cancel->cancel_next = dest_pe->cancel_q;
378  dest_pe->cancel_q = cancel;
379 
380  tw_event_free(me, e);
381 
382  return;
383  }
384 
388  tw_hash_insert(me->hash_t, e, e->send_pe);
389  e->state.remote = 1;
390  }
391 
392  /* NOTE: the final check in the if conditional below was added to make sure
393  * that we do not execute the fast case unless the cancellation queue is
394  * empty on the destination PE. Otherwise we need to invoke the normal
395  * scheduling routines to make sure that a forward event doesn't bypass a
396  * cancellation event with an earlier timestamp. This is helpful for
397  * stateful models that produce incorrect results when presented with
398  * duplicate messages with no rollback between them.
399  */
400  if(me == dest_pe && TW_STIME_CMP(e->dest_lp->kp->last_time, e->recv_ts) <= 0 && !dest_pe->cancel_q) {
401  /* Fast case, we are sending to our own PE and
402  * there is no rollback caused by this send.
403  */
404  start = tw_clock_read();
405  tw_pq_enqueue(dest_pe->pq, e);
406  dest_pe->stats.s_pq += tw_clock_read() - start;
407  return;
408  }
409 
410  if (me->id == dest_pe->id) {
411  /* Slower, but still local send, so put into top
412  * of dest_pe->event_q.
413  */
415  tw_eventq_push(&dest_pe->event_q, e);
416  return;
417  }
418 
419  /* Never should happen; MPI should have gotten the
420  * message to the correct node without needing us
421  * to redirect the message there for it. This is
422  * probably a serious bug with the event headers
423  * not being formatted right.
424  */
425  tw_error(
426  TW_LOC,
427  "Event recived by PE %u but meant for PE %u",
428  me->id,
429  dest_pe->id);
430 }
431 
432 /**
433  * @brief If there are any openings in the posted_sends queue, start sends
434  * for events in the outgoing queue.
435  *
436  * @param[in] me pointer to the PE
437  * @return 0 if no changes are made to the posted_sends queue, 1 otherwise.
438  */
439 static int
441 {
442  int changed = 0;
443 
444  while (posted_sends.cur < send_buffer)
445  {
446  tw_event *e = tw_eventq_peek(&outq);
447  tw_peid dest_pe;
448 
449  unsigned id = posted_sends.cur;
450 
451  if (!e)
452  break;
453 
454  if(e == me->abort_event)
455  tw_error(TW_LOC, "Sending abort event!");
456 
457  dest_pe = (*e->src_lp->type->map) ((tw_lpid) e->dest_lp);
458 
459  e->send_pe = (tw_peid) g_tw_mynode;
460  e->send_lp = e->src_lp->gid;
461 
462  if (MPI_Isend(e,
463  (int)EVENT_SIZE(e),
464  MPI_BYTE,
465  (int)dest_pe,
466  EVENT_TAG,
468  &posted_sends.req_list[id]) != MPI_SUCCESS) {
469  return changed;
470  }
471 
472  tw_eventq_pop(&outq);
473  e->state.owner = e->state.cancel_q
475  : TW_net_asend;
476 
477  posted_sends.event_list[id] = e;
478  posted_sends.cur++;
479  me->s_nwhite_sent++;
480 
481  changed = 1;
482  }
483  return changed;
484 }
485 
486 /**
487  * @brief Determines how to handle the buffer of event whose send operation
488  * just finished.
489  *
490  * @param[in] me pointer to PE
491  * @param[in] e pointer to event that we just received
492  * @param[in] buffer not currently used
493  */
494 static void
495 send_finish(tw_pe *me, tw_event *e, char * buffer)
496 {
497  (void) buffer;
498  me->stats.s_nsend_network++;
499  // instrumentation
502 
503  if (e->state.owner == TW_net_asend) {
504  if (e->state.cancel_asend) {
505  /* Event was cancelled during transmission. We must
506  * send another message to pass the cancel flag to
507  * the other node.
508  */
509  e->state.cancel_asend = 0;
510  e->state.cancel_q = 1;
511  tw_eventq_push(&outq, e);
512  } else {
513  /* Event finished transmission and was not cancelled.
514  * Add to our sent event queue so we can retain the
515  * event in case we need to cancel it later. Note it
516  * is currently in remote format and must be converted
517  * back to local format for fossil collection.
518  */
521  tw_event_free(me, e);
522  }
523 
524  return;
525  }
526 
527  if (e->state.owner == TW_net_acancel) {
528  /* We just finished sending the cancellation message
529  * for this event. We need to free the buffer and
530  * make it available for reuse.
531  */
532  tw_event_free(me, e);
533  return;
534  }
535 
536  /* Never should happen, not unless we somehow broke this
537  * module's other functions related to sending an event.
538  */
539 
540  tw_error(
541  TW_LOC,
542  "Don't know how to finish send of owner=%u, cancel_q=%d",
543  e->state.owner,
544  e->state.cancel_q);
545 
546 }
547 
548 /**
549  * @brief Start checks for finished operations in send/recv queues,
550  * and post new sends/recvs if possible.
551  * @param[in] me pointer to PE
552  */
553 static void
555 {
556  int changed;
557  do {
558  changed = test_q(&posted_recvs, me, recv_finish);
559  changed |= test_q(&posted_sends, me, send_finish);
560  changed |= recv_begin(me);
561  changed |= send_begin(me);
562  } while (changed);
563 }
564 
565 /*
566  * NOTE: Chris believes that this network layer is too aggressive at
567  * reading events out of the network.. so we are modifying the algorithm
568  * to only send events when tw_net_send it called, and only read events
569  * when tw_net_read is called.
570  */
571 void
573 {
574  service_queues(me);
575 }
576 
577 void
579 {
580  tw_pe * me = e->src_lp->pe;
581  int changed = 0;
582 
583  e->state.remote = 0;
584  e->state.owner = TW_net_outq;
585  tw_eventq_unshift(&outq, e);
586 
587  do
588  {
589  changed = test_q(&posted_sends, me, send_finish);
590  changed |= send_begin(me);
591  } while (changed);
592 }
593 
594 void
596 {
597  tw_pe *src_pe = e->src_lp->pe;
598 
599  switch (e->state.owner) {
600  case TW_net_outq:
601  /* Cancelled before we could transmit it. Do not
602  * transmit the event and instead just release the
603  * buffer back into our own free list.
604  */
605  tw_eventq_delete_any(&outq, e);
606  tw_event_free(src_pe, e);
607 
608  return;
609 
610  break;
611 
612  case TW_net_asend:
613  /* Too late. We've already let MPI start to send
614  * this event over the network. We can't pull it
615  * back now without sending another message to do
616  * the cancel.
617  *
618  * Setting the cancel_q flag will signal us to do
619  * another message send once the current send of
620  * this message is completed.
621  */
622  e->state.cancel_asend = 1;
623  break;
624 
625  case TW_pe_sevent_q:
626  /* Way late; the event was already sent and is in
627  * our sent event queue. Mark it as a cancel and
628  * place it at the front of the outq.
629  */
630  e->state.cancel_q = 1;
631  tw_eventq_unshift(&outq, e);
632  break;
633 
634  default:
635  /* Huh? Where did you come from? Why are we being
636  * told about you? We did not send you so we cannot
637  * cancel you!
638  */
639  tw_error(
640  TW_LOC,
641  "Don't know how to cancel event owned by %u",
642  e->state.owner);
643  }
644 
645  service_queues(src_pe);
646 }
647 
648 /**
649  * tw_net_statistics
650  * @brief Function to output the statistics
651  * @attention Notice that the MPI_Reduce "count" parameter is greater than one.
652  * We are reducing on multiple variables *simultaneously* so if you change
653  * this function or the struct tw_statistics, you must update the other.
654  **/
657 {
658  if(MPI_Reduce(&(s->s_max_run_time),
659  &me->stats.s_max_run_time,
660  1,
661  MPI_DOUBLE,
662  MPI_MAX,
663  (int)g_tw_masternode,
664  MPI_COMM_ROSS) != MPI_SUCCESS)
665  tw_error(TW_LOC, "Unable to reduce statistics!");
666 
667  if(MPI_Reduce(&(s->s_net_events),
668  &me->stats.s_net_events,
669  17,
670  MPI_UNSIGNED_LONG_LONG,
671  MPI_SUM,
672  (int)g_tw_masternode,
673  MPI_COMM_ROSS) != MPI_SUCCESS)
674  tw_error(TW_LOC, "Unable to reduce statistics!");
675 
676  if(MPI_Reduce(&s->s_min_detected_offset,
678  1,
679  MPI_DOUBLE,
680  MPI_MIN,
681  (int)g_tw_masternode,
682  MPI_COMM_ROSS) != MPI_SUCCESS)
683  tw_error(TW_LOC, "Unable to reduce statistics!");
684 
685  if(MPI_Reduce(&(s->s_total),
686  &me->stats.s_total,
687  16,
688  MPI_UNSIGNED_LONG_LONG,
689  MPI_MAX,
690  (int)g_tw_masternode,
691  MPI_COMM_ROSS) != MPI_SUCCESS)
692  tw_error(TW_LOC, "Unable to reduce statistics!");
693 
694  if (MPI_Reduce(&s->s_events_past_end,
696  3,
697  MPI_UNSIGNED_LONG_LONG,
698  MPI_SUM,
699  (int)g_tw_masternode,
700  MPI_COMM_ROSS) != MPI_SUCCESS)
701  tw_error(TW_LOC, "Unable to reduce statistics!");
702 
703 #ifdef USE_RIO
704  if (MPI_Reduce(&s->s_rio_load,
705  &me->stats.s_rio_load,
706  1,
707  MPI_UNSIGNED_LONG_LONG,
708  MPI_MAX,
709  (int)g_tw_masternode,
710  MPI_COMM_ROSS) != MPI_SUCCESS)
711  tw_error(TW_LOC, "Unable to reduce statistics!");
712  if (MPI_Reduce(&s->s_rio_lp_init,
713  &me->stats.s_rio_lp_init,
714  1,
715  MPI_UNSIGNED_LONG_LONG,
716  MPI_MAX,
717  (int)g_tw_masternode,
718  MPI_COMM_ROSS) != MPI_SUCCESS)
719  tw_error(TW_LOC, "Unable to reduce statistics!");
720 #endif
721 
722  return &me->stats;
723 }
long long s_nwhite_recv
Definition: ross-types.h:409
tw_synch g_tw_synchronization_protocol
Definition: ross-global.c:18
#define TW_LOC
Definition: ross-extern.h:164
Network transmission in progress.
Definition: ross-types.h:220
unsigned int s_nsend_network
static unsigned int send_buffer
Definition: network-mpi.c:36
tw_lp * dest_lp
Destination LP ID.
Definition: ross-types.h:280
tw_eventq event_q
Linked list of events sent to this PE.
Definition: ross-types.h:379
void tw_net_cancel(tw_event *e)
Cancel the given remote event by either removing from the outq or sending an antimessage, depending on the status of the original positive send.
Definition: network-mpi.c:595
const char * name
Definition: network-mpi.c:18
double tw_stime
Definition: ross.h:150
static tw_event * tw_event_grab(tw_pe *pe)
Definition: ross-inline.h:5
tw_clock s_pq
Definition: ross-types.h:143
void tw_net_stop(void)
Stops the network library after simulation end.
Definition: network-mpi.c:154
tw_event * head
Definition: ross-types.h:167
struct st_lp_stats * lp_stats
Definition: ross-types.h:323
void tw_error(const char *file, int line, const char *fmt,...) NORETURN
Definition: tw-util.c:74
tw_lptype * type
Type of this LP, including service callbacks.
Definition: ross-types.h:316
static void recv_finish(tw_pe *me, tw_event *e, char *buffer)
Determines how to handle the newly received event.
Definition: network-mpi.c:329
struct st_kp_stats * kp_stats
Definition: ross-types.h:366
void tw_pe_init(void)
Definition: tw-pe.c:32
unsigned int cur
Definition: network-mpi.c:24
static struct act_q posted_sends
Definition: network-mpi.c:31
tw_statistics stats
per PE counters
Definition: ross-types.h:415
static tw_event * tw_eventq_peek(tw_eventq *q)
Definition: tw-eventq.h:280
static int world_size
Definition: network-mpi.c:37
tw_stime recv_ts
Actual time to be received.
Definition: ross-types.h:282
MPI_Status * status_list
Definition: network-mpi.c:23
void tw_comm_set(MPI_Comm comm)
Setup the MPI_COMM_ROSS communicator to use instead of MPI_COMM_WORLD.
Definition: network-mpi.c:59
static void tw_eventq_delete_any(tw_eventq *q, tw_event *e)
Definition: tw-eventq.h:384
void tw_net_read(tw_pe *me)
starts service_queues() to poll network
Definition: network-mpi.c:572
tw_event * cancel_next
Next event in the cancel queue for the dest_pe.
Definition: ross-types.h:260
static tw_clock tw_clock_read(void)
Definition: aarch64.h:6
static void tw_event_free(tw_pe *, tw_event *)
map_f map
LP Mapping of LP gid -> remote PE routine.
Definition: ross-types.h:94
tw_stime trans_msg_ts
Last transient messages' time stamp.
Definition: ross-types.h:402
Holds the entire PE state.
Definition: ross-types.h:375
const tw_optdef * tw_net_init(int *argc, char ***argv)
Initalize the network library and parse options.
Definition: network-mpi.c:66
Network transmission in progress.
Definition: ross-types.h:219
MPI_Comm MPI_COMM_ROSS
Definition: network-mpi.c:4
tw_event * cancel_q
List of canceled events.
Definition: ross-types.h:380
unsigned int tw_nnodes(void)
Definition: network-mpi.c:103
unsigned int s_nsend_network
tw_stat s_nsend_network
Definition: ross-types.h:121
static unsigned int read_buffer
Definition: network-mpi.c:35
void tw_net_barrier(void)
Definition: network-mpi.c:175
tw_stime tw_net_minimum(void)
Obtain the lowest timestamp inside the network buffers.
Definition: network-mpi.c:182
#define EVENT_TAG
Definition: network-mpi.c:27
Keeps track of posted send or recv operations.
Definition: network-mpi.c:16
uint64_t tw_lpid
Definition: ross.h:160
tw_stat s_net_events
Definition: ross-types.h:110
tw_kp * kp
kp – Kernel process that we belong to (must match pe).
Definition: ross-types.h:313
Statistics tallied over the duration of the simulation.
Definition: ross-types.h:107
unsigned int g_tw_net_device_size
Definition: ross-global.c:87
Event Stucture.
Definition: ross-types.h:250
static tw_eventq outq
Definition: network-mpi.c:33
void tw_hash_insert(void *h, tw_event *event, long pe)
unsigned int s_nread_network
tw_stat s_nread_network
Definition: ross-types.h:122
tw_lpid gid
global LP id
Definition: ross-types.h:306
#define TW_STIME_CMP(x, y)
Definition: ross.h:154
static const tw_optdef mpi_opts[]
Definition: network-mpi.c:39
tw_event * abort_event
Placeholder event for when free_q is empty.
Definition: ross-types.h:384
tw_event * next
Definition: ross-types.h:251
static void init_q(struct act_q *q, const char *name, unsigned int size)
Initializes queues used for posted sends and receives.
Definition: network-mpi.c:93
tw_event ** event_list
Definition: network-mpi.c:20
void * hash_t
Array of incoming events from remote pes, Note: only necessary for distributed DSR.
Definition: ross-types.h:418
double s_max_run_time
Definition: ross-types.h:108
static int tw_gvt_inprogress(tw_pe *pe)
Definition: mpi_allreduce.h:8
void tw_pq_enqueue(splay_tree *st, tw_event *e)
Definition: splay.c:195
tw_event * cause_next
Next in parent's caused_by_me chain.
Definition: ross-types.h:262
#define EVENT_SIZE(e)
Definition: network-mpi.c:29
tw_lpid send_lp
sending LP ID for data collection uses
Definition: ross-types.h:285
tw_event * caused_by_me
Start of event list caused by this event.
Definition: ross-types.h:261
tw_peid g_tw_mynode
Definition: ross-global.c:88
#define TWOPT_UINT(n, v, h)
Definition: tw-opts.h:30
#define TW_STIME_MAX
Definition: ross.h:156
tw_peid g_tw_masternode
Definition: ross-global.c:89
#define TWOPT_END()
Definition: tw-opts.h:35
int custom_communicator
Definition: network-mpi.c:5
tw_pq * pq
Priority queue used to sort events.
Definition: ross-types.h:381
static int send_begin(tw_pe *me)
If there are any openings in the posted_sends queue, start sends for events in the outgoing queue...
Definition: network-mpi.c:440
tw_statistics * tw_net_statistics(tw_pe *me, tw_statistics *s)
Function to output the statistics.
Definition: network-mpi.c:656
static tw_event * tw_eventq_pop(tw_eventq *q)
Definition: tw-eventq.h:289
unsigned int s_nread_network
double s_min_detected_offset
Definition: ross-types.h:132
Pending network transmission.
Definition: ross-types.h:218
static void tw_eventq_push(tw_eventq *q, tw_event *e)
Definition: tw-eventq.h:257
tw_peid send_pe
Definition: ross-types.h:284
In tw_pe.sevent_q.
Definition: ross-types.h:221
tw_pe * g_tw_pe
Definition: ross-global.c:75
void tw_net_abort(void)
Definition: network-mpi.c:147
struct tw_event::@0 state
static void tw_eventq_unshift(tw_eventq *q, tw_event *e)
Definition: tw-eventq.h:320
tw_pe * pe
Definition: ross-types.h:308
long long s_nwhite_sent
Definition: ross-types.h:408
unsigned char remote
Indicates union addr is in 'remote' storage.
Definition: ross-types.h:271
tw_stime GVT
Global Virtual Time.
Definition: ross-types.h:403
static struct act_q posted_recvs
Definition: network-mpi.c:32
MPI_Request * req_list
Definition: network-mpi.c:21
unsigned long tw_peid
Definition: ross.h:147
uint64_t tw_clock
Definition: aarch64.h:4
#define TWOPT_GROUP(h)
Definition: tw-opts.h:27
tw_lp * src_lp
Sending LP ID.
Definition: ross-types.h:281
static int recv_begin(tw_pe *me)
If there are any openings in the posted_recvs queue, post more Irecvs.
Definition: network-mpi.c:284
void tw_net_send(tw_event *e)
Adds the event to the outgoing queue of events to be sent, polls for finished sends, and attempts to start sends from outq.
Definition: network-mpi.c:578
void tw_net_start(void)
Starts the network library after option parsing.
Definition: network-mpi.c:109
static int test_q(struct act_q *q, tw_pe *me, void(*finish)(tw_pe *, tw_event *, char *))
Calls MPI_Testsome on the provided queue, to check for finished operations.
Definition: network-mpi.c:215
tw_peid id
Definition: ross-types.h:376
tw_stat s_events_past_end
Definition: ross-types.h:154
static tw_lp * tw_getlocal_lp(tw_lpid gid)
tw_event * tw_hash_remove(void *h, tw_event *event, long pe)
tw_clock s_total
Definition: ross-types.h:134
void * tw_calloc(const char *file, int line, const char *for_who, size_t e_sz, size_t n)
Definition: tw-util.c:203
static void service_queues(tw_pe *me)
Start checks for finished operations in send/recv queues, and post new sends/recvs if possible...
Definition: network-mpi.c:554
unsigned char cancel_q
Actively on a dest_lp->pe's cancel_q.
Definition: ross-types.h:269
tw_stime last_time
Time of the current event being processed.
Definition: ross-types.h:360
int * idx_list
Definition: network-mpi.c:22
unsigned char cancel_asend
Definition: ross-types.h:270
static void send_finish(tw_pe *me, tw_event *e, char *buffer)
Determines how to handle the buffer of event whose send operation just finished.
Definition: network-mpi.c:495
In a tw_pe.event_q list.
Definition: ross-types.h:214
unsigned char owner
Owner of the next/prev pointers; see tw_event_owner.
Definition: ross-types.h:268