diff --git a/bindings/C/adios2/c/adios2_c_engine.cpp b/bindings/C/adios2/c/adios2_c_engine.cpp index 9d6cecf32f..1836893657 100644 --- a/bindings/C/adios2/c/adios2_c_engine.cpp +++ b/bindings/C/adios2/c/adios2_c_engine.cpp @@ -34,9 +34,6 @@ adios2::Mode adios2_ToMode(const adios2_mode mode, const std::string &hint) case adios2_mode_readRandomAccess: modeCpp = adios2::Mode::ReadRandomAccess; break; - case adios2_mode_readFlattenSteps: - modeCpp = adios2::Mode::ReadFlattenSteps; - break; case adios2_mode_deferred: modeCpp = adios2::Mode::Deferred; break; @@ -66,9 +63,6 @@ adios2_mode adios2_fromMode(const adios2::Mode mode, const std::string &hint) case adios2::Mode::ReadRandomAccess: modeC = adios2_mode_readRandomAccess; break; - case adios2::Mode::ReadFlattenSteps: - modeC = adios2_mode_readFlattenSteps; - break; case adios2::Mode::Deferred: modeC = adios2_mode_deferred; break; diff --git a/bindings/C/adios2/c/adios2_c_io.h b/bindings/C/adios2/c/adios2_c_io.h index a622328e38..c790cd0647 100644 --- a/bindings/C/adios2/c/adios2_c_io.h +++ b/bindings/C/adios2/c/adios2_c_io.h @@ -329,8 +329,8 @@ adios2_error adios2_remove_all_attributes(adios2_io *io); * MPI Collective function as it calls MPI_Comm_dup * @param io engine owner * @param name unique engine identifier - * @param mode adios2_mode_write, adios2_mode_read, adios2_mode_append, - * adios2_mode_readRandomAccess and adios2_mode_readFlattenSteps + * @param mode adios2_mode_write, adios2_mode_read, adios2_mode_append + * and adios2_mode_readRandomAccess * @return success: handler, failure: NULL */ adios2_engine *adios2_open(adios2_io *io, const char *name, const adios2_mode mode); @@ -341,8 +341,8 @@ adios2_engine *adios2_open(adios2_io *io, const char *name, const adios2_mode mo * MPI Collective function as it calls MPI_Comm_dup * @param io engine owner * @param name unique engine identifier - * @param mode adios2_mode_write, adios2_mode_read, adios2_mode_append, - * adios2_mode_readRandomAccess and adios2_mode_readFlattenSteps + * @param mode adios2_mode_write, adios2_mode_read, adios2_mode_append and + * adios2_mode_readRandomAccess * @param comm communicator other than adios' handler comm. MPI only. * @return success: handler, failure: NULL */ diff --git a/bindings/C/adios2/c/adios2_c_io.tcc b/bindings/C/adios2/c/adios2_c_io.tcc index 9c9000cd44..29607b87d8 100644 --- a/bindings/C/adios2/c/adios2_c_io.tcc +++ b/bindings/C/adios2/c/adios2_c_io.tcc @@ -36,10 +36,6 @@ adios2::Mode adios2_ToOpenMode(const adios2_mode modeC) mode = adios2::Mode::ReadRandomAccess; break; - case adios2_mode_readFlattenSteps: - mode = adios2::Mode::ReadFlattenSteps; - break; - default: break; } diff --git a/bindings/C/adios2/c/adios2_c_types.h b/bindings/C/adios2/c/adios2_c_types.h index b28bc7f21e..fb102df4cb 100644 --- a/bindings/C/adios2/c/adios2_c_types.h +++ b/bindings/C/adios2/c/adios2_c_types.h @@ -103,7 +103,6 @@ typedef enum adios2_mode_read = 2, adios2_mode_append = 3, adios2_mode_readRandomAccess = 6, - adios2_mode_readFlattenSteps = 7, adios2_mode_deferred = 4, adios2_mode_sync = 5 diff --git a/bindings/CXX11/adios2/cxx11/fstream/ADIOS2fstream.cpp b/bindings/CXX11/adios2/cxx11/fstream/ADIOS2fstream.cpp index 12d083beb2..03b881e7fa 100644 --- a/bindings/CXX11/adios2/cxx11/fstream/ADIOS2fstream.cpp +++ b/bindings/CXX11/adios2/cxx11/fstream/ADIOS2fstream.cpp @@ -89,9 +89,6 @@ adios2::Mode fstream::ToMode(const openmode mode) const noexcept case (openmode::in_random_access): modeCpp = adios2::Mode::ReadRandomAccess; break; - case (openmode::in_flatten_steps): - modeCpp = adios2::Mode::ReadFlattenSteps; - break; case (openmode::app): modeCpp = adios2::Mode::Append; break; diff --git a/bindings/CXX11/adios2/cxx11/fstream/ADIOS2fstream.h b/bindings/CXX11/adios2/cxx11/fstream/ADIOS2fstream.h index d96a7a749b..546bf54ccb 100644 --- a/bindings/CXX11/adios2/cxx11/fstream/ADIOS2fstream.h +++ b/bindings/CXX11/adios2/cxx11/fstream/ADIOS2fstream.h @@ -48,7 +48,6 @@ class fstream out, //!< write in, //!< read in_random_access, //!< read_random_access - in_flatten_steps, //!< flatten all input steps to 1 app //!< append, not yet supported }; diff --git a/bindings/Fortran/modules/adios2_parameters_mod.f90 b/bindings/Fortran/modules/adios2_parameters_mod.f90 index f73561702e..bf0dd18c9b 100644 --- a/bindings/Fortran/modules/adios2_parameters_mod.f90 +++ b/bindings/Fortran/modules/adios2_parameters_mod.f90 @@ -56,7 +56,6 @@ module adios2_parameters_mod integer, parameter :: adios2_mode_read = 2 integer, parameter :: adios2_mode_append = 3 integer, parameter :: adios2_mode_readRandomAccess = 6 - integer, parameter :: adios2_mode_readFlattenSteps = 7 integer, parameter :: adios2_mode_deferred = 4 integer, parameter :: adios2_mode_sync = 5 diff --git a/bindings/Python/py11glue.cpp b/bindings/Python/py11glue.cpp index b1989f7ece..2c40280f99 100644 --- a/bindings/Python/py11glue.cpp +++ b/bindings/Python/py11glue.cpp @@ -98,7 +98,6 @@ PYBIND11_MODULE(ADIOS2_PYTHON_MODULE_NAME, m) .value("Write", adios2::Mode::Write) .value("Read", adios2::Mode::Read) .value("ReadRandomAccess", adios2::Mode::ReadRandomAccess) - .value("ReadFlattenSteps", adios2::Mode::ReadFlattenSteps) .value("Append", adios2::Mode::Append) .value("Deferred", adios2::Mode::Deferred) .value("Sync", adios2::Mode::Sync) diff --git a/docs/user_guide/source/components/anatomy.rst b/docs/user_guide/source/components/anatomy.rst index 2aa8c7f89a..27f325b646 100644 --- a/docs/user_guide/source/components/anatomy.rst +++ b/docs/user_guide/source/components/anatomy.rst @@ -169,13 +169,3 @@ mode. Also newer file Engines like BP5 to not allow |--> ADIOS goes out of scope or adios2_finalize() -In addition to the two read modes discussed above, ADIOS has another -input mode named `adios2::Mode::ReadFlattenSteps`. This is a highly -specialized mode built that is unlikely to be of general utility, but -we describe it for completeness. In `ReadFlattenSteps` mode, ADIOS -loads all the metadata in the file upon Open (just like -`ReadRandomAccess` mode, but everything that was written appears that -it was output on the same step, regardless of how many steps actually -appear in the file. This affects the operation of many reader-side -ADIOS functions, including Steps(), BlocksInfo(), Get(), etc. - diff --git a/docs/user_guide/source/components/io.rst b/docs/user_guide/source/components/io.rst index 4e6906bc6d..fefebe7f5f 100644 --- a/docs/user_guide/source/components/io.rst +++ b/docs/user_guide/source/components/io.rst @@ -196,7 +196,7 @@ A particular ``Engine`` type is set to the current ``IO`` component with the ``I Engine polymorphism is handled internally by the ``IO`` class, which allows subclassing future derived ``Engine`` types without changing the basic API. ``Engine`` objects are created in various modes. -The available modes are ``adios2::Mode::Read``, ``adios2::Mode::ReadRandomAccess``, ``adios2::Mode::ReadFlattenSteps``, ``adios2::Mode::Write``, ``adios2::Mode::Append``, ``adios2::Mode::Sync``, ``adios2::Mode::Deferred``, and ``adios2::Mode::Undefined``. +The available modes are ``adios2::Mode::Read``, ``adios2::Mode::ReadRandomAccess``, ``adios2::Mode::Write``, ``adios2::Mode::Append``, ``adios2::Mode::Sync``, ``adios2::Mode::Deferred``, and ``adios2::Mode::Undefined``. .. code-block:: c++ diff --git a/docs/user_guide/source/engines/bp5.rst b/docs/user_guide/source/engines/bp5.rst index b29ec71eb5..76696d427a 100644 --- a/docs/user_guide/source/engines/bp5.rst +++ b/docs/user_guide/source/engines/bp5.rst @@ -130,6 +130,14 @@ This engine allows the user to fine tune the buffering operations through the fo #. **Threads**: Read side: Specify how many threads one process can use to speed up reading. The default value is *0*, to let the engine estimate the number of threads based on how many processes are running on the compute node and how many hardware threads are available on the compute node but it will use maximum 16 threads. Value *1* forces the engine to read everything within the main thread of the process. Other values specify the exact number of threads the engine can use. Although multithreaded reading works in a single *Get(adios2::Mode::Sync)* call if the read selection spans multiple data blocks in the file, the best parallelization is achieved by using deferred mode and reading everything in *PerformGets()/EndStep()*. + #. **FlattenSteps**: This is a writer-side parameter specifies that the + reader should interpret multiple writer-created timesteps as a + single timestep, essentially flattening all Put()s into a single step. + + #. **IgnoreFlattenSteps**: This is a reader-side parameter that + tells the reader to ignore any FlattenSteps parameter supplied + to the writer. + ============================== ===================== =========================================================== **Key** **Value Format** **Default** and Examples ============================== ===================== =========================================================== @@ -156,6 +164,8 @@ This engine allows the user to fine tune the buffering operations through the fo StatsLevel integer, 0 or 1 **1**, 0 MaxOpenFilesAtOnce integer >= 0 **UINT_MAX**, 1024, 1 Threads integer >= 0 **0**, 1, 32 + FlattenSteps boolean **off**, on, true, false + IgnoreFlattenSteps boolean **off**, on, true, false ============================== ===================== =========================================================== diff --git a/source/adios2/common/ADIOSTypes.h b/source/adios2/common/ADIOSTypes.h index 111ebe4a1d..fad51e8fd9 100644 --- a/source/adios2/common/ADIOSTypes.h +++ b/source/adios2/common/ADIOSTypes.h @@ -80,7 +80,6 @@ enum class Mode Read, Append, ReadRandomAccess, // reader random access mode - ReadFlattenSteps, // reader flatten steps to one // launch execution modes Sync, Deferred diff --git a/source/adios2/core/Engine.cpp b/source/adios2/core/Engine.cpp index 56e6f02c08..72ab54d4ac 100644 --- a/source/adios2/core/Engine.cpp +++ b/source/adios2/core/Engine.cpp @@ -135,8 +135,7 @@ void Engine::Put(VariableStruct &variable, const void *data, const Mode launch) void Engine::Get(VariableStruct &variable, void *data, const Mode launch) { - CommonChecks(variable, data, {Mode::Read, Mode::ReadRandomAccess, Mode::ReadFlattenSteps}, - "in call to Get"); + CommonChecks(variable, data, {Mode::Read, Mode::ReadRandomAccess}, "in call to Get"); switch (launch) { diff --git a/source/adios2/core/Engine.tcc b/source/adios2/core/Engine.tcc index 656b2fc30a..b06050b86c 100644 --- a/source/adios2/core/Engine.tcc +++ b/source/adios2/core/Engine.tcc @@ -87,8 +87,7 @@ void Engine::Put(const std::string &variableName, const T &datum, const Mode /*l template void Engine::Get(Variable &variable, T *data, const Mode launch) { - CommonChecks(variable, data, {Mode::Read, Mode::ReadRandomAccess, Mode::ReadFlattenSteps}, - "in call to Get"); + CommonChecks(variable, data, {Mode::Read, Mode::ReadRandomAccess}, "in call to Get"); switch (launch) { diff --git a/source/adios2/core/IO.cpp b/source/adios2/core/IO.cpp index eaf4394351..83bf0f3781 100644 --- a/source/adios2/core/IO.cpp +++ b/source/adios2/core/IO.cpp @@ -150,14 +150,6 @@ const std::unordered_map ReadRandomAccess_Supported = { {"campaign", true}, }; -const std::unordered_map ReadFlattenSteps_Supported = { - {"bp3", false}, {"bp4", false}, {"bp5", true}, {"dataman", false}, - {"ssc", false}, {"mhs", false}, {"sst", false}, {"daos", false}, - {"effis", false}, {"dataspaces", false}, {"hdf5", false}, {"skeleton", false}, - {"inline", false}, {"null", true}, {"nullcore", true}, {"plugin", false}, - {"campaign", true}, -}; - // Synchronize access to the factory in case one thread is // looking up while another registers additional entries. std::mutex FactoryMutex; @@ -568,8 +560,7 @@ Engine &IO::Open(const std::string &name, const Mode mode, helper::Comm comm) { engineTypeLC = "campaign"; } - else if ((mode_to_use == Mode::Read) || (mode_to_use == Mode::ReadRandomAccess) || - (mode_to_use == Mode::ReadFlattenSteps)) + else if ((mode_to_use == Mode::Read) || (mode_to_use == Mode::ReadRandomAccess)) { if (adios2sys::SystemTools::FileIsDirectory(name)) { @@ -677,26 +668,10 @@ Engine &IO::Open(const std::string &name, const Mode mode, helper::Comm comm) } } - if (mode_to_use == Mode::ReadFlattenSteps) - { - // older engines don't know about ReadFlattenSteps Mode, throw an exception - auto it = ReadFlattenSteps_Supported.find(engineTypeLC); - if (it != ReadFlattenSteps_Supported.end()) - { - if (!it->second) - { - helper::Throw("Core", "IO", "Open", - "Engine " + engineTypeLC + - " doesn't support ReadFlattenSteps mode"); - } - } - } - auto f = FactoryLookup(engineTypeLC); if (f != Factory.end()) { - if ((mode_to_use == Mode::Read) || (mode_to_use == Mode::ReadRandomAccess) || - (mode_to_use == Mode::ReadFlattenSteps)) + if ((mode_to_use == Mode::Read) || (mode_to_use == Mode::ReadRandomAccess)) { engine = f->second.MakeReader(*this, name, mode_to_use, std::move(comm)); } diff --git a/source/adios2/core/Stream.cpp b/source/adios2/core/Stream.cpp index 2b923886ae..43abacc703 100644 --- a/source/adios2/core/Stream.cpp +++ b/source/adios2/core/Stream.cpp @@ -23,8 +23,7 @@ Stream::Stream(const std::string &name, const Mode mode, helper::Comm comm, : m_ADIOS(std::make_shared(std::move(comm), hostLanguage)), m_IO(&m_ADIOS->DeclareIO(name)), m_Name(name), m_Mode(mode), m_EngineType(engineType) { - if ((mode == adios2::Mode::Read) || (mode == adios2::Mode::ReadRandomAccess) || - (mode == adios2::Mode::ReadFlattenSteps)) + if ((mode == adios2::Mode::Read) || (mode == adios2::Mode::ReadRandomAccess)) { CheckOpen(); } @@ -42,8 +41,7 @@ Stream::Stream(const std::string &name, const Mode mode, helper::Comm comm, : m_ADIOS(std::make_shared(configFile, std::move(comm), hostLanguage)), m_IO(&m_ADIOS->DeclareIO(ioInConfigFile)), m_Name(name), m_Mode(mode) { - if ((mode == adios2::Mode::Read) || (mode == adios2::Mode::ReadRandomAccess) || - (mode == adios2::Mode::ReadFlattenSteps)) + if ((mode == adios2::Mode::Read) || (mode == adios2::Mode::ReadRandomAccess)) { CheckOpen(); } diff --git a/source/adios2/engine/bp5/BP5Engine.h b/source/adios2/engine/bp5/BP5Engine.h index 354ec67949..be7f40a3b1 100644 --- a/source/adios2/engine/bp5/BP5Engine.h +++ b/source/adios2/engine/bp5/BP5Engine.h @@ -56,15 +56,33 @@ class BP5Engine format::BufferSTL m_MetadataIndex; - /** Positions of flags in Index Table Header that Reader uses */ - static constexpr size_t m_IndexHeaderSize = 64; - static constexpr size_t m_EndianFlagPosition = 36; - static constexpr size_t m_BPVersionPosition = 37; - static constexpr size_t m_BPMinorVersionPosition = 38; - static constexpr size_t m_ActiveFlagPosition = 39; - static constexpr size_t m_ColumnMajorFlagPosition = 40; - static constexpr size_t m_VersionTagPosition = 0; - static constexpr size_t m_VersionTagLength = 32; + /** Positions of flags in Index Table Header that Reader uses - MUST BE 64 bytes total */ + struct BP5IndexTableHeader + { + char VersionTag[32]; + uint8_t adiosMajorVersion; + uint8_t adiosMinorVersion; + uint8_t adiosPatchVersion; + uint8_t unused1; // init to zero + uint8_t isLittleEndian; // boolean + uint8_t bpVersion; // 5 here + uint8_t bpMinorVersion; + uint8_t activeFlag; + char columnMajor; // y or n + uint8_t flattenSteps; // writer requests all steps flattened to one on read + char unused2[22]; // init to zero + }; + static constexpr size_t m_IndexHeaderSize = sizeof(BP5IndexTableHeader); + static constexpr size_t m_EndianFlagPosition = offsetof(BP5IndexTableHeader, isLittleEndian); + static constexpr size_t m_BPVersionPosition = offsetof(BP5IndexTableHeader, bpVersion); + static constexpr size_t m_BPMinorVersionPosition = + offsetof(BP5IndexTableHeader, bpMinorVersion); + static constexpr size_t m_ActiveFlagPosition = offsetof(BP5IndexTableHeader, activeFlag); + static constexpr size_t m_ColumnMajorFlagPosition = offsetof(BP5IndexTableHeader, columnMajor); + static constexpr size_t m_FlattenStepsPosition = offsetof(BP5IndexTableHeader, flattenSteps); + static constexpr size_t m_VersionTagPosition = offsetof(BP5IndexTableHeader, VersionTag); + static constexpr size_t m_VersionTagLength = sizeof(BP5IndexTableHeader().VersionTag); + static constexpr size_t m_HeaderTailPadding = sizeof(BP5IndexTableHeader().unused2); static constexpr uint8_t m_BP5MinorVersion = 2; @@ -154,6 +172,8 @@ class BP5Engine MACRO(StatsBlockSize, SizeBytes, size_t, DefaultStatsBlockSize) \ MACRO(Threads, UInt, unsigned int, 0) \ MACRO(UseOneTimeAttributes, Bool, bool, true) \ + MACRO(FlattenSteps, Bool, bool, false) \ + MACRO(IgnoreFlattenSteps, Bool, bool, false) \ MACRO(RemoteDataPath, String, std::string, "") \ MACRO(MaxOpenFilesAtOnce, UInt, unsigned int, UINT_MAX) diff --git a/source/adios2/engine/bp5/BP5Reader.cpp b/source/adios2/engine/bp5/BP5Reader.cpp index 5f6ad0d030..dcddb24a57 100644 --- a/source/adios2/engine/bp5/BP5Reader.cpp +++ b/source/adios2/engine/bp5/BP5Reader.cpp @@ -72,7 +72,7 @@ void BP5Reader::InstallMetadataForTimestep(size_t Step) size_t ThisMDSize = helper::ReadValue(m_Metadata.Data(), Position, m_Minifooter.IsLittleEndian); char *ThisMD = m_Metadata.Data() + MDPosition; - if ((m_OpenMode == Mode::ReadRandomAccess) || (m_OpenMode == Mode::ReadFlattenSteps)) + if ((m_OpenMode == Mode::ReadRandomAccess) || (m_FlattenSteps)) { m_BP5Deserializer->InstallMetaData(ThisMD, ThisMDSize, WriterRank, Step); } @@ -475,14 +475,12 @@ void BP5Reader::PerformLocalGets() // PRIVATE void BP5Reader::Init() { - if ((m_OpenMode != Mode::Read) && (m_OpenMode != Mode::ReadRandomAccess) && - (m_OpenMode != Mode::ReadFlattenSteps)) + if ((m_OpenMode != Mode::Read) && (m_OpenMode != Mode::ReadRandomAccess)) { - helper::Throw( - "Engine", "BP5Reader", "Init", - "BPFileReader only supports OpenMode::Read, " - "OpenMode::ReadRandomAccess, or OpenMode::ReadFlattenSteps from" + - m_Name); + helper::Throw("Engine", "BP5Reader", "Init", + "BPFileReader only supports OpenMode::Read or " + "OpenMode::ReadRandomAccess from" + + m_Name); } // if IO was involved in reading before this flag may be true now @@ -521,7 +519,7 @@ void BP5Reader::InitParameters() ParseParams(m_IO, m_Parameters); if (m_Parameters.OpenTimeoutSecs < 0.0f) { - if ((m_OpenMode == Mode::ReadRandomAccess) || (m_OpenMode == Mode::ReadFlattenSteps)) + if (m_OpenMode == Mode::ReadRandomAccess) { m_Parameters.OpenTimeoutSecs = 0.0f; } @@ -809,9 +807,9 @@ void BP5Reader::UpdateBuffer(const TimePoint &timeoutInstant, const Seconds &pol // create the serializer object if (!m_BP5Deserializer) { - m_BP5Deserializer = new format::BP5Deserializer(m_WriterIsRowMajor, m_ReaderIsRowMajor, - (m_OpenMode != Mode::Read), - (m_OpenMode == Mode::ReadFlattenSteps)); + m_BP5Deserializer = + new format::BP5Deserializer(m_WriterIsRowMajor, m_ReaderIsRowMajor, + (m_OpenMode != Mode::Read), (m_FlattenSteps)); m_BP5Deserializer->m_Engine = this; } } @@ -908,7 +906,7 @@ void BP5Reader::UpdateBuffer(const TimePoint &timeoutInstant, const Seconds &pol m_Comm.Bcast(m_Metadata.Data(), inputSize, 0); - if ((m_OpenMode == Mode::ReadRandomAccess) || (m_OpenMode == Mode::ReadFlattenSteps)) + if ((m_OpenMode == Mode::ReadRandomAccess) || m_FlattenSteps) { for (size_t Step = 0; Step < m_MetadataIndexTable.size(); Step++) { @@ -985,6 +983,15 @@ size_t BP5Reader::ParseMetadataIndex(format::BufferSTL &bufferSTL, const size_t const uint8_t val = helper::ReadValue(buffer, position, m_Minifooter.IsLittleEndian); m_WriterIsRowMajor = val == 'n'; + + position = m_FlattenStepsPosition; + const uint8_t flatten_val = + helper::ReadValue(buffer, position, m_Minifooter.IsLittleEndian); + m_FlattenSteps = (flatten_val != 0); + + if (m_Parameters.IgnoreFlattenSteps) + m_FlattenSteps = false; + // move position to first row position = m_IndexHeaderSize; } @@ -1253,7 +1260,7 @@ void BP5Reader::DoGetStructDeferred(VariableStruct &variable, void *data) void BP5Reader::DoClose(const int transportIndex) { PERFSTUBS_SCOPED_TIMER("BP5Reader::Close"); - if ((m_OpenMode == Mode::ReadRandomAccess) || (m_OpenMode == Mode::ReadFlattenSteps)) + if (m_OpenMode == Mode::ReadRandomAccess) { PerformGets(); } @@ -1316,7 +1323,7 @@ void BP5Reader::FlushProfiler() size_t BP5Reader::DoSteps() const { - if (m_OpenMode == Mode::ReadFlattenSteps) + if (m_FlattenSteps) return 1; else return m_StepsCount; diff --git a/source/adios2/engine/bp5/BP5Reader.h b/source/adios2/engine/bp5/BP5Reader.h index 8bac09d3eb..6e8508041c 100644 --- a/source/adios2/engine/bp5/BP5Reader.h +++ b/source/adios2/engine/bp5/BP5Reader.h @@ -58,6 +58,7 @@ class BP5Reader : public BP5Engine, public Engine bool VarShape(const VariableBase &Var, const size_t Step, Dims &Shape) const; bool VariableMinMax(const VariableBase &, const size_t Step, MinMaxStruct &MinMax); const char *VariableExprStr(const VariableBase &Var); + void SetFlattenMode(bool flatten) { m_FlattenSteps = flatten; }; private: format::BP5Deserializer *m_BP5Deserializer = nullptr; @@ -223,6 +224,7 @@ class BP5Reader : public BP5Engine, public Engine uint32_t m_WriterColumnMajor = 0; bool m_ReaderIsRowMajor = true; bool m_WriterIsRowMajor = true; + bool m_FlattenSteps = false; // set to true of writer requested all steps be flattened into 1 format::BufferSTL m_MetadataIndex; format::BufferSTL m_MetaMetadata; diff --git a/source/adios2/engine/bp5/BP5Writer.cpp b/source/adios2/engine/bp5/BP5Writer.cpp index ff1889577e..a9257922d4 100644 --- a/source/adios2/engine/bp5/BP5Writer.cpp +++ b/source/adios2/engine/bp5/BP5Writer.cpp @@ -1218,9 +1218,12 @@ void BP5Writer::MakeHeader(std::vector &buffer, size_t &position, const st helper::CopyToBuffer(buffer, position, version.c_str()); }; - // auto &buffer = b.m_Buffer; - // auto &position = b.m_Position; - // auto &absolutePosition = b.m_AbsolutePosition; + if (sizeof(BP5IndexTableHeader) != 64) + { + std::cerr << "BP6 Index Table Header must be 64 bytes" << std::endl; + exit(1); + } + if (position > 0) { helper::Throw( @@ -1273,11 +1276,7 @@ void BP5Writer::MakeHeader(std::vector &buffer, size_t &position, const st lf_CopyVersionChar(majorVersion, buffer, position); lf_CopyVersionChar(minorVersion, buffer, position); lf_CopyVersionChar(patchVersion, buffer, position); - ++position; - - // Note: Reader does process and use bytes 36-38 in - // BP4Deserialize.cpp::ParseMetadataIndex(). - // Order and position must match there. + position = m_EndianFlagPosition; // byte 36: endianness if (position != m_EndianFlagPosition) @@ -1327,8 +1326,9 @@ void BP5Writer::MakeHeader(std::vector &buffer, size_t &position, const st const uint8_t columnMajor = (m_IO.m_ArrayOrder == ArrayOrdering::ColumnMajor) ? 'y' : 'n'; helper::CopyToBuffer(buffer, position, &columnMajor); - // byte 41-63: unused - position += 23; + helper::CopyToBuffer(buffer, position, &m_Parameters.FlattenSteps); + // remainder unused + position = m_IndexHeaderSize; // absolutePosition = position; } diff --git a/source/adios2/toolkit/remote/Remote.cpp b/source/adios2/toolkit/remote/Remote.cpp index 053925a0fa..1d3a1afe62 100644 --- a/source/adios2/toolkit/remote/Remote.cpp +++ b/source/adios2/toolkit/remote/Remote.cpp @@ -112,9 +112,6 @@ void Remote::Open(const std::string hostname, const int32_t port, const std::str case Mode::ReadRandomAccess: open_msg.Mode = RemoteCommon::RemoteFileMode::RemoteOpenRandomAccess; break; - case Mode::ReadFlattenSteps: - open_msg.Mode = RemoteCommon::RemoteFileMode::RemoteOpenFlattenSteps; - break; default: break; } diff --git a/source/adios2/toolkit/remote/remote_common.h b/source/adios2/toolkit/remote/remote_common.h index ba98cb383f..0d78bd290a 100644 --- a/source/adios2/toolkit/remote/remote_common.h +++ b/source/adios2/toolkit/remote/remote_common.h @@ -15,7 +15,6 @@ enum RemoteFileMode { RemoteOpen, RemoteOpenRandomAccess, - RemoteOpenFlattenSteps, }; /* */ diff --git a/source/adios2/toolkit/remote/remote_server.cpp b/source/adios2/toolkit/remote/remote_server.cpp index dfc5680a42..cef276ac08 100644 --- a/source/adios2/toolkit/remote/remote_server.cpp +++ b/source/adios2/toolkit/remote/remote_server.cpp @@ -106,8 +106,6 @@ class AnonADIOSFile m_mode = mode; if (m_mode == RemoteOpenRandomAccess) adios_read_mode = adios2::Mode::ReadRandomAccess; - if (m_mode == RemoteOpenFlattenSteps) - adios_read_mode = adios2::Mode::ReadFlattenSteps; m_engine = &m_io->Open(FileName, adios_read_mode); memcpy(&m_ID, m_IOname.c_str(), sizeof(m_ID)); } @@ -191,8 +189,6 @@ static void OpenHandler(CManager cm, CMConnection conn, void *vevent, void *clie std::string strMode = "Streaming"; if (open_msg->Mode == RemoteOpenRandomAccess) strMode = "RandomAccess"; - if (open_msg->Mode == RemoteOpenFlattenSteps) - strMode = "FlattenSteps"; std::cout << "Got an open request (mode " << strMode << ") for file " << open_msg->FileName << std::endl; AnonADIOSFile *f = diff --git a/source/utils/bpls/bpls.cpp b/source/utils/bpls/bpls.cpp index b390c6b3cd..f2f94c3df7 100644 --- a/source/utils/bpls/bpls.cpp +++ b/source/utils/bpls/bpls.cpp @@ -96,7 +96,7 @@ bool listmeshes; // do list meshes too bool attrsonly; // do list attributes only bool longopt; // -l is turned on bool timestep; // read step by step -bool flatten; // flatten steps to one +bool ignore_flatten; // dont flatten steps to one bool filestream = false; // are we using an engine through FileStream? bool noindex; // do no print array indices with data bool printByteAsChar; // print 8 bit integer arrays as string @@ -147,7 +147,8 @@ void display_help() */ " --timestep | -t Read content step by step (stream " "reading)\n" - " --flatten Flatten Steps into one step (open in flatten mode)\n" + " --ignore_flatten Display steps as written (don't flatten, even if writer " + "said to)\n" " --dump | -d Dump matched variables/attributes\n" " To match attributes too, add option " "-a\n" @@ -450,6 +451,7 @@ bool introspectAsBPDir(const std::string &name) noexcept char patch = buffer[34]; bool isBigEndian = static_cast(buffer[36]); uint8_t BPVersion = static_cast(buffer[37]); + uint8_t flatten = static_cast(buffer[41]); bool isActive = false; if (BPVersion == 4) { @@ -462,9 +464,9 @@ bool introspectAsBPDir(const std::string &name) noexcept { uint8_t minversion = static_cast(buffer[38]); isActive = static_cast(buffer[39]); - printf("ADIOS-BP Version %d.%d %s - ADIOS v%c.%c.%c %s\n", BPVersion, minversion, + printf("ADIOS-BP Version %d.%d %s - ADIOS v%c.%c.%c %s%s\n", BPVersion, minversion, (isBigEndian ? "Big Endian" : "Little Endian"), major, minor, patch, - (isActive ? "- active" : "")); + (isActive ? "- active" : ""), (flatten ? "- flatten_steps " : "")); } else { @@ -622,7 +624,7 @@ int bplsMain(int argc, char *argv[]) arg.AddBooleanArgument("--noindex", &noindex, " | -y Print data without array indices"); arg.AddBooleanArgument("-y", &noindex, ""); arg.AddBooleanArgument("--timestep", ×tep, " | -t Print values of timestep elements"); - arg.AddBooleanArgument("--flatten", &flatten, " Flatten steps to one"); + arg.AddBooleanArgument("--ignore_flatten", &ignore_flatten, " Don't flatten steps to one"); arg.AddBooleanArgument("-t", ×tep, ""); arg.AddBooleanArgument("--attrs", &listattrs, " | -a List/match attributes too"); arg.AddBooleanArgument("-a", &listattrs, ""); @@ -773,7 +775,7 @@ void init_globals() output_xml = false; noindex = false; timestep = false; - flatten = false; + ignore_flatten = false; sortnames = false; listattrs = false; listmeshes = false; @@ -867,8 +869,8 @@ void printSettings(void) printf(" -V : show binary version info of file\n"); if (timestep) printf(" -t : read step-by-step\n"); - if (flatten) - printf(" --flatten : flatten steps into one\n"); + if (ignore_flatten) + printf(" --ignore_flatten : ignore FlattenSteps writer specification\n"); if (hidden_attrs) { @@ -1672,6 +1674,11 @@ int doList(std::string path) io.SetParameters(p); } + if (ignore_flatten) + { + io.SetParameters("IgnoreFlattenSteps=on"); + } + for (auto &engineName : engineList) { if (verbose > 2) @@ -1683,10 +1690,6 @@ int doList(std::string path) { fp = &io.Open(path, Mode::Read); } - else if (flatten) - { - fp = &io.Open(path, Mode::ReadFlattenSteps); - } else { fp = &io.Open(path, Mode::ReadRandomAccess); @@ -1704,7 +1707,13 @@ int doList(std::string path) break; } - if (fp != nullptr) + if (fp == nullptr) + { + fprintf(stderr, "\nError: Could not open this file with any ADIOS2 " + "file reading engines\n"); + return 4; + } + { //, variables, timesteps, and attributes // all parameters are integers, @@ -1774,12 +1783,6 @@ int doList(std::string path) } fp->Close(); } - else - { - fprintf(stderr, "\nError: Could not open this file with any ADIOS2 " - "file reading engines\n"); - return 4; - } return 0; } @@ -3707,9 +3710,12 @@ void print_decomp_singlestep(core::Engine *fp, core::IO *io, core::Variable * DataType adiosvartype = variable->m_Type; const auto minBlocks = fp->MinBlocksInfo(*variable, fp->CurrentStep()); - std::vector::BPInfo> coreBlocks = - fp->BlocksInfo(*variable, fp->CurrentStep()); + std::vector::BPInfo> coreBlocks; + if (!minBlocks) + { + coreBlocks = fp->BlocksInfo(*variable, fp->CurrentStep()); + } if (!minBlocks && coreBlocks.empty()) { return; diff --git a/testing/adios2/engine/bp/TestBPWriteReadFlatten.cpp b/testing/adios2/engine/bp/TestBPWriteReadFlatten.cpp index 5f5b9e50fb..cef5459af9 100644 --- a/testing/adios2/engine/bp/TestBPWriteReadFlatten.cpp +++ b/testing/adios2/engine/bp/TestBPWriteReadFlatten.cpp @@ -106,6 +106,7 @@ TEST_F(BPWriteReadTestFlatten, FlattenBPWriteRead1D8) io.SetParameters(engineParameters); } + io.SetParameters("FlattenSteps=on"); io.AddTransport("file"); adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write); @@ -188,7 +189,7 @@ TEST_F(BPWriteReadTestFlatten, FlattenBPWriteRead1D8) io.SetParameters(engineParameters); } - adios2::Engine bpReader = io.Open(fname, adios2::Mode::ReadFlattenSteps); + adios2::Engine bpReader = io.Open(fname, adios2::Mode::ReadRandomAccess); EXPECT_EQ(bpReader.Steps(), 1); @@ -429,6 +430,7 @@ TEST_F(BPWriteReadTestFlatten, FlattenBPWriteRead2D2x4) } io.AddTransport("file"); + io.SetParameters("FlattenSteps=on"); adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write); for (size_t step = 0; step < (size_t)mpiSize; ++step) @@ -501,7 +503,7 @@ TEST_F(BPWriteReadTestFlatten, FlattenBPWriteRead2D2x4) io.SetParameters(engineParameters); } - adios2::Engine bpReader = io.Open(fname, adios2::Mode::ReadFlattenSteps); + adios2::Engine bpReader = io.Open(fname, adios2::Mode::ReadRandomAccess); EXPECT_EQ(bpReader.Steps(), 1); auto var_iString = io.InquireVariable("iString"); @@ -748,6 +750,7 @@ TEST_F(BPWriteReadTestFlatten, FlattenBPWriteRead2D4x2) io.AddTransport("file"); + io.SetParameters("FlattenSteps=on"); adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write); for (size_t step = 0; step < (size_t)mpiSize; ++step) @@ -818,7 +821,7 @@ TEST_F(BPWriteReadTestFlatten, FlattenBPWriteRead2D4x2) io.SetParameters(engineParameters); } - adios2::Engine bpReader = io.Open(fname, adios2::Mode::ReadFlattenSteps); + adios2::Engine bpReader = io.Open(fname, adios2::Mode::ReadRandomAccess); EXPECT_EQ(bpReader.Steps(), 1); @@ -1038,6 +1041,7 @@ TEST_F(BPWriteReadTestFlatten, FlattenBPWriteRead10D2x2) io.AddTransport("file"); + io.SetParameters("FlattenSteps=on"); adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write); for (size_t step = 0; step < (size_t)mpiSize; ++step) @@ -1093,7 +1097,7 @@ TEST_F(BPWriteReadTestFlatten, FlattenBPWriteRead10D2x2) io.SetParameters(engineParameters); } - adios2::Engine bpReader = io.Open(fname, adios2::Mode::ReadFlattenSteps); + adios2::Engine bpReader = io.Open(fname, adios2::Mode::ReadRandomAccess); EXPECT_EQ(bpReader.Steps(), 1); @@ -1220,6 +1224,7 @@ TEST_F(BPWriteReadTestFlatten, FlattenBPWriteReadEmptyProcess) io.SetParameters(engineParameters); } + io.SetParameters("FlattenSteps=on"); adios2::Engine bpWriter = io.Open(fname, adios2::Mode::Write); for (size_t step = 0; step < NSteps; ++step) @@ -1255,7 +1260,7 @@ TEST_F(BPWriteReadTestFlatten, FlattenBPWriteReadEmptyProcess) io.SetParameters(engineParameters); } - adios2::Engine bpReader = io.Open(fname, adios2::Mode::ReadFlattenSteps); + adios2::Engine bpReader = io.Open(fname, adios2::Mode::ReadRandomAccess); for (size_t step = 0; step < 1; ++step) { diff --git a/testing/utils/cwriter/TestUtilsCWriter.bplsh.expected.txt b/testing/utils/cwriter/TestUtilsCWriter.bplsh.expected.txt index ba3fecafca..94f0894e45 100644 --- a/testing/utils/cwriter/TestUtilsCWriter.bplsh.expected.txt +++ b/testing/utils/cwriter/TestUtilsCWriter.bplsh.expected.txt @@ -11,7 +11,7 @@ The time dimension is the first dimension then. --attrsonly | -A List attributes only --meshes | -m List meshes --timestep | -t Read content step by step (stream reading) - --flatten Flatten Steps into one step (open in flatten mode) + --ignore_flatten Display steps as written (don't flatten, even if writer said to) --dump | -d Dump matched variables/attributes To match attributes too, add option -a --regexp | -e Treat masks as extended regular expressions