1 /* Copyright (c) 2009 - 2013. The SimGrid Team.
2 * All rights reserved. */
4 /* This program is free software; you can redistribute it and/or modify it
5 * under the terms of the license (GNU LGPL) which comes with this package. */
11 #include <xbt/replay.h>
13 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_replay,smpi,"Trace Replay with SMPI");
15 int communicator_size = 0;
16 static int active_processes = 0;
17 xbt_dynar_t *reqq = NULL;
19 MPI_Datatype MPI_DEFAULT_TYPE;
20 MPI_Datatype MPI_CURRENT_TYPE;
22 static void log_timed_action (const char *const *action, double clock){
23 if (XBT_LOG_ISENABLED(smpi_replay, xbt_log_priority_verbose)){
24 char *name = xbt_str_join_array(action, " ");
25 XBT_VERB("%s %f", name, smpi_process_simulated_elapsed()-clock);
31 xbt_dynar_t irecvs; /* of MPI_Request */
32 } s_smpi_replay_globals_t, *smpi_replay_globals_t;
36 static double parse_double(const char *string)
40 value = strtod(string, &endptr);
42 THROWF(unknown_error, 0, "%s is not a double", string);
46 static MPI_Datatype decode_datatype(const char *const action)
48 // Declared datatypes,
53 MPI_CURRENT_TYPE=MPI_DOUBLE;
56 MPI_CURRENT_TYPE=MPI_INT;
59 MPI_CURRENT_TYPE=MPI_CHAR;
62 MPI_CURRENT_TYPE=MPI_SHORT;
65 MPI_CURRENT_TYPE=MPI_LONG;
68 MPI_CURRENT_TYPE=MPI_FLOAT;
71 MPI_CURRENT_TYPE=MPI_BYTE;
74 MPI_CURRENT_TYPE=MPI_DEFAULT_TYPE;
77 return MPI_CURRENT_TYPE;
80 static void action_init(const char *const *action)
83 XBT_DEBUG("Initialize the counters");
84 smpi_replay_globals_t globals = xbt_new(s_smpi_replay_globals_t, 1);
85 globals->irecvs = xbt_dynar_new(sizeof(MPI_Request),NULL);
87 if(action[2]) MPI_DEFAULT_TYPE= MPI_DOUBLE; // default MPE dataype
88 else MPI_DEFAULT_TYPE= MPI_BYTE; // default TAU datatype
90 smpi_process_set_user_data((void*) globals);
92 /* start a simulated timer */
93 smpi_process_simulated_start();
94 /*initialize the number of active processes */
95 active_processes = smpi_process_count();
98 reqq=xbt_new0(xbt_dynar_t,active_processes);
100 for(i=0;i<active_processes;i++){
101 reqq[i]=xbt_dynar_new(sizeof(MPI_Request),NULL);
106 static void action_finalize(const char *const *action)
108 smpi_replay_globals_t globals =
109 (smpi_replay_globals_t) smpi_process_get_user_data();
111 XBT_DEBUG("There are %lu irecvs in the dynar",
112 xbt_dynar_length(globals->irecvs));
113 xbt_dynar_free_container(&(globals->irecvs));
118 static void action_comm_size(const char *const *action)
120 double clock = smpi_process_simulated_elapsed();
122 communicator_size = parse_double(action[2]);
123 log_timed_action (action, clock);
126 static void action_comm_split(const char *const *action)
128 double clock = smpi_process_simulated_elapsed();
130 log_timed_action (action, clock);
133 static void action_comm_dup(const char *const *action)
135 double clock = smpi_process_simulated_elapsed();
137 log_timed_action (action, clock);
140 static void action_compute(const char *const *action)
142 double clock = smpi_process_simulated_elapsed();
143 smpi_execute_flops(parse_double(action[2]));
145 log_timed_action (action, clock);
148 static void action_send(const char *const *action)
150 int to = atoi(action[2]);
151 double size=parse_double(action[3]);
152 double clock = smpi_process_simulated_elapsed();
155 MPI_CURRENT_TYPE=decode_datatype(action[4]);
157 MPI_CURRENT_TYPE= MPI_DEFAULT_TYPE;
161 int rank = smpi_comm_rank(MPI_COMM_WORLD);
162 TRACE_smpi_computing_out(rank);
163 int dst_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), to);
164 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__);
165 TRACE_smpi_send(rank, rank, dst_traced);
168 smpi_mpi_send(NULL, size, MPI_CURRENT_TYPE, to , 0, MPI_COMM_WORLD);
170 log_timed_action (action, clock);
173 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
174 TRACE_smpi_computing_in(rank);
179 static void action_Isend(const char *const *action)
181 int to = atoi(action[2]);
182 double size=parse_double(action[3]);
183 double clock = smpi_process_simulated_elapsed();
186 if(action[4]) MPI_CURRENT_TYPE=decode_datatype(action[4]);
187 else MPI_CURRENT_TYPE= MPI_DEFAULT_TYPE;
190 int rank = smpi_comm_rank(MPI_COMM_WORLD);
191 TRACE_smpi_computing_out(rank);
192 int dst_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), to);
193 TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__);
194 TRACE_smpi_send(rank, rank, dst_traced);
197 request = smpi_mpi_isend(NULL, size, MPI_CURRENT_TYPE, to, 0,MPI_COMM_WORLD);
200 TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__);
202 TRACE_smpi_computing_in(rank);
205 xbt_dynar_push(reqq[smpi_comm_rank(MPI_COMM_WORLD)],&request);
207 log_timed_action (action, clock);
210 static void action_recv(const char *const *action) {
211 int from = atoi(action[2]);
212 double size=parse_double(action[3]);
213 double clock = smpi_process_simulated_elapsed();
216 if(action[4]) MPI_CURRENT_TYPE=decode_datatype(action[4]);
217 else MPI_CURRENT_TYPE= MPI_DEFAULT_TYPE;
220 int rank = smpi_comm_rank(MPI_COMM_WORLD);
221 int src_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), from);
222 TRACE_smpi_computing_out(rank);
224 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__);
227 smpi_mpi_recv(NULL, size, MPI_CURRENT_TYPE, from, 0, MPI_COMM_WORLD, &status);
230 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
231 TRACE_smpi_recv(rank, src_traced, rank);
232 TRACE_smpi_computing_in(rank);
235 log_timed_action (action, clock);
238 static void action_Irecv(const char *const *action)
240 int from = atoi(action[2]);
241 double size=parse_double(action[3]);
242 double clock = smpi_process_simulated_elapsed();
245 smpi_replay_globals_t globals =
246 (smpi_replay_globals_t) smpi_process_get_user_data();
248 if(action[4]) MPI_CURRENT_TYPE=decode_datatype(action[4]);
249 else MPI_CURRENT_TYPE= MPI_DEFAULT_TYPE;
252 int rank = smpi_comm_rank(MPI_COMM_WORLD);
253 int src_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), from);
254 TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__);
257 request = smpi_mpi_irecv(NULL, size, MPI_CURRENT_TYPE, from, 0, MPI_COMM_WORLD);
260 TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__);
263 xbt_dynar_push(globals->irecvs,&request);
264 xbt_dynar_push(reqq[smpi_comm_rank(MPI_COMM_WORLD)],&request);
266 log_timed_action (action, clock);
269 static void action_wait(const char *const *action){
270 double clock = smpi_process_simulated_elapsed();
273 smpi_replay_globals_t globals =
274 (smpi_replay_globals_t) smpi_process_get_user_data();
276 xbt_assert(xbt_dynar_length(globals->irecvs),
277 "action wait not preceded by any irecv: %s",
278 xbt_str_join_array(action," "));
279 request = xbt_dynar_pop_as(globals->irecvs,MPI_Request);
281 int rank = request && request->comm != MPI_COMM_NULL
282 ? smpi_comm_rank(request->comm)
284 TRACE_smpi_computing_out(rank);
286 MPI_Group group = smpi_comm_group(request->comm);
287 int src_traced = smpi_group_rank(group, request->src);
288 int dst_traced = smpi_group_rank(group, request->dst);
289 int is_wait_for_receive = request->recv;
290 TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__);
292 smpi_mpi_wait(&request, &status);
294 TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__);
295 if (is_wait_for_receive) {
296 TRACE_smpi_recv(rank, src_traced, dst_traced);
298 TRACE_smpi_computing_in(rank);
301 log_timed_action (action, clock);
304 static void action_waitall(const char *const *action){
305 double clock = smpi_process_simulated_elapsed();
306 int count_requests=0;
309 count_requests=xbt_dynar_length(reqq[smpi_comm_rank(MPI_COMM_WORLD)]);
311 if (count_requests>0) {
312 MPI_Request requests[count_requests];
313 MPI_Status status[count_requests];
315 /* The reqq is an array of dynars. Its index corresponds to the rank.
316 Thus each rank saves its own requests to the array request. */
317 xbt_dynar_foreach(reqq[smpi_comm_rank(MPI_COMM_WORLD)],i,requests[i]);
320 //save information from requests
322 xbt_dynar_t srcs = xbt_dynar_new(sizeof(int), NULL);
323 xbt_dynar_t dsts = xbt_dynar_new(sizeof(int), NULL);
324 xbt_dynar_t recvs = xbt_dynar_new(sizeof(int), NULL);
325 for (i = 0; i < count_requests; i++) {
327 int *asrc = xbt_new(int, 1);
328 int *adst = xbt_new(int, 1);
329 int *arecv = xbt_new(int, 1);
330 *asrc = requests[i]->src;
331 *adst = requests[i]->dst;
332 *arecv = requests[i]->recv;
333 xbt_dynar_insert_at(srcs, i, asrc);
334 xbt_dynar_insert_at(dsts, i, adst);
335 xbt_dynar_insert_at(recvs, i, arecv);
340 int *t = xbt_new(int, 1);
341 xbt_dynar_insert_at(srcs, i, t);
342 xbt_dynar_insert_at(dsts, i, t);
343 xbt_dynar_insert_at(recvs, i, t);
347 int rank_traced = smpi_process_index();
348 TRACE_smpi_computing_out(rank_traced);
350 TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__);
353 smpi_mpi_waitall(count_requests, requests, status);
356 for (i = 0; i < count_requests; i++) {
357 int src_traced, dst_traced, is_wait_for_receive;
358 xbt_dynar_get_cpy(srcs, i, &src_traced);
359 xbt_dynar_get_cpy(dsts, i, &dst_traced);
360 xbt_dynar_get_cpy(recvs, i, &is_wait_for_receive);
361 if (is_wait_for_receive) {
362 TRACE_smpi_recv(rank_traced, src_traced, dst_traced);
365 TRACE_smpi_ptp_out(rank_traced, -1, -1, __FUNCTION__);
367 xbt_dynar_free(&srcs);
368 xbt_dynar_free(&dsts);
369 xbt_dynar_free(&recvs);
370 TRACE_smpi_computing_in(rank_traced);
373 xbt_dynar_reset(reqq[smpi_comm_rank(MPI_COMM_WORLD)]);
375 log_timed_action (action, clock);
378 static void action_barrier(const char *const *action){
379 double clock = smpi_process_simulated_elapsed();
381 int rank = smpi_comm_rank(MPI_COMM_WORLD);
382 TRACE_smpi_computing_out(rank);
383 TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
385 smpi_mpi_barrier(MPI_COMM_WORLD);
387 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
388 TRACE_smpi_computing_in(rank);
391 log_timed_action (action, clock);
395 static void action_bcast(const char *const *action)
397 double size = parse_double(action[2]);
398 double clock = smpi_process_simulated_elapsed();
401 * Initialize MPI_CURRENT_TYPE in order to decrease
402 * the number of the checks
404 MPI_CURRENT_TYPE= MPI_DEFAULT_TYPE;
407 root= atoi(action[3]);
409 MPI_CURRENT_TYPE=decode_datatype(action[4]);
414 int rank = smpi_comm_rank(MPI_COMM_WORLD);
415 TRACE_smpi_computing_out(rank);
416 int root_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), 0);
417 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__);
420 smpi_mpi_bcast(NULL, size, MPI_CURRENT_TYPE, root, MPI_COMM_WORLD);
422 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
423 TRACE_smpi_computing_in(rank);
426 log_timed_action (action, clock);
429 static void action_reduce(const char *const *action)
431 double comm_size = parse_double(action[2]);
432 double comp_size = parse_double(action[3]);
433 double clock = smpi_process_simulated_elapsed();
435 MPI_CURRENT_TYPE= MPI_DEFAULT_TYPE;
438 root= atoi(action[4]);
440 MPI_CURRENT_TYPE=decode_datatype(action[5]);
445 int rank = smpi_comm_rank(MPI_COMM_WORLD);
446 TRACE_smpi_computing_out(rank);
447 int root_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), 0);
448 TRACE_smpi_collective_in(rank, root_traced, __FUNCTION__);
450 mpi_coll_reduce_fun(NULL, NULL, comm_size, MPI_CURRENT_TYPE, MPI_OP_NULL, root, MPI_COMM_WORLD);
451 smpi_execute_flops(comp_size);
453 TRACE_smpi_collective_out(rank, root_traced, __FUNCTION__);
454 TRACE_smpi_computing_in(rank);
457 log_timed_action (action, clock);
460 static void action_allReduce(const char *const *action) {
461 double comm_size = parse_double(action[2]);
462 double comp_size = parse_double(action[3]);
464 if(action[4]) MPI_CURRENT_TYPE=decode_datatype(action[4]);
465 else MPI_CURRENT_TYPE= MPI_DEFAULT_TYPE;
467 double clock = smpi_process_simulated_elapsed();
469 int rank = smpi_comm_rank(MPI_COMM_WORLD);
470 TRACE_smpi_computing_out(rank);
471 TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
473 mpi_coll_reduce_fun(NULL, NULL, comm_size, MPI_CURRENT_TYPE, MPI_OP_NULL, 0, MPI_COMM_WORLD);
474 smpi_execute_flops(comp_size);
475 mpi_coll_bcast_fun(NULL, comm_size, MPI_CURRENT_TYPE, 0, MPI_COMM_WORLD);
477 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
478 TRACE_smpi_computing_in(rank);
481 log_timed_action (action, clock);
484 static void action_allToAll(const char *const *action) {
485 double clock = smpi_process_simulated_elapsed();
486 int comm_size = smpi_comm_size(MPI_COMM_WORLD);
487 int send_size = parse_double(action[2]);
488 int recv_size = parse_double(action[3]);
489 MPI_Datatype MPI_CURRENT_TYPE2;
492 MPI_CURRENT_TYPE=decode_datatype(action[4]);
493 MPI_CURRENT_TYPE2=decode_datatype(action[5]);
496 MPI_CURRENT_TYPE=MPI_DEFAULT_TYPE;
497 MPI_CURRENT_TYPE2=MPI_DEFAULT_TYPE;
499 void *send = calloc(send_size*comm_size, smpi_datatype_size(MPI_CURRENT_TYPE));
500 void *recv = calloc(recv_size*comm_size, smpi_datatype_size(MPI_CURRENT_TYPE2));
503 int rank = smpi_process_index();
504 TRACE_smpi_computing_out(rank);
505 TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
508 mpi_coll_alltoall_fun(send, send_size, MPI_CURRENT_TYPE, recv, recv_size, MPI_CURRENT_TYPE2, MPI_COMM_WORLD);
511 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
512 TRACE_smpi_computing_in(rank);
515 log_timed_action (action, clock);
521 static void action_gather(const char *const *action) {
523 The structure of the gather action for the rank 0 (total 4 processes)
528 1) 68 is the sendcounts
529 2) 68 is the recvcounts
530 3) 0 is the root node
531 4) 0 is the send datatype id, see decode_datatype()
532 5) 0 is the recv datatype id, see decode_datatype()
534 double clock = smpi_process_simulated_elapsed();
535 int comm_size = smpi_comm_size(MPI_COMM_WORLD);
536 int send_size = parse_double(action[2]);
537 int recv_size = parse_double(action[3]);
538 MPI_Datatype MPI_CURRENT_TYPE2;
540 MPI_CURRENT_TYPE=decode_datatype(action[5]);
541 MPI_CURRENT_TYPE2=decode_datatype(action[6]);
543 MPI_CURRENT_TYPE=MPI_DEFAULT_TYPE;
544 MPI_CURRENT_TYPE2=MPI_DEFAULT_TYPE;
546 void *send = calloc(send_size, smpi_datatype_size(MPI_CURRENT_TYPE));
547 void *recv = calloc(recv_size, smpi_datatype_size(MPI_CURRENT_TYPE2));
549 int root=atoi(action[4]);
550 int rank = smpi_process_index();
553 recv = calloc(recv_size*comm_size, smpi_datatype_size(MPI_CURRENT_TYPE2));
556 TRACE_smpi_computing_out(rank);
557 TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
559 smpi_mpi_gather(send, send_size, MPI_CURRENT_TYPE,
560 recv, recv_size, MPI_CURRENT_TYPE2,
561 root, MPI_COMM_WORLD);
564 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
565 TRACE_smpi_computing_in(rank);
568 log_timed_action (action, clock);
574 static void action_reducescatter(const char *const *action) {
577 The structure of the reducescatter action for the rank 0 (total 4 processes)
579 0 reduceScatter 275427 275427 275427 204020 11346849 0
582 1) The first four values after the name of the action declare the recvcounts array
583 2) The value 11346849 is the amount of instructions
584 3) The last value corresponds to the datatype, see decode_datatype().
586 We analyze a MPI_Reduce_scatter call to one MPI_Reduce and one MPI_Scatterv.
590 double clock = smpi_process_simulated_elapsed();
591 int comm_size = smpi_comm_size(MPI_COMM_WORLD);
592 int comp_size = parse_double(action[2+comm_size]);
593 int *recvcounts = xbt_new0(int, comm_size);
594 int *disps = xbt_new0(int, comm_size);
597 int rank = smpi_process_index();
599 if(action[3+comm_size])
600 MPI_CURRENT_TYPE=decode_datatype(action[3+comm_size]);
602 MPI_CURRENT_TYPE= MPI_DEFAULT_TYPE;
604 for(i=0;i<comm_size;i++) {
605 recvcounts[i] = atoi(action[i+2]);
606 recv_sum=recv_sum+recvcounts[i];
611 TRACE_smpi_computing_out(rank);
612 TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
614 mpi_coll_reduce_fun(NULL, NULL, recv_sum, MPI_CURRENT_TYPE, MPI_OP_NULL,
615 root, MPI_COMM_WORLD);
616 smpi_mpi_scatterv(NULL, recvcounts, disps, MPI_CURRENT_TYPE, NULL,
617 recvcounts[rank], MPI_CURRENT_TYPE, 0, MPI_COMM_WORLD);
618 smpi_execute_flops(comp_size);
622 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
623 TRACE_smpi_computing_in(rank);
626 log_timed_action (action, clock);
630 static void action_allgatherv(const char *const *action) {
633 The structure of the allgatherv action for the rank 0 (total 4 processes)
635 0 allGatherV 275427 275427 275427 275427 204020 0 275427 550854 826281
638 1) 275427 is the sendcount
639 2) The next four elements declare the recvcounts array
640 3) The next four values declare the disps array
641 4) No more values mean that the datatype for sent and receive buffer
642 is the default one, see decode_datatype().
646 double clock = smpi_process_simulated_elapsed();
648 int comm_size = smpi_comm_size(MPI_COMM_WORLD);
650 int sendcount=atoi(action[2]);
651 int *recvcounts = xbt_new0(int, comm_size);
652 int *disps = xbt_new0(int, comm_size);
654 MPI_Datatype MPI_CURRENT_TYPE2;
656 if(action[3+2*comm_size]) {
657 MPI_CURRENT_TYPE = decode_datatype(action[3+2*comm_size]);
658 MPI_CURRENT_TYPE2 = decode_datatype(action[4+2*comm_size]);
660 MPI_CURRENT_TYPE = MPI_DEFAULT_TYPE;
661 MPI_CURRENT_TYPE2 = MPI_DEFAULT_TYPE;
663 void *sendbuf = calloc(sendcount, smpi_datatype_size(MPI_CURRENT_TYPE));
665 for(i=0;i<comm_size;i++) {
666 recvcounts[i] = atoi(action[i+3]);
667 recv_sum=recv_sum+recvcounts[i];
668 disps[i] = atoi(action[i+3+comm_size]);
670 void *recvbuf = calloc(recv_sum, smpi_datatype_size(MPI_CURRENT_TYPE2));
673 int rank = MPI_COMM_WORLD != MPI_COMM_NULL ? smpi_process_index() : -1;
674 TRACE_smpi_computing_out(rank);
675 TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
678 mpi_coll_allgatherv_fun(sendbuf, sendcount, MPI_CURRENT_TYPE, recvbuf, recvcounts, disps, MPI_CURRENT_TYPE2, MPI_COMM_WORLD);
681 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
682 TRACE_smpi_computing_in(rank);
685 log_timed_action (action, clock);
688 xbt_free(recvcounts);
693 static void action_allToAllv(const char *const *action) {
695 The structure of the allToAllV action for the rank 0 (total 4 processes)
697 0 allToAllV 100 1 7 10 12 5 10 20 45 100 1 70 10 5 1 5 77 90
700 1) 100 is the size of the send buffer *sizeof(int),
701 2) 1 7 10 12 is the sendcounts array
702 3) 5 10 20 45 is the sdispls array
703 4) 100*sizeof(int) is the size of the receiver buffer
704 5) 1 70 10 5 is the recvcounts array
705 6) 1 5 77 90 is the rdispls array
710 double clock = smpi_process_simulated_elapsed();
712 int comm_size = smpi_comm_size(MPI_COMM_WORLD);
713 int send_buf_size=0,recv_buf_size=0,i=0;
714 int *sendcounts = xbt_new0(int, comm_size);
715 int *recvcounts = xbt_new0(int, comm_size);
716 int *senddisps = xbt_new0(int, comm_size);
717 int *recvdisps = xbt_new0(int, comm_size);
719 MPI_Datatype MPI_CURRENT_TYPE2;
721 send_buf_size=parse_double(action[2]);
722 recv_buf_size=parse_double(action[3+2*comm_size]);
723 if(action[4+4*comm_size]) {
724 MPI_CURRENT_TYPE=decode_datatype(action[4+4*comm_size]);
725 MPI_CURRENT_TYPE2=decode_datatype(action[5+4*comm_size]);
728 MPI_CURRENT_TYPE=MPI_DEFAULT_TYPE;
729 MPI_CURRENT_TYPE2=MPI_DEFAULT_TYPE;
732 void *sendbuf = calloc(send_buf_size, smpi_datatype_size(MPI_CURRENT_TYPE));
733 void *recvbuf = calloc(recv_buf_size, smpi_datatype_size(MPI_CURRENT_TYPE2));
735 for(i=0;i<comm_size;i++) {
736 sendcounts[i] = atoi(action[i+3]);
737 senddisps[i] = atoi(action[i+3+comm_size]);
738 recvcounts[i] = atoi(action[i+4+2*comm_size]);
739 recvdisps[i] = atoi(action[i+4+3*comm_size]);
744 int rank = MPI_COMM_WORLD != MPI_COMM_NULL ? smpi_process_index() : -1;
745 TRACE_smpi_computing_out(rank);
746 TRACE_smpi_collective_in(rank, -1, __FUNCTION__);
748 mpi_coll_alltoallv_fun(sendbuf, sendcounts, senddisps, MPI_CURRENT_TYPE,
749 recvbuf, recvcounts, recvdisps, MPI_CURRENT_TYPE,
752 TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
753 TRACE_smpi_computing_in(rank);
756 log_timed_action (action, clock);
759 xbt_free(sendcounts);
760 xbt_free(recvcounts);
767 void smpi_replay_init(int *argc, char***argv){
768 PMPI_Init(argc, argv);
769 if (!smpi_process_index()){
770 _xbt_replay_action_init();
771 xbt_replay_action_register("init", action_init);
772 xbt_replay_action_register("finalize", action_finalize);
773 xbt_replay_action_register("comm_size", action_comm_size);
774 xbt_replay_action_register("comm_split", action_comm_split);
775 xbt_replay_action_register("comm_dup", action_comm_dup);
776 xbt_replay_action_register("send", action_send);
777 xbt_replay_action_register("Isend", action_Isend);
778 xbt_replay_action_register("recv", action_recv);
779 xbt_replay_action_register("Irecv", action_Irecv);
780 xbt_replay_action_register("wait", action_wait);
781 xbt_replay_action_register("waitAll", action_waitall);
782 xbt_replay_action_register("barrier", action_barrier);
783 xbt_replay_action_register("bcast", action_bcast);
784 xbt_replay_action_register("reduce", action_reduce);
785 xbt_replay_action_register("allReduce", action_allReduce);
786 xbt_replay_action_register("allToAll", action_allToAll);
787 xbt_replay_action_register("allToAllV", action_allToAllv);
788 xbt_replay_action_register("gather", action_gather);
789 xbt_replay_action_register("allGatherV", action_allgatherv);
790 xbt_replay_action_register("reduceScatter", action_reducescatter);
791 xbt_replay_action_register("compute", action_compute);
794 xbt_replay_action_runner(*argc, *argv);
797 int smpi_replay_finalize(){
799 /* One active process will stop. Decrease the counter*/
801 XBT_DEBUG("There are %lu elements in reqq[*]",
802 xbt_dynar_length(reqq[smpi_comm_rank(MPI_COMM_WORLD)]));
803 xbt_dynar_free(&reqq[smpi_comm_rank(MPI_COMM_WORLD)]);
804 if(!active_processes){
805 /* Last process alive speaking */
806 /* end the simulated timer */
807 sim_time = smpi_process_simulated_elapsed();
808 XBT_INFO("Simulation time %g", sim_time);
809 _xbt_replay_action_exit();
813 smpi_mpi_barrier(MPI_COMM_WORLD);
814 return PMPI_Finalize();