Commit f7fec28f authored by Brad King's avatar Brad King
Browse files

core: Refactor ADIOS factory to use Comm encapsulation

Implement the Comm encapsulation by moving MPI code out of the factory.
parent a9a46ce9
......@@ -59,10 +59,9 @@ namespace core
ADIOS::ADIOS(const std::string configFile, MPI_Comm mpiComm,
const bool debugMode, const std::string hostLanguage)
: m_ConfigFile(configFile), m_DebugMode(debugMode), m_HostLanguage(hostLanguage)
: m_ConfigFile(configFile), m_DebugMode(debugMode),
m_HostLanguage(hostLanguage), m_Comm(helper::Comm::Duplicate(mpiComm))
{
SMPI_Comm_dup(mpiComm, &m_MPIComm);
if (!configFile.empty())
{
if (configFile.substr(configFile.size() - 3) == "xml")
......@@ -90,17 +89,7 @@ ADIOS::ADIOS(const bool debugMode, const std::string hostLanguage)
{
}
ADIOS::~ADIOS()
{
// Handle the case where MPI is finalized before the ADIOS destructor is
// called, which happens, e.g., with global / static ADIOS objects
int flag;
MPI_Finalized(&flag);
if (!flag)
{
SMPI_Comm_free(&m_MPIComm);
}
}
ADIOS::~ADIOS() = default;
IO &ADIOS::DeclareIO(const std::string name)
{
......
......@@ -22,6 +22,7 @@
#include "adios2/common/ADIOSMPI.h"
#include "adios2/common/ADIOSTypes.h"
#include "adios2/core/Operator.h"
#include "adios2/helper/adiosComm.h"
namespace adios2
{
......@@ -39,7 +40,7 @@ public:
const bool m_DebugMode = true;
/** Get the communicator passed to constructor for parallel case. */
MPI_Comm GetComm() const { return m_MPIComm; }
MPI_Comm GetComm() const { return m_Comm; }
/** Changed by language bindings in constructor */
const std::string m_HostLanguage = "C++";
......@@ -184,8 +185,8 @@ public:
void RemoveAllIOs() noexcept;
private:
/** Passed from parallel constructor, MPI_Comm is a pointer itself. */
MPI_Comm m_MPIComm;
/** Communicator given to parallel constructor. */
helper::Comm m_Comm;
/** XML File to be read containing configuration information */
const std::string m_ConfigFile;
......
......@@ -8,12 +8,54 @@
#include "adiosComm.h"
#include "adiosComm.tcc"
#include <ios> //std::ios_base::failure
#include "adios2/common/ADIOSMPI.h"
namespace adios2
{
namespace helper
{
Comm::~Comm() = default;
Comm::Comm() = default;
Comm::Comm(MPI_Comm mpiComm) : m_MPIComm(mpiComm) {}
Comm::~Comm()
{
// Handle the case where MPI is finalized before the ADIOS destructor is
// called, which happens, e.g., with global / static ADIOS objects
int flag;
MPI_Finalized(&flag);
if (!flag)
{
if (m_MPIComm != MPI_COMM_NULL && m_MPIComm != MPI_COMM_WORLD &&
m_MPIComm != MPI_COMM_SELF)
{
SMPI_Comm_free(&m_MPIComm);
}
}
}
Comm::Comm(Comm &&comm) : m_MPIComm(comm.m_MPIComm)
{
comm.m_MPIComm = MPI_COMM_NULL;
}
Comm &Comm::operator=(Comm &&comm)
{
Comm(std::move(comm)).swap(*this);
return *this;
}
void Comm::swap(Comm &comm) { std::swap(this->m_MPIComm, comm.m_MPIComm); }
Comm Comm::Duplicate(MPI_Comm mpiComm)
{
MPI_Comm newComm;
SMPI_Comm_dup(mpiComm, &newComm);
return Comm(newComm);
}
} // end namespace helper
} // end namespace adios2
......@@ -8,6 +8,8 @@
#ifndef ADIOS2_HELPER_ADIOSCOMM_H_
#define ADIOS2_HELPER_ADIOSCOMM_H_
#include "adios2/common/ADIOSMPI.h"
namespace adios2
{
namespace helper
......@@ -17,7 +19,66 @@ namespace helper
class Comm
{
public:
/**
* @brief Default constructor. Produces an empty communicator.
*
* An empty communicator may not be used for communcation.
*/
Comm();
/**
* @brief Move constructor. Moves communicator state from that given.
*
* The moved-from communicator is left empty and may not be used for
* communication.
*/
Comm(Comm &&);
/**
* @brief Deleted copy constructor. A communicator may not be copied.
*/
Comm(Comm const &) = delete;
~Comm();
/**
* @brief Move assignment. Moves communicator state from that given.
*
* The moved-from communicator is left empty and may not be used for
* communication.
*/
Comm &operator=(Comm &&);
/**
* @brief Deleted copy assignment. A communicator may not be copied.
*/
Comm &operator=(Comm const &) = delete;
/**
* @brief Swap communicator state with another.
*/
void swap(Comm &comm);
// FIXME: Remove conversion after clients transition to encapsulation.
/** Convert to a concrete MPI communicator. */
operator MPI_Comm() const { return m_MPIComm; }
/**
* @brief Create a communicator by duplicating a MPI communicator.
*/
static Comm Duplicate(MPI_Comm mpiComm);
private:
/**
* @brief Construct by taking ownership of a MPI communicator.
*
* This is a private implementation detail used by static
* methods like Duplicate.
*/
explicit Comm(MPI_Comm mpiComm);
/** Encapsulated MPI communicator instance. */
MPI_Comm m_MPIComm = MPI_COMM_NULL;
};
} // end namespace helper
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment