Simplify storage of communicators

We don't need unique ptrs for the communicators. These are just simple
integers that can be copied into a std::vector.
This commit is contained in:
Håkon Hægland 2024-12-02 14:05:17 +01:00
parent 402bb85103
commit 5ae50c90e1
6 changed files with 21 additions and 35 deletions

View File

@ -37,18 +37,6 @@ enum class MessageTag : int {
MasterGroupNamesSize,
};
// Custom deleter for MPI_Comm
struct MPI_Comm_Deleter {
void operator()(MPI_Comm* comm) const {
if (*comm != MPI_COMM_NULL) {
MPI_Comm_free(comm);
}
delete comm;
}
};
using MPI_Comm_Ptr = std::unique_ptr<MPI_Comm, MPI_Comm_Deleter>;
// This class represents a time point.
// It is currently used to represent an epoch time (a double value in seconds since the epoch),
// or an elapsed time (a double value in seconds since the start of the simulation).

View File

@ -34,7 +34,6 @@ namespace Opm {
class ReservoirCouplingMaster {
public:
using MPI_Comm_Ptr = ReservoirCoupling::MPI_Comm_Ptr;
using MessageTag = ReservoirCoupling::MessageTag;
using TimePoint = ReservoirCoupling::TimePoint;
ReservoirCouplingMaster(
@ -44,8 +43,8 @@ public:
);
bool activated() { return this->numSlavesStarted() > 0; }
void addSlaveCommunicator(MPI_Comm_Ptr comm) {
this->master_slave_comm_.push_back(std::move(comm));
void addSlaveCommunicator(MPI_Comm comm) {
this->master_slave_comm_.push_back(comm);
}
void addSlaveName(const std::string &name) { this->slave_names_.push_back(name); }
void addSlaveStartDate(std::time_t date) { this->slave_start_dates_.push_back(date); }
@ -55,7 +54,7 @@ public:
char **getArgv() const { return this->argv_; }
const Parallel::Communication &getComm() const { return this->comm_; }
double getSimulationStartDate() const { return this->schedule_.getStartTime(); }
const MPI_Comm &getSlaveComm(int index) const { return *this->master_slave_comm_[index].get(); }
MPI_Comm getSlaveComm(int index) const { return this->master_slave_comm_[index]; }
const std::string &getSlaveName(int index) const { return this->slave_names_[index]; }
const double *getSlaveStartDates() { return this->slave_start_dates_.data(); }
double maybeChopSubStep(double suggested_timestep, double current_time) const;
@ -73,7 +72,8 @@ private:
const Schedule& schedule_;
int argc_;
char **argv_;
std::vector<MPI_Comm_Ptr> master_slave_comm_; // MPI communicators for the slave processes
// NOTE: MPI_Comm is just an integer handle, so we can just copy it into the vector
std::vector<MPI_Comm> master_slave_comm_; // MPI communicators for the slave processes
std::vector<std::string> slave_names_;
// The start dates are in whole seconds since the epoch. We use a double to store the value
// since both schedule_.getStartTime() and schedule_.stepLength(report_step) returns

View File

@ -43,12 +43,12 @@ ReservoirCouplingSlave(
schedule_{schedule},
timer_{timer}
{
this->slave_master_comm_ = MPI_Comm_Ptr(new MPI_Comm(MPI_COMM_NULL));
MPI_Comm_get_parent(this->slave_master_comm_.get());
if (*(this->slave_master_comm_) == MPI_COMM_NULL) {
this->slave_master_comm_ = MPI_COMM_NULL;
MPI_Comm_get_parent(&this->slave_master_comm_);
if (this->slave_master_comm_ == MPI_COMM_NULL) {
OPM_THROW(std::runtime_error, "Slave process is not spawned by a master process");
}
ReservoirCoupling::setErrhandler(*this->slave_master_comm_, /*is_master=*/false);
ReservoirCoupling::setErrhandler(this->slave_master_comm_, /*is_master=*/false);
}
double
@ -62,7 +62,7 @@ receiveNextTimeStepFromMaster() {
/*datatype=*/MPI_DOUBLE,
/*source_rank=*/0,
/*tag=*/static_cast<int>(MessageTag::SlaveNextTimeStep),
*this->slave_master_comm_,
this->slave_master_comm_,
MPI_STATUS_IGNORE
);
if (result != MPI_SUCCESS) {
@ -90,7 +90,7 @@ receiveMasterGroupNamesFromMasterProcess() {
/*datatype=*/MPI_AINT,
/*source_rank=*/0,
/*tag=*/static_cast<int>(MessageTag::MasterGroupNamesSize),
*this->slave_master_comm_,
this->slave_master_comm_,
MPI_STATUS_IGNORE
);
OpmLog::info("Received master group names size from master process rank 0");
@ -108,7 +108,7 @@ receiveMasterGroupNamesFromMasterProcess() {
/*datatype=*/MPI_CHAR,
/*source_rank=*/0,
/*tag=*/static_cast<int>(MessageTag::MasterGroupNames),
*this->slave_master_comm_,
this->slave_master_comm_,
MPI_STATUS_IGNORE
);
if (result2 != MPI_SUCCESS) {
@ -142,7 +142,7 @@ sendNextReportDateToMasterProcess() const
/*datatype=*/MPI_DOUBLE,
/*dest_rank=*/0,
/*tag=*/static_cast<int>(MessageTag::SlaveNextReportDate),
*this->slave_master_comm_
this->slave_master_comm_
);
OpmLog::info("Sent next report date to master process from rank 0");
}
@ -161,7 +161,7 @@ sendActivationDateToMasterProcess() const
/*datatype=*/MPI_DOUBLE,
/*dest_rank=*/0,
/*tag=*/static_cast<int>(MessageTag::SlaveActivationDate),
*this->slave_master_comm_
this->slave_master_comm_
);
OpmLog::info("Sent simulation start date to master process from rank 0");
}
@ -180,7 +180,7 @@ sendSimulationStartDateToMasterProcess() const
/*datatype=*/MPI_DOUBLE,
/*dest_rank=*/0,
/*tag=*/static_cast<int>(MessageTag::SlaveSimulationStartDate),
*this->slave_master_comm_
this->slave_master_comm_
);
OpmLog::info("Sent simulation start date to master process from rank 0");
}

View File

@ -34,7 +34,6 @@ namespace Opm {
class ReservoirCouplingSlave {
public:
using MPI_Comm_Ptr = ReservoirCoupling::MPI_Comm_Ptr;
using MessageTag = ReservoirCoupling::MessageTag;
ReservoirCouplingSlave(
@ -57,7 +56,7 @@ private:
const Schedule& schedule_;
const SimulatorTimer &timer_;
// MPI parent communicator for a slave process
MPI_Comm_Ptr slave_master_comm_{nullptr};
MPI_Comm slave_master_comm_{MPI_COMM_NULL};
std::map<std::string, std::string> master_group_names_;
bool activated_{false};
};

View File

@ -275,7 +275,7 @@ spawnSlaveProcesses_()
{
char *flow_program_name = this->master_.getArgv(0);
for (const auto& [slave_name, slave] : this->rescoup_.slaves()) {
auto master_slave_comm = MPI_Comm_Ptr(new MPI_Comm(MPI_COMM_NULL));
MPI_Comm master_slave_comm = MPI_COMM_NULL;
const auto& data_file_name = slave.dataFilename();
const auto& directory_path = slave.directoryPath();
// Concatenate the directory path and the data file name to get the full path
@ -298,10 +298,10 @@ spawnSlaveProcesses_()
/*info=*/MPI_INFO_NULL,
/*root=*/0, // Rank 0 spawns the slave processes
/*comm=*/this->comm_,
/*intercomm=*/master_slave_comm.get(),
/*intercomm=*/&master_slave_comm,
/*array_of_errcodes=*/errcodes.data()
);
if (spawn_result != MPI_SUCCESS || (*master_slave_comm == MPI_COMM_NULL)) {
if (spawn_result != MPI_SUCCESS || (master_slave_comm == MPI_COMM_NULL)) {
for (unsigned int i = 0; i < num_procs; i++) {
if (errcodes[i] != MPI_SUCCESS) {
char error_string[MPI_MAX_ERROR_STRING];
@ -312,14 +312,14 @@ spawnSlaveProcesses_()
}
OPM_THROW(std::runtime_error, "Failed to spawn slave process");
}
ReservoirCoupling::setErrhandler(*master_slave_comm, /*is_master=*/true);
ReservoirCoupling::setErrhandler(master_slave_comm, /*is_master=*/true);
OpmLog::info(
fmt::format(
"Spawned reservoir coupling slave simulation for slave with name: "
"{}. Standard output logfile name: {}.log", slave_name, slave_name
)
);
this->master_.addSlaveCommunicator(std::move(master_slave_comm));
this->master_.addSlaveCommunicator(master_slave_comm);
this->master_.addSlaveName(slave_name);
}
}

View File

@ -37,7 +37,6 @@ namespace Opm {
class ReservoirCouplingSpawnSlaves {
public:
using MPI_Comm_Ptr = ReservoirCoupling::MPI_Comm_Ptr;
using MessageTag = ReservoirCoupling::MessageTag;
ReservoirCouplingSpawnSlaves(