diff --git a/examples/heatTransfer/read/heatRead_adios2.cpp b/examples/heatTransfer/read/heatRead_adios2.cpp index 01d103925770758ea605e08de6d9f907ece6c99d..ef37e6fdd06cb992be4328abf971791c4ded8d9a 100644 --- a/examples/heatTransfer/read/heatRead_adios2.cpp +++ b/examples/heatTransfer/read/heatRead_adios2.cpp @@ -60,12 +60,14 @@ int main(int argc, char *argv[]) // ISO-POSIX file is the default transport // Passing parameters to the transport bpReaderSettings.AddTransport("File", "verbose=4"); + bpReaderSettings.SetParameters("OpenAsFile"); } auto bpReader = ad.Open(inputfile, "r", mpiReaderComm, bpReaderSettings); if (bpReader == nullptr) - throw std::ios_base::failure("ERROR: failed to open ADIOS bpReader\n"); + throw std::ios_base::failure("ERROR: failed to open " + + std::string(inputfile) + "\n"); unsigned int gndx; unsigned int gndy; @@ -81,8 +83,9 @@ int main(int argc, char *argv[]) if (rank == 0) { - std::cout << "gndx = " << gndx << std::endl; - std::cout << "gndy = " << gndy << std::endl; + std::cout << "gndx = " << gndx << std::endl; + std::cout << "gndy = " << gndy << std::endl; + std::cout << "# of steps = " << vgndy->GetNSteps() << std::endl; } // 1D decomposition of the columns, which is inefficient for reading! diff --git a/source/adios2/core/Engine.h b/source/adios2/core/Engine.h index 5e70fc64d0928568489f8da7aa7de61c78f29c91..60f32d1bde14582270813f9034a0615ed6ee693c 100644 --- a/source/adios2/core/Engine.h +++ b/source/adios2/core/Engine.h @@ -44,6 +44,14 @@ typedef enum { LATEST_AVAILABLE = 3, // reader advance modes } AdvanceMode; +enum class AdvanceStatus +{ + OK = 0, + STEP_NOT_READY = 1, + END_OF_STREAM = 2, + OTHER_ERROR = 3 +}; + /** * Base class for Engine operations managing shared-memory, and buffer and * variables transform and transport operations @@ -462,6 +470,8 @@ public: AdvanceAsync(AdvanceMode mode, std::function<void(std::shared_ptr<adios::Engine>)> callback); + AdvanceStatus GetAdvanceStatus() { return m_AdvanceStatus; } + // Read API /** * Inquires and (optionally) allocates and copies the contents of a variable @@ -562,6 +572,7 @@ protected: const std::string m_EndMessage; ///< added to exceptions to improve debugging std::set<std::string> m_WrittenVariables; + AdvanceStatus m_AdvanceStatus = AdvanceStatus::OK; virtual void Init(); ///< Initialize m_Capsules and m_Transports virtual void InitParameters(); ///< Initialize parameters from Method diff --git a/source/adios2/core/VariableBase.h b/source/adios2/core/VariableBase.h index 98ac37ecf33e54000c4093c1e9a262ea9f1c3694..ad81e63ea15cfdbfab9211aa0d26c6b4e5ca8013 100644 --- a/source/adios2/core/VariableBase.h +++ b/source/adios2/core/VariableBase.h @@ -148,11 +148,14 @@ public: /** Return the number of steps available for the variable * @return Number of steps */ - int GetNSteps() { return m_nsteps; } + unsigned int GetNSteps() { return m_nsteps; } + + ///< Should only be called by read engines + void SetNSteps(unsigned int steps) { m_nsteps = steps; } private: /* Values filled by InquireVariable() */ - int m_nsteps = + unsigned int m_nsteps = 1; ///< number of steps available in a file (or 1 in staging), }; diff --git a/source/adios2/engine/adios1/ADIOS1Reader.cpp b/source/adios2/engine/adios1/ADIOS1Reader.cpp index 3cfc0769351f74e7fa29d55cc19580d9cf7b08ee..680e2186f16c45fb8be18342861e9ad2ed62a8b6 100644 --- a/source/adios2/engine/adios1/ADIOS1Reader.cpp +++ b/source/adios2/engine/adios1/ADIOS1Reader.cpp @@ -16,6 +16,8 @@ #include "adios2/transport/file/FileDescriptor.h" // uses POSIX #include "adios2/transport/file/FilePointer.h" // uses C FILE* +#include <adios_error.h> + namespace adios { @@ -27,8 +29,15 @@ ADIOS1Reader::ADIOS1Reader(ADIOS &adios, const std::string &name, { Init(); adios_read_init_method(m_ReadMethod, mpiComm, ""); - m_fh = adios_read_open(name.c_str(), m_ReadMethod, mpiComm, - ADIOS_LOCKMODE_CURRENT, 0.0); + if (m_OpenAsFile) + { + m_fh = adios_read_open_file(name.c_str(), m_ReadMethod, mpiComm); + } + else + { + m_fh = adios_read_open(name.c_str(), m_ReadMethod, mpiComm, + ADIOS_LOCKMODE_CURRENT, 0.0); + } } ADIOS1Reader::~ADIOS1Reader() @@ -357,7 +366,55 @@ void ADIOS1Reader::PerformReads(PerformReadMode mode) adios_perform_reads(m_fh, (int)mode); } -void ADIOS1Reader::Close(const int transportIndex) { adios_read_close(m_fh); } +void ADIOS1Reader::Release() { adios_release_step(m_fh); } + +void ADIOS1Reader::Advance(const float timeout_sec) +{ + Advance(AdvanceMode::NEXT_AVAILABLE, timeout_sec); +} + +void ADIOS1Reader::Advance(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"); + } + int last = (mode == AdvanceMode::NEXT_AVAILABLE ? 0 : 1); + float *to = const_cast<float *>(&timeout_sec); + adios_advance_step(m_fh, last, *to); + + switch (adios_errno) + { + case err_no_error: + m_AdvanceStatus = AdvanceStatus::OK; + break; + case err_end_of_stream: + m_AdvanceStatus = AdvanceStatus::END_OF_STREAM; + break; + case err_step_notready: + m_AdvanceStatus = AdvanceStatus::STEP_NOT_READY; + break; + default: + m_AdvanceStatus = AdvanceStatus::OTHER_ERROR; + break; + } +} + +void ADIOS1Reader::AdvanceAsync( + AdvanceMode mode, + std::function<void(std::shared_ptr<adios::Engine>)> callback) +{ + throw std::invalid_argument( + "ERROR: ADIOS1Reader doesn't support AdvanceSync()\n"); +} + +void ADIOS1Reader::Close(const int transportIndex) +{ + adios_read_close(m_fh); + m_fh = nullptr; +} // PRIVATE void ADIOS1Reader::Init() @@ -374,7 +431,14 @@ void ADIOS1Reader::Init() InitTransports(); } -void ADIOS1Reader::InitParameters() {} +void ADIOS1Reader::InitParameters() +{ + auto itOpenAsFile = m_Method.m_Parameters.find("OpenAsFile"); + if (itOpenAsFile != m_Method.m_Parameters.end()) + { + m_OpenAsFile = true; + } +} void ADIOS1Reader::InitTransports() { @@ -409,56 +473,69 @@ void ADIOS1Reader::InitTransports() } } -bool ADIOS1Reader::CheckADIOS1TypeCompatibility(std::string adios2Type, +static void CheckADIOS1Type(const std::string &name, std::string adios2Type, + std::string adios1Type) +{ + if (adios1Type != adios2Type) + { + throw std::invalid_argument( + "Type mismatch. The expected ADIOS2 type <" + adios2Type + + "> is not compatible with ADIOS1 type <" + adios1Type + + "> of the requested variable '" + name + "'\n"); + } +} + +bool ADIOS1Reader::CheckADIOS1TypeCompatibility(const std::string &name, + std::string adios2Type, enum ADIOS_DATATYPES adios1Type) { bool compatible = false; switch (adios1Type) { case adios_unsigned_byte: - compatible = (adios2Type == "unsigned char"); + CheckADIOS1Type(name, adios2Type, "unsigned char"); break; case adios_unsigned_short: - compatible = (adios2Type == "unsigned short"); + CheckADIOS1Type(name, adios2Type, "unsigned short"); break; case adios_unsigned_integer: - compatible = (adios2Type == "unsigned int"); + CheckADIOS1Type(name, adios2Type, "unsigned int"); break; case adios_unsigned_long: - compatible = (adios2Type == "unsigned long long int"); + CheckADIOS1Type(name, adios2Type, "unsigned long long int"); break; case adios_byte: - compatible = (adios2Type == "char"); + CheckADIOS1Type(name, adios2Type, "char"); break; case adios_short: - compatible = (adios2Type == "short"); + CheckADIOS1Type(name, adios2Type, "short"); break; case adios_integer: - compatible = (adios2Type == "int"); + CheckADIOS1Type(name, adios2Type, "int"); break; case adios_long: - compatible = (adios2Type == "long long int"); + CheckADIOS1Type(name, adios2Type, "long long int"); break; case adios_real: - compatible = (adios2Type == "float"); + CheckADIOS1Type(name, adios2Type, "float"); break; case adios_double: - compatible = (adios2Type == "double"); + CheckADIOS1Type(name, adios2Type, "double"); break; case adios_long_double: - compatible = (adios2Type == "long double"); + CheckADIOS1Type(name, adios2Type, "long double"); break; case adios_string: - compatible = (adios2Type == "string"); + CheckADIOS1Type(name, adios2Type, "string"); break; case adios_complex: - compatible = (adios2Type == "float complex"); + CheckADIOS1Type(name, adios2Type, "float complex"); break; case adios_double_complex: - compatible = (adios2Type == "double complex"); + CheckADIOS1Type(name, adios2Type, "double complex"); break; case adios_string_array: @@ -467,14 +544,6 @@ bool ADIOS1Reader::CheckADIOS1TypeCompatibility(std::string adios2Type, default: compatible = false; } - if (!compatible) - { - std::string typeStr(adios_type_to_string(adios1Type)); - throw std::invalid_argument("Type mismatch. The expected ADIOS2 type " + - adios2Type + - " is not compatible with ADIOS1 type " + - typeStr + " of the requested variable\n"); - } return true; } diff --git a/source/adios2/engine/adios1/ADIOS1Reader.h b/source/adios2/engine/adios1/ADIOS1Reader.h index b7c7c843a03e66693ee78248653585cdd3232c27..cd455f2a74b39cd9e86154d3da9287b229415486 100644 --- a/source/adios2/engine/adios1/ADIOS1Reader.h +++ b/source/adios2/engine/adios1/ADIOS1Reader.h @@ -146,10 +146,20 @@ public: std::complex<long double> *values); void PerformReads(PerformReadMode mode); + + void Release(); + void Advance(const float timeout_sec = 0.0); + void Advance(AdvanceMode mode, const float timeout_sec = 0.0); + void + AdvanceAsync(AdvanceMode mode, + std::function<void(std::shared_ptr<adios::Engine>)> callback); + void Close(const int transportIndex = -1); private: ADIOS_FILE *m_fh = nullptr; ///< ADIOS1 file handler + bool m_OpenAsFile = false; + void Init(); ///< called from constructor, gets the selected ADIOS1 /// transport method from settings void InitParameters(); @@ -170,7 +180,8 @@ private: adios::Variable<T> *var = nullptr; if (vi != nullptr) { - CheckADIOS1TypeCompatibility(GetType<T>(), vi->type); // throws + CheckADIOS1TypeCompatibility(name, GetType<T>(), + vi->type); // throws if (vi->ndim > 0) { Dims gdims = Uint64ArrayToSizetVector(vi->ndim, vi->dims); @@ -185,6 +196,7 @@ private: var->m_Data[0] = *static_cast<T *>(vi->value); } } + var->SetNSteps(vi->nsteps); adios_free_varinfo(vi); } return var; @@ -193,7 +205,8 @@ private: void ScheduleReadCommon(const std::string &name, const Dims &ldims, const Dims &offs, void *data); - bool CheckADIOS1TypeCompatibility(std::string adios2Type, + bool CheckADIOS1TypeCompatibility(const std::string &name, + std::string adios2Type, enum ADIOS_DATATYPES adios1Type); enum ADIOS_READ_METHOD m_ReadMethod = ADIOS_READ_METHOD_BP;