From: Augustin Degomme Date: Tue, 24 Jul 2018 19:55:19 +0000 (+0200) Subject: Rework SMPI initialization to handle argc and argv earlier than in MPI_Init when... X-Git-Tag: v3_21~364 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/2818cfc3410f2a4b4aebc56514c823f2b4b5e856 Rework SMPI initialization to handle argc and argv earlier than in MPI_Init when possible. Add support for MPI_Init(NULL,NULL). Might break MC for now. --- diff --git a/src/smpi/bindings/smpi_pmpi.cpp b/src/smpi/bindings/smpi_pmpi.cpp index 1a44473ab8..e8622ac0cf 100644 --- a/src/smpi/bindings/smpi_pmpi.cpp +++ b/src/smpi/bindings/smpi_pmpi.cpp @@ -31,12 +31,11 @@ int PMPI_Init(int *argc, char ***argv) { xbt_assert(simgrid::s4u::Engine::is_initialized(), "Your MPI program was not properly initialized. The easiest is to use smpirun to start it."); - // PMPI_Init is called only once per SMPI process - int already_init; - MPI_Initialized(&already_init); - if(already_init == 0){ + // Init is called only once per SMPI process + if (not smpi_process()->initializing()){ simgrid::smpi::ActorExt::init(argc, argv); - smpi_process()->mark_as_initialized(); + } + if (not smpi_process()->initialized()){ int rank = simgrid::s4u::this_actor::get_pid(); TRACE_smpi_init(rank); TRACE_smpi_comm_in(rank, __func__, new simgrid::instr::NoOpTIData("init")); @@ -44,6 +43,7 @@ int PMPI_Init(int *argc, char ***argv) TRACE_smpi_computing_init(rank); TRACE_smpi_sleeping_init(rank); smpi_bench_begin(); + smpi_process()->mark_as_initialized(); } smpi_mpi_init(); diff --git a/src/smpi/include/private.hpp b/src/smpi/include/private.hpp index 9fee7fc0e8..d650bf8700 100644 --- a/src/smpi/include/private.hpp +++ b/src/smpi/include/private.hpp @@ -26,7 +26,7 @@ #define MPI_REQ_RMA 0x200 #define MPI_REQ_ACCUMULATE 0x400 -enum class SmpiProcessState { UNINITIALIZED, INITIALIZED, FINALIZED }; +enum class SmpiProcessState { UNINITIALIZED, INITIALIZING, INITIALIZED, FINALIZED }; #define COLL_TAG_REDUCE -112 #define COLL_TAG_SCATTER -223 diff --git a/src/smpi/include/smpi_actor.hpp b/src/smpi/include/smpi_actor.hpp index e5ca136237..bf6371cdcc 100644 --- a/src/smpi/include/smpi_actor.hpp +++ b/src/smpi/include/smpi_actor.hpp @@ -46,6 +46,7 @@ public: void set_data(int* argc, char*** argv); void finalize(); int finalized(); + int initializing(); int initialized(); void mark_as_initialized(); void set_replaying(bool value); diff --git a/src/smpi/internals/smpi_actor.cpp b/src/smpi/internals/smpi_actor.cpp index 376f966b1b..42847cfb98 100644 --- a/src/smpi/internals/smpi_actor.cpp +++ b/src/smpi/internals/smpi_actor.cpp @@ -101,6 +101,12 @@ int ActorExt::finalized() return (state_ == SmpiProcessState::FINALIZED); } +/** @brief Check if a process is partially initialized already */ +int ActorExt::initializing() +{ + return (state_ == SmpiProcessState::INITIALIZING); +} + /** @brief Check if a process is initialized */ int ActorExt::initialized() { @@ -239,7 +245,15 @@ void ActorExt::init(int* argc, char*** argv) if (argc != nullptr && argv != nullptr) { simgrid::s4u::ActorPtr proc = simgrid::s4u::Actor::self(); proc->get_impl()->context_->set_cleanup(&SIMIX_process_cleanup); - + // cheinrich: I'm not sure what the impact of the SMPI_switch_data_segment on this call is. I moved + // this up here so that I can set the privatized region before the switch. + ActorExt* process = smpi_process_remote(proc); + //if we are in MPI_Init and argc handling has already been done. + if (process->initialized()) + return; + + process->state_ = SmpiProcessState::INITIALIZING; + char* instance_id = (*argv)[1]; try { int rank = std::stoi(std::string((*argv)[2])); @@ -248,9 +262,6 @@ void ActorExt::init(int* argc, char*** argv) throw std::invalid_argument(std::string("Invalid rank: ") + (*argv)[2]); } - // cheinrich: I'm not sure what the impact of the SMPI_switch_data_segment on this call is. I moved - // this up here so that I can set the privatized region before the switch. - ActorExt* process = smpi_process_remote(proc); if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) { /* Now using the segment index of this process */ process->set_privatized_region(smpi_init_global_memory_segment_process()); @@ -259,10 +270,7 @@ void ActorExt::init(int* argc, char*** argv) } process->set_data(argc, argv); - } - xbt_assert(smpi_process(), "smpi_process() returned nullptr. You probably gave a nullptr parameter to MPI_Init. " - "Although it's required by MPI-2, this is currently not supported by SMPI. " - "Please use MPI_Init(&argc, &argv) as usual instead."); + } } int ActorExt::get_optind() diff --git a/src/smpi/internals/smpi_global.cpp b/src/smpi/internals/smpi_global.cpp index a8f461be9a..5e70fb2eb6 100644 --- a/src/smpi/internals/smpi_global.cpp +++ b/src/smpi/internals/smpi_global.cpp @@ -417,13 +417,16 @@ typedef void (*smpi_fortran_entry_point_type)(); static int smpi_run_entry_point(smpi_entry_point_type entry_point, std::vector args) { char noarg[] = {'\0'}; - const int argc = args.size(); + int argc = args.size(); std::unique_ptr argv(new char*[argc + 1]); for (int i = 0; i != argc; ++i) argv[i] = args[i].empty() ? noarg : &args[i].front(); argv[argc] = nullptr; + char ** argvptr=argv.get(); - int res = entry_point(argc, argv.get()); + simgrid::smpi::ActorExt::init(&argc, &argvptr); + + int res = entry_point(argc, argvptr); if (res != 0){ XBT_WARN("SMPI process did not return 0. Return value : %d", res); if (smpi_exit_status == 0) @@ -439,7 +442,6 @@ static smpi_entry_point_type smpi_resolve_function(void* handle) smpi_fortran_entry_point_type entry_point_fortran = (smpi_fortran_entry_point_type)dlsym(handle, "user_main_"); if (entry_point_fortran != nullptr) { return [entry_point_fortran](int argc, char** argv) { - smpi_process_init(&argc, &argv); entry_point_fortran(); return 0; }; diff --git a/src/smpi/internals/smpi_replay.cpp b/src/smpi/internals/smpi_replay.cpp index dd65a620c4..d55ff234b9 100644 --- a/src/smpi/internals/smpi_replay.cpp +++ b/src/smpi/internals/smpi_replay.cpp @@ -704,7 +704,9 @@ static std::unordered_map storage; /** @brief Only initialize the replay, don't do it for real */ void smpi_replay_init(int* argc, char*** argv) { - simgrid::smpi::ActorExt::init(argc, argv); + if (not smpi_process()->initializing()){ + simgrid::smpi::ActorExt::init(argc, argv); + } smpi_process()->mark_as_initialized(); smpi_process()->set_replaying(true); diff --git a/teshsuite/smpi/pt2pt-dsend/pt2pt-dsend.c b/teshsuite/smpi/pt2pt-dsend/pt2pt-dsend.c index 33f6846ce4..32a7656bbb 100644 --- a/teshsuite/smpi/pt2pt-dsend/pt2pt-dsend.c +++ b/teshsuite/smpi/pt2pt-dsend/pt2pt-dsend.c @@ -15,7 +15,7 @@ int main(int argc, char *argv[]) { int rank; int32_t data=11; - MPI_Init(&argc, &argv); + MPI_Init(NULL, NULL); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Request r; if (rank==1) {