static void action_test(const char *const *action){ CHECK_ACTION_PARAMS(action, 0, 0); double clock = smpi_process_simulated_elapsed(); MPI_Request request; MPI_Status status; int flag = TRUE; request = xbt_dynar_pop_as(get_reqq_self(),MPI_Request); //if request is null here, this may mean that a previous test has succeeded //Different times in traced application and replayed version may lead to this //In this case, ignore the extra calls. if(request){ int rank = smpi_process_index(); instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1); extra->type=TRACING_TEST; TRACE_smpi_testing_in(rank, extra); flag = smpi_mpi_test(&request, &status); XBT_DEBUG("MPI_Test result: %d", flag); /* push back request in dynar to be caught by a subsequent wait. if the test * did succeed, the request is now NULL. */ xbt_dynar_push_as(get_reqq_self(),MPI_Request, request); TRACE_smpi_testing_out(rank); } log_timed_action (action, clock); }
static void action_Irecv(const char *const *action) { CHECK_ACTION_PARAMS(action, 2, 1); int from = atoi(action[2]); double size=parse_double(action[3]); double clock = smpi_process_simulated_elapsed(); MPI_Request request; if(action[4]) MPI_CURRENT_TYPE=decode_datatype(action[4]); else MPI_CURRENT_TYPE= MPI_DEFAULT_TYPE; int rank = smpi_process_index(); int src_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), from); instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1); extra->type = TRACING_IRECV; extra->send_size = size; extra->src = src_traced; extra->dst = rank; extra->datatype1 = encode_datatype(MPI_CURRENT_TYPE, NULL); TRACE_smpi_ptp_in(rank, src_traced, rank, __FUNCTION__, extra); MPI_Status status; //unknow size from the receiver pov if(size==-1){ smpi_mpi_probe(from, 0, MPI_COMM_WORLD, &status); size=status.count; } request = smpi_mpi_irecv(NULL, size, MPI_CURRENT_TYPE, from, 0, MPI_COMM_WORLD); TRACE_smpi_ptp_out(rank, src_traced, rank, __FUNCTION__); request->recv = 1; xbt_dynar_push(get_reqq_self(),&request); log_timed_action (action, clock); }
static void action_Isend(const char *const *action) { CHECK_ACTION_PARAMS(action, 2, 1); int to = atoi(action[2]); double size=parse_double(action[3]); double clock = smpi_process_simulated_elapsed(); MPI_Request request; if(action[4]) MPI_CURRENT_TYPE=decode_datatype(action[4]); else MPI_CURRENT_TYPE= MPI_DEFAULT_TYPE; int rank = smpi_process_index(); int dst_traced = smpi_group_rank(smpi_comm_group(MPI_COMM_WORLD), to); instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1); extra->type = TRACING_ISEND; extra->send_size = size; extra->src = rank; extra->dst = dst_traced; extra->datatype1 = encode_datatype(MPI_CURRENT_TYPE, NULL); TRACE_smpi_ptp_in(rank, rank, dst_traced, __FUNCTION__, extra); if (!TRACE_smpi_view_internals()) { TRACE_smpi_send(rank, rank, dst_traced, size*smpi_datatype_size(MPI_CURRENT_TYPE)); } request = smpi_mpi_isend(NULL, size, MPI_CURRENT_TYPE, to, 0,MPI_COMM_WORLD); TRACE_smpi_ptp_out(rank, rank, dst_traced, __FUNCTION__); request->send = 1; xbt_dynar_push(get_reqq_self(),&request); log_timed_action (action, clock); }
static void action_init(const char *const *action) { XBT_DEBUG("Initialize the counters"); CHECK_ACTION_PARAMS(action, 0, 1); if(action[2]) MPI_DEFAULT_TYPE= MPI_DOUBLE; // default MPE dataype else MPI_DEFAULT_TYPE= MPI_BYTE; // default TAU datatype /* start a simulated timer */ smpi_process_simulated_start(); /*initialize the number of active processes */ active_processes = smpi_process_count(); if (!reqq) { reqq = xbt_dict_new(); } set_reqq_self(xbt_dynar_new(sizeof(MPI_Request),&xbt_free_ref)); /* reqq=xbt_new0(xbt_dynar_t,active_processes); for(i=0;i<active_processes;i++){ reqq[i]=xbt_dynar_new(sizeof(MPI_Request),&xbt_free_ref); } } */ }
static void action_compute(const char *const *action) { CHECK_ACTION_PARAMS(action, 1, 0); double clock = smpi_process_simulated_elapsed(); double flops= parse_double(action[2]); int rank = smpi_process_index(); instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1); extra->type=TRACING_COMPUTING; extra->comp_size=flops; TRACE_smpi_computing_in(rank, extra); smpi_execute_flops(flops); TRACE_smpi_computing_out(rank); log_timed_action (action, clock); }
static void action_waitall(const char *const *action){ CHECK_ACTION_PARAMS(action, 0, 0); double clock = smpi_process_simulated_elapsed(); int count_requests=0; unsigned int i=0; count_requests=xbt_dynar_length(get_reqq_self()); if (count_requests>0) { MPI_Request requests[count_requests]; MPI_Status status[count_requests]; /* The reqq is an array of dynars. Its index corresponds to the rank. Thus each rank saves its own requests to the array request. */ xbt_dynar_foreach(get_reqq_self(),i,requests[i]); //save information from requests xbt_dynar_t srcs = xbt_dynar_new(sizeof(int), NULL); xbt_dynar_t dsts = xbt_dynar_new(sizeof(int), NULL); xbt_dynar_t recvs = xbt_dynar_new(sizeof(int), NULL); for (i = 0; i < count_requests; i++) { if(requests[i]){ int *asrc = xbt_new(int, 1); int *adst = xbt_new(int, 1); int *arecv = xbt_new(int, 1); *asrc = requests[i]->src; *adst = requests[i]->dst; *arecv = requests[i]->recv; xbt_dynar_insert_at(srcs, i, asrc); xbt_dynar_insert_at(dsts, i, adst); xbt_dynar_insert_at(recvs, i, arecv); xbt_free(asrc); xbt_free(adst); xbt_free(arecv); }else { int *t = xbt_new(int, 1); xbt_dynar_insert_at(srcs, i, t); xbt_dynar_insert_at(dsts, i, t); xbt_dynar_insert_at(recvs, i, t); xbt_free(t); } }
static void action_wait(const char *const *action){ CHECK_ACTION_PARAMS(action, 0, 0); double clock = smpi_process_simulated_elapsed(); MPI_Request request; MPI_Status status; xbt_assert(xbt_dynar_length(get_reqq_self()), "action wait not preceded by any irecv or isend: %s", xbt_str_join_array(action," ")); request = xbt_dynar_pop_as(get_reqq_self(),MPI_Request); if (!request){ /* Assuming that the trace is well formed, this mean the comm might have * been caught by a MPI_test. Then just return. */ return; } int rank = request->comm != MPI_COMM_NULL ? smpi_comm_rank(request->comm) : -1; MPI_Group group = smpi_comm_group(request->comm); int src_traced = smpi_group_rank(group, request->src); int dst_traced = smpi_group_rank(group, request->dst); int is_wait_for_receive = request->recv; instr_extra_data extra = xbt_new0(s_instr_extra_data_t,1); extra->type = TRACING_WAIT; TRACE_smpi_ptp_in(rank, src_traced, dst_traced, __FUNCTION__, extra); smpi_mpi_wait(&request, &status); TRACE_smpi_ptp_out(rank, src_traced, dst_traced, __FUNCTION__); if (is_wait_for_receive) TRACE_smpi_recv(rank, src_traced, dst_traced); log_timed_action (action, clock); }
void parse(simgrid::xbt::ReplayAction& action, const std::string&) { // The only parameter is the amount of memory used by the current process. CHECK_ACTION_PARAMS(action, 1, 0); memory_consumption = std::stod(action[2]); }
void action_iteration_out(simgrid::xbt::ReplayAction& action) { CHECK_ACTION_PARAMS(action, 0, 0) TRACE_Iteration_out(simgrid::s4u::this_actor::get_pid(), nullptr); simgrid::smpi::plugin::ampi::on_iteration_out(*MPI_COMM_WORLD->group()->actor(std::stol(action[0]))); }