Add support for MPI_Init(NULL,NULL).
Might break MC for now.
{
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"));
TRACE_smpi_computing_init(rank);
TRACE_smpi_sleeping_init(rank);
smpi_bench_begin();
+ smpi_process()->mark_as_initialized();
}
smpi_mpi_init();
#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
void set_data(int* argc, char*** argv);
void finalize();
int finalized();
+ int initializing();
int initialized();
void mark_as_initialized();
void set_replaying(bool value);
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()
{
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]));
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());
}
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()
static int smpi_run_entry_point(smpi_entry_point_type entry_point, std::vector<std::string> args)
{
char noarg[] = {'\0'};
- const int argc = args.size();
+ int argc = args.size();
std::unique_ptr<char*[]> 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)
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;
};
/** @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);
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) {