Newer
Older
/*
* Distributed under the OSI-approved Apache License, Version 2.0. See
* accompanying file Copyright.txt for details.
*
* IO.cpp
*
* Created on: Jan 6, 2017
* Author: William F Godoy godoywf@ornl.gov
*/
#include "IO.h"
#include "IO.tcc"
#include "adios2/ADIOSMPI.h"
#include "adios2/engine/bp/BPFileReader.h"
#include "adios2/engine/bp/BPFileWriter.h"
//#include "adios2/engine/plugin/PluginEngine.h"
#include "adios2/helper/adiosFunctions.h" //BuildParametersMap
#ifdef ADIOS2_HAVE_DATAMAN // external dependencies
#include "adios2/engine/dataman/DataManReader.h"
#include "adios2/engine/dataman/DataManWriter.h"
#endif
#ifdef ADIOS2_HAVE_ADIOS1 // external dependencies
#include "adios2/engine/adios1/ADIOS1Reader.h"
#include "adios2/engine/adios1/ADIOS1Writer.h"
#endif
#ifdef ADIOS2_HAVE_HDF5 // external dependencies
#include "adios2/engine/hdf5/HDF5ReaderP.h"
#include "adios2/engine/hdf5/HDF5WriterP.h"
#endif
{
IO::IO(const std::string name, MPI_Comm mpiComm, const bool inConfigFile,
const bool debugMode)
: m_Name(name), m_MPIComm(mpiComm), m_InConfigFile(inConfigFile),
m_DebugMode(debugMode)
{
}
void IO::SetEngine(const std::string engineType) { m_EngineType = engineType; }
void IO::SetIOMode(const IOMode ioMode) { m_IOMode = ioMode; };
void IO::SetParameters(const Params ¶meters) { m_Parameters = parameters; }
void IO::SetSingleParameter(const std::string key,
const std::string value) noexcept
{
m_Parameters[key] = value;
}
const Params &IO::GetParameters() const { return m_Parameters; }
unsigned int IO::AddTransport(const std::string type, const Params ¶meters)
{
Params parametersMap(parameters);
if (m_DebugMode)
{
CheckTransportType(type);
}
parametersMap["transport"] = type;
m_TransportsParameters.push_back(parametersMap);
return static_cast<unsigned int>(m_TransportsParameters.size() - 1);
void IO::SetTransportSingleParameter(const unsigned int transportIndex,
const std::string key,
const std::string value)
{
if (m_DebugMode)
{
if (transportIndex >=
static_cast<unsigned int>(m_TransportsParameters.size()))
{
throw std::invalid_argument("ERROR: transportIndex is larger than "
"transports created with AddTransport "
"function calls\n");
}
}
m_TransportsParameters[transportIndex][key] = value;
}
VariableCompound &
IO::DefineVariableCompound(const std::string &name, const size_t sizeOfVariable,
const Dims &shape, const Dims &start,
const Dims &count, const bool constantDims)
{
if (m_DebugMode)
{
auto itVariable = m_Variables.find(name);
if (!IsEnd(itVariable, m_Variables))
{
throw std::invalid_argument("ERROR: variable " + name +
" exists in IO object " + m_Name +
", in call to DefineVariable\n");
}
}
const unsigned int size = m_Compound.size();
auto itVariableCompound = m_Compound.emplace(
size, VariableCompound(name, sizeOfVariable, shape, start, count,
constantDims, m_DebugMode));
m_Variables.emplace(name, std::make_pair("compound", size));
return itVariableCompound.first->second;
}
VariableCompound &IO::GetVariableCompound(const std::string &name)
{
return m_Compound.at(GetMapIndex(name, m_Variables, "VariableCompound"));
const DataMap &IO::GetVariablesDataMap() const noexcept { return m_Variables; }
const DataMap &IO::GetAttributesDataMap() const noexcept
{
return m_Attributes;
}
VariableBase *IO::GetVariableBase(const std::string &name) noexcept
{
VariableBase *variableBase = nullptr;
auto itVariable = m_Variables.find(name);
if (itVariable == m_Variables.end())
{
return variableBase;
}
const std::string type(itVariable->second.first);
if (type == "compound")
{
variableBase = &GetVariableCompound(name);
}
#define declare_type(T) \
else if (type == GetType<T>()) { variableBase = &GetVariable<T>(name); }
ADIOS2_FOREACH_TYPE_1ARG(declare_type)
#undef declare_type
return variableBase;
}
std::string IO::GetVariableType(const std::string &name) const
{
std::string type;
auto itVariable = m_Variables.find(name);
if (itVariable != m_Variables.end())
{
type = itVariable->second.first;
}
return type;
}
bool IO::InConfigFile() const { return m_InConfigFile; };
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
bool IO::RemoveVariable(const std::string &name) noexcept
{
bool isRemoved = false;
auto itVariable = m_Variables.find(name);
// variable exists
if (itVariable != m_Variables.end())
{
// first remove the Variable object
const std::string type(itVariable->second.first);
const unsigned int index(itVariable->second.second);
if (type == "compound")
{
auto variableMap = m_Compound;
variableMap.erase(index);
}
#define declare_type(T) \
else if (type == GetType<T>()) \
{ \
auto variableMap = GetVariableMap<T>(); \
variableMap.erase(index); \
}
ADIOS2_FOREACH_TYPE_1ARG(declare_type)
#undef declare_type
isRemoved = true;
}
{
m_Variables.erase(name);
}
return isRemoved;
}
Engine &IO::Open(const std::string &name, const Mode openMode, MPI_Comm mpiComm)
if (m_Engines.count(name) == 1)
throw std::invalid_argument("ERROR: IO Engine with name " + name +
" already created, in call to Open.\n");
}
}
std::shared_ptr<Engine> engine;
const bool isDefaultWriter =
m_EngineType.empty() &&
(openMode == Mode::Write || openMode == Mode::Append)
? true
: false;
const bool isDefaultReader =
m_EngineType.empty() && (openMode == Mode::Read) ? true : false;
if (isDefaultWriter || m_EngineType == "BPFileWriter")
{
engine = std::make_shared<BPFileWriter>(*this, name, openMode, mpiComm);
}
else if (isDefaultReader || m_EngineType == "BPFileReader")
{
engine = std::make_shared<BPFileReader>(*this, name, openMode, mpiComm);
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
}
else if (m_EngineType == "DataManWriter")
{
#ifdef ADIOS2_HAVE_DATAMAN
engine =
std::make_shared<DataManWriter>(*this, name, openMode, mpiComm);
#else
throw std::invalid_argument(
"ERROR: this version didn't compile with "
"DataMan library, can't Open DataManWriter\n");
#endif
}
else if (m_EngineType == "DataManReader")
{
#ifdef ADIOS2_HAVE_DATAMAN
engine =
std::make_shared<DataManReader>(*this, name, openMode, mpiComm);
#else
throw std::invalid_argument(
"ERROR: this version didn't compile with "
"DataMan library, can't Open DataManReader\n");
#endif
}
else if (m_EngineType == "ADIOS1Writer")
{
#ifdef ADIOS2_HAVE_ADIOS1
engine = std::make_shared<ADIOS1Writer>(*this, name, openMode, mpiComm);
#else
throw std::invalid_argument(
"ERROR: this version didn't compile with ADIOS "
"1.x library, can't Open ADIOS1Writer\n");
#endif
}
else if (m_EngineType == "ADIOS1Reader")
{
#ifdef ADIOS2_HAVE_ADIOS1
engine = std::make_shared<ADIOS1Reader>(*this, name, openMode, mpiComm);
#else
throw std::invalid_argument(
"ERROR: this version didn't compile with ADIOS "
"1.x library, can't Open ADIOS1Reader\n");
#endif
}
else if (m_EngineType == "HDF5Writer")
{
#ifdef ADIOS2_HAVE_HDF5
engine = std::make_shared<HDF5WriterP>(*this, name, openMode, mpiComm);
#else
throw std::invalid_argument("ERROR: this version didn't compile with "
"HDF5 library, can't use HDF5\n");
#endif
}
else if (m_EngineType == "HDF5Reader")
{
#ifdef ADIOS2_HAVE_HDF5
engine = std::make_shared<HDF5ReaderP>(*this, name, openMode, mpiComm);
#else
throw std::invalid_argument("ERROR: this version didn't compile with "
"HDF5 library, can't use HDF5\n");
#endif
}
else if (m_EngineType == "PluginEngine")
{
// engine = std::make_shared<PluginEngine>(*this, name, openMode,
// mpiComm);
else
{
if (m_DebugMode)
{
throw std::invalid_argument("ERROR: engine " + m_EngineType +
" not supported, IO SetEngine must add "
"a supported engine, in call to "
"Open\n");
}
}
auto itEngine = m_Engines.emplace(name, std::move(engine));
if (m_DebugMode)
{
if (!itEngine.second)
{
throw std::invalid_argument(
"ERROR: engine of type " + m_EngineType + " and name " + name +
" could not be created, in call to Open\n");
}
}
// return a reference
return *itEngine.first->second.get();
Engine &IO::Open(const std::string &name, const Mode openMode)
{
return Open(name, openMode, m_MPIComm);
}
// PRIVATE Functions
unsigned int IO::GetMapIndex(const std::string &name, const DataMap &dataMap,
const std::string hint) const
auto itDataMap = dataMap.find(name);
throw std::invalid_argument("ERROR: " + hint + " " + m_Name +
" wasn't created with Define " + hint +
", in call to IO object " + m_Name +
" Get" + hint + "\n");
return itDataMap->second.second;
}
void IO::CheckAttributeCommon(const std::string &name) const
{
auto itAttribute = m_Attributes.find(name);
if (!IsEnd(itAttribute, m_Attributes))
{
throw std::invalid_argument("ERROR: attribute " + name +
" exists in IO object " + m_Name +
", in call to DefineAttribute\n");
}
bool IO::IsEnd(DataMap::const_iterator itDataMap, const DataMap &dataMap) const
void IO::CheckTransportType(const std::string type) const
{
if (type.empty() || type.find("=") != type.npos)
{
throw std::invalid_argument(
"ERROR: wrong first argument " + type +
", must "
"be a single word for a supported transport type, in "
"call to IO AddTransport \n");
}
}
// Explicitly instantiate the necessary public template implementations
#define define_template_instantiation(T) \
template Variable<T> &IO::DefineVariable<T>(const std::string &, \
const Dims &, const Dims &, \
const Dims &, const bool); \
template Variable<T> &IO::GetVariable<T>(const std::string &);
ADIOS2_FOREACH_TYPE_1ARG(define_template_instantiation)
#undef define_template_instatiation
#define declare_template_instantiation(T) \
template Attribute<T> &IO::DefineAttribute<T>(const std::string &, \
const T *, const size_t); \
template Attribute<T> &IO::DefineAttribute<T>(const std::string &, \
const T &); \
template Attribute<T> &IO::GetAttribute(const std::string &);
ADIOS2_FOREACH_ATTRIBUTE_TYPE_1ARG(declare_template_instantiation)
#undef declare_template_instantiation