From 40fee81fecc1e3762d784ea9139729b17c359178 Mon Sep 17 00:00:00 2001 From: wgodoy <wgodoy@wgodoy-desktop> Date: Sun, 26 Mar 2017 22:05:01 -0400 Subject: [PATCH] Condensing BP1 Write functions for aggregation --- include/format/BP1.h | 21 ++ include/format/BP1Writer.h | 417 ++++++++++++++--------------- include/functions/adiosTemplates.h | 1 - src/format/BP1Writer.cpp | 102 +++---- 4 files changed, 283 insertions(+), 258 deletions(-) diff --git a/include/format/BP1.h b/include/format/BP1.h index ffc6eb6ec..4a5a95098 100644 --- a/include/format/BP1.h +++ b/include/format/BP1.h @@ -10,6 +10,9 @@ /// \cond EXCLUDE_FROM_DOXYGEN #include <memory> //std::shared_ptr +#include <cstdint> //std::uintX_t +#include <unordered_map> +#include <vector> //#include <queue> //std::priority_queue to be added later /// \endcond @@ -191,6 +194,24 @@ protected: statistic_finite = 6 }; + template<class T> + struct Stats + { + T Min; + T Max; + std::uint64_t Offset; + std::uint64_t PayloadOffset; + std::uint32_t TimeIndex; + + +// unsigned long int count; +// long double sum; +// long double sumSquare; + //unsigned long int histogram + //bool finite?? + }; + + /** * Returns data type index from enum Datatypes diff --git a/include/format/BP1Writer.h b/include/format/BP1Writer.h index 572616797..ff53b0573 100644 --- a/include/format/BP1Writer.h +++ b/include/format/BP1Writer.h @@ -9,8 +9,6 @@ #define BP1WRITER_H_ /// \cond EXCLUDE_FROM_DOXYGEN -#include <vector> -#include <cstdint> //std::intX_t fixed size integers #include <algorithm> //std::count, std::copy, std::for_each #include <cstring> //std::memcpy #include <cmath> //std::ceil @@ -66,8 +64,8 @@ public: void WriteProcessGroupIndex( const bool isFortran, const std::string name, const unsigned int processID, const std::string timeStepName, const unsigned int timeStep, const std::vector< std::shared_ptr<Transport> >& transports, - capsule::STLVector& buffer, - BP1MetadataSet& metadataSet ) const noexcept; + capsule::STLVector& buffer, BP1MetadataSet& metadataSet ) const noexcept; + /** * Returns the estimated variable index size @@ -118,120 +116,59 @@ public: } /** - * + * Version for primitive types (except std::complex<T>) * @param variable - * @param dataBuffers - * @param dataPositions - * @param dataAbsolutePositions - * @param metadataBuffers - * @param metadataPositions - * @param variablesCount + * @param heap + * @param metadataSet */ - template<class T> - void WriteVariableMetadata( const Variable<T>& variable, capsule::STLVector& buffer, BP1MetadataSet& metadataSet ) const noexcept + template<class T> inline + void WriteVariableMetadata( const Variable<T>& variable, capsule::STLVector& heap, BP1MetadataSet& metadataSet ) const noexcept { - auto itName = metadataSet.VarsIndices.find( variable.m_Name ); - if( itName == metadataSet.VarsIndices.end() ) - { - metadataSet.VarsIndices.emplace( variable.m_Name, BP1Index( metadataSet.VarsIndices.size() ) ); - } - else - { - //WriteExistingVariableMetadata( variable, buffer, itName->second ); need to implement - } + Stats<T> stats = GetStats( variable ); + WriteVariableMetadataCommon( variable, stats, heap, metadataSet ); } - - template< class T > - void WriteVariableMetadataInData( const Variable<T>& variable, capsule::STLVector& heap, BP1Index& varIndex ) + /** + * 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 { - auto& buffer = heap.m_Data; - auto& position = heap.m_DataPosition; - - const std::size_t dataVarLengthPosition = position; //capture initial position for variable length - position += 8; //skip var length - - CopyToBuffer( buffer, position, &varIndex.MemberID ); //memberID - WriteNameRecord( variable.m_Name, buffer, position ); //variable name - position += 2; //skip path - //dataType - const std::uint8_t dataType = GetDataType<T>(); - CopyToBuffer( buffer, position, &dataType ); - //variable is not dimension (removed in ADIOS2) check if constexpr works - const char no = 'n'; - CopyToBuffer( buffer, position, &no ); - - //write variable dimensions - const auto& localDimensions = variable.m_Dimensions; - //write dimensions count and length in data - const std::uint8_t dimensions = localDimensions.size(); - CopyToBuffer( buffer, position, &dimensions ); - const std::uint16_t dimensionsLength = dimensions * 27; //27 is from 9 bytes for each: var y/n + local, var y/n + global dimension, var y/n + global offset - CopyToBuffer( buffer, position, &dimensionsLength ); - - std::uint8_t characteristicsCounter = 0; - std::uint8_t characteristicID = characteristic_dimensions; - std::size_t characteristicsCountPosition = position; //will be modified + Stats<T> stats = GetStats( variable ); + WriteVariableMetadataCommon( variable, stats, heap, metadataSet ); + } - if( variable.m_GlobalDimensions.empty() ) //local variable - { - WriteDimensionRecord( buffer, position, localDimensions, 18, true ); //not using memberID for now - characteristicsCountPosition = position; //very important to track as writer is going back to this position - position += 5; //skip characteristics count(1) + length (4) + template< class T, class U> + void WriteVariableMetadata( const Variable<T>& variable, const Stats<U>& stats, const bool isNew, BP1Index& index ) + { + auto& buffer = index.Metadata; + auto& position = index.Position; - //dimensions in data characteristic entry - CopyToBuffer( buffer, position, &characteristicID ); - const std::int16_t lengthOfDimensionsCharacteristic = 24 * dimensions; // 24 = 3 local, global, global offset x 8 bytes/each - CopyToBuffer( buffer, position, &lengthOfDimensionsCharacteristic ); - CopyToBuffer( buffer, position, &dimensions ); - CopyToBuffer( buffer, position, &dimensionsLength ); - WriteDimensionRecord( buffer, position, localDimensions, 16 ); - } - else //global variable - { - const auto& globalDimensions = variable.m_GlobalDimensions; - const auto& globalOffsets = variable.m_GlobalOffsets; + if( isNew == true ) //write header if variable is new + { + position += 4; + CopyToBuffer( buffer, position, &index.MemberID ); + position += 2; //skip group name + WriteNameRecord( variable.m_Name, buffer, position ); + position += 2; //skip path + const std::uint8_t dataType = GetDataType<T>(); //dataType + CopyToBuffer( buffer, position, &dataType ); - WriteDimensionRecord( buffer, position, localDimensions, globalDimensions, globalOffsets, true ); + //Characteristics Sets Count in Metadata + index.Count = 1; + CopyToBuffer( buffer, position, &index.Count ); + } - characteristicsCountPosition = position; //very important, going back to these positions - position += 5; //skip characteristics count(1) + length (4) + //Characteristics sets: - //dimensions in data characteristic entry - CopyToBuffer( buffer, position, &characteristicID, 1 ); //id - const std::int16_t lengthOfDimensionsCharacteristic = 24 * dimensions; // 24 = 3 local, global, global offset x 8 bytes/each - CopyToBuffer( buffer, position, &lengthOfDimensionsCharacteristic, 2 ); - CopyToBuffer( buffer, position, &dimensions, 1 ); - CopyToBuffer( buffer, position, &dimensionsLength, 2 ); - WriteDimensionRecord( buffer, position, localDimensions, globalDimensions, globalOffsets ); - } - ++characteristicsCounter; - //VALUE for SCALAR or STAT min, max for ARRAY - //Value for scalar - if( variable.m_IsScalar ) //scalar //just doing string scalars for now (by name), needs to be modified when user passes value - { - characteristicID = characteristic_value; - CopyToBuffer( buffer, position, &characteristicID, 1 ); - const std::uint16_t lengthOfValue = sizeof( T ); - CopyToBuffer( buffer, position, &lengthOfValue, 2 ); //add length of characteristic in data - CopyToBuffer( buffer, position, variable.m_AppValues, sizeof(T) ); - ++characteristicsCounter; - } - else // Stat -> Min, Max for arrays, - { - if( m_Verbosity == 0 ) //default verbose - { - // FIXME: fixe WriteMinMax - WriteMinMax( variable, buffer, metadataSet ); - characteristicsCounter += 2; - } - } - - } + } @@ -444,6 +381,95 @@ public: private: + template< class T, class U > + void WriteVariableMetadataCommon( const Variable<T>& variable, Stats<U>& stats, + capsule::STLVector& heap, BP1MetadataSet& metadataSet ) const noexcept + { + bool isNew = true; //flag to check if variable is new + BP1Index& varIndex = GetBP1Index( variable.m_Name, metadataSet.VarsIndices, isNew ); + + stats.Offset = heap.m_DataAbsolutePosition; + WriteVariableMetadataInData( variable, stats, varIndex.MemberID, metadataSet.TimeStep, heap ); + stats.PayloadOffset = heap.m_DataAbsolutePosition; + + if( isNew == true ) + { + //NewVariable + } + else + { + //Existing variables, just add to characteristics sets + } + } + + + template< class T, class U > + void WriteVariableMetadataInData( const Variable<T>& variable, const Stats<U>& stats, const std::uint32_t memberID, + const std::uint32_t timeStep, capsule::STLVector& heap ) + { + auto& buffer = heap.m_Data; + auto& position = heap.m_DataPosition; + + const std::size_t varLengthPosition = position; //capture initial position for variable length + position += 8; //skip var length + + CopyToBuffer( buffer, position, &memberID ); //memberID + WriteNameRecord( variable.m_Name, buffer, position ); //variable name + position += 2; //skip path + const std::uint8_t dataType = GetDataType<T>(); //dataType + CopyToBuffer( buffer, position, &dataType ); + constexpr char no = 'n'; //isDimension + CopyToBuffer( buffer, position, &no ); + + //write variable dimensions + const auto& localDimensions = variable.m_Dimensions; + const auto& globalDimensions = variable.m_GlobalDimensions; + const auto& globalOffsets = variable.m_GlobalOffsets; + + //write dimensions count and length in data + const std::uint8_t dimensions = localDimensions.size(); + CopyToBuffer( buffer, position, &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, position, &dimensionsLength ); //length + WriteDimensionsRecord( buffer, position, localDimensions, globalDimensions, globalOffsets, 18, true ); + + //START CHARACTERISTICS + const std::size_t characteristicsCountPosition = position; //very important to track as writer is going back to this position + position += 5; //skip characteristics count(1) + length (4) + std::uint8_t characteristicsCounter = 0; + + //DIMENSIONS + std::uint8_t characteristicID = characteristic_dimensions; + CopyToBuffer( buffer, position, &characteristicID ); + const std::int16_t lengthOfDimensionsCharacteristic = 24 * dimensions + 3; // 24 = 3 local, global, global offset x 8 bytes/each + CopyToBuffer( buffer, position, &lengthOfDimensionsCharacteristic ); + CopyToBuffer( buffer, position, &dimensions ); //count + dimensionsLength = 24 * dimensions; + CopyToBuffer( buffer, position, &dimensionsLength ); //length + WriteDimensionsRecord( buffer, position, localDimensions, globalDimensions, globalOffsets, 16 ); + ++characteristicsCounter; + + //VALUE for SCALAR or STAT min, max for ARRAY + WriteStatsRecord( variable.m_IsScalar, stats, buffer, position, characteristicsCounter, true ); + //TIME INDEX + WriteStatsValueRecord( characteristic_time_index, timeStep, buffer, position, characteristicsCounter, true ); + //END OF CHARACTERISTICS + + //Back to characteristics count and length + std::size_t backPosition = characteristicsCountPosition; + CopyToBuffer( buffer, backPosition, &characteristicsCounter ); //count + const std::uint32_t characteristicsLength = position - characteristicsCountPosition - 4 - 1; //remove its own length (4 bytes) + characteristic counter ( 1 byte ) + CopyToBuffer( buffer, backPosition, &characteristicsLength ); //length + + //Back to varLength including payload size + const std::uint64_t varLength = position - varLengthPosition + variable.PayLoadSize() - 8; //remove its own size + backPosition = varLengthPosition; + CopyToBuffer( buffer, backPosition, &varLength ); //length + heap.m_DataAbsolutePosition += position - varLengthPosition; // update absolute position to be used as payload position + } + + + /** * Writes from &buffer[position]: [2 bytes:string.length()][string.length(): string.c_str()] * @param name @@ -453,7 +479,6 @@ private: void WriteNameRecord( const std::string name, std::vector<char>& buffer, std::size_t& position ); - /** * Write a dimension record for a global variable used by WriteVariableCommon * @param buffer @@ -463,88 +488,111 @@ private: * @param globalOffsets * @param addType true: for data buffers, false: for metadata buffer and data characteristic */ - void WriteDimensionRecord( std::vector<char>& buffer, std::size_t& position, - const std::vector<std::size_t>& localDimensions, - const std::vector<std::size_t>& globalDimensions, - const std::vector<std::size_t>& globalOffsets, - const bool addType = false ) const noexcept; + void WriteDimensionsRecord( std::vector<char>& buffer, std::size_t& position, + 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; /** - * Write a dimension record for a local variable used by WriteVariableCommon - * @param buffer - * @param position - * @param localDimensions - * @param skip - * @param addType true: for data buffers, false: for metadata buffer and data characteristic + * GetStats for primitive types except std::complex<T> types + * @param variable + * @return stats */ - void WriteDimensionRecord( std::vector<char>& buffer, std::size_t& position, - const std::vector<std::size_t>& localDimensions, - const unsigned int skip, - const bool addType = false ) const noexcept; + 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 ) + { + 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_Cores ); //here we can add cores from constructor + else + GetMinMax( variable.m_AppValues, valuesSize, stats.Min, stats.Max ); + } + return stats; + } /** - * Function that writes min and max into data and metadata, called from WriteVariableIndex common. - * Will be specialized for complex types, this is the version for primitive types + * GetStats for std::complex<T> types * @param variable - * @param dataBuffers - * @param dataPositions - * @param metadataBuffers - * @param metadataPositions + * @return stats */ - template<class T> inline - void WriteMinMax( const Variable<T>& variable, capsule::STLVector& buffer, BP1MetadataSet& metadataSet ) const noexcept - { - T min, max; - const std::size_t valuesSize = variable.TotalSize(); - if( valuesSize >= 10000000 ) //ten million? this needs actual results //here we can make decisions for threads based on valuesSize - GetMinMax( variable.m_AppValues, valuesSize, min, max, m_Cores ); //here we can add cores from constructor - else - GetMinMax( variable.m_AppValues, valuesSize, min, max ); - - WriteMinMaxValues( min, max, buffer, metadataSet ); - } + 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 ) + { + 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_Cores ); //here we can add cores from constructor + else + GetMinMax( variable.m_AppValues, valuesSize, stats.Min, stats.Max ); + } + return stats; + } - /** - * Common part of WriteMinMax specialized templates. Writes to buffers after min and max are calculated. - */ - template<class T> - void WriteMinMaxValues( const T min, const T max, capsule::STLVector& buffer, BP1MetadataSet& metadataSet ) const noexcept + template< class T > + void WriteStatsRecord( const bool isScalar, const Stats<T>& stats, std::vector<char>& buffer, std::size_t& position, + std::uint8_t& characteristicsCounter, const bool addLength = false ) { - constexpr std::int8_t characteristicMinID = characteristic_min; - constexpr std::int8_t characteristicMaxID = characteristic_max; + if( isScalar == true ) + { + WriteStatsValueRecord( characteristic_value, stats.min, buffer, position, characteristicsCounter, true ); //stats.min = stats.max = value + return; + } - WriteValueRecord( characteristicMinID, min, metadataSet.VarsIndex, metadataSet.VarsIndexPosition ); - WriteValueRecord( characteristicMaxID, max, metadataSet.VarsIndex, metadataSet.VarsIndexPosition ); - WriteValueRecord( characteristicMinID, min, buffer.m_Data, buffer.m_DataPosition, true ); //true: addLength in between for data - WriteValueRecord( characteristicMaxID, max, buffer.m_Data, buffer.m_DataPosition, true ); //true: addLength in between for data + if( m_Verbosity == 0 ) //default verbose + { + WriteStatsValueRecord( characteristic_min, stats.Min, buffer, position, characteristicsCounter, true ); + WriteStatsValueRecord( characteristic_max, stats.Max, buffer, position, characteristicsCounter, true ); + } } - /** - * Write a statistics record to buffer + * 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 WriteValueRecord( const std::uint8_t& characteristicID, const T& value, - std::vector<char>& buffer, std::size_t& position, - const bool addLength = false ) const noexcept + void WriteStatsValueRecord( const std::uint8_t characteristicID, const T& value, + std::vector<char>& buffer, std::size_t& position, + std::uint8_t& characteristicsCounter, + const bool addLength = false ) const noexcept { - MemcpyToBuffer( buffer, position, &characteristicID, 1 ); + const std::uint8_t id = characteristicID; + CopyToBuffer( buffer, position, &id ); if( addLength == true ) { - const std::uint16_t lengthCharacteristic = 1 + sizeof( T ); //id - MemcpyToBuffer( buffer, position, &lengthCharacteristic, 2 ); + const std::uint16_t lengthCharacteristic = sizeof( T ); //id + CopyToBuffer( buffer, position, &lengthCharacteristic ); } - MemcpyToBuffer( buffer, position, &value, sizeof(T) ); + CopyToBuffer( buffer, position, &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 ); + /** * Flattens the data and fills the pg length, vars count, vars length and attributes * @param metadataSet @@ -563,61 +611,6 @@ private: -/** - * Specialized version of WriteMinMax for std::complex<float> - * @param variable - * @param dataBuffers - * @param dataPositions - * @param metadataBuffers - * @param metadataPositions - */ -template<> inline -void BP1Writer::WriteMinMax<std::complex<float>>( const Variable<std::complex<float>>& variable, capsule::STLVector& buffer, - BP1MetadataSet& metadataSet ) const noexcept -{ - float min, max; - const std::size_t valuesSize = variable.TotalSize(); - if( valuesSize >= 10000000 ) //ten million? this needs actual results //here we can make decisions for threads based on valuesSize - GetMinMax( variable.m_AppValues, valuesSize, min, max, m_Cores ); //here we can add cores from constructor - else - GetMinMax( variable.m_AppValues, valuesSize, min, max ); - - WriteMinMaxValues( min, max, buffer, metadataSet ); -} - - -template<> inline -void BP1Writer::WriteMinMax<std::complex<double>>( const Variable<std::complex<double>>& variable, capsule::STLVector& buffer, - BP1MetadataSet& metadataSet ) const noexcept -{ - double min, max; - const std::size_t valuesSize = variable.TotalSize(); - if( valuesSize >= 10000000 ) //ten million? this needs actual results //here we can make decisions for threads based on valuesSize - GetMinMax( variable.m_AppValues, valuesSize, min, max, m_Cores ); //here we can add cores from constructor - else - GetMinMax( variable.m_AppValues, valuesSize, min, max ); - - WriteMinMaxValues( min, max, buffer, metadataSet ); -} - - -template<> inline -void BP1Writer::WriteMinMax<std::complex<long double>>( const Variable<std::complex<long double>>& variable, - capsule::STLVector& buffer, - BP1MetadataSet& metadataSet ) const noexcept -{ - long double min, max; - const std::size_t valuesSize = variable.TotalSize(); - if( valuesSize >= 10000000 ) //ten million? this needs actual results //here we can make decisions for threads based on valuesSize - GetMinMax( variable.m_AppValues, valuesSize, min, max, m_Cores ); //here we can add cores from constructor - else - GetMinMax( variable.m_AppValues, valuesSize, min, max ); - - WriteMinMaxValues( min, max, buffer, metadataSet ); -} - - - } //end namespace format } //end namespace adios diff --git a/include/functions/adiosTemplates.h b/include/functions/adiosTemplates.h index 6f8bd763b..9178c4e59 100644 --- a/include/functions/adiosTemplates.h +++ b/include/functions/adiosTemplates.h @@ -185,7 +185,6 @@ void CopyToBuffer( std::vector<char>& raw, std::size_t& position, const T* sourc position += elements * sizeof(T); } - template<class T> void CopyFromBuffer( T* destination, std::size_t elements, const std::vector<char>& raw, std::size_t& position ) noexcept { diff --git a/src/format/BP1Writer.cpp b/src/format/BP1Writer.cpp index 453f6ee30..825217899 100644 --- a/src/format/BP1Writer.cpp +++ b/src/format/BP1Writer.cpp @@ -181,60 +181,62 @@ std::string BP1Writer::GetRankProfilingLog( const int rank, const BP1MetadataSet //PRIVATE FUNCTIONS -void BP1Writer::WriteDimensionRecord( std::vector<char>& buffer, std::size_t& position, - const std::vector<std::size_t>& localDimensions, - const std::vector<std::size_t>& globalDimensions, - const std::vector<std::size_t>& globalOffsets, - const bool addType ) const noexcept +void BP1Writer::WriteDimensionsRecord( std::vector<char>& buffer, std::size_t& position, + 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 ) const noexcept { - if( addType == true ) + auto lf_WriteFlaggedDim = []( std::vector<char>& buffer, std::size_t& position, const char no, + const std::size_t dimension ) { - constexpr char no = 'n'; //dimension format unsigned int value for now - for( unsigned int d = 0; d < localDimensions.size(); ++d ) - { - CopyToBuffer( buffer, position, &no ); - CopyToBuffer( buffer, position, reinterpret_cast<std::uint64_t*>( &localDimensions[d] ) ); - - CopyToBuffer( buffer, position, &no ); - CopyToBuffer( buffer, position, reinterpret_cast<std::uint64_t*>( &globalDimensions[d] ) ); + CopyToBuffer( buffer, position, &no ); + CopyToBuffer( buffer, position, reinterpret_cast<std::uint64_t*>( &dimension ) ); + }; - CopyToBuffer( buffer, position, &no ); - CopyToBuffer( buffer, position, reinterpret_cast<std::uint64_t*>( &globalOffsets[d] ) ); - } - } - else + //BODY Starts here + if( globalDimensions.empty() ) { - for( unsigned int d = 0; d < localDimensions.size(); ++d ) + if( addType == true ) { - CopyToBuffer( buffer, position, reinterpret_cast<std::uint64_t*>( &localDimensions[d] ) ); - CopyToBuffer( buffer, position, reinterpret_cast<std::uint64_t*>( &globalDimensions[d] ) ); - CopyToBuffer( buffer, position, reinterpret_cast<std::uint64_t*>( &globalOffsets[d] ) ); + constexpr char no = 'n'; //dimension format unsigned int value (not using memberID for now) + for( const auto& localDimension : localDimensions ) + { + lf_WriteFlaggedDim( buffer, position, no, localDimension ); + position += skip; + } } - } -} - -void BP1Writer::WriteDimensionRecord( std::vector<char>& buffer, std::size_t& position, - const std::vector<std::size_t>& localDimensions, - const unsigned int skip, - const bool addType ) const noexcept -{ - if( addType == true ) - { - constexpr char no = 'n'; //dimension format unsigned int value (not using memberID for now) - for( const auto& localDimension : localDimensions ) + else { - CopyToBuffer( buffer, position, &no ); - CopyToBuffer( buffer, position, reinterpret_cast<std::uint64_t*>( &localDimension ) ); - position += skip; + for( const auto& localDimension : localDimensions ) + { + CopyToBuffer( buffer, position, reinterpret_cast<std::uint64_t*>( &localDimension ) ); + position += skip; + } } } else { - for( const auto& localDimension : localDimensions ) - { - CopyToBuffer( buffer, position, reinterpret_cast<std::uint64_t*>( &localDimension ) ); - position += skip; - } + if( addType == true ) + { + constexpr char no = 'n'; //dimension format unsigned int value for now + for( unsigned int d = 0; d < localDimensions.size(); ++d ) + { + lf_WriteFlaggedDim( buffer, position, no, localDimensions[d] ); + lf_WriteFlaggedDim( buffer, position, no, globalDimensions[d] ); + lf_WriteFlaggedDim( buffer, position, no, globalOffsets[d] ); + } + } + else + { + for( unsigned int d = 0; d < localDimensions.size(); ++d ) + { + CopyToBuffer( buffer, position, reinterpret_cast<std::uint64_t*>( &localDimensions[d] ) ); + CopyToBuffer( buffer, position, reinterpret_cast<std::uint64_t*>( &globalDimensions[d] ) ); + CopyToBuffer( buffer, position, reinterpret_cast<std::uint64_t*>( &globalOffsets[d] ) ); + } + } } } @@ -248,9 +250,19 @@ void BP1Writer::WriteNameRecord( const std::string name, std::vector<char>& buff +BP1Index& GetBP1Index( const std::string name, std::unordered_map<std::string, BP1Index>& indices, bool& isNew ) +{ + 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& buffer ) const noexcept -- GitLab