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 char *sample_location(int global, const char *file, int line) { if (global) { return bprintf("%s:%d", file, line); } else { return bprintf("%s:%d:%d", file, line, smpi_process_index()); } }
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); }
/** @brief Check if a process is finalized */ int smpi_process_finalized() { int index = smpi_process_index(); if (index != MPI_UNDEFINED) return (process_data[index_to_process_data[index]]->state == SMPI_FINALIZED); else return 0; }
static xbt_dynar_t get_reqq_self() { char * key = bprintf("%d", smpi_process_index()); xbt_dynar_t dynar_mpi_request = static_cast<xbt_dynar_t>(xbt_dict_get(reqq, key)); xbt_free(key); return dynar_mpi_request; }
static void set_reqq_self(xbt_dynar_t mpi_request){ char * key; int size = asprintf(&key, "%d", smpi_process_index()); if(size==-1) xbt_die("could not allocate memory for asprintf"); xbt_dict_set(reqq, key, mpi_request, free); free(key); }
void smpi_process_destroy(void) { int index = smpi_process_index(); if(smpi_privatize_global_variables){ smpi_switch_data_segment(index); } process_data[index_to_process_data[index]]->state = SMPI_FINALIZED; XBT_DEBUG("<%d> Process left the game", index); }
/** @brief Check if a process is initialized */ int smpi_process_initialized(void) { if (!index_to_process_data){ return false; } else{ int index = smpi_process_index(); return ((index != MPI_UNDEFINED) && (process_data[index_to_process_data[index]]->state == SMPI_INITIALIZED)); } }
/** @brief Prepares the current process for termination. */ void smpi_process_finalize(void) { // This leads to an explosion of the search graph which cannot be reduced: if(MC_is_active() || MC_record_replay_is_active()) return; int index = smpi_process_index(); // wait for all pending asynchronous comms to finish xbt_barrier_wait(process_data[index_to_process_data[index]]->finalization_barrier); }
MPI_Comm smpi_process_comm_self(void) { smpi_process_data_t data = smpi_process_data(); if(data->comm_self==MPI_COMM_NULL){ MPI_Group group = smpi_group_new(1); data->comm_self = smpi_comm_new(group, NULL); smpi_group_set_mapping(group, smpi_process_index(), 0); } return data->comm_self; }
static xbt_dynar_t get_reqq_self(){ char * key; int size = asprintf(&key, "%d", smpi_process_index()); if(size==-1) xbt_die("could not allocate memory for asprintf"); xbt_dynar_t dynar_mpi_request = (xbt_dynar_t) xbt_dict_get(reqq, key); free(key); return dynar_mpi_request; }
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); }
void smpi_replay_init(int *argc, char***argv){ PMPI_Init(argc, argv); if (!smpi_process_index()){ _xbt_replay_action_init(); xbt_replay_action_register("init", action_init); xbt_replay_action_register("finalize", action_finalize); xbt_replay_action_register("comm_size",action_comm_size); xbt_replay_action_register("send", action_send); xbt_replay_action_register("Isend", action_Isend); xbt_replay_action_register("recv", action_recv); xbt_replay_action_register("Irecv", action_Irecv); xbt_replay_action_register("wait", action_wait); xbt_replay_action_register("barrier", action_barrier); xbt_replay_action_register("bcast", action_bcast); xbt_replay_action_register("reduce", action_reduce); xbt_replay_action_register("allReduce",action_allReduce); xbt_replay_action_register("compute", action_compute); } xbt_replay_action_runner(*argc, *argv); }
int smpi_process_get_replaying(){ int index = smpi_process_index(); if (index != MPI_UNDEFINED) return process_data[index_to_process_data[index]]->replaying; else return _xbt_replay_is_active(); }
void smpi_process_set_replaying(int value){ int index = smpi_process_index(); if ((index != MPI_UNDEFINED) && (process_data[index_to_process_data[index]]->state != SMPI_FINALIZED)) process_data[index_to_process_data[index]]->replaying = value; }
/** @brief Mark a process as initialized (=MPI_Init called) */ void smpi_process_mark_as_initialized(void) { int index = smpi_process_index(); if ((index != MPI_UNDEFINED) && (process_data[index_to_process_data[index]]->state != SMPI_FINALIZED)) process_data[index_to_process_data[index]]->state = SMPI_INITIALIZED; }
void smpi_bench_begin(void) { xbt_os_timer_start(smpi_process_timer()); smpi_current_rank = smpi_process_index(); }
log_timed_action (action, clock); } static void action_comm_dup(const char *const *action) { double clock = smpi_process_simulated_elapsed(); log_timed_action (action, clock); } 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_send(const char *const *action) { CHECK_ACTION_PARAMS(action, 2, 1) int to = atoi(action[2]);
static std::vector<MPI_Request>* get_reqq_self() { return reqq.at(smpi_process_index()); }
*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); } } int rank_traced = smpi_process_index(); TRACE_smpi_computing_out(rank_traced); TRACE_smpi_ptp_in(rank_traced, -1, -1, __FUNCTION__); #endif smpi_mpi_waitall(count_requests, requests, status); #ifdef HAVE_TRACING for (i = 0; i < count_requests; i++) { int src_traced, dst_traced, is_wait_for_receive; xbt_dynar_get_cpy(srcs, i, &src_traced); xbt_dynar_get_cpy(dsts, i, &dst_traced); xbt_dynar_get_cpy(recvs, i, &is_wait_for_receive); if (is_wait_for_receive) { TRACE_smpi_recv(rank_traced, src_traced, dst_traced);
static void set_reqq_self(std::vector<MPI_Request> *mpi_request) { reqq.insert({smpi_process_index(), mpi_request}); }
static void set_reqq_self(xbt_dynar_t mpi_request) { char * key = bprintf("%d", smpi_process_index()); xbt_dict_set(reqq, key, mpi_request, free); xbt_free(key); }