-
Atkins, Charles Vernon authoredAtkins, Charles Vernon authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ADIOS.cpp 12.52 KiB
/*
* Distributed under the OSI-approved Apache License, Version 2.0. See
* accompanying file Copyright.txt for details.
*
* ADIOS.cpp
*
* Created on: Sep 29, 2016
* Author: William F Godoy
*/
/// \cond EXCLUDE_FROM_DOXYGEN
#include <fstream>
#include <ios> //std::ios_base::failure
#include <iostream>
#include <sstream>
#include <utility>
/// \endcond
#include "ADIOS.h"
#include "ADIOS.tcc"
#include "ADIOSMacros.h"
#include "functions/adiosFunctions.h"
// Engines
#include "engine/bp/BPFileReader.h"
#include "engine/bp/BPFileWriter.h"
#ifdef ADIOS_HAVE_DATAMAN // external dependencies
#include "engine/dataman/DataManReader.h"
#include "engine/dataman/DataManWriter.h"
#endif
#ifdef ADIOS_HAVE_ADIOS1 // external dependencies
#include "engine/adios1/ADIOS1Reader.h"
#include "engine/adios1/ADIOS1Writer.h"
#endif
#ifdef ADIOS_HAVE_HDF5 // external dependencies
#include "engine/hdf5/HDF5ReaderP.h"
#include "engine/hdf5/HDF5WriterP.h"
#endif
namespace adios
{
ADIOS::ADIOS(const Verbose verbose, const bool debugMode)
: m_DebugMode{debugMode}
{
InitMPI();
}
ADIOS::ADIOS(const std::string config, const Verbose verbose,
const bool debugMode)
: m_ConfigFile(config), m_DebugMode(debugMode)
{
InitMPI();
// InitXML( m_ConfigFile, m_MPIComm, m_DebugMode, m_Transforms );
}
ADIOS::ADIOS(const std::string configFile, MPI_Comm mpiComm,
const Verbose verbose, const bool debugMode)
: m_MPIComm(mpiComm), m_ConfigFile(configFile), m_DebugMode(debugMode)
{
InitMPI();
// InitXML( m_XMLConfigFile, m_MPIComm, m_DebugMode, m_HostLanguage,
// m_Transforms, m_Groups );
}
ADIOS::ADIOS(MPI_Comm mpiComm, const Verbose verbose, const bool debugMode)
: m_MPIComm(mpiComm), m_DebugMode(debugMode)
{
InitMPI();
}
// ADIOS::~ADIOS() {}
void ADIOS::InitMPI()
{
if (m_DebugMode == true)
{
if (m_MPIComm == MPI_COMM_NULL)
{
throw std::ios_base::failure(
"ERROR: engine communicator is MPI_COMM_NULL,"
" in call to ADIOS Open or Constructor\n");
}
}
MPI_Comm_rank(m_MPIComm, &m_RankMPI);
MPI_Comm_size(m_MPIComm, &m_SizeMPI);
}
Method &ADIOS::DeclareMethod(const std::string methodName)
{
if (m_DebugMode == true)
{
if (m_Methods.count(methodName) == 1)
{
throw std::invalid_argument(
"ERROR: method " + methodName +
" already declared, from DeclareMethod\n");
}
}
m_Methods.emplace(methodName, Method(methodName, m_DebugMode));
return m_Methods.at(methodName);
}
std::shared_ptr<Engine> ADIOS::Open(const std::string &name,
const std::string accessMode,
MPI_Comm mpiComm, const Method &method)
{
if (m_DebugMode == true)
{
if (m_EngineNames.count(name) == 1) // Check if Engine already exists
{
throw std::invalid_argument(
"ERROR: engine name " + name +
" already created by Open, in call from Open.\n");
}
}
m_EngineNames.insert(name);
const std::string type(method.m_Type);
const bool isDefaultWriter =
(accessMode == "w" || accessMode == "write" || accessMode == "a" ||
accessMode == "append") &&
type.empty()
? true
: false;
const bool isDefaultReader =
(accessMode == "r" || accessMode == "read") && type.empty() ? true
: false;
if (isDefaultWriter || type == "BPFileWriter" || type == "bpfilewriter")
{
return std::make_shared<BPFileWriter>(*this, name, accessMode, mpiComm,
method);
}
else if (isDefaultReader || type == "BPReader" || type == "bpreader")
{
return std::make_shared<BPFileReader>(*this, name, accessMode, mpiComm,
method);
}
else if (type == "SIRIUS" || type == "sirius" || type == "Sirius")
{
// not yet supported
// return std::make_shared<engine::DataMan>( *this, name, accessMode,
// mpiComm, method, iomode, timeout_sec, m_DebugMode, method.m_nThreads
// );
}
else if (type == "DataManWriter")
{
#ifdef ADIOS_HAVE_DATAMAN
return std::make_shared<DataManWriter>(*this, name, accessMode, mpiComm,
method);
#else
throw std::invalid_argument(
"ERROR: this version didn't compile with "
"Dataman library, can't Open DataManWriter\n");
#endif
}
else if (type == "DataManReader")
{
#ifdef ADIOS_HAVE_DATAMAN
return std::make_shared<DataManReader>(*this, name, accessMode, mpiComm,
method);
#else
throw std::invalid_argument(
"ERROR: this version didn't compile with "
"Dataman library, can't Open DataManReader\n");
#endif
}
else if (type == "ADIOS1Writer")
{
#ifdef ADIOS_HAVE_ADIOS1
return std::make_shared<ADIOS1Writer>(*this, name, accessMode, mpiComm,
method);
#else
throw std::invalid_argument(
"ERROR: this version didn't compile with ADIOS "
"1.x library, can't Open ADIOS1Writer\n");
#endif
}
else if (type == "Vis")
{
// return std::make_shared<Vis>( *this, name, accessMode, mpiComm,
// method,
// iomode, timeout_sec, m_DebugMode, method.m_nThreads );
}
else if (type == "HDF5Writer") // -junmin
{
#ifdef ADIOS_HAVE_HDF5
return std::make_shared<HDF5Writer>(*this, name, accessMode, mpiComm,
method);
#else
throw std::invalid_argument("ERROR: this version didn't compile with "
"HDF5 library, can't use HDF5\n");
#endif
}
else
{
if (m_DebugMode == true)
{
throw std::invalid_argument("ERROR: method type " + type +
" not supported for " + name +
", in call to Open\n");
}
}
return nullptr; // if debug mode is off
}
std::shared_ptr<Engine> ADIOS::Open(const std::string &name,
const std::string accessMode,
const Method &method)
{
return Open(name, accessMode, m_MPIComm, method);
}
std::shared_ptr<Engine> ADIOS::Open(const std::string &name,
const std::string accessMode,
MPI_Comm mpiComm,
const std::string methodName)
{
auto itMethod = m_Methods.find(methodName);
if (m_DebugMode == true)
{
CheckMethod(itMethod, methodName, " in call to Open\n");
}
return Open(name, accessMode, mpiComm, itMethod->second);
}
std::shared_ptr<Engine> ADIOS::Open(const std::string &name,
const std::string accessMode,
const std::string methodName)
{
return Open(name, accessMode, m_MPIComm, methodName);
}
std::shared_ptr<Engine> ADIOS::OpenFileReader(const std::string &fileName,
MPI_Comm mpiComm,
const Method &method)
{
return Open(fileName, "r", mpiComm, method);
}
std::shared_ptr<Engine> ADIOS::OpenFileReader(const std::string &name,
MPI_Comm mpiComm,
const std::string methodName)
{
auto itMethod = m_Methods.find(methodName);
if (m_DebugMode == true)
{
CheckMethod(itMethod, methodName, " in call to Open\n");
}
return Open(name, "r", m_MPIComm, itMethod->second);
}
VariableCompound &ADIOS::GetVariableCompound(const std::string &name)
{
return m_Compound.at(GetVariableIndex<void>(name));
}
void ADIOS::MonitorVariables(std::ostream &logStream)
{
logStream << "\tVariable \t Type\n";
for (auto &variablePair : m_Variables)
{
const std::string name(variablePair.first);
const std::string type(variablePair.second.first);
if (type == GetType<char>())
{
GetVariable<char>(name).Monitor(logStream);
}
else if (type == GetType<unsigned char>())
{
GetVariable<unsigned char>(name).Monitor(logStream);
}
else if (type == GetType<short>())
{
GetVariable<short>(name).Monitor(logStream);
}
else if (type == GetType<unsigned short>())
{
GetVariable<unsigned short>(name).Monitor(logStream);
}
else if (type == GetType<int>())
{
GetVariable<int>(name).Monitor(logStream);
}
else if (type == GetType<unsigned int>())
{
GetVariable<unsigned int>(name).Monitor(logStream);
}
else if (type == GetType<long int>())
{
GetVariable<long int>(name).Monitor(logStream);
}
else if (type == GetType<unsigned long int>())
{
GetVariable<unsigned long int>(name).Monitor(logStream);
}
else if (type == GetType<long long int>())
{
GetVariable<long long int>(name).Monitor(logStream);
}
else if (type == GetType<unsigned long long int>())
{
GetVariable<unsigned long long int>(name).Monitor(logStream);
}
else if (type == GetType<float>())
{
GetVariable<float>(name).Monitor(logStream);
}
else if (type == GetType<double>())
{
GetVariable<double>(name).Monitor(logStream);
}
else if (type == GetType<long double>())
{
GetVariable<long double>(name).Monitor(logStream);
}
else if (type == GetType<std::complex<float>>())
{
GetVariable<std::complex<float>>(name).Monitor(logStream);
}
else if (type == GetType<std::complex<double>>())
{
GetVariable<std::complex<double>>(name).Monitor(logStream);
}
else if (type == GetType<std::complex<long double>>())
{
GetVariable<std::complex<long double>>(name).Monitor(logStream);
}
}
}
// PRIVATE FUNCTIONS BELOW
void ADIOS::CheckVariableInput(const std::string &name,
const Dims &dimensions) const
{
if (m_DebugMode == true)
{
if (m_Variables.count(name) == 1)
{
throw std::invalid_argument(
"ERROR: variable " + name +
" already exists, in call to DefineVariable\n");
}
if (dimensions.empty() == true)
{
throw std::invalid_argument(
"ERROR: variable " + name +
" dimensions can't be empty, in call to DefineVariable\n");
}
}
}
void ADIOS::CheckVariableName(
std::map<std::string, std::pair<std::string, unsigned int>>::const_iterator
itVariable,
const std::string &name, const std::string hint) const
{
if (m_DebugMode == true)
{
if (itVariable == m_Variables.end())
{
throw std::invalid_argument("ERROR: variable " + name +
" does not exist " + hint + "\n");
}
}
}
void ADIOS::CheckMethod(std::map<std::string, Method>::const_iterator itMethod,
const std::string methodName,
const std::string hint) const
{
if (itMethod == m_Methods.end())
{
throw std::invalid_argument("ERROR: method " + methodName +
" not found " + hint + "\n");
}
}
//------------------------------------------------------------------------------
// Explicitly instantiate the necessary template implementations
#define define_template_instantiation(T) \
template Variable<T> &ADIOS::DefineVariable<T>( \
const std::string &, const Dims, const Dims, const Dims); \
\
template Variable<T> &ADIOS::GetVariable<T>(const std::string &);
ADIOS_FOREACH_TYPE_1ARG(define_template_instantiation)
template unsigned int ADIOS::GetVariableIndex<void>(const std::string &);
#undef define_template_instatiation
//------------------------------------------------------------------------------
} // end namespace adios