From b13f812b3ea9c0886302fe10deb5606bf2cfd814 Mon Sep 17 00:00:00 2001 From: wfg <wfg@pc0098504.ornl.gov> Date: Fri, 7 Apr 2017 16:52:36 -0400 Subject: [PATCH] Verified that test cases worked helloBPWriter and timeBPWriter --- examples/hello/bpWriter/helloBPWriter.cpp | 6 +- .../datamanWriter/helloDataManWriter.cpp | 3 +- .../helloDataManWriter_nompi.cpp | 3 +- examples/hello/timeBP/timeBPWriter.cpp | 2 + include/ADIOS.h | 31 +- include/core/Engine.h | 5 +- include/core/Variable.h | 12 +- include/core/VariableBase.h | 57 +- include/engine/adios1/ADIOS1Writer.h | 42 +- include/functions/adiosFunctions.h | 7 + include/utilities/format/bp1/BP1Writer.h | 910 +++++++++--------- source/ADIOS_inst.cpp | 55 +- source/engine/adios1/ADIOS1Writer.cpp | 138 +-- source/functions/adiosFunctions.cpp | 17 + source/utilities/format/bp1/BP1Writer.cpp | 590 ++++++------ 15 files changed, 953 insertions(+), 925 deletions(-) diff --git a/examples/hello/bpWriter/helloBPWriter.cpp b/examples/hello/bpWriter/helloBPWriter.cpp index 27691eae1..6dc601b17 100644 --- a/examples/hello/bpWriter/helloBPWriter.cpp +++ b/examples/hello/bpWriter/helloBPWriter.cpp @@ -18,8 +18,10 @@ int main(int argc, char *argv[]) { MPI_Init(&argc, &argv); - int rank; + int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &size); + const bool adiosDebug = true; adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::INFO, adiosDebug); @@ -49,8 +51,10 @@ int main(int argc, char *argv[]) // Define variable and local size adios::Variable<double> &ioMyDoubles = adios.DefineVariable<double>("myDoubles", {Nx}); + adios::Variable<float> &ioMyMatrix = adios.DefineVariable<float>("myMatrix", {rows, columns}); + adios::Variable<float> &ioMyMatrix2 = adios.DefineVariable<float>("myMatrix2", {rows, columns}); diff --git a/examples/hello/datamanWriter/helloDataManWriter.cpp b/examples/hello/datamanWriter/helloDataManWriter.cpp index 745722051..c6894ed08 100644 --- a/examples/hello/datamanWriter/helloDataManWriter.cpp +++ b/examples/hello/datamanWriter/helloDataManWriter.cpp @@ -72,8 +72,7 @@ int main(int argc, char *argv[]) // adios::DataManWriter datamanWriter; - auto datamanWriter = adios.Open("myDoubles.bp", "w", datamanSettings, - adios::IOMode::INDEPENDENT); + auto datamanWriter = adios.Open("myDoubles.bp", "w", datamanSettings); if (datamanWriter == nullptr) throw std::ios_base::failure( diff --git a/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp b/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp index 58df48ab4..fa7158c37 100644 --- a/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp +++ b/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp @@ -63,8 +63,7 @@ int main(int argc, char *argv[]) // Create engine smart pointer to DataMan Engine due to polymorphism, // Open returns a smart pointer to Engine containing the Derived class // DataMan - auto datamanWriter = adios.Open("myDoubles.bp", "w", datamanSettings, - adios::IOMode::INDEPENDENT); + auto datamanWriter = adios.Open("myDoubles.bp", "w", datamanSettings); if (datamanWriter == nullptr) throw std::ios_base::failure( diff --git a/examples/hello/timeBP/timeBPWriter.cpp b/examples/hello/timeBP/timeBPWriter.cpp index b9ae445de..3bcff1b43 100644 --- a/examples/hello/timeBP/timeBPWriter.cpp +++ b/examples/hello/timeBP/timeBPWriter.cpp @@ -49,8 +49,10 @@ int main(int argc, char *argv[]) // Define variable and local size adios::Variable<double> &ioMyDoubles = adios.DefineVariable<double>("myDoubles", {Nx}); + adios::Variable<float> &ioMyMatrix = adios.DefineVariable<float>("myMatrix", {rows, columns}); + adios::Variable<float> &ioMyMatrix2 = adios.DefineVariable<float>("myMatrix2", {rows, columns}); diff --git a/include/ADIOS.h b/include/ADIOS.h index 999890bd7..e389c9bdd 100644 --- a/include/ADIOS.h +++ b/include/ADIOS.h @@ -50,7 +50,7 @@ public: int m_RankMPI = 0; ///< current MPI rank process int m_SizeMPI = 1; ///< current MPI processes size - std::string m_HostLanguage = "C++"; ///< changed by bindings + std::string m_HostLanguage = "C++"; ///< changed by language bindings /** * @brief ADIOS empty constructor. Used for non XML config file API calls. @@ -91,28 +91,27 @@ public: void InitMPI(); ///< sets rank and size in m_rank and m_Size, respectively. /** - * Look for template specialization - * @param name + * Define a Variable for I/O. Default is a local scalar to be compatible + * with ADIOS1 + * @param name variable name, must be unique * @param dimensions - * @param globalDimensions - * @param globalOffsets - * @return + * @param selections + * @param offsets + * @return reference to Variable object */ template <class T> Variable<T> &DefineVariable(const std::string &name, - const Dims dimensions = Dims{1}, - const Dims globalDimensions = Dims(), - const Dims globalOffsets = Dims()); + const Dims localDimensions = Dims{1}, + const Dims globalDimensions = Dims{}, + const Dims offsets = Dims{}); template <class T> Variable<T> &GetVariable(const std::string &name); template <class T> - VariableCompound & - DefineVariableCompound(const std::string &name, - const Dims dimensions = Dims{1}, - const Dims globalDimensions = Dims(), - const Dims globalOffsets = Dims()); + VariableCompound &DefineVariableCompound( + const std::string &name, const Dims globalDimensions = Dims{}, + const Dims localDimensions = Dims{1}, const Dims offsets = Dims{}); VariableCompound &GetVariableCompound(const std::string &name); @@ -341,7 +340,7 @@ protected: // no const to allow default empty and copy constructors // Helper function for DefineVariable template <class T> - std::map<unsigned int, Variable<T>> &GetVarMap(); + std::map<unsigned int, Variable<T>> &GetVariableMap(); }; // Explicit declaration of the template methods @@ -352,7 +351,7 @@ protected: // no const to allow default empty and copy constructors extern template unsigned int ADIOS::GetVariableIndex<T>( \ const std::string &name); \ template <> \ - std::map<unsigned int, Variable<T>> &ADIOS::GetVarMap<T>(); + std::map<unsigned int, Variable<T>> &ADIOS::GetVariableMap<T>(); ADIOS_FOREACH_TYPE_1ARG(declare_template_instantiation) extern template unsigned int ADIOS::GetVariableIndex<void>(const std::string &); #undef declare_template_instantiation diff --git a/include/core/Engine.h b/include/core/Engine.h index 6f73fde1c..2e2b1f423 100644 --- a/include/core/Engine.h +++ b/include/core/Engine.h @@ -18,6 +18,7 @@ #include <string> #include <utility> //std::pair #include <vector> +#include <functional> //std::function /// \endcond #include "ADIOS_MPI.h" @@ -384,7 +385,7 @@ public: * Indicates that a new step is going to be written as new variables come * in. */ - virtual void Advance(float timeout_sec = 0.0); + virtual void Advance(const float timeout_sec = 0.0); /** * Indicates that a new step is going to be written as new variables come @@ -392,7 +393,7 @@ public: * @param mode Advance mode, there are different options for writers and * readers */ - virtual void Advance(AdvanceMode mode, float timeout_sec = 0.0); + virtual void Advance(AdvanceMode mode, const float timeout_sec = 0.0); /** @brief Advance asynchronously and get a callback when readers release * access to the buffered step. diff --git a/include/core/Variable.h b/include/core/Variable.h index cc932a484..ca91c790f 100644 --- a/include/core/Variable.h +++ b/include/core/Variable.h @@ -26,7 +26,7 @@ namespace adios struct TransformData { - Transform &Operation; ///< pointer to transform object + Transform &Operation; ///< from ADIOS.DefineTransform std::map<std::string, std::string> Parameters; ///< transforms parameters std::vector<std::size_t> Size; ///< vector that carries the sizes after a /// transformation is applied @@ -51,13 +51,13 @@ public: /// Transforms[1]. Pointer used as /// reference (no memory management). - Variable<T>(const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets, + Variable<T>(const std::string &name, const Dims localDimensions, + const Dims globalDimensions, const Dims offsets, const bool debugMode) - : VariableBase(name, GetType<T>(), sizeof(T), dimensions, globalDimensions, - globalOffsets, debugMode) + : VariableBase(name, GetType<T>(), sizeof(T), localDimensions, + globalDimensions, offsets, debugMode) { - if (m_Dimensions == Dims{1}) + if (m_LocalDimensions == Dims{1}) m_IsScalar = true; } diff --git a/include/core/VariableBase.h b/include/core/VariableBase.h index eea1d261c..fb223613b 100644 --- a/include/core/VariableBase.h +++ b/include/core/VariableBase.h @@ -18,7 +18,7 @@ #include <vector> /// \endcond -#include "functions/adiosFunctions.h" //GetTotalSize +#include "functions/adiosFunctions.h" //GetTotalSize, DimsToCSV #include "functions/adiosTemplates.h" //GetType<T> namespace adios @@ -32,26 +32,35 @@ class VariableBase public: const std::string m_Name; ///< variable name const std::string m_Type; ///< variable type - const std::size_t - m_ElementSize; ///< Variable -> sizeof(T), VariableCompound - ///-> from constructor + /** + * Variable -> sizeof(T), + * VariableCompound -> from constructor sizeof(struct) + */ + const std::size_t m_ElementSize; + + Dims m_LocalDimensions; ///< dimensions per rank (MPI) + Dims m_GlobalDimensions; ///< total dimensions across MPI + Dims m_Offsets; ///< selections offset bool m_IsScalar = false; const bool m_IsDimension = false; VariableBase(const std::string name, const std::string type, - const std::size_t elementSize, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets, + const std::size_t elementSize, const Dims localDimensions, + const Dims globalDimensions, const Dims offsets, const bool debugMode) : m_Name{name}, m_Type{type}, m_ElementSize{elementSize}, - m_Dimensions{dimensions}, m_GlobalDimensions{globalDimensions}, - m_GlobalOffsets{globalOffsets}, m_DebugMode{debugMode} + m_LocalDimensions{localDimensions}, m_GlobalDimensions{globalDimensions}, + m_Offsets{offsets}, m_DebugMode{debugMode} { } virtual ~VariableBase() {} - std::size_t DimensionsSize() const noexcept { return m_Dimensions.size(); } + std::size_t DimensionsSize() const noexcept + { + return m_LocalDimensions.size(); + } /** * Returns the payload size in bytes @@ -59,7 +68,7 @@ public: */ std::size_t PayLoadSize() const noexcept { - return GetTotalSize(m_Dimensions) * m_ElementSize; + return GetTotalSize(m_LocalDimensions) * m_ElementSize; } /** @@ -68,37 +77,11 @@ public: */ std::size_t TotalSize() const noexcept { - return GetTotalSize(m_Dimensions); + return GetTotalSize(m_LocalDimensions); } // protected: off for now - - Dims m_Dimensions; ///< array of local dimensions - Dims m_GlobalDimensions; ///< array of global dimensions - Dims m_GlobalOffsets; ///< array of global offsets const bool m_DebugMode = false; - - std::string GetDimensionAsString() { return dimsToString(m_Dimensions); } - std::string GetGlobalDimensionAsString() - { - return dimsToString(m_GlobalDimensions); - } - std::string GetOffsetsAsString() { return dimsToString(m_GlobalOffsets); } - -private: - std::string dimsToString(Dims dims) - { - std::ostringstream oss; - if (!dims.empty()) - { - // Convert all but the last element to avoid a trailing "," - std::copy(dims.begin(), dims.end() - 1, - std::ostream_iterator<std::size_t>(oss, ",")); - // Now add the last element with no delimiter - oss << dims.back(); - } - return oss.str(); - } }; } diff --git a/include/engine/adios1/ADIOS1Writer.h b/include/engine/adios1/ADIOS1Writer.h index a8c114b28..d783c02f7 100644 --- a/include/engine/adios1/ADIOS1Writer.h +++ b/include/engine/adios1/ADIOS1Writer.h @@ -38,11 +38,9 @@ public: * @param method * @param debugMode */ - ADIOS1Writer(ADIOS &adios, const std::string name, + ADIOS1Writer(ADIOS &adios, const std::string &name, const std::string accessMode, MPI_Comm mpiComm, - const Method &method, const IOMode iomode, - const float timeout_sec, const bool debugMode = false, - const unsigned int nthreads = 1); + const Method &method); ~ADIOS1Writer(); @@ -70,29 +68,29 @@ public: const std::complex<long double> *values); void Write(VariableCompound &variable, const void *values); - void Write(const std::string variableName, const char *values); - void Write(const std::string variableName, const unsigned char *values); - void Write(const std::string variableName, const short *values); - void Write(const std::string variableName, const unsigned short *values); - void Write(const std::string variableName, const int *values); - void Write(const std::string variableName, const unsigned int *values); - void Write(const std::string variableName, const long int *values); - void Write(const std::string variableName, const unsigned long int *values); - void Write(const std::string variableName, const long long int *values); - void Write(const std::string variableName, + void Write(const std::string &variableName, const char *values); + void Write(const std::string &variableName, const unsigned char *values); + void Write(const std::string &variableName, const short *values); + void Write(const std::string &variableName, const unsigned short *values); + void Write(const std::string &variableName, const int *values); + void Write(const std::string &variableName, const unsigned int *values); + void Write(const std::string &variableName, const long int *values); + void Write(const std::string &variableName, const unsigned long int *values); + void Write(const std::string &variableName, const long long int *values); + void Write(const std::string &variableName, const unsigned long long int *values); - void Write(const std::string variableName, const float *values); - void Write(const std::string variableName, const double *values); - void Write(const std::string variableName, const long double *values); - void Write(const std::string variableName, + void Write(const std::string &variableName, const float *values); + void Write(const std::string &variableName, const double *values); + void Write(const std::string &variableName, const long double *values); + void Write(const std::string &variableName, const std::complex<float> *values); - void Write(const std::string variableName, + void Write(const std::string &variableName, const std::complex<double> *values); - void Write(const std::string variableName, + void Write(const std::string &variableName, const std::complex<long double> *values); - void Write(const std::string variableName, const void *values); + void Write(const std::string &variableName, const void *values); - void Advance(); + void Advance( const float timeout_sec = 0. ); /** * Closes a single transport or all transports diff --git a/include/functions/adiosFunctions.h b/include/functions/adiosFunctions.h index ab6edba1d..c9b88a03e 100644 --- a/include/functions/adiosFunctions.h +++ b/include/functions/adiosFunctions.h @@ -182,6 +182,13 @@ BuildParametersMap(const std::vector<std::string> ¶meters, */ std::vector<int> CSVToVectorInt(const std::string csv); +/** + * Converts a vector of dimensions to a CSV string + * @param dims vector of dimensions + * @return comma separate value (CSV) + */ +std::string DimsToCSV(const std::vector<std::size_t> &dims); + /** * Common strategy to check for heap buffer allocation for data and metadata * typically calculated in Write diff --git a/include/utilities/format/bp1/BP1Writer.h b/include/utilities/format/bp1/BP1Writer.h index fa4382cf9..3dc4db2b1 100644 --- a/include/utilities/format/bp1/BP1Writer.h +++ b/include/utilities/format/bp1/BP1Writer.h @@ -34,484 +34,496 @@ class BP1Writer : public BP1Base { public: - unsigned int m_Threads = 1; ///< thread operations in large array (min,max) - unsigned int m_Verbosity = 0; ///< statistics verbosity, only 0 is supported - float m_GrowthFactor = 1.5; ///< memory growth factor - const std::uint8_t m_Version = 3; ///< BP format version - - /** - * Calculates the Process Index size in bytes according to the BP format, - * including list of method with no parameters (for now) - * @param name - * @param timeStepName - * @param numberOfTransports - * @return size of pg index - */ - std::size_t - GetProcessGroupIndexSize(const std::string name, - const std::string timeStepName, - const std::size_t numberOfTransports) const noexcept; - - /** - * Writes a process group index PGIndex and list of methods (from transports), - * done at Open or aggregation of new time step - * Version that operates on a single heap buffer and metadataset. - * @param isFortran - * @param name - * @param processID - * @param transports - * @param buffer - * @param metadataSet - */ - void WriteProcessGroupIndex( - const bool isFortran, const std::string name, - const std::uint32_t processID, - const std::vector<std::shared_ptr<Transport>> &transports, - capsule::STLVector &heap, BP1MetadataSet &metadataSet) const noexcept; - - /** - * Returns the estimated variable index size - * @param group - * @param variableName - * @param variable - * @param verbosity - * @return variable index size - */ - template <class T> - size_t GetVariableIndexSize(const Variable<T> &variable) const noexcept - { - // size_t indexSize = varEntryLength + memberID + lengthGroupName + - // groupName + lengthVariableName + lengthOfPath + path + datatype - size_t indexSize = 23; // without characteristics - indexSize += variable.m_Name.size(); - - // characteristics 3 and 4, check variable number of dimensions - const std::size_t dimensions = - variable.DimensionsSize(); // commas in CSV + 1 - indexSize += 28 * dimensions; // 28 bytes per dimension - indexSize += 1; // id - - // characteristics, offset + payload offset in data - indexSize += 2 * (1 + 8); - // characteristic 0, if scalar add value, for now only allowing string - if (dimensions == 1) + unsigned int m_Threads = 1; ///< thread operations in large array (min,max) + unsigned int m_Verbosity = 0; ///< statistics verbosity, only 0 is supported + float m_GrowthFactor = 1.5; ///< memory growth factor + const std::uint8_t m_Version = 3; ///< BP format version + + /** + * Calculates the Process Index size in bytes according to the BP format, + * including list of method with no parameters (for now) + * @param name + * @param timeStepName + * @param numberOfTransports + * @return size of pg index + */ + std::size_t GetProcessGroupIndexSize( + const std::string name, const std::string timeStepName, + const std::size_t numberOfTransports) const noexcept; + + /** + * Writes a process group index PGIndex and list of methods (from + * transports), + * done at Open or aggregation of new time step + * Version that operates on a single heap buffer and metadataset. + * @param isFortran + * @param name + * @param processID + * @param transports + * @param buffer + * @param metadataSet + */ + void WriteProcessGroupIndex( + const bool isFortran, const std::string name, + const std::uint32_t processID, + const std::vector<std::shared_ptr<Transport>> &transports, + capsule::STLVector &heap, BP1MetadataSet &metadataSet) const noexcept; + + /** + * Returns the estimated variable index size + * @param group + * @param variableName + * @param variable + * @param verbosity + * @return variable index size + */ + template <class T> + size_t GetVariableIndexSize(const Variable<T> &variable) const noexcept { - indexSize += sizeof(T); - indexSize += 1; // id - // must have an if here - indexSize += 2 + variable.m_Name.size(); - indexSize += 1; // id + // size_t indexSize = varEntryLength + memberID + lengthGroupName + + // groupName + lengthVariableName + lengthOfPath + path + datatype + size_t indexSize = 23; // without characteristics + indexSize += variable.m_Name.size(); + + // characteristics 3 and 4, check variable number of dimensions + const std::size_t dimensions = + variable.DimensionsSize(); // commas in CSV + 1 + indexSize += 28 * dimensions; // 28 bytes per dimension + indexSize += 1; // id + + // characteristics, offset + payload offset in data + indexSize += 2 * (1 + 8); + // characteristic 0, if scalar add value, for now only allowing string + if (dimensions == 1) + { + indexSize += sizeof(T); + indexSize += 1; // id + // must have an if here + indexSize += 2 + variable.m_Name.size(); + indexSize += 1; // id + } + + // characteristic statistics + if (m_Verbosity == 0) // default, only min and max + { + indexSize += 2 * (sizeof(T) + 1); + indexSize += 1 + 1; // id + } + + return indexSize + 12; /// extra 12 bytes in case of attributes + // need to add transform characteristics } - // characteristic statistics - if (m_Verbosity == 0) // default, only min and max + /** + * Version for primitive types (except std::complex<T>) + * @param variable + * @param heap + * @param metadataSet + */ + template <class T> + void WriteVariableMetadata(const Variable<T> &variable, + capsule::STLVector &heap, + BP1MetadataSet &metadataSet) const noexcept { - indexSize += 2 * (sizeof(T) + 1); - indexSize += 1 + 1; // id + Stats<T> stats = GetStats(variable); + WriteVariableMetadataCommon(variable, stats, heap, metadataSet); } - return indexSize + 12; /// extra 12 bytes in case of attributes - // need to add transform characteristics - } - - /** - * Version for primitive types (except std::complex<T>) - * @param variable - * @param heap - * @param metadataSet - */ - template <class T> - void WriteVariableMetadata(const Variable<T> &variable, - capsule::STLVector &heap, - BP1MetadataSet &metadataSet) const noexcept - { - Stats<T> stats = GetStats(variable); - WriteVariableMetadataCommon(variable, stats, heap, metadataSet); - } - - /** - * Overloaded version for std::complex<T> variables - * @param variable - * @param heap - * @param metadataSet - */ - template <class T> - void WriteVariableMetadata(const Variable<std::complex<T>> &variable, - capsule::STLVector &heap, - BP1MetadataSet &metadataSet) const noexcept - { - Stats<T> stats = GetStats(variable); - WriteVariableMetadataCommon(variable, stats, heap, metadataSet); - } - - /** - * Expensive part this is only for heap buffers need to adapt to vector of - * capsules - * @param variable - * @param buffer - */ - template <class T> - void WriteVariablePayload(const Variable<T> &variable, - capsule::STLVector &heap, - const unsigned int nthreads = 1) const noexcept - { - // EXPENSIVE part, might want to use threads if large, serial for now - CopyToBuffer(heap.m_Data, variable.m_AppValues, variable.TotalSize()); - heap.m_DataAbsolutePosition += variable.PayLoadSize(); - } - - void Advance(BP1MetadataSet &metadataSet, capsule::STLVector &buffer); - - /** - * Function that sets metadata (if first close) and writes to a single - * transport - * @param metadataSet current rank metadata set - * @param heap contains data buffer - * @param transport does a write after data and metadata is setup - * @param isFirstClose true: metadata has been set and aggregated - * @param doAggregation true: for N-to-M, false: for N-to-N - */ - void Close(BP1MetadataSet &metadataSet, capsule::STLVector &heap, - Transport &transport, bool &isFirstClose, - const bool doAggregation) const noexcept; - - /** - * Writes the ADIOS log information (buffering, open, write and close) for a - * rank process - * @param rank current rank - * @param metadataSet contains Profile info for buffering - * @param transports contains Profile info for transport open, writes and - * close - * @return string for this rank that will be aggregated into profiling.log - */ - std::string GetRankProfilingLog( - const int rank, const BP1MetadataSet &metadataSet, - const std::vector<std::shared_ptr<Transport>> &transports) const noexcept; + /** + * Overloaded version for std::complex<T> variables + * @param variable + * @param heap + * @param metadataSet + */ + template <class T> + void WriteVariableMetadata(const Variable<std::complex<T>> &variable, + capsule::STLVector &heap, + BP1MetadataSet &metadataSet) const noexcept + { + Stats<T> stats = GetStats(variable); + WriteVariableMetadataCommon(variable, stats, heap, metadataSet); + } -private: - template <class T, class U> - void WriteVariableMetadataCommon(const Variable<T> &variable, Stats<U> &stats, - capsule::STLVector &heap, - BP1MetadataSet &metadataSet) const noexcept - { - stats.TimeIndex = metadataSet.TimeStep; - - // Get new Index or point to existing index - bool isNew = true; // flag to check if variable is new - BP1Index &varIndex = - GetBP1Index(variable.m_Name, metadataSet.VarsIndices, isNew); - stats.MemberID = varIndex.MemberID; - - // write metadata header in data and extract offsets - stats.Offset = heap.m_DataAbsolutePosition; - WriteVariableMetadataInData(variable, stats, heap); - stats.PayloadOffset = heap.m_DataAbsolutePosition; - - // write to metadata index - WriteVariableMetadataInIndex(variable, stats, isNew, varIndex); - - ++metadataSet.DataPGVarsCount; - } - - template <class T, class U> - void WriteVariableMetadataInData(const Variable<T> &variable, - const Stats<U> &stats, - capsule::STLVector &heap) const noexcept - { - auto &buffer = heap.m_Data; - - const std::size_t varLengthPosition = - buffer.size(); // capture initial position for variable length - buffer.insert(buffer.end(), 8, 0); // skip var length (8) - CopyToBuffer(buffer, &stats.MemberID); // memberID - WriteNameRecord(variable.m_Name, buffer); // variable name - buffer.insert(buffer.end(), 2, 0); // skip path - const std::uint8_t dataType = GetDataType<T>(); // dataType - CopyToBuffer(buffer, &dataType); - constexpr char no = 'n'; // isDimension - CopyToBuffer(buffer, &no); - - // write variable dimensions - const std::uint8_t dimensions = variable.m_Dimensions.size(); - CopyToBuffer(buffer, &dimensions); // count - std::uint16_t dimensionsLength = - 27 * dimensions; // 27 is from 9 bytes for each: var y/n + local, var - // y/n + global dimension, var y/n + global offset, - // changed for characteristic - CopyToBuffer(buffer, &dimensionsLength); // length - WriteDimensionsRecord(buffer, variable.m_Dimensions, - variable.m_GlobalDimensions, variable.m_GlobalOffsets, - 18, true); - - // CHARACTERISTICS - WriteVariableCharacteristics(variable, stats, buffer, true); - - // Back to varLength including payload size - const std::uint64_t varLength = buffer.size() - varLengthPosition + - variable.PayLoadSize() - - 8; // remove its own size - CopyToBuffer(buffer, varLengthPosition, &varLength); // length - - heap.m_DataAbsolutePosition += - buffer.size() - varLengthPosition; // update absolute position to be - // used as payload position - } - - template <class T, class U> - void WriteVariableMetadataInIndex(const Variable<T> &variable, - const Stats<U> &stats, const bool isNew, - BP1Index &index) const noexcept - { - auto &buffer = index.Buffer; - - if (isNew == - true) // write variable header (might be shared with attributes index) + /** + * Expensive part this is only for heap buffers need to adapt to vector of + * capsules + * @param variable + * @param buffer + */ + template <class T> + void WriteVariablePayload(const Variable<T> &variable, + capsule::STLVector &heap, + const unsigned int nthreads = 1) const noexcept { - buffer.insert(buffer.end(), 4, 0); // skip var length (4) - CopyToBuffer(buffer, &stats.MemberID); - buffer.insert(buffer.end(), 2, 0); // skip group name - WriteNameRecord(variable.m_Name, buffer); - buffer.insert(buffer.end(), 2, 0); // skip path - - const std::uint8_t dataType = GetDataType<T>(); - CopyToBuffer(buffer, &dataType); - - // Characteristics Sets Count in Metadata - index.Count = 1; - CopyToBuffer(buffer, &index.Count); + // EXPENSIVE part, might want to use threads if large, serial for now + CopyToBuffer(heap.m_Data, variable.m_AppValues, variable.TotalSize()); + heap.m_DataAbsolutePosition += variable.PayLoadSize(); } - else // update characteristics sets count + + void Advance(BP1MetadataSet &metadataSet, capsule::STLVector &buffer); + + /** + * Function that sets metadata (if first close) and writes to a single + * transport + * @param metadataSet current rank metadata set + * @param heap contains data buffer + * @param transport does a write after data and metadata is setup + * @param isFirstClose true: metadata has been set and aggregated + * @param doAggregation true: for N-to-M, false: for N-to-N + */ + void Close(BP1MetadataSet &metadataSet, capsule::STLVector &heap, + Transport &transport, bool &isFirstClose, + const bool doAggregation) const noexcept; + + /** + * Writes the ADIOS log information (buffering, open, write and close) for a + * rank process + * @param rank current rank + * @param metadataSet contains Profile info for buffering + * @param transports contains Profile info for transport open, writes and + * close + * @return string for this rank that will be aggregated into profiling.log + */ + std::string GetRankProfilingLog( + const int rank, const BP1MetadataSet &metadataSet, + const std::vector<std::shared_ptr<Transport>> &transports) const + noexcept; + +private: + template <class T, class U> + void WriteVariableMetadataCommon(const Variable<T> &variable, + Stats<U> &stats, capsule::STLVector &heap, + BP1MetadataSet &metadataSet) const noexcept { - const std::size_t characteristicsSetsCountPosition = - 15 + variable.m_Name.size(); - ++index.Count; - CopyToBuffer(buffer, characteristicsSetsCountPosition, - &index.Count); // test + stats.TimeIndex = metadataSet.TimeStep; + + // Get new Index or point to existing index + bool isNew = true; // flag to check if variable is new + BP1Index &varIndex = + GetBP1Index(variable.m_Name, metadataSet.VarsIndices, isNew); + stats.MemberID = varIndex.MemberID; + + // write metadata header in data and extract offsets + stats.Offset = heap.m_DataAbsolutePosition; + WriteVariableMetadataInData(variable, stats, heap); + stats.PayloadOffset = heap.m_DataAbsolutePosition; + + // write to metadata index + WriteVariableMetadataInIndex(variable, stats, isNew, varIndex); + + ++metadataSet.DataPGVarsCount; } - WriteVariableCharacteristics(variable, stats, buffer); - } - - template <class T, class U> - void WriteVariableCharacteristics(const Variable<T> &variable, - const Stats<U> &stats, - std::vector<char> &buffer, - const bool addLength = false) const noexcept - { - const std::size_t characteristicsCountPosition = - buffer.size(); // very important to track as writer is going back to - // this position - buffer.insert(buffer.end(), 5, - 0); // skip characteristics count(1) + length (4) - std::uint8_t characteristicsCounter = 0; - - // DIMENSIONS - std::uint8_t characteristicID = characteristic_dimensions; - CopyToBuffer(buffer, &characteristicID); - const std::uint8_t dimensions = variable.m_Dimensions.size(); - - if (addLength == true) + template <class T, class U> + void WriteVariableMetadataInData(const Variable<T> &variable, + const Stats<U> &stats, + capsule::STLVector &heap) const noexcept { - const std::int16_t lengthOfDimensionsCharacteristic = - 24 * dimensions + - 3; // 24 = 3 local, global, global offset x 8 bytes/each - CopyToBuffer(buffer, &lengthOfDimensionsCharacteristic); + auto &buffer = heap.m_Data; + + const std::size_t varLengthPosition = + buffer.size(); // capture initial position for variable length + buffer.insert(buffer.end(), 8, 0); // skip var length (8) + CopyToBuffer(buffer, &stats.MemberID); // memberID + WriteNameRecord(variable.m_Name, buffer); // variable name + buffer.insert(buffer.end(), 2, 0); // skip path + const std::uint8_t dataType = GetDataType<T>(); // dataType + CopyToBuffer(buffer, &dataType); + constexpr char no = 'n'; // isDimension + CopyToBuffer(buffer, &no); + + // write variable dimensions + const std::uint8_t dimensions = variable.m_LocalDimensions.size(); + CopyToBuffer(buffer, &dimensions); // count + std::uint16_t dimensionsLength = + 27 * + dimensions; // 27 is from 9 bytes for each: var y/n + local, var + // y/n + global dimension, var y/n + global offset, + // changed for characteristic + CopyToBuffer(buffer, &dimensionsLength); // length + WriteDimensionsRecord(buffer, variable.m_LocalDimensions, + variable.m_GlobalDimensions, variable.m_Offsets, + 18, true); + + // CHARACTERISTICS + WriteVariableCharacteristics(variable, stats, buffer, true); + + // Back to varLength including payload size + const std::uint64_t varLength = buffer.size() - varLengthPosition + + variable.PayLoadSize() - + 8; // remove its own size + CopyToBuffer(buffer, varLengthPosition, &varLength); // length + + heap.m_DataAbsolutePosition += + buffer.size() - varLengthPosition; // update absolute position to be + // used as payload position } - CopyToBuffer(buffer, &dimensions); // count - const std::uint16_t dimensionsLength = 24 * dimensions; - CopyToBuffer(buffer, &dimensionsLength); // length - WriteDimensionsRecord(buffer, variable.m_Dimensions, - variable.m_GlobalDimensions, variable.m_GlobalOffsets, - 16, addLength); - ++characteristicsCounter; - - // VALUE for SCALAR or STAT min, max for ARRAY - WriteBoundsRecord(variable.m_IsScalar, stats, buffer, - characteristicsCounter, addLength); - // TIME INDEX - WriteCharacteristicRecord(characteristic_time_index, stats.TimeIndex, - buffer, characteristicsCounter, addLength); - - if (addLength == false) // only in metadata offset and payload offset + template <class T, class U> + void WriteVariableMetadataInIndex(const Variable<T> &variable, + const Stats<U> &stats, const bool isNew, + BP1Index &index) const noexcept { - WriteCharacteristicRecord(characteristic_offset, stats.Offset, buffer, - characteristicsCounter); - WriteCharacteristicRecord(characteristic_payload_offset, - stats.PayloadOffset, buffer, - characteristicsCounter); + auto &buffer = index.Buffer; + + if (isNew == true) // write variable header (might be shared with + // attributes index) + { + buffer.insert(buffer.end(), 4, 0); // skip var length (4) + CopyToBuffer(buffer, &stats.MemberID); + buffer.insert(buffer.end(), 2, 0); // skip group name + WriteNameRecord(variable.m_Name, buffer); + buffer.insert(buffer.end(), 2, 0); // skip path + + const std::uint8_t dataType = GetDataType<T>(); + CopyToBuffer(buffer, &dataType); + + // Characteristics Sets Count in Metadata + index.Count = 1; + CopyToBuffer(buffer, &index.Count); + } + else // update characteristics sets count + { + const std::size_t characteristicsSetsCountPosition = + 15 + variable.m_Name.size(); + ++index.Count; + CopyToBuffer(buffer, characteristicsSetsCountPosition, + &index.Count); // test + } + + WriteVariableCharacteristics(variable, stats, buffer); } - // END OF CHARACTERISTICS - - // Back to characteristics count and length - CopyToBuffer(buffer, characteristicsCountPosition, - &characteristicsCounter); // count (1) - const std::uint32_t characteristicsLength = - buffer.size() - characteristicsCountPosition - 4 - - 1; // remove its own length (4 bytes) + characteristic counter ( 1 byte - // ) - CopyToBuffer(buffer, characteristicsCountPosition + 1, - &characteristicsLength); // length - } - - /** - * Writes from &buffer[position]: [2 bytes:string.length()][string.length(): - * string.c_str()] - * @param name - * @param buffer - * @param position - */ - void WriteNameRecord(const std::string name, std::vector<char> &buffer) const - noexcept; - - /** - * Write a dimension record for a global variable used by WriteVariableCommon - * @param buffer - * @param position - * @param localDimensions - * @param globalDimensions - * @param globalOffsets - * @param addType true: for data buffers, false: for metadata buffer and data - * characteristic - */ - void WriteDimensionsRecord(std::vector<char> &buffer, - const std::vector<std::size_t> &localDimensions, - const std::vector<std::size_t> &globalDimensions, - const std::vector<std::size_t> &globalOffsets, - const unsigned int skip, - const bool addType = false) const noexcept; - - /** - * GetStats for primitive types except std::complex<T> types - * @param variable - * @return stats - */ - template <class T> - Stats<T> GetStats(const Variable<T> &variable) const noexcept - { - Stats<T> stats; - const std::size_t valuesSize = variable.TotalSize(); - - if (m_Verbosity == 0) + + template <class T, class U> + void WriteVariableCharacteristics(const Variable<T> &variable, + const Stats<U> &stats, + std::vector<char> &buffer, + const bool addLength = false) const + noexcept { - if (valuesSize >= 10000000) // ten million? this needs actual results - // //here we can make decisions for threads - // based on valuesSize - GetMinMax(variable.m_AppValues, valuesSize, stats.Min, stats.Max, - m_Threads); // here we can add cores from constructor - else - GetMinMax(variable.m_AppValues, valuesSize, stats.Min, stats.Max); + const std::size_t characteristicsCountPosition = + buffer.size(); // very important to track as writer is going back to + // this position + buffer.insert(buffer.end(), 5, + 0); // skip characteristics count(1) + length (4) + std::uint8_t characteristicsCounter = 0; + + // DIMENSIONS + std::uint8_t characteristicID = characteristic_dimensions; + CopyToBuffer(buffer, &characteristicID); + const std::uint8_t dimensions = variable.m_LocalDimensions.size(); + + if (addLength == true) + { + const std::int16_t lengthOfDimensionsCharacteristic = + 24 * dimensions + + 3; // 24 = 3 local, global, global offset x 8 bytes/each + CopyToBuffer(buffer, &lengthOfDimensionsCharacteristic); + } + + CopyToBuffer(buffer, &dimensions); // count + const std::uint16_t dimensionsLength = 24 * dimensions; + CopyToBuffer(buffer, &dimensionsLength); // length + WriteDimensionsRecord(buffer, variable.m_LocalDimensions, + variable.m_GlobalDimensions, variable.m_Offsets, + 16, addLength); + ++characteristicsCounter; + + // VALUE for SCALAR or STAT min, max for ARRAY + WriteBoundsRecord(variable.m_IsScalar, stats, buffer, + characteristicsCounter, addLength); + // TIME INDEX + WriteCharacteristicRecord(characteristic_time_index, stats.TimeIndex, + buffer, characteristicsCounter, addLength); + + if (addLength == false) // only in metadata offset and payload offset + { + WriteCharacteristicRecord(characteristic_offset, stats.Offset, + buffer, characteristicsCounter); + WriteCharacteristicRecord(characteristic_payload_offset, + stats.PayloadOffset, buffer, + characteristicsCounter); + } + // END OF CHARACTERISTICS + + // Back to characteristics count and length + CopyToBuffer(buffer, characteristicsCountPosition, + &characteristicsCounter); // count (1) + const std::uint32_t characteristicsLength = + buffer.size() - characteristicsCountPosition - 4 - + 1; // remove its own length (4 bytes) + characteristic counter ( 1 + // byte + // ) + CopyToBuffer(buffer, characteristicsCountPosition + 1, + &characteristicsLength); // length } - return stats; - } - - /** - * GetStats for std::complex<T> types - * @param variable - * @return stats - */ - template <class T> - Stats<T> GetStats(const Variable<std::complex<T>> &variable) const noexcept - { - Stats<T> stats; - const std::size_t valuesSize = variable.TotalSize(); - - if (m_Verbosity == 0) + + /** + * Writes from &buffer[position]: [2 + * bytes:string.length()][string.length(): + * string.c_str()] + * @param name + * @param buffer + * @param position + */ + void WriteNameRecord(const std::string name, + std::vector<char> &buffer) const noexcept; + + /** + * Write a dimension record for a global variable used by + * WriteVariableCommon + * @param buffer + * @param position + * @param localDimensions + * @param globalDimensions + * @param offsets + * @param addType true: for data buffers, false: for metadata buffer and + * data + * characteristic + */ + void WriteDimensionsRecord(std::vector<char> &buffer, + const std::vector<std::size_t> &localDimensions, + const std::vector<std::size_t> &globalDimensions, + const std::vector<std::size_t> &offsets, + const unsigned int skip, + const bool addType = false) const noexcept; + + /** + * GetStats for primitive types except std::complex<T> types + * @param variable + * @return stats + */ + template <class T> + Stats<T> GetStats(const Variable<T> &variable) const noexcept { - if (valuesSize >= 10000000) // ten million? this needs actual results - // //here we can make decisions for threads - // based on valuesSize - GetMinMax(variable.m_AppValues, valuesSize, stats.Min, stats.Max, - m_Threads); - else - GetMinMax(variable.m_AppValues, valuesSize, stats.Min, stats.Max); + Stats<T> stats; + const std::size_t valuesSize = variable.TotalSize(); + + if (m_Verbosity == 0) + { + if (valuesSize >= + 10000000) // ten million? this needs actual results + // //here we can make decisions for threads + // based on valuesSize + GetMinMax(variable.m_AppValues, valuesSize, stats.Min, + stats.Max, + m_Threads); // here we can add cores from constructor + else + GetMinMax(variable.m_AppValues, valuesSize, stats.Min, + stats.Max); + } + return stats; } - return stats; - } - - template <class T> - void WriteBoundsRecord(const bool isScalar, const Stats<T> &stats, - std::vector<char> &buffer, - std::uint8_t &characteristicsCounter, - const bool addLength) const noexcept - { - if (isScalar == true) + + /** + * GetStats for std::complex<T> types + * @param variable + * @return stats + */ + template <class T> + Stats<T> GetStats(const Variable<std::complex<T>> &variable) const noexcept { - WriteCharacteristicRecord(characteristic_value, stats.Min, buffer, - characteristicsCounter, - addLength); // stats.min = stats.max = value - return; + Stats<T> stats; + const std::size_t valuesSize = variable.TotalSize(); + + if (m_Verbosity == 0) + { + if (valuesSize >= + 10000000) // ten million? this needs actual results + // //here we can make decisions for threads + // based on valuesSize + GetMinMax(variable.m_AppValues, valuesSize, stats.Min, + stats.Max, m_Threads); + else + GetMinMax(variable.m_AppValues, valuesSize, stats.Min, + stats.Max); + } + return stats; } - if (m_Verbosity == 0) // default verbose + template <class T> + void WriteBoundsRecord(const bool isScalar, const Stats<T> &stats, + std::vector<char> &buffer, + std::uint8_t &characteristicsCounter, + const bool addLength) const noexcept { - WriteCharacteristicRecord(characteristic_min, stats.Min, buffer, - characteristicsCounter, addLength); - WriteCharacteristicRecord(characteristic_max, stats.Max, buffer, - characteristicsCounter, addLength); + if (isScalar == true) + { + WriteCharacteristicRecord( + characteristic_value, stats.Min, buffer, characteristicsCounter, + addLength); // stats.min = stats.max = value + return; + } + + if (m_Verbosity == 0) // default verbose + { + WriteCharacteristicRecord(characteristic_min, stats.Min, buffer, + characteristicsCounter, addLength); + WriteCharacteristicRecord(characteristic_max, stats.Max, buffer, + characteristicsCounter, addLength); + } } - } - - /** - * Write a characteristic value record to buffer - * @param id - * @param value - * @param buffers - * @param positions - * @param characvteristicsCounter to be updated by 1 - * @param addLength true for data, false for metadata - */ - template <class T> - void WriteCharacteristicRecord(const std::uint8_t characteristicID, - const T &value, std::vector<char> &buffer, - std::uint8_t &characteristicsCounter, - const bool addLength = false) const noexcept - { - const std::uint8_t id = characteristicID; - CopyToBuffer(buffer, &id); - - if (addLength == true) + + /** + * Write a characteristic value record to buffer + * @param id + * @param value + * @param buffers + * @param positions + * @param characvteristicsCounter to be updated by 1 + * @param addLength true for data, false for metadata + */ + template <class T> + void WriteCharacteristicRecord(const std::uint8_t characteristicID, + const T &value, std::vector<char> &buffer, + std::uint8_t &characteristicsCounter, + const bool addLength = false) const noexcept { - const std::uint16_t lengthOfCharacteristic = sizeof(T); // id - CopyToBuffer(buffer, &lengthOfCharacteristic); + const std::uint8_t id = characteristicID; + CopyToBuffer(buffer, &id); + + if (addLength == true) + { + const std::uint16_t lengthOfCharacteristic = sizeof(T); // id + CopyToBuffer(buffer, &lengthOfCharacteristic); + } + + CopyToBuffer(buffer, &value); + ++characteristicsCounter; } - CopyToBuffer(buffer, &value); - ++characteristicsCounter; - } - - /** - * Returns corresponding index of type BP1Index, if doesn't exists creates a - * new one. - * Used for variables and attributes - * @param name variable or attribute name to look for index - * @param indices look up hash table of indices - * @param isNew true: index is newly created, false: index already exists in - * indices - * @return reference to BP1Index in indices - */ - BP1Index &GetBP1Index(const std::string name, - std::unordered_map<std::string, BP1Index> &indices, - bool &isNew) const noexcept; - - /** - * Flattens the data and fills the pg length, vars count, vars length and - * attributes - * @param metadataSet - * @param buffer - */ - void FlattenData(BP1MetadataSet &metadataSet, - capsule::STLVector &buffer) const noexcept; - - /** - * Flattens the metadata indices into a single metadata buffer in capsule - * @param metadataSet - * @param buffer - */ - void FlattenMetadata(BP1MetadataSet &metadataSet, - capsule::STLVector &buffer) const - noexcept; ///< sets the metadata buffer in capsule with indices and - /// minifooter + /** + * Returns corresponding index of type BP1Index, if doesn't exists creates a + * new one. + * Used for variables and attributes + * @param name variable or attribute name to look for index + * @param indices look up hash table of indices + * @param isNew true: index is newly created, false: index already exists in + * indices + * @return reference to BP1Index in indices + */ + BP1Index &GetBP1Index(const std::string name, + std::unordered_map<std::string, BP1Index> &indices, + bool &isNew) const noexcept; + + /** + * Flattens the data and fills the pg length, vars count, vars length and + * attributes + * @param metadataSet + * @param buffer + */ + void FlattenData(BP1MetadataSet &metadataSet, + capsule::STLVector &buffer) const noexcept; + + /** + * Flattens the metadata indices into a single metadata buffer in capsule + * @param metadataSet + * @param buffer + */ + void FlattenMetadata(BP1MetadataSet &metadataSet, + capsule::STLVector &buffer) const + noexcept; ///< sets the metadata buffer in capsule with indices and + /// minifooter }; } // end namespace format diff --git a/source/ADIOS_inst.cpp b/source/ADIOS_inst.cpp index c494bc3e2..81b91e56c 100644 --- a/source/ADIOS_inst.cpp +++ b/source/ADIOS_inst.cpp @@ -17,97 +17,99 @@ namespace adios // ----------------------------------------------------------------------------- template <> -std::map<unsigned int, Variable<char>> &ADIOS::GetVarMap() +std::map<unsigned int, Variable<char>> &ADIOS::GetVariableMap() { return m_Char; } template <> -std::map<unsigned int, Variable<unsigned char>> &ADIOS::GetVarMap() +std::map<unsigned int, Variable<unsigned char>> &ADIOS::GetVariableMap() { return m_UChar; } template <> -std::map<unsigned int, Variable<short>> &ADIOS::GetVarMap() +std::map<unsigned int, Variable<short>> &ADIOS::GetVariableMap() { return m_Short; } template <> -std::map<unsigned int, Variable<unsigned short>> &ADIOS::GetVarMap() +std::map<unsigned int, Variable<unsigned short>> &ADIOS::GetVariableMap() { return m_UShort; } template <> -std::map<unsigned int, Variable<int>> &ADIOS::GetVarMap() +std::map<unsigned int, Variable<int>> &ADIOS::GetVariableMap() { return m_Int; } template <> -std::map<unsigned int, Variable<unsigned int>> &ADIOS::GetVarMap() +std::map<unsigned int, Variable<unsigned int>> &ADIOS::GetVariableMap() { return m_UInt; } template <> -std::map<unsigned int, Variable<long int>> &ADIOS::GetVarMap() +std::map<unsigned int, Variable<long int>> &ADIOS::GetVariableMap() { return m_LInt; } template <> -std::map<unsigned int, Variable<unsigned long int>> &ADIOS::GetVarMap() +std::map<unsigned int, Variable<unsigned long int>> &ADIOS::GetVariableMap() { return m_ULInt; } template <> -std::map<unsigned int, Variable<long long int>> &ADIOS::GetVarMap() +std::map<unsigned int, Variable<long long int>> &ADIOS::GetVariableMap() { return m_LLInt; } template <> -std::map<unsigned int, Variable<unsigned long long int>> &ADIOS::GetVarMap() +std::map<unsigned int, Variable<unsigned long long int>> & +ADIOS::GetVariableMap() { return m_ULLInt; } template <> -std::map<unsigned int, Variable<float>> &ADIOS::GetVarMap() +std::map<unsigned int, Variable<float>> &ADIOS::GetVariableMap() { return m_Float; } template <> -std::map<unsigned int, Variable<double>> &ADIOS::GetVarMap() +std::map<unsigned int, Variable<double>> &ADIOS::GetVariableMap() { return m_Double; } template <> -std::map<unsigned int, Variable<long double>> &ADIOS::GetVarMap() +std::map<unsigned int, Variable<long double>> &ADIOS::GetVariableMap() { return m_LDouble; } template <> -std::map<unsigned int, Variable<std::complex<float>>> &ADIOS::GetVarMap() +std::map<unsigned int, Variable<std::complex<float>>> &ADIOS::GetVariableMap() { return m_CFloat; } template <> -std::map<unsigned int, Variable<std::complex<double>>> &ADIOS::GetVarMap() +std::map<unsigned int, Variable<std::complex<double>>> &ADIOS::GetVariableMap() { return m_CDouble; } template <> -std::map<unsigned int, Variable<std::complex<long double>>> &ADIOS::GetVarMap() +std::map<unsigned int, Variable<std::complex<long double>>> & +ADIOS::GetVariableMap() { return m_CLDouble; } @@ -118,16 +120,17 @@ std::map<unsigned int, Variable<std::complex<long double>>> &ADIOS::GetVarMap() template <typename T> Variable<T> & -ADIOS::DefineVariable(const std::string &name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets) -{ - auto &varMap = GetVarMap<T>(); - CheckVariableInput(name, dimensions); - const unsigned int size = varMap.size(); - varMap.emplace(size, Variable<T>(name, dimensions, globalDimensions, - globalOffsets, m_DebugMode)); +ADIOS::DefineVariable(const std::string &name, const Dims globalDimensions, + const Dims localDimensions, const Dims offsets) +{ + auto &variableMap = GetVariableMap<T>(); + CheckVariableInput(name, globalDimensions); + const unsigned int size = variableMap.size(); + variableMap.emplace(size, + Variable<T>(name, globalDimensions, localDimensions, + offsets, m_DebugMode)); m_Variables.emplace(name, std::make_pair(GetType<T>(), size)); - return varMap.at(size); + return variableMap.at(size); } #define define_template_instantiation(T) \ @@ -154,7 +157,7 @@ unsigned int ADIOS::GetVariableIndex(const std::string &name) template <typename T> Variable<T> &ADIOS::GetVariable(const std::string &name) { - return GetVarMap<T>().at(GetVariableIndex<T>(name)); + return GetVariableMap<T>().at(GetVariableIndex<T>(name)); } #define define_template_instatiation(T) \ diff --git a/source/engine/adios1/ADIOS1Writer.cpp b/source/engine/adios1/ADIOS1Writer.cpp index 81813dc63..4a719f765 100644 --- a/source/engine/adios1/ADIOS1Writer.cpp +++ b/source/engine/adios1/ADIOS1Writer.cpp @@ -12,6 +12,7 @@ #include "engine/adios1/ADIOS1Writer.h" #include "ADIOS.h" +#include "functions/adiosFunctions.h" extern int adios_verbose_level; extern int adios_errno; @@ -19,13 +20,11 @@ extern int adios_errno; namespace adios { -ADIOS1Writer::ADIOS1Writer(ADIOS &adios, const std::string name, +ADIOS1Writer::ADIOS1Writer(ADIOS &adios, const std::string &name, const std::string accessMode, MPI_Comm mpiComm, - const Method &method, const IOMode iomode, - const float timeout_sec, const bool debugMode, - const unsigned int nthreads) -: Engine(adios, "ADIOS1Writer", name, accessMode, mpiComm, method, debugMode, - nthreads, " ADIOS1Writer constructor (or call to ADIOS Open).\n"), + const Method &method) +: Engine(adios, "ADIOS1Writer", name, accessMode, mpiComm, method, + " ADIOS1Writer constructor (or call to ADIOS Open).\n"), m_groupname{method.m_Name.c_str()}, m_filename{name.c_str()}, m_comm{mpiComm} { Init(); @@ -104,52 +103,52 @@ void ADIOS1Writer::WriteVariable(std::string name, bool isScalar, void ADIOS1Writer::Write(Variable<char> &variable, const char *values) { WriteVariable(variable.m_Name, variable.m_IsScalar, adios_byte, - variable.GetDimensionAsString(), - variable.GetGlobalDimensionAsString(), - variable.GetOffsetsAsString(), values); + DimsToCSV(variable.m_LocalDimensions), + DimsToCSV(variable.m_GlobalDimensions), + DimsToCSV(variable.m_Offsets), values); } void ADIOS1Writer::Write(Variable<unsigned char> &variable, const unsigned char *values) { WriteVariable(variable.m_Name, variable.m_IsScalar, adios_unsigned_byte, - variable.GetDimensionAsString(), - variable.GetGlobalDimensionAsString(), - variable.GetOffsetsAsString(), values); + DimsToCSV(variable.m_LocalDimensions), + DimsToCSV(variable.m_GlobalDimensions), + DimsToCSV(variable.m_Offsets), values); } void ADIOS1Writer::Write(Variable<short> &variable, const short *values) { WriteVariable(variable.m_Name, variable.m_IsScalar, adios_short, - variable.GetDimensionAsString(), - variable.GetGlobalDimensionAsString(), - variable.GetOffsetsAsString(), values); + DimsToCSV(variable.m_LocalDimensions), + DimsToCSV(variable.m_GlobalDimensions), + DimsToCSV(variable.m_Offsets), values); } void ADIOS1Writer::Write(Variable<unsigned short> &variable, const unsigned short *values) { WriteVariable(variable.m_Name, variable.m_IsScalar, adios_unsigned_short, - variable.GetDimensionAsString(), - variable.GetGlobalDimensionAsString(), - variable.GetOffsetsAsString(), values); + DimsToCSV(variable.m_LocalDimensions), + DimsToCSV(variable.m_GlobalDimensions), + DimsToCSV(variable.m_Offsets), values); } void ADIOS1Writer::Write(Variable<int> &variable, const int *values) { WriteVariable(variable.m_Name, variable.m_IsScalar, adios_integer, - variable.GetDimensionAsString(), - variable.GetGlobalDimensionAsString(), - variable.GetOffsetsAsString(), values); + DimsToCSV(variable.m_LocalDimensions), + DimsToCSV(variable.m_GlobalDimensions), + DimsToCSV(variable.m_Offsets), values); } void ADIOS1Writer::Write(Variable<unsigned int> &variable, const unsigned int *values) { WriteVariable(variable.m_Name, variable.m_IsScalar, adios_unsigned_integer, - variable.GetDimensionAsString(), - variable.GetGlobalDimensionAsString(), - variable.GetOffsetsAsString(), values); + DimsToCSV(variable.m_LocalDimensions), + DimsToCSV(variable.m_GlobalDimensions), + DimsToCSV(variable.m_Offsets), values); } void ADIOS1Writer::Write(Variable<long int> &variable, const long int *values) @@ -161,9 +160,9 @@ void ADIOS1Writer::Write(Variable<long int> &variable, const long int *values) type = adios_long; } WriteVariable(variable.m_Name, variable.m_IsScalar, type, - variable.GetDimensionAsString(), - variable.GetGlobalDimensionAsString(), - variable.GetOffsetsAsString(), values); + DimsToCSV(variable.m_LocalDimensions), + DimsToCSV(variable.m_GlobalDimensions), + DimsToCSV(variable.m_Offsets), values); } void ADIOS1Writer::Write(Variable<unsigned long int> &variable, @@ -176,43 +175,43 @@ void ADIOS1Writer::Write(Variable<unsigned long int> &variable, type = adios_unsigned_long; } WriteVariable(variable.m_Name, variable.m_IsScalar, type, - variable.GetDimensionAsString(), - variable.GetGlobalDimensionAsString(), - variable.GetOffsetsAsString(), values); + DimsToCSV(variable.m_LocalDimensions), + DimsToCSV(variable.m_GlobalDimensions), + DimsToCSV(variable.m_Offsets), values); } void ADIOS1Writer::Write(Variable<long long int> &variable, const long long int *values) { WriteVariable(variable.m_Name, variable.m_IsScalar, adios_long, - variable.GetDimensionAsString(), - variable.GetGlobalDimensionAsString(), - variable.GetOffsetsAsString(), values); + DimsToCSV(variable.m_LocalDimensions), + DimsToCSV(variable.m_GlobalDimensions), + DimsToCSV(variable.m_Offsets), values); } void ADIOS1Writer::Write(Variable<unsigned long long int> &variable, const unsigned long long int *values) { WriteVariable(variable.m_Name, variable.m_IsScalar, adios_unsigned_long, - variable.GetDimensionAsString(), - variable.GetGlobalDimensionAsString(), - variable.GetOffsetsAsString(), values); + DimsToCSV(variable.m_LocalDimensions), + DimsToCSV(variable.m_GlobalDimensions), + DimsToCSV(variable.m_Offsets), values); } void ADIOS1Writer::Write(Variable<float> &variable, const float *values) { WriteVariable(variable.m_Name, variable.m_IsScalar, adios_real, - variable.GetDimensionAsString(), - variable.GetGlobalDimensionAsString(), - variable.GetOffsetsAsString(), values); + DimsToCSV(variable.m_LocalDimensions), + DimsToCSV(variable.m_GlobalDimensions), + DimsToCSV(variable.m_Offsets), values); } void ADIOS1Writer::Write(Variable<double> &variable, const double *values) { WriteVariable(variable.m_Name, variable.m_IsScalar, adios_double, - variable.GetDimensionAsString(), - variable.GetGlobalDimensionAsString(), - variable.GetOffsetsAsString(), values); + DimsToCSV(variable.m_LocalDimensions), + DimsToCSV(variable.m_GlobalDimensions), + DimsToCSV(variable.m_Offsets), values); } void ADIOS1Writer::Write(Variable<long double> &variable, @@ -222,27 +221,27 @@ void ADIOS1Writer::Write(Variable<long double> &variable, * but * long double is compiler dependent */ WriteVariable(variable.m_Name, variable.m_IsScalar, adios_long_double, - variable.GetDimensionAsString(), - variable.GetGlobalDimensionAsString(), - variable.GetOffsetsAsString(), values); + DimsToCSV(variable.m_LocalDimensions), + DimsToCSV(variable.m_GlobalDimensions), + DimsToCSV(variable.m_Offsets), values); } void ADIOS1Writer::Write(Variable<std::complex<float>> &variable, const std::complex<float> *values) { WriteVariable(variable.m_Name, variable.m_IsScalar, adios_complex, - variable.GetDimensionAsString(), - variable.GetGlobalDimensionAsString(), - variable.GetOffsetsAsString(), values); + DimsToCSV(variable.m_LocalDimensions), + DimsToCSV(variable.m_GlobalDimensions), + DimsToCSV(variable.m_Offsets), values); } void ADIOS1Writer::Write(Variable<std::complex<double>> &variable, const std::complex<double> *values) { WriteVariable(variable.m_Name, variable.m_IsScalar, adios_double_complex, - variable.GetDimensionAsString(), - variable.GetGlobalDimensionAsString(), - variable.GetOffsetsAsString(), values); + DimsToCSV(variable.m_LocalDimensions), + DimsToCSV(variable.m_GlobalDimensions), + DimsToCSV(variable.m_Offsets), values); } void ADIOS1Writer::Write(Variable<std::complex<long double>> &variable, @@ -262,97 +261,98 @@ void ADIOS1Writer::Write(VariableCompound &variable, const void *values) } // String version -void ADIOS1Writer::Write(const std::string variableName, const char *values) +void ADIOS1Writer::Write(const std::string &variableName, const char *values) { Write(m_ADIOS.GetVariable<char>(variableName), values); } -void ADIOS1Writer::Write(const std::string variableName, +void ADIOS1Writer::Write(const std::string &variableName, const unsigned char *values) { Write(m_ADIOS.GetVariable<unsigned char>(variableName), values); } -void ADIOS1Writer::Write(const std::string variableName, const short *values) +void ADIOS1Writer::Write(const std::string &variableName, const short *values) { Write(m_ADIOS.GetVariable<short>(variableName), values); } -void ADIOS1Writer::Write(const std::string variableName, +void ADIOS1Writer::Write(const std::string &variableName, const unsigned short *values) { Write(m_ADIOS.GetVariable<unsigned short>(variableName), values); } -void ADIOS1Writer::Write(const std::string variableName, const int *values) +void ADIOS1Writer::Write(const std::string &variableName, const int *values) { Write(m_ADIOS.GetVariable<int>(variableName), values); } -void ADIOS1Writer::Write(const std::string variableName, +void ADIOS1Writer::Write(const std::string &variableName, const unsigned int *values) { Write(m_ADIOS.GetVariable<unsigned int>(variableName), values); } -void ADIOS1Writer::Write(const std::string variableName, const long int *values) +void ADIOS1Writer::Write(const std::string &variableName, + const long int *values) { Write(m_ADIOS.GetVariable<long int>(variableName), values); } -void ADIOS1Writer::Write(const std::string variableName, +void ADIOS1Writer::Write(const std::string &variableName, const unsigned long int *values) { Write(m_ADIOS.GetVariable<unsigned long int>(variableName), values); } -void ADIOS1Writer::Write(const std::string variableName, +void ADIOS1Writer::Write(const std::string &variableName, const long long int *values) { Write(m_ADIOS.GetVariable<long long int>(variableName), values); } -void ADIOS1Writer::Write(const std::string variableName, +void ADIOS1Writer::Write(const std::string &variableName, const unsigned long long int *values) { Write(m_ADIOS.GetVariable<unsigned long long int>(variableName), values); } -void ADIOS1Writer::Write(const std::string variableName, const float *values) +void ADIOS1Writer::Write(const std::string &variableName, const float *values) { Write(m_ADIOS.GetVariable<float>(variableName), values); } -void ADIOS1Writer::Write(const std::string variableName, const double *values) +void ADIOS1Writer::Write(const std::string &variableName, const double *values) { Write(m_ADIOS.GetVariable<double>(variableName), values); } -void ADIOS1Writer::Write(const std::string variableName, +void ADIOS1Writer::Write(const std::string &variableName, const long double *values) { Write(m_ADIOS.GetVariable<long double>(variableName), values); } -void ADIOS1Writer::Write(const std::string variableName, +void ADIOS1Writer::Write(const std::string &variableName, const std::complex<float> *values) { Write(m_ADIOS.GetVariable<std::complex<float>>(variableName), values); } -void ADIOS1Writer::Write(const std::string variableName, +void ADIOS1Writer::Write(const std::string &variableName, const std::complex<double> *values) { Write(m_ADIOS.GetVariable<std::complex<double>>(variableName), values); } -void ADIOS1Writer::Write(const std::string variableName, +void ADIOS1Writer::Write(const std::string &variableName, const std::complex<long double> *values) { Write(m_ADIOS.GetVariable<std::complex<long double>>(variableName), values); } -void ADIOS1Writer::Write(const std::string variableName, +void ADIOS1Writer::Write(const std::string &variableName, const void *values) // Compound type { throw std::invalid_argument("ERROR: Adios 1.x does not support compound " @@ -360,7 +360,7 @@ void ADIOS1Writer::Write(const std::string variableName, variableName + "\n"); } -void ADIOS1Writer::Advance() +void ADIOS1Writer::Advance(const float /*timeout_sec*/) { if (m_IsFileOpen) { diff --git a/source/functions/adiosFunctions.cpp b/source/functions/adiosFunctions.cpp index f2d703b5b..dcd7ece82 100644 --- a/source/functions/adiosFunctions.cpp +++ b/source/functions/adiosFunctions.cpp @@ -633,6 +633,23 @@ std::vector<int> CSVToVectorInt(const std::string csv) return numbers; } +std::string DimsToCSV(const std::vector<std::size_t> &dims) +{ + std::string dimsCSV; + + for (const auto dim : dims) + { + dimsCSV += std::to_string(dim) + ","; + } + + if (dimsCSV.empty() == false) + { + dimsCSV.pop_back(); + } + + return dimsCSV; +} + bool CheckBufferAllocation(const std::size_t newSize, const float growthFactor, const std::size_t maxBufferSize, std::vector<char> &buffer) diff --git a/source/utilities/format/bp1/BP1Writer.cpp b/source/utilities/format/bp1/BP1Writer.cpp index db59eb9ee..30d393e9f 100644 --- a/source/utilities/format/bp1/BP1Writer.cpp +++ b/source/utilities/format/bp1/BP1Writer.cpp @@ -24,10 +24,11 @@ std::size_t BP1Writer::GetProcessGroupIndexSize( const std::string name, const std::string timeStepName, const std::size_t numberOfTransports) const noexcept { - // pgIndex + list of methods (transports) - return (name.length() + timeStepName.length() + 23) + - (3 + numberOfTransports); // should be sufficient for data and metadata - // pgindices + // pgIndex + list of methods (transports) + return (name.length() + timeStepName.length() + 23) + + (3 + + numberOfTransports); // should be sufficient for data and metadata + // pgindices } void BP1Writer::WriteProcessGroupIndex( @@ -35,155 +36,156 @@ void BP1Writer::WriteProcessGroupIndex( const std::vector<std::shared_ptr<Transport>> &transports, capsule::STLVector &heap, BP1MetadataSet &metadataSet) const noexcept { - std::vector<char> &metadataBuffer = metadataSet.PGIndex.Buffer; - std::vector<char> &dataBuffer = heap.m_Data; - - metadataSet.DataPGLengthPosition = dataBuffer.size(); - dataBuffer.insert(dataBuffer.end(), 8, 0); // skip pg length (8) - - const std::size_t metadataPGLengthPosition = metadataBuffer.size(); - metadataBuffer.insert(metadataBuffer.end(), 2, 0); // skip pg length (2) - - // write name to metadata - WriteNameRecord(name, metadataBuffer); - // write if host language Fortran in metadata and data - const char hostFortran = - (isFortran) ? 'y' : 'n'; // if host language is fortran - CopyToBuffer(metadataBuffer, &hostFortran); - CopyToBuffer(dataBuffer, &hostFortran); - // write name in data - WriteNameRecord(name, dataBuffer); - - // processID in metadata, - CopyToBuffer(metadataBuffer, &processID); - // skip coordination var in data ....what is coordination var? - dataBuffer.insert(dataBuffer.end(), 4, 0); - - // time step name to metadata and data - const std::string timeStepName(std::to_string(metadataSet.TimeStep)); - WriteNameRecord(timeStepName, metadataBuffer); - WriteNameRecord(timeStepName, dataBuffer); - - // time step to metadata and data - CopyToBuffer(metadataBuffer, &metadataSet.TimeStep); - CopyToBuffer(dataBuffer, &metadataSet.TimeStep); - - // offset to pg in data in metadata which is the current absolute position - CopyToBuffer(metadataBuffer, - reinterpret_cast<std::uint64_t *>(&heap.m_DataAbsolutePosition)); - - // Back to writing metadata pg index length (length of group) - const std::uint16_t metadataPGIndexLength = - metadataBuffer.size() - metadataPGLengthPosition - - 2; // without length of group record - CopyToBuffer(metadataBuffer, metadataPGLengthPosition, - &metadataPGIndexLength); - // DONE With metadataBuffer - - // here write method in data - const std::vector<std::uint8_t> methodIDs = GetMethodIDs(transports); - const std::uint8_t methodsCount = methodIDs.size(); - CopyToBuffer(dataBuffer, &methodsCount); // count - const std::uint16_t methodsLength = - methodIDs.size() * - 3; // methodID (1) + method params length(2), no parameters for now - CopyToBuffer(dataBuffer, &methodsLength); // length - - for (const auto methodID : methodIDs) - { - CopyToBuffer(dataBuffer, &methodID); // method ID, - dataBuffer.insert(dataBuffer.end(), 2, - 0); // skip method params length = 0 (2 bytes) for now - } - - // update absolute position - heap.m_DataAbsolutePosition += - dataBuffer.size() - metadataSet.DataPGLengthPosition; - // pg vars count and position - metadataSet.DataPGVarsCount = 0; - metadataSet.DataPGVarsCountPosition = dataBuffer.size(); - // add vars count and length - dataBuffer.insert(dataBuffer.end(), 12, 0); - heap.m_DataAbsolutePosition += 12; // add vars count and length - - ++metadataSet.DataPGCount; - metadataSet.DataPGIsOpen = true; + std::vector<char> &metadataBuffer = metadataSet.PGIndex.Buffer; + std::vector<char> &dataBuffer = heap.m_Data; + + metadataSet.DataPGLengthPosition = dataBuffer.size(); + dataBuffer.insert(dataBuffer.end(), 8, 0); // skip pg length (8) + + const std::size_t metadataPGLengthPosition = metadataBuffer.size(); + metadataBuffer.insert(metadataBuffer.end(), 2, 0); // skip pg length (2) + + // write name to metadata + WriteNameRecord(name, metadataBuffer); + // write if host language Fortran in metadata and data + const char hostFortran = + (isFortran) ? 'y' : 'n'; // if host language is fortran + CopyToBuffer(metadataBuffer, &hostFortran); + CopyToBuffer(dataBuffer, &hostFortran); + // write name in data + WriteNameRecord(name, dataBuffer); + + // processID in metadata, + CopyToBuffer(metadataBuffer, &processID); + // skip coordination var in data ....what is coordination var? + dataBuffer.insert(dataBuffer.end(), 4, 0); + + // time step name to metadata and data + const std::string timeStepName(std::to_string(metadataSet.TimeStep)); + WriteNameRecord(timeStepName, metadataBuffer); + WriteNameRecord(timeStepName, dataBuffer); + + // time step to metadata and data + CopyToBuffer(metadataBuffer, &metadataSet.TimeStep); + CopyToBuffer(dataBuffer, &metadataSet.TimeStep); + + // offset to pg in data in metadata which is the current absolute position + CopyToBuffer(metadataBuffer, reinterpret_cast<std::uint64_t *>( + &heap.m_DataAbsolutePosition)); + + // Back to writing metadata pg index length (length of group) + const std::uint16_t metadataPGIndexLength = + metadataBuffer.size() - metadataPGLengthPosition - + 2; // without length of group record + CopyToBuffer(metadataBuffer, metadataPGLengthPosition, + &metadataPGIndexLength); + // DONE With metadataBuffer + + // here write method in data + const std::vector<std::uint8_t> methodIDs = GetMethodIDs(transports); + const std::uint8_t methodsCount = methodIDs.size(); + CopyToBuffer(dataBuffer, &methodsCount); // count + const std::uint16_t methodsLength = + methodIDs.size() * + 3; // methodID (1) + method params length(2), no parameters for now + CopyToBuffer(dataBuffer, &methodsLength); // length + + for (const auto methodID : methodIDs) + { + CopyToBuffer(dataBuffer, &methodID); // method ID, + dataBuffer.insert(dataBuffer.end(), 2, + 0); // skip method params length = 0 (2 bytes) for now + } + + // update absolute position + heap.m_DataAbsolutePosition += + dataBuffer.size() - metadataSet.DataPGLengthPosition; + // pg vars count and position + metadataSet.DataPGVarsCount = 0; + metadataSet.DataPGVarsCountPosition = dataBuffer.size(); + // add vars count and length + dataBuffer.insert(dataBuffer.end(), 12, 0); + heap.m_DataAbsolutePosition += 12; // add vars count and length + + ++metadataSet.DataPGCount; + metadataSet.DataPGIsOpen = true; } void BP1Writer::Advance(BP1MetadataSet &metadataSet, capsule::STLVector &buffer) { - FlattenData(metadataSet, buffer); + FlattenData(metadataSet, buffer); } void BP1Writer::Close(BP1MetadataSet &metadataSet, capsule::STLVector &heap, Transport &transport, bool &isFirstClose, const bool doAggregation) const noexcept { - if (metadataSet.Log.IsActive == true) - metadataSet.Log.Timers[0].SetInitialTime(); + if (metadataSet.Log.IsActive == true) + metadataSet.Log.Timers[0].SetInitialTime(); - if (isFirstClose == true) - { - if (metadataSet.DataPGIsOpen == true) - FlattenData(metadataSet, heap); + if (isFirstClose == true) + { + if (metadataSet.DataPGIsOpen == true) + FlattenData(metadataSet, heap); - FlattenMetadata(metadataSet, heap); + FlattenMetadata(metadataSet, heap); - if (metadataSet.Log.IsActive == true) - metadataSet.Log.Timers[0].SetInitialTime(); + if (metadataSet.Log.IsActive == true) + metadataSet.Log.Timers[0].SetInitialTime(); - if (doAggregation == true) // N-to-M where 1 <= M <= N-1, might need a new - // Log metadataSet.Log.m_Timers just for - // aggregation + if (doAggregation == + true) // N-to-M where 1 <= M <= N-1, might need a new + // Log metadataSet.Log.m_Timers just for + // aggregation + { + // here call aggregator + } + isFirstClose = false; + } + + if (doAggregation == true) // N-to-M where 1 <= M <= N-1 + { + // here call aggregator to select transports for Write and Close + } + else // N-to-N { - // here call aggregator + transport.Write(heap.m_Data.data(), heap.m_Data.size()); // single write + transport.Close(); } - isFirstClose = false; - } - - if (doAggregation == true) // N-to-M where 1 <= M <= N-1 - { - // here call aggregator to select transports for Write and Close - } - else // N-to-N - { - transport.Write(heap.m_Data.data(), heap.m_Data.size()); // single write - transport.Close(); - } } std::string BP1Writer::GetRankProfilingLog( const int rank, const BP1MetadataSet &metadataSet, const std::vector<std::shared_ptr<Transport>> &transports) const noexcept { - auto lf_WriterTimer = [](std::string &rankLog, - const profiling::Timer &timer) { - rankLog += "'" + timer.m_Process + "_" + timer.GetUnits() + "': " + - std::to_string(timer.m_ProcessTime) + ", "; - }; + auto lf_WriterTimer = [](std::string &rankLog, + const profiling::Timer &timer) { + rankLog += "'" + timer.m_Process + "_" + timer.GetUnits() + "': " + + std::to_string(timer.m_ProcessTime) + ", "; + }; - // prepare string dictionary per rank - std::string rankLog("'rank_" + std::to_string(rank) + "': { "); + // prepare string dictionary per rank + std::string rankLog("'rank_" + std::to_string(rank) + "': { "); - auto &profiler = metadataSet.Log; - rankLog += "'bytes': " + std::to_string(profiler.TotalBytes[0]) + ", "; - lf_WriterTimer(rankLog, profiler.Timers[0]); + auto &profiler = metadataSet.Log; + rankLog += "'bytes': " + std::to_string(profiler.TotalBytes[0]) + ", "; + lf_WriterTimer(rankLog, profiler.Timers[0]); - for (unsigned int t = 0; t < transports.size(); ++t) - { - auto &timers = transports[t]->m_Profiler.Timers; + for (unsigned int t = 0; t < transports.size(); ++t) + { + auto &timers = transports[t]->m_Profiler.Timers; - rankLog += "'transport_" + std::to_string(t) + "': { "; - rankLog += "'lib': " + transports[t]->m_Type + ", "; + rankLog += "'transport_" + std::to_string(t) + "': { "; + rankLog += "'lib': " + transports[t]->m_Type + ", "; - for (unsigned int i = 0; i < 3; ++i) - lf_WriterTimer(rankLog, timers[i]); + for (unsigned int i = 0; i < 3; ++i) + lf_WriterTimer(rankLog, timers[i]); + rankLog += "}, "; + } rankLog += "}, "; - } - rankLog += "}, "; - return rankLog; + return rankLog; } // PRIVATE FUNCTIONS @@ -193,68 +195,70 @@ void BP1Writer::WriteDimensionsRecord( const std::vector<std::size_t> &globalOffsets, const unsigned int skip, const bool addType) const noexcept { - auto lf_WriteFlaggedDim = [](std::vector<char> &buffer, const char no, - const std::size_t dimension) { - CopyToBuffer(buffer, &no); - CopyToBuffer(buffer, reinterpret_cast<const std::uint64_t *>(&dimension)); - }; - - // BODY Starts here - if (globalDimensions.empty()) - { - if (addType == true) - { - constexpr char no = 'n'; // dimension format unsigned int value (not using - // memberID for now) - for (const auto &localDimension : localDimensions) - { - lf_WriteFlaggedDim(buffer, no, localDimension); - buffer.insert(buffer.end(), skip, 0); - } - } - else - { - for (const auto &localDimension : localDimensions) - { + auto lf_WriteFlaggedDim = [](std::vector<char> &buffer, const char no, + const std::size_t dimension) { + CopyToBuffer(buffer, &no); CopyToBuffer(buffer, - reinterpret_cast<const std::uint64_t *>(&localDimension)); - buffer.insert(buffer.end(), skip, 0); - } - } - } - else - { - if (addType == true) + reinterpret_cast<const std::uint64_t *>(&dimension)); + }; + + // BODY Starts here + if (globalDimensions.empty()) { - constexpr char no = 'n'; // dimension format unsigned int value for now - for (unsigned int d = 0; d < localDimensions.size(); ++d) - { - lf_WriteFlaggedDim(buffer, no, localDimensions[d]); - lf_WriteFlaggedDim(buffer, no, globalDimensions[d]); - lf_WriteFlaggedDim(buffer, no, globalOffsets[d]); - } + if (addType == true) + { + constexpr char no = + 'n'; // dimension format unsigned int value (not using + // memberID for now) + for (const auto &localDimension : localDimensions) + { + lf_WriteFlaggedDim(buffer, no, localDimension); + buffer.insert(buffer.end(), skip, 0); + } + } + else + { + for (const auto &localDimension : localDimensions) + { + CopyToBuffer(buffer, reinterpret_cast<const std::uint64_t *>( + &localDimension)); + buffer.insert(buffer.end(), skip, 0); + } + } } else { - for (unsigned int d = 0; d < localDimensions.size(); ++d) - { - CopyToBuffer(buffer, reinterpret_cast<const std::uint64_t *>( - &localDimensions[d])); - CopyToBuffer(buffer, reinterpret_cast<const std::uint64_t *>( - &globalDimensions[d])); - CopyToBuffer( - buffer, reinterpret_cast<const std::uint64_t *>(&globalOffsets[d])); - } + if (addType == true) + { + constexpr char no = 'n'; + for (unsigned int d = 0; d < localDimensions.size(); ++d) + { + lf_WriteFlaggedDim(buffer, no, localDimensions[d]); + lf_WriteFlaggedDim(buffer, no, globalDimensions[d]); + lf_WriteFlaggedDim(buffer, no, globalOffsets[d]); + } + } + else + { + for (unsigned int d = 0; d < localDimensions.size(); ++d) + { + CopyToBuffer(buffer, reinterpret_cast<const std::uint64_t *>( + &localDimensions[d])); + CopyToBuffer(buffer, reinterpret_cast<const std::uint64_t *>( + &globalDimensions[d])); + CopyToBuffer(buffer, reinterpret_cast<const std::uint64_t *>( + &globalOffsets[d])); + } + } } - } } void BP1Writer::WriteNameRecord(const std::string name, std::vector<char> &buffer) const noexcept { - const std::uint16_t length = name.length(); - CopyToBuffer(buffer, &length); - CopyToBuffer(buffer, name.c_str(), length); + const std::uint16_t length = name.length(); + CopyToBuffer(buffer, &length); + CopyToBuffer(buffer, name.c_str(), length); } BP1Index & @@ -262,137 +266,137 @@ BP1Writer::GetBP1Index(const std::string name, std::unordered_map<std::string, BP1Index> &indices, bool &isNew) const noexcept { - auto itName = indices.find(name); - if (itName == indices.end()) - { - indices.emplace(name, BP1Index(indices.size())); - isNew = true; - return indices.at(name); - } - - isNew = false; - return itName->second; + auto itName = indices.find(name); + if (itName == indices.end()) + { + indices.emplace(name, BP1Index(indices.size())); + isNew = true; + return indices.at(name); + } + + isNew = false; + return itName->second; } void BP1Writer::FlattenData(BP1MetadataSet &metadataSet, capsule::STLVector &heap) const noexcept { - auto &buffer = heap.m_Data; - // vars count and Length (only for PG) - CopyToBuffer(buffer, metadataSet.DataPGVarsCountPosition, - &metadataSet.DataPGVarsCount); - const std::uint64_t varsLength = buffer.size() - - metadataSet.DataPGVarsCountPosition - 8 - - 4; // without record itself and vars count - CopyToBuffer(buffer, metadataSet.DataPGVarsCountPosition + 4, &varsLength); - - // attributes (empty for now) count (4) and length (8) are zero by moving - // positions in time step zero - buffer.insert(buffer.end(), 12, 0); - heap.m_DataAbsolutePosition += 12; - - // Finish writing pg group length - const std::uint64_t dataPGLength = - buffer.size() - metadataSet.DataPGLengthPosition - - 8; // without record itself, 12 due to empty attributes - CopyToBuffer(buffer, metadataSet.DataPGLengthPosition, &dataPGLength); - - ++metadataSet.TimeStep; - metadataSet.DataPGIsOpen = false; + auto &buffer = heap.m_Data; + // vars count and Length (only for PG) + CopyToBuffer(buffer, metadataSet.DataPGVarsCountPosition, + &metadataSet.DataPGVarsCount); + const std::uint64_t varsLength = buffer.size() - + metadataSet.DataPGVarsCountPosition - 8 - + 4; // without record itself and vars count + CopyToBuffer(buffer, metadataSet.DataPGVarsCountPosition + 4, &varsLength); + + // attributes (empty for now) count (4) and length (8) are zero by moving + // positions in time step zero + buffer.insert(buffer.end(), 12, 0); + heap.m_DataAbsolutePosition += 12; + + // Finish writing pg group length + const std::uint64_t dataPGLength = + buffer.size() - metadataSet.DataPGLengthPosition - + 8; // without record itself, 12 due to empty attributes + CopyToBuffer(buffer, metadataSet.DataPGLengthPosition, &dataPGLength); + + ++metadataSet.TimeStep; + metadataSet.DataPGIsOpen = false; } void BP1Writer::FlattenMetadata(BP1MetadataSet &metadataSet, capsule::STLVector &heap) const noexcept { - auto lf_IndexCountLength = - [](std::unordered_map<std::string, BP1Index> &indices, - std::uint32_t &count, std::uint64_t &length) { - - count = indices.size(); - length = 0; - for (auto &indexPair : indices) // set each index length - { - auto &indexBuffer = indexPair.second.Buffer; - const std::uint32_t indexLength = indexBuffer.size() - 4; - CopyToBuffer(indexBuffer, 0, &indexLength); - - length += indexBuffer.size(); // overall length - } - }; + auto lf_IndexCountLength = + [](std::unordered_map<std::string, BP1Index> &indices, + std::uint32_t &count, std::uint64_t &length) { + + count = indices.size(); + length = 0; + for (auto &indexPair : indices) // set each index length + { + auto &indexBuffer = indexPair.second.Buffer; + const std::uint32_t indexLength = indexBuffer.size() - 4; + CopyToBuffer(indexBuffer, 0, &indexLength); + + length += indexBuffer.size(); // overall length + } + }; + + auto lf_FlattenIndices = + [](const std::uint32_t count, const std::uint64_t length, + const std::unordered_map<std::string, BP1Index> &indices, + std::vector<char> &buffer) { + CopyToBuffer(buffer, &count); + CopyToBuffer(buffer, &length); + + for (const auto &indexPair : indices) // set each index length + { + const auto &indexBuffer = indexPair.second.Buffer; + CopyToBuffer(buffer, indexBuffer.data(), indexBuffer.size()); + } + }; + + // Finish writing metadata counts and lengths + // PG Index + const std::uint64_t pgCount = metadataSet.DataPGCount; + const std::uint64_t pgLength = metadataSet.PGIndex.Buffer.size(); + + // var index count and length (total), and each index length + std::uint32_t varsCount; + std::uint64_t varsLength; + lf_IndexCountLength(metadataSet.VarsIndices, varsCount, varsLength); + // attribute index count and length, and each index length + std::uint32_t attributesCount; + std::uint64_t attributesLength; + lf_IndexCountLength(metadataSet.AttributesIndices, attributesCount, + attributesLength); + + const std::size_t footerSize = (pgLength + 16) + (varsLength + 12) + + (attributesLength + 12) + + metadataSet.MiniFooterSize; + auto &buffer = heap.m_Data; + buffer.reserve(buffer.size() + footerSize); // reserve data to fit metadata, + // must replace with growth buffer + // strategy + + // write pg index + CopyToBuffer(buffer, &pgCount); + CopyToBuffer(buffer, &pgLength); + CopyToBuffer(buffer, metadataSet.PGIndex.Buffer.data(), pgLength); + // Vars indices + lf_FlattenIndices(varsCount, varsLength, metadataSet.VarsIndices, buffer); + // Attribute indices + lf_FlattenIndices(attributesCount, attributesLength, + metadataSet.AttributesIndices, buffer); + + // getting absolute offsets, minifooter is 28 bytes for now + const std::uint64_t offsetPGIndex = heap.m_DataAbsolutePosition; + const std::uint64_t offsetVarsIndex = offsetPGIndex + (pgLength + 16); + const std::uint64_t offsetAttributeIndex = + offsetVarsIndex + (varsLength + 12); + + CopyToBuffer(buffer, &offsetPGIndex); + CopyToBuffer(buffer, &offsetVarsIndex); + CopyToBuffer(buffer, &offsetAttributeIndex); + + // version + if (IsLittleEndian()) + { + const std::uint8_t endian = 0; + CopyToBuffer(buffer, &endian); + buffer.insert(buffer.end(), 2, 0); + CopyToBuffer(buffer, &m_Version); + } + else + { + } - auto lf_FlattenIndices = - [](const std::uint32_t count, const std::uint64_t length, - const std::unordered_map<std::string, BP1Index> &indices, - std::vector<char> &buffer) { - CopyToBuffer(buffer, &count); - CopyToBuffer(buffer, &length); + heap.m_DataAbsolutePosition += footerSize; - for (const auto &indexPair : indices) // set each index length - { - const auto &indexBuffer = indexPair.second.Buffer; - CopyToBuffer(buffer, indexBuffer.data(), indexBuffer.size()); - } - }; - - // Finish writing metadata counts and lengths - // PG Index - const std::uint64_t pgCount = metadataSet.DataPGCount; - const std::uint64_t pgLength = metadataSet.PGIndex.Buffer.size(); - - // var index count and length (total), and each index length - std::uint32_t varsCount; - std::uint64_t varsLength; - lf_IndexCountLength(metadataSet.VarsIndices, varsCount, varsLength); - // attribute index count and length, and each index length - std::uint32_t attributesCount; - std::uint64_t attributesLength; - lf_IndexCountLength(metadataSet.AttributesIndices, attributesCount, - attributesLength); - - const std::size_t footerSize = (pgLength + 16) + (varsLength + 12) + - (attributesLength + 12) + - metadataSet.MiniFooterSize; - auto &buffer = heap.m_Data; - buffer.reserve(buffer.size() + footerSize); // reserve data to fit metadata, - // must replace with growth buffer - // strategy - - // write pg index - CopyToBuffer(buffer, &pgCount); - CopyToBuffer(buffer, &pgLength); - CopyToBuffer(buffer, metadataSet.PGIndex.Buffer.data(), pgLength); - // Vars indices - lf_FlattenIndices(varsCount, varsLength, metadataSet.VarsIndices, buffer); - // Attribute indices - lf_FlattenIndices(attributesCount, attributesLength, - metadataSet.AttributesIndices, buffer); - - // getting absolute offsets, minifooter is 28 bytes for now - const std::uint64_t offsetPGIndex = heap.m_DataAbsolutePosition; - const std::uint64_t offsetVarsIndex = offsetPGIndex + (pgLength + 16); - const std::uint64_t offsetAttributeIndex = - offsetVarsIndex + (varsLength + 12); - - CopyToBuffer(buffer, &offsetPGIndex); - CopyToBuffer(buffer, &offsetVarsIndex); - CopyToBuffer(buffer, &offsetAttributeIndex); - - // version - if (IsLittleEndian()) - { - const std::uint8_t endian = 0; - CopyToBuffer(buffer, &endian); - buffer.insert(buffer.end(), 2, 0); - CopyToBuffer(buffer, &m_Version); - } - else - { - } - - heap.m_DataAbsolutePosition += footerSize; - - if (metadataSet.Log.IsActive == true) - metadataSet.Log.TotalBytes.push_back(heap.m_DataAbsolutePosition); + if (metadataSet.Log.IsActive == true) + metadataSet.Log.TotalBytes.push_back(heap.m_DataAbsolutePosition); } } // end namespace format -- GitLab