Skip to content
Snippets Groups Projects
Commit 1756bed3 authored by pnorbert's avatar pnorbert Committed by williamfgc
Browse files

Bp1read (#23)

* Support PutDeferred() in ADIOS1 writer

* added PerformPuts() to ADIOS1Writer

* refactor toolkit/interop/adios1/ADIOS1Common in preparation for having separate Write and Read classes

* Working towards ADIOS1 Reader. Changes the Engine.BeginStep() signature for all engines.

* Updates to ADIOS1 reader, variables and scalar values are propagated now at Open
parent bdd7572e
No related branches found
No related tags found
1 merge request!294Bp1read : Initial Reading Capabilities and latest API
......@@ -102,7 +102,7 @@ if(ADIOS2_HAVE_ADIOS1)
toolkit/interop/adios1/ADIOS1Common.cpp toolkit/interop/adios1/ADIOS1Common.tcc
toolkit/interop/adios1/ADIOS1CommonWrite.cpp toolkit/interop/adios1/ADIOS1CommonWrite.tcc
toolkit/interop/adios1/ADIOS1CommonRead.cpp
toolkit/interop/adios1/ADIOS1CommonRead.cpp toolkit/interop/adios1/ADIOS1CommonRead.tcc
)
target_link_libraries(adios2 PRIVATE adios1::adios)
endif()
......
/*
* Distributed under the OSI-approved Apache License, Version 2.0. See
* accompanying file Copyright.txt for details.
*
* ADIOS1CommonRead.cpp
*
* Created on: Oct 26, 2017
* Author: Norbert Podhorszki pnorbert@ornl.gov
* William F Godoy godoywf@ornl.gov
*/
#include "ADIOS1CommonRead.h"
#include "ADIOS1CommonRead.tcc"
#include "adios2/ADIOSMPI.h"
#include "adios2/helper/adiosFunctions.h" //OpenModeToString, GetType
extern int adios_verbose_level;
extern int adios_errno;
namespace adios2
{
namespace interop
{
ADIOS1CommonRead::ADIOS1CommonRead(const std::string &fileName,
MPI_Comm mpiComm, const bool debugMode)
: ADIOS1Common(fileName, mpiComm, debugMode)
{
Init();
adios_read_init_method(m_ReadMethod, m_MPIComm, "");
}
ADIOS1CommonRead::~ADIOS1CommonRead()
{
Close();
adios_read_finalize_method(m_ReadMethod);
}
bool ADIOS1CommonRead::Open()
{
if (m_OpenAsFile)
{
m_fh =
adios_read_open_file(m_FileName.c_str(), m_ReadMethod, m_MPIComm);
}
else
{
m_fh = adios_read_open(m_FileName.c_str(), m_ReadMethod, m_MPIComm,
ADIOS_LOCKMODE_CURRENT, 0.0);
}
return (m_fh != NULL);
}
void ADIOS1CommonRead::DefineADIOS2Variable(IO &io, const char *name,
const ADIOS_VARINFO *vi, Dims gdims,
bool isJoined, bool isGlobal)
{
switch (vi->type)
{
case adios_unsigned_byte:
DefineADIOS2Variable<unsigned char>(io, name, vi, gdims, isJoined,
isGlobal);
break;
case adios_unsigned_short:
DefineADIOS2Variable<unsigned short>(io, name, vi, gdims, isJoined,
isGlobal);
break;
case adios_unsigned_integer:
DefineADIOS2Variable<unsigned int>(io, name, vi, gdims, isJoined,
isGlobal);
break;
case adios_unsigned_long:
DefineADIOS2Variable<unsigned long long int>(io, name, vi, gdims,
isJoined, isGlobal);
break;
case adios_byte:
DefineADIOS2Variable<char>(io, name, vi, gdims, isJoined, isGlobal);
break;
case adios_short:
DefineADIOS2Variable<short>(io, name, vi, gdims, isJoined, isGlobal);
break;
case adios_integer:
DefineADIOS2Variable<int>(io, name, vi, gdims, isJoined, isGlobal);
break;
case adios_long:
DefineADIOS2Variable<long long int>(io, name, vi, gdims, isJoined,
isGlobal);
break;
case adios_real:
DefineADIOS2Variable<float>(io, name, vi, gdims, isJoined, isGlobal);
break;
case adios_double:
DefineADIOS2Variable<double>(io, name, vi, gdims, isJoined, isGlobal);
break;
case adios_long_double:
DefineADIOS2Variable<long double>(io, name, vi, gdims, isJoined,
isGlobal);
break;
case adios_string:
/*FIXME: DefineADIOS2Variable<std::string>(io, name, vi, gdims,
isJoined,
isGlobal);*/
break;
case adios_complex:
DefineADIOS2Variable<std::complex<float>>(io, name, vi, gdims, isJoined,
isGlobal);
break;
case adios_double_complex:
DefineADIOS2Variable<std::complex<double>>(io, name, vi, gdims,
isJoined, isGlobal);
break;
default:
break;
}
}
void ADIOS1CommonRead::GenerateVariables(IO &io)
{
/* Create a Variable for each variable in the file */
for (int varid = 0; varid < m_fh->nvars; varid++)
{
// here read variable metadata (dimensions, type, etc.)...then create a
// Variable like below:
// Variable<T>& variable = io.DefineVariable<T>( m_Name + "/" +
// name, )
// return &variable; //return address if success
ADIOS_VARINFO *vi = adios_inq_var(m_fh, m_fh->var_namelist[varid]);
if (vi != nullptr)
{
if (vi->ndim > 0)
{
Dims gdims = Uint64ArrayToSizetVector(vi->ndim, vi->dims);
bool joinedread = false;
if (gdims[0] == JoinedDim)
{
/* Joined Array */
InqVarBlockInfo(vi);
size_t joined_size = 0;
for (int i = 0; i < *vi->nblocks; i++)
{
joined_size += vi->blockinfo[i].count[0];
}
gdims[0] = joined_size;
joinedread = true;
}
if (!vi->global)
{
/* Local array */
for (int j = 0; j < vi->ndim; ++j)
{
gdims[j] = IrregularDim;
}
}
else
{
/* Check if dimensions change in time */
for (int step = 1; step < vi->nsteps; ++step)
{
Dims dims =
gdims; // GetGlobalDimsAtStep(vi, step, joinedread);
for (int j = 0; j < vi->ndim; ++j)
{
if (dims[j] != gdims[j])
gdims[j] = IrregularDim;
}
}
}
DefineADIOS2Variable(io, m_fh->var_namelist[vi->varid], vi,
gdims, joinedread, (vi->global > 0));
}
else /* Scalars */
{
/* scalar variable but global value or local value*/
bool isChangingDim = false;
bool isLocalValue = IsVarLocalValue(vi);
if (isLocalValue)
{
/* Local Value */
for (int step = 1; step < vi->nsteps; ++step)
{
if (vi->nblocks[step] != vi->nblocks[0])
isChangingDim = true;
}
if (isChangingDim)
{
DefineADIOS2Variable(io, m_fh->var_namelist[vi->varid],
vi, {IrregularDim}, false, false);
}
else
{
DefineADIOS2Variable(io, m_fh->var_namelist[vi->varid],
vi, {(unsigned int)vi->nblocks[0]},
false, false);
}
}
else
{
DefineADIOS2Variable(io, m_fh->var_namelist[vi->varid], vi,
{}, false, true);
}
}
adios_free_varinfo(vi);
}
}
}
void ADIOS1CommonRead::ScheduleReadCommon(const std::string &name,
const Dims &offs, const Dims &ldims,
const int fromStep, const int nSteps,
const bool readAsLocalValue,
const bool readAsJoinedArray,
void *data)
{
if (readAsLocalValue)
{
/* Get all the requested values from metadata now */
ADIOS_VARINFO *vi = adios_inq_var(m_fh, name.c_str());
if (vi)
{
adios_inq_var_stat(m_fh, vi, 0, 1);
int elemsize = adios_type_size(vi->type, nullptr);
long long blockidx = 0;
for (int i = 0; i < fromStep; i++)
{
blockidx += vi->nblocks[i];
}
char *dest = (char *)data;
for (int i = fromStep; i < fromStep + nSteps; i++)
{
for (int j = 0; j < vi->nblocks[i]; j++)
{
memcpy(dest, vi->statistics->blocks->mins[blockidx],
elemsize);
++blockidx;
dest += elemsize;
}
}
adios_free_varinfo(vi);
}
}
else
{
uint64_t start[32], count[32];
for (int i = 0; i < ldims.size(); i++)
{
start[i] = (uint64_t)offs[i];
count[i] = (uint64_t)ldims[i];
}
ADIOS_SELECTION *sel = nullptr;
if (ldims.size() > 0)
{
sel = adios_selection_boundingbox(ldims.size(), start, count);
}
adios_schedule_read(m_fh, sel, name.c_str(), (int)fromStep, (int)nSteps,
data);
adios_selection_delete(sel);
}
}
void ADIOS1CommonRead::PerformReads()
{
adios_perform_reads(m_fh, static_cast<int>(ReadMode::Blocking));
}
AdvanceStatus ADIOS1CommonRead::AdvanceStep(AdvanceMode mode,
const float timeout_sec)
{
if (m_OpenAsFile)
{
throw std::invalid_argument("ERROR: ADIOS1Reader does not allow "
"Advance() on a file which was opened for "
"read as File\n");
}
if (mode != AdvanceMode::NextAvailable &&
mode != AdvanceMode::LatestAvailable)
{
throw std::invalid_argument(
"ERROR: ADIOS1Reader.Advance() only allows "
"for NextAvailable or LatestAvailable modes.\n");
}
int last = (mode == AdvanceMode::NextAvailable ? 0 : 1);
float *to = const_cast<float *>(&timeout_sec);
adios_advance_step(m_fh, last, *to);
AdvanceStatus status;
switch (adios_errno)
{
case err_no_error:
status = AdvanceStatus::OK;
break;
case err_end_of_stream:
status = AdvanceStatus::EndOfStream;
break;
case err_step_notready:
status = AdvanceStatus::StepNotReady;
break;
default:
status = AdvanceStatus::OtherError;
break;
}
return status;
}
void ADIOS1CommonRead::ReleaseStep() { adios_release_step(m_fh); }
ADIOS_VARINFO *ADIOS1CommonRead::InqVar(const std::string &varName)
{
return adios_inq_var(m_fh, varName.c_str());
}
void ADIOS1CommonRead::InqVarBlockInfo(ADIOS_VARINFO *vi)
{
adios_inq_var_blockinfo(m_fh, vi);
}
void ADIOS1CommonRead::FreeVarInfo(ADIOS_VARINFO *vi) {}
bool ADIOS1CommonRead::IsVarLocalValue(ADIOS_VARINFO *vi)
{
bool isLocalValue = false;
std::string aname(m_fh->var_namelist[vi->varid]);
aname = aname + "/ReadAsArray";
for (int i = 0; i < vi->nattrs; ++i)
{
if (!strcmp(m_fh->attr_namelist[vi->attr_ids[i]], aname.c_str()))
{
isLocalValue = true;
break;
}
}
return isLocalValue;
}
void ADIOS1CommonRead::Close()
{
if (m_IsFileOpen)
{
adios_read_close(m_fh);
m_IsFileOpen = false;
}
}
// PRIVATE
void ADIOS1CommonRead::Init()
{
if (!m_IsInitialized)
{
m_IsInitialized = true;
}
}
void ADIOS1CommonRead::InitParameters(const Params &parameters)
{
auto itOpenAsFile = parameters.find("OpenAsFile");
if (itOpenAsFile == parameters.end())
{
m_OpenAsFile = false;
}
else if (itOpenAsFile->second == "true")
{
m_OpenAsFile = true;
}
auto itVerbosity = parameters.find("verbose");
if (itVerbosity != parameters.end())
{
int verbosity = std::stoi(itVerbosity->second);
if (m_DebugMode)
{
if (verbosity < 0 || verbosity > 5)
throw std::invalid_argument(
"ERROR: Method verbose argument must be an "
"integer in the range [0,5], in call to "
"Open or Engine constructor\n");
}
adios_verbose_level = verbosity;
}
}
void ADIOS1CommonRead::InitTransports(
const std::vector<Params> &transportsParameters)
{
for (const auto &parameters : transportsParameters)
{
auto itTransport = parameters.find("transport");
if (itTransport->second == "file" || itTransport->second == "File" ||
itTransport->second == "bp" || itTransport->second == "BP")
{
m_ReadMethod = ADIOS_READ_METHOD_BP;
}
else
{
if (m_DebugMode)
{
throw std::invalid_argument(
"ERROR: transport " + itTransport->second +
" (you mean File?) not supported, in " + m_FileName + "\n");
}
}
}
}
/*
void ADIOS1CommonRead::DefineVariable(const std::string &name,
const ShapeID shapeID,
enum ADIOS_DATATYPES vartype,
const std::string ldims,
const std::string gdims,
const std::string offsets)
{
switch (shapeID)
{
case ShapeID::GlobalValue:
adios_define_var(m_ADIOSGroup, name.c_str(), "", vartype, "", "",
"");
break;
case ShapeID::LocalValue:
adios_define_var(m_ADIOSGroup, name.c_str(), "", vartype, "", "",
"");
adios_define_attribute(m_ADIOSGroup, "ReadAsArray", name.c_str(),
adios_byte, "1", nullptr);
break;
case ShapeID::GlobalArray:
case ShapeID::LocalArray:
case ShapeID::JoinedArray:
adios_define_var(m_ADIOSGroup, name.c_str(), "", vartype,
ldims.c_str(),
gdims.c_str(), offsets.c_str());
break;
}
}*/
/*
// Explicit declaration of the public template methods
#define declare_template_instantiation(T) \
template void ADIOS1CommonRead::ReadVariable<T>( \
const std::string &name, const ShapeID shapeID, const Dims ldims, \
const Dims gdims, const Dims offsets, const T *values);
ADIOS2_FOREACH_TYPE_1ARG(declare_template_instantiation)
#undef declare_template_instantiation
*/
} // end namespace interop
} // end namespace adios
/*
* Distributed under the OSI-approved Apache License, Version 2.0. See
* accompanying file Copyright.txt for details.
*
* ADIOS1CommonRead.h
*
* Created on: Oct 26, 2017
* Author: Norbert Podhorszki pnorbert@ornl.gov
* William F Godoy godoywf@ornl.gov
*/
#ifndef ADIOS2_TOOLKIT_INTEROP_ADIOS1_ADIOS1COMMONREAD_H_
#define ADIOS2_TOOLKIT_INTEROP_ADIOS1_ADIOS1COMMONREAD_H_
// Fake out the include guard from ADIOS1's mpidummy.h to prevent it from
// getting included
#ifdef _NOMPI
#define __MPI_DUMMY_H__
#define MPI_Comm int
#endif
#include <adios_error.h>
#include <adios_read.h>
#ifdef _NOMPI
#undef MPI_Comm
#undef __MPI_DUMMY_H__
#endif
#include "ADIOS1Common.h"
#include "adios2/ADIOSMPICommOnly.h"
#include "adios2/ADIOSMacros.h"
#include "adios2/ADIOSTypes.h"
#include "adios2/core/Attribute.h"
#include "adios2/core/IO.h"
#include "adios2/core/Variable.h"
namespace adios2
{
namespace interop
{
class ADIOS1CommonRead : public ADIOS1Common
{
public:
ADIOS1CommonRead(const std::string &fileName, MPI_Comm mpiComm,
const bool debugMode);
~ADIOS1CommonRead();
void InitParameters(const Params &parameters);
void InitTransports(const std::vector<Params> &transportsParameters);
bool Open(); // return true if file is opened successfully
void GenerateVariables(IO &io);
void ScheduleReadCommon(const std::string &name, const Dims &offs,
const Dims &ldims, const int fromStep,
const int nSteps, const bool readAsLocalValue,
const bool readAsJoinedArray, void *data);
void PerformReads();
AdvanceStatus AdvanceStep(AdvanceMode mode, const float timeout_sec = 0.0);
void ReleaseStep();
ADIOS_VARINFO *InqVar(const std::string &varName);
void InqVarBlockInfo(ADIOS_VARINFO *vi);
void FreeVarInfo(ADIOS_VARINFO *vi);
bool IsVarLocalValue(ADIOS_VARINFO *vi);
void Close();
private:
enum ADIOS_READ_METHOD m_ReadMethod;
bool m_OpenAsFile = false;
ADIOS_FILE *m_fh = nullptr; ///< ADIOS1 file handler
void Init();
void DefineADIOS2Variable(IO &io, const char *name, const ADIOS_VARINFO *vi,
Dims gdims, bool isJoined, bool isGlobal);
template <class T>
void DefineADIOS2Variable(IO &io, const char *name, const ADIOS_VARINFO *vi,
Dims gdims, bool isJoined, bool isGlobal);
};
} // end namespace interop
} // end namespace adios2
#endif /* ADIOS2_TOOLKIT_INTEROP_ADIOS1_ADIOS1COMMONREAD_H_ */
/*
* Distributed under the OSI-approved Apache License, Version 2.0. See
* accompanying file Copyright.txt for details.
*
* ADIOS1Common.tcc
*
* Created on: Jun 1, 2017
* Author: Norbert Podhorszki pnorbert@ornl.gov
* William F Godoy godoywf@ornl.gov
*/
#ifndef ADIOS2_TOOLKIT_INTEROP_ADIOS1_ADIOS1COMMONREAD_TCC_
#define ADIOS2_TOOLKIT_INTEROP_ADIOS1_ADIOS1COMMONREAD_TCC_
#include "ADIOS1CommonRead.h"
#include "adios2/helper/adiosFunctions.h" //GetType
namespace adios2
{
namespace interop
{
template <class T>
void ADIOS1CommonRead::DefineADIOS2Variable(IO &io, const char *name,
const ADIOS_VARINFO *vi, Dims gdims,
bool isJoined, bool isGlobal)
{
if (vi != nullptr)
{
adios2::Variable<T> &var = io.DefineVariable<T>(name, gdims);
if (vi->ndim == 0 && isGlobal)
{
/* Global value: store the value now */
/*var.m_Data = std::vector<T>(1);
var.m_Data[0] = *static_cast<T *>(vi->value);*/
var.m_Value = *(
reinterpret_cast<typename TypeInfo<T>::ValueType *>(vi->value));
var.m_Min = var.m_Max = var.m_Value;
}
var.m_ReadAsLocalValue = (vi->ndim > 0 && !isGlobal);
var.m_ReadAsJoined = isJoined;
var.m_AvailableStepsCount = vi->nsteps;
}
}
} // end namespace interop
} // end namespace adios2
#endif /* ADIOS2_TOOLKIT_INTEROP_ADIOS1_ADIOS1COMMONREAD_TCC_ */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment