+
+static void action_gatherv(const char *const *action) {
+ /*
+ The structure of the gatherv action for the rank 0 (total 4 processes)
+ is the following:
+ 0 gather 68 68 10 10 10 0 0 0
+
+ where:
+ 1) 68 is the sendcount
+ 2) 68 10 10 10 is the recvcounts
+ 3) 0 is the root node
+ 4) 0 is the send datatype id, see decode_datatype()
+ 5) 0 is the recv datatype id, see decode_datatype()
+ */
+ double clock = smpi_process_simulated_elapsed();
+ int comm_size = smpi_comm_size(MPI_COMM_WORLD);
+ int send_size = parse_double(action[2]);
+ int *disps = xbt_new0(int, comm_size);
+ int *recvcounts = xbt_new0(int, comm_size);
+ int i=0,recv_sum=0;
+
+ MPI_Datatype MPI_CURRENT_TYPE2;
+ if(action[4+comm_size]) {
+ MPI_CURRENT_TYPE=decode_datatype(action[4+comm_size]);
+ MPI_CURRENT_TYPE2=decode_datatype(action[5+comm_size]);
+ } else {
+ MPI_CURRENT_TYPE=MPI_DEFAULT_TYPE;
+ MPI_CURRENT_TYPE2=MPI_DEFAULT_TYPE;
+ }
+ void *send = calloc(send_size, smpi_datatype_size(MPI_CURRENT_TYPE));
+ void *recv = NULL;
+ for(i=0;i<comm_size;i++) {
+ recvcounts[i] = atoi(action[i+3]);
+ recv_sum=recv_sum+recvcounts[i];
+ disps[i] = 0;
+ }
+
+ int root=atoi(action[3+comm_size]);
+ int rank = smpi_process_index();
+
+ if(rank==root)
+ recv = calloc(recv_sum, smpi_datatype_size(MPI_CURRENT_TYPE2));
+
+#ifdef HAVE_TRACING
+ instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1);
+ extra->type = TRACING_GATHERV;
+ extra->send_size = send_size;
+ extra->recvcounts= xbt_malloc(comm_size*sizeof(int));
+ for(i=0; i< comm_size; i++)//copy data to avoid bad free
+ extra->recvcounts[i] = recvcounts[i];
+ extra->root = root;
+ extra->num_processes = comm_size;
+ extra->datatype1 = encode_datatype(MPI_CURRENT_TYPE);
+ extra->datatype2 = encode_datatype(MPI_CURRENT_TYPE2);
+
+ TRACE_smpi_collective_in(rank, root, __FUNCTION__, extra);
+#endif
+smpi_mpi_gatherv(send, send_size, MPI_CURRENT_TYPE,
+ recv, recvcounts, disps, MPI_CURRENT_TYPE2,
+ root, MPI_COMM_WORLD);
+
+#ifdef HAVE_TRACING
+ TRACE_smpi_collective_out(rank, -1, __FUNCTION__);
+#endif
+
+ log_timed_action (action, clock);
+ xbt_free(recvcounts);
+ xbt_free(send);
+ xbt_free(recv);
+ xbt_free(disps);
+
+}
+