From c413fcb3803145ae2aa2207f0e8eee07e597449f Mon Sep 17 00:00:00 2001 From: Greg Eisenhauer Date: Fri, 8 Oct 2021 09:41:21 -0400 Subject: [PATCH 1/4] BP5 Local var tests --- source/adios2/common/ADIOSMacros.h | 14 + source/adios2/common/ADIOSTypes.h | 2 +- source/adios2/core/Engine.h | 26 +- source/adios2/core/Variable.tcc | 43 ++ source/adios2/engine/bp5/BP5Reader.cpp | 6 + source/adios2/engine/bp5/BP5Reader.h | 2 + .../toolkit/format/bp5/BP5Deserializer.cpp | 504 +++++++++++++++--- .../toolkit/format/bp5/BP5Deserializer.h | 12 +- .../toolkit/format/bp5/BP5Serializer.cpp | 63 ++- .../adios2/toolkit/format/bp5/BP5Serializer.h | 5 +- testing/adios2/engine/bp/CMakeLists.txt | 2 +- .../bp/TestBPWriteReadLocalVariables.cpp | 39 +- 12 files changed, 586 insertions(+), 132 deletions(-) diff --git a/source/adios2/common/ADIOSMacros.h b/source/adios2/common/ADIOSMacros.h index b79fb3e59d..6e05fd968f 100644 --- a/source/adios2/common/ADIOSMacros.h +++ b/source/adios2/common/ADIOSMacros.h @@ -245,6 +245,20 @@ MACRO(std::complex, cfloat) \ MACRO(std::complex, cdouble) +#define ADIOS2_FOREACH_MINMAX_STDTYPE_2ARGS(MACRO) \ + MACRO(int8_t, int8) \ + MACRO(char, char) \ + MACRO(uint8_t, uint8) \ + MACRO(int16_t, int16) \ + MACRO(uint16_t, uint16) \ + MACRO(int32_t, int32) \ + MACRO(uint32_t, uint32) \ + MACRO(int64_t, int64) \ + MACRO(uint64_t, uint64) \ + MACRO(float, float) \ + MACRO(double, double) \ + MACRO(long double, ldouble) + #define ADIOS2_FOREACH_STDTYPE_2ARGS(MACRO) \ ADIOS2_FOREACH_ATTRIBUTE_STDTYPE_2ARGS(MACRO) diff --git a/source/adios2/common/ADIOSTypes.h b/source/adios2/common/ADIOSTypes.h index 5030d0fe9a..d141645ca2 100644 --- a/source/adios2/common/ADIOSTypes.h +++ b/source/adios2/common/ADIOSTypes.h @@ -41,7 +41,7 @@ enum class ShapeID GlobalArray, ///< global (across MPI_Comm) array, common case JoinedArray, ///< global array with a common (joinable) dimension LocalValue, ///< special case, local independent value - LocalArray ///< special case, local independent array + LocalArray, ///< special case, local independent array }; /** Used to set IO class */ diff --git a/source/adios2/core/Engine.h b/source/adios2/core/Engine.h index 1055fbe5f1..5df8e340fb 100644 --- a/source/adios2/core/Engine.h +++ b/source/adios2/core/Engine.h @@ -452,17 +452,9 @@ class Engine union PrimitiveStdtypeUnion { - int8_t int8; - int16_t int16; - int32_t int32; - int64_t int64; - uint8_t uint8; - uint16_t uint16; - uint32_t uint32; - uint64_t uint64; - float f; - double d; - long double ld; +#define declare_field(T, N) T field_##N; + ADIOS2_FOREACH_MINMAX_STDTYPE_2ARGS(declare_field) +#undef declare_field }; struct MinBlockInfo @@ -475,6 +467,11 @@ class Engine union PrimitiveStdtypeUnion MaxUnion; void *BufferP = NULL; }; + struct MinMaxStruct + { + union PrimitiveStdtypeUnion MinUnion; + union PrimitiveStdtypeUnion MaxUnion; + }; struct MinVarInfo { int Dims; @@ -489,12 +486,19 @@ class Engine } }; + // in this call, Step is RELATIVE, not absolute virtual MinVarInfo *MinBlocksInfo(const VariableBase &, const size_t Step) const { return nullptr; } + virtual bool VariableMinMax(const VariableBase &, const size_t Step, + MinMaxStruct &MinMax) + { + return false; + } + /** Notify the engine when a new attribute is defined. Called from IO.tcc */ virtual void NotifyEngineAttribute(std::string name, diff --git a/source/adios2/core/Variable.tcc b/source/adios2/core/Variable.tcc index 206642fe91..1fae3b9a5d 100644 --- a/source/adios2/core/Variable.tcc +++ b/source/adios2/core/Variable.tcc @@ -64,6 +64,30 @@ Dims Variable::DoCount() const if (m_Engine != nullptr && m_SelectionType == SelectionType::WriteBlock) { + auto MVI = m_Engine->MinBlocksInfo(*this, m_StepsStart); + if (MVI) + { + if (m_BlockID >= MVI->BlocksInfo.size()) + { + throw std::invalid_argument( + "ERROR: blockID " + std::to_string(m_BlockID) + + " from SetBlockSelection is out of bounds for available " + "blocks size " + + std::to_string(MVI->BlocksInfo.size()) + " for variable " + + m_Name + " for step " + std::to_string(m_StepsStart) + + ", in call to Variable::Count()"); + } + + size_t *DimsPtr = (MVI->BlocksInfo)[m_BlockID].Count; + Dims D; + D.resize(MVI->Dims); + for (int i = 0; i < MVI->Dims; i++) + { + D[i] = DimsPtr[i]; + } + return D; + } + const size_t step = !m_FirstStreamingStep ? m_Engine->CurrentStep() : lf_Step(); @@ -101,6 +125,25 @@ std::pair Variable::DoMinMax(const size_t step) const minMax.first = {}; minMax.second = {}; + if (m_Engine != nullptr) + { + + Engine::MinMaxStruct MM; + if (m_Engine->VariableMinMax(*this, step, MM)) + { + if (false) + ; +#define declare_assign(T, N) \ + else if (#T == ToString(helper::GetDataType())) \ + { \ + minMax.first = MM.MinUnion.field_##N; \ + minMax.second = MM.MaxUnion.field_##N; \ + } + ADIOS2_FOREACH_MINMAX_STDTYPE_2ARGS(declare_assign) + + return minMax; + } + } if (m_Engine != nullptr && !m_FirstStreamingStep) { const size_t stepInput = diff --git a/source/adios2/engine/bp5/BP5Reader.cpp b/source/adios2/engine/bp5/BP5Reader.cpp index cccebf7b01..857a61b76e 100644 --- a/source/adios2/engine/bp5/BP5Reader.cpp +++ b/source/adios2/engine/bp5/BP5Reader.cpp @@ -427,6 +427,12 @@ Engine::MinVarInfo *BP5Reader::MinBlocksInfo(const VariableBase &Var, return m_BP5Deserializer->MinBlocksInfo(Var, Step); } +bool BP5Reader::VariableMinMax(const VariableBase &Var, const size_t Step, + Engine::MinMaxStruct &MinMax) +{ + return m_BP5Deserializer->VariableMinMax(Var, Step, MinMax); +} + void BP5Reader::InitTransports() { if (m_IO.m_TransportsParameters.empty()) diff --git a/source/adios2/engine/bp5/BP5Reader.h b/source/adios2/engine/bp5/BP5Reader.h index 7de7f8bb71..f4f5e14c59 100644 --- a/source/adios2/engine/bp5/BP5Reader.h +++ b/source/adios2/engine/bp5/BP5Reader.h @@ -54,6 +54,8 @@ class BP5Reader : public BP5Engine, public Engine void PerformGets() final; MinVarInfo *MinBlocksInfo(const VariableBase &, const size_t Step) const; + bool VariableMinMax(const VariableBase &, const size_t Step, + MinMaxStruct &MinMax); private: format::BP5Deserializer *m_BP5Deserializer = nullptr; diff --git a/source/adios2/toolkit/format/bp5/BP5Deserializer.cpp b/source/adios2/toolkit/format/bp5/BP5Deserializer.cpp index 027acc8008..efe278396d 100644 --- a/source/adios2/toolkit/format/bp5/BP5Deserializer.cpp +++ b/source/adios2/toolkit/format/bp5/BP5Deserializer.cpp @@ -14,6 +14,7 @@ #include "BP5Deserializer.h" #include "BP5Deserializer.tcc" +#include #include #include #include @@ -141,7 +142,8 @@ void BP5Deserializer::BreakdownVarName(const char *Name, char **base_name_p, int Type; int ElementSize; const char *NameStart = strchr(strchr(Name, '_') + 1, '_') + 1; - sscanf(Name, "SST%d_%d_", &ElementSize, &Type); + // + 3 to skip BP5 or bp5 prefix + sscanf(Name + 3, "%d_%d_", &ElementSize, &Type); *element_size_p = ElementSize; *type_p = (DataType)Type; *base_name_p = strdup(NameStart); @@ -153,7 +155,8 @@ void BP5Deserializer::BreakdownArrayName(const char *Name, char **base_name_p, int Type; int ElementSize; const char *NameStart = strchr(strchr(Name, '_') + 1, '_') + 1; - sscanf(Name, "SST%d_%d_", &ElementSize, &Type); + // + 3 to skip BP5 or bp5 prefix + sscanf(Name + 3, "%d_%d_", &ElementSize, &Type); *element_size_p = ElementSize; *type_p = (DataType)Type; *base_name_p = strdup(NameStart); @@ -209,6 +212,25 @@ BP5Deserializer::ControlInfo *BP5Deserializer::BuildControl(FMFormat Format) ControlCount++; C->FieldOffset = FieldList[i].field_offset; + C->OrigShapeID = ShapeID::Unknown; + switch (FieldList[i].field_name[2]) + { + case 'g': + C->OrigShapeID = ShapeID::GlobalValue; + break; + case 'G': + C->OrigShapeID = ShapeID::GlobalArray; + break; + case 'J': + C->OrigShapeID = ShapeID::JoinedArray; + break; + case 'l': + C->OrigShapeID = ShapeID::LocalValue; + break; + case 'L': + C->OrigShapeID = ShapeID::LocalArray; + break; + } BP5VarRec *VarRec = nullptr; if (NameIndicatesArray(FieldList[i].field_name)) @@ -216,7 +238,6 @@ BP5Deserializer::ControlInfo *BP5Deserializer::BuildControl(FMFormat Format) char *ArrayName; DataType Type; int ElementSize; - C->IsArray = 1; BreakdownArrayName(FieldList[i].field_name, &ArrayName, &Type, &ElementSize); VarRec = LookupVarByName(ArrayName); @@ -225,6 +246,7 @@ BP5Deserializer::ControlInfo *BP5Deserializer::BuildControl(FMFormat Format) VarRec = CreateVarRec(ArrayName); VarRec->Type = Type; VarRec->ElementSize = ElementSize; + VarRec->OrigShapeID = C->OrigShapeID; C->ElementSize = ElementSize; } i += 7; // number of fields in MetaArrayRec @@ -234,8 +256,7 @@ BP5Deserializer::ControlInfo *BP5Deserializer::BuildControl(FMFormat Format) else { /* simple field */ - char *FieldName = strdup(FieldList[i].field_name + 4); // skip SST_ - C->IsArray = 0; + char *FieldName = strdup(FieldList[i].field_name + 4); // skip BP5_ VarRec = LookupVarByName(FieldName); if (!VarRec) { @@ -244,6 +265,7 @@ BP5Deserializer::ControlInfo *BP5Deserializer::BuildControl(FMFormat Format) VarRec = CreateVarRec(FieldName); VarRec->DimCount = 0; C->Type = Type; + VarRec->OrigShapeID = C->OrigShapeID; VarRec->Type = Type; } VarRec->ElementSize = FieldList[i].field_size; @@ -335,9 +357,14 @@ void *BP5Deserializer::ArrayVarSetup(core::Engine *engine, #define declare_type(T) \ else if (Type == helper::GetDataType()) \ { \ - core::Variable *variable = &(engine->m_IO.DefineVariable( \ - variableName, VecShape, VecStart, VecCount)); \ + core::Variable *variable = \ + &(engine->m_IO.DefineVariable(variableName)); \ + variable->m_Shape = VecShape; \ + variable->m_Start = VecStart; \ + variable->m_Count = VecCount; \ variable->m_AvailableStepsCount = 1; \ + variable->m_ShapeID = ShapeID::GlobalArray; \ + variable->m_SingleValue = false; \ return (void *)variable; \ } ADIOS2_FOREACH_STDTYPE_1ARG(declare_type) @@ -454,7 +481,8 @@ void BP5Deserializer::InstallMetaData(void *MetadataBlock, size_t BlockLen, } if (!m_RandomAccessMode) VarRec->PerWriterMetaFieldOffset[WriterRank] = FieldOffset; - if (ControlFields[i].IsArray) + if ((ControlFields[i].OrigShapeID == ShapeID::GlobalArray) || + (ControlFields[i].OrigShapeID == ShapeID::LocalArray)) { MetaArrayRec *meta_base = (MetaArrayRec *)field_data; if ((meta_base->Dims > 1) && @@ -480,6 +508,11 @@ void BP5Deserializer::InstallMetaData(void *MetadataBlock, size_t BlockLen, m_Engine; VarByKey[VarRec->Variable] = VarRec; VarRec->LastTSAdded = Step; // starts at 1 + if (!meta_base->Shape) + { + static_cast(VarRec->Variable)->m_ShapeID = + ShapeID::LocalArray; + } } VarRec->DimCount = meta_base->Dims; @@ -520,8 +553,28 @@ void BP5Deserializer::InstallMetaData(void *MetadataBlock, size_t BlockLen, { if (!VarRec->Variable) { - VarRec->Variable = VarSetup(m_Engine, VarRec->VarName, - VarRec->Type, field_data); + if (ControlFields[i].OrigShapeID == ShapeID::LocalValue) + { + // Local single values show up as global arrays on the + // reader + size_t zero = 0; + size_t writerSize = m_WriterCohortSize; + VarRec->Variable = + ArrayVarSetup(m_Engine, VarRec->VarName, VarRec->Type, + 1, &writerSize, &zero, &writerSize); + auto VB = static_cast(VarRec->Variable); + static_cast(VarRec->Variable)->m_Engine = + m_Engine; + VB->m_ShapeID = ShapeID::GlobalArray; + } + else + { + // Global single value + VarRec->Variable = VarSetup(m_Engine, VarRec->VarName, + VarRec->Type, field_data); + static_cast(VarRec->Variable)->m_Engine = + m_Engine; + } VarByKey[VarRec->Variable] = VarRec; VarRec->LastTSAdded = Step; // starts at 1 } @@ -532,6 +585,10 @@ void BP5Deserializer::InstallMetaData(void *MetadataBlock, size_t BlockLen, ->m_AvailableStepsCount++; VarRec->LastTSAdded = Step; } + if (VarRec->FirstTSSeen == SIZE_MAX) + { + VarRec->FirstTSSeen = Step; + } } } @@ -635,7 +692,7 @@ void BP5Deserializer::InstallAttributeData(void *AttributeBlock, size_t ElemCount = *(size_t *)field_data; field_data = (void *)((char *)field_data + sizeof(size_t)); i++; - char *FieldName = strdup(FieldList[i].field_name + 4); // skip SST_ + char *FieldName = strdup(FieldList[i].field_name + 4); // skip BP5_ char *FieldType = strdup(FieldList[i].field_type); *index(FieldType, '[') = 0; Type = (DataType)TranslateFFSType2ADIOS(FieldType, @@ -709,48 +766,72 @@ bool BP5Deserializer::QueueGet(core::VariableBase &variable, void *DestData) } } +void BP5Deserializer::GetSingleValueFromMetadata(core::VariableBase &variable, + BP5VarRec *VarRec, + void *DestData, size_t Step, + size_t WriterRank) +{ + char *src; + if (m_RandomAccessMode) + { + ControlInfo *CI = + m_ControlArray[Step][WriterRank]; // writer 0 control array + size_t MetadataFieldOffset = (*CI->MetaFieldOffset)[VarRec->VarNum]; + char *MetadataBase = (char *)((*MetadataBaseArray[Step])[WriterRank]); + src = MetadataBase + MetadataFieldOffset; + } + else + { + src = ((char *)(*m_MetadataBaseAddrs)[WriterRank]) + + VarRec->PerWriterMetaFieldOffset[WriterRank]; + } + if (variable.m_SelectionType == adios2::SelectionType::WriteBlock) + WriterRank = variable.m_BlockID; + + if (variable.m_Type != DataType::String) + { + memcpy(DestData, src, variable.m_ElementSize); + } + else + { + std::string *TmpStr = static_cast(DestData); + TmpStr->assign(*(const char **)src); + } +} + bool BP5Deserializer::QueueGetSingle(core::VariableBase &variable, void *DestData, size_t Step) { - if (variable.m_SingleValue) + BP5VarRec *VarRec = VarByKey[&variable]; + if (VarRec->OrigShapeID == ShapeID::GlobalValue) { - char *src; - BP5VarRec *VarRec = VarByKey[&variable]; int WriterRank = 0; - if (m_RandomAccessMode) - { - ControlInfo *CI = - m_ControlArray[Step][WriterRank]; // writer 0 control array - size_t MetadataFieldOffset = (*CI->MetaFieldOffset)[VarRec->VarNum]; - char *MetadataBase = - (char *)((*MetadataBaseArray[Step])[WriterRank]); - src = MetadataBase + MetadataFieldOffset; - } - else - { - src = ((char *)(*m_MetadataBaseAddrs)[WriterRank]) + - VarRec->PerWriterMetaFieldOffset[WriterRank]; - } - if (variable.m_SelectionType == adios2::SelectionType::WriteBlock) - WriterRank = variable.m_BlockID; - - if (variable.m_Type != DataType::String) - { - std::cout << "Performing get for var " << variable.m_Name << " TS " - << Step << " Mdatabase " << (void *)src << std::endl; - memcpy(DestData, src, variable.m_ElementSize); - } - else + GetSingleValueFromMetadata(variable, VarRec, DestData, Step, + WriterRank); + return false; + } + if (VarRec->OrigShapeID == ShapeID::LocalValue) + { + // Shows up as global array with one element per writer rank + DestData = (char *)DestData + variable.m_Start[0] * VarRec->ElementSize; + for (size_t WriterRank = variable.m_Start[0]; + WriterRank < variable.m_Count[0] + variable.m_Start[0]; + WriterRank++) { - std::string *TmpStr = static_cast(DestData); - TmpStr->assign(*(const char **)src); + GetSingleValueFromMetadata(variable, VarRec, DestData, Step, + WriterRank); + DestData = (char *)DestData + + variable.m_ElementSize; // use variable.m_ElementSize + // because it's the size in local + // memory, VarRec->ElementSize is + // the size in metadata } return false; } if (variable.m_SelectionType == adios2::SelectionType::BoundingBox) { BP5ArrayRequest Req; - Req.VarRec = VarByKey[&variable]; + Req.VarRec = VarRec; Req.RequestType = Global; Req.BlockID = variable.m_BlockID; Req.Count = variable.m_Count; @@ -776,7 +857,8 @@ bool BP5Deserializer::QueueGetSingle(core::VariableBase &variable, return true; } -bool BP5Deserializer::NeedWriter(BP5ArrayRequest Req, size_t WriterRank) +bool BP5Deserializer::NeedWriter(BP5ArrayRequest Req, size_t WriterRank, + size_t &NodeFirst) { MetaArrayRec *writer_meta_base; if (m_RandomAccessMode) @@ -802,7 +884,33 @@ bool BP5Deserializer::NeedWriter(BP5ArrayRequest Req, size_t WriterRank) writer_meta_base->Dims ? writer_meta_base->DBCount / writer_meta_base->Dims : 1; - size_t NodeFirst = Req.VarRec->PerWriterBlockStart[WriterRank]; + if (m_RandomAccessMode) + { + // Not ideal, but we don't keep this around for every var in random + // access mode, so calc from scratch + NodeFirst = 0; + for (size_t TmpRank = 0; TmpRank < WriterRank; TmpRank++) + { + ControlInfo *TmpCI = + m_ControlArray[Req.Step][TmpRank]; // writer control array + + size_t MetadataFieldOffset = + (*TmpCI->MetaFieldOffset)[Req.VarRec->VarNum]; + MetaArrayRec *tmp_meta_base = + (MetaArrayRec + *)(((char *)(*MetadataBaseArray[Req.Step])[TmpRank]) + + MetadataFieldOffset); + size_t TmpBlockCount = + tmp_meta_base->Dims + ? tmp_meta_base->DBCount / tmp_meta_base->Dims + : 1; + NodeFirst += TmpBlockCount; + } + } + else + { + NodeFirst = Req.VarRec->PerWriterBlockStart[WriterRank]; + } size_t NodeLast = WriterBlockCount + NodeFirst - 1; bool res = (NodeFirst <= Req.BlockID) && (NodeLast >= Req.BlockID); return res; @@ -888,7 +996,8 @@ void BP5Deserializer::FinalizeGets(std::vector Requests) for (size_t WriterRank = 0; WriterRank < m_WriterCohortSize; WriterRank++) { - if (NeedWriter(Req, WriterRank)) + size_t NodeFirst = 0; + if (NeedWriter(Req, WriterRank, NodeFirst)) { /* if needed this writer fill destination with acquired data */ int ElementSize = Req.VarRec->ElementSize; @@ -945,9 +1054,7 @@ void BP5Deserializer::FinalizeGets(std::vector Requests) } if (Req.RequestType == Local) { - int LocalBlockID = - Req.BlockID - - Req.VarRec->PerWriterBlockStart[WriterRank]; + int LocalBlockID = Req.BlockID - NodeFirst; IncomingData = (char *)Requests[ReqIndex].DestinationAddr + writer_meta_base->DataLocation[LocalBlockID]; @@ -1261,26 +1368,38 @@ BP5Deserializer::~BP5Deserializer() } Engine::MinVarInfo *BP5Deserializer::MinBlocksInfo(const VariableBase &Var, - const size_t Step) + size_t Step) { BP5VarRec *VarRec = LookupVarByKey((void *)&Var); - MetaArrayRec *meta_base = - (MetaArrayRec *)(((char *)(*m_MetadataBaseAddrs)[0]) + - VarRec->PerWriterMetaFieldOffset[0]); + Engine::MinVarInfo *MV = - new Engine::MinVarInfo(meta_base->Dims, meta_base->Shape); + new Engine::MinVarInfo(VarRec->DimCount, VarRec->GlobalDims); - MV->Dims = meta_base->Dims; - MV->Shape = meta_base->Shape; + MV->Dims = VarRec->DimCount; + MV->Shape = VarRec->GlobalDims; MV->IsReverseDims = - ((meta_base->Dims > 1) && (m_WriterIsRowMajor != m_ReaderIsRowMajor)); + ((MV->Dims > 1) && (m_WriterIsRowMajor != m_ReaderIsRowMajor)); int Id = 0; for (size_t WriterRank = 0; WriterRank < m_WriterCohortSize; WriterRank++) { - MetaArrayRec *writer_meta_base = - (MetaArrayRec *)(((char *)(*m_MetadataBaseAddrs)[WriterRank]) + - VarRec->PerWriterMetaFieldOffset[WriterRank]); + MetaArrayRec *writer_meta_base; + if (m_RandomAccessMode) + { + ControlInfo *CI = + m_ControlArray[Step][WriterRank]; // writer 0 control array + size_t MetadataFieldOffset = (*CI->MetaFieldOffset)[VarRec->VarNum]; + writer_meta_base = + (MetaArrayRec + *)(((char *)(*MetadataBaseArray[Step])[WriterRank]) + + MetadataFieldOffset); + } + else + { + writer_meta_base = + (MetaArrayRec *)(((char *)(*m_MetadataBaseAddrs)[WriterRank]) + + VarRec->PerWriterMetaFieldOffset[WriterRank]); + } size_t WriterBlockCount = writer_meta_base->Dims ? writer_meta_base->DBCount / writer_meta_base->Dims @@ -1292,20 +1411,33 @@ Engine::MinVarInfo *BP5Deserializer::MinBlocksInfo(const VariableBase &Var, Id = 0; for (size_t WriterRank = 0; WriterRank < m_WriterCohortSize; WriterRank++) { - MetaArrayRec *writer_meta_base = - (MetaArrayRec *)(((char *)(*m_MetadataBaseAddrs)[WriterRank]) + - VarRec->PerWriterMetaFieldOffset[WriterRank]); - + MetaArrayRec *writer_meta_base; + if (m_RandomAccessMode) + { + ControlInfo *CI = + m_ControlArray[Step][WriterRank]; // writer 0 control array + size_t MetadataFieldOffset = (*CI->MetaFieldOffset)[VarRec->VarNum]; + writer_meta_base = + (MetaArrayRec + *)(((char *)(*MetadataBaseArray[Step])[WriterRank]) + + MetadataFieldOffset); + } + else + { + writer_meta_base = + (MetaArrayRec *)(((char *)(*m_MetadataBaseAddrs)[WriterRank]) + + VarRec->PerWriterMetaFieldOffset[WriterRank]); + } size_t WriterBlockCount = - meta_base->Dims ? meta_base->DBCount / meta_base->Dims : 1; + MV->Dims ? writer_meta_base->DBCount / MV->Dims : 1; for (size_t i = 0; i < WriterBlockCount; i++) { size_t *Offsets = NULL; size_t *Count = NULL; if (writer_meta_base->Offsets) - Offsets = writer_meta_base->Offsets + (i * meta_base->Dims); + Offsets = writer_meta_base->Offsets + (i * MV->Dims); if (writer_meta_base->Count) - Count = writer_meta_base->Count + (i * meta_base->Dims); + Count = writer_meta_base->Count + (i * MV->Dims); Engine::MinBlockInfo Blk; Blk.WriterID = WriterRank; Blk.BlockID = Id++; @@ -1320,5 +1452,247 @@ Engine::MinVarInfo *BP5Deserializer::MinBlocksInfo(const VariableBase &Var, return MV; } +void InitMinMax(Engine::MinMaxStruct &MinMax, DataType Type) +{ + switch (Type) + { + case DataType::None: + break; + case DataType::Char: + MinMax.MinUnion.field_char = SCHAR_MAX; + MinMax.MaxUnion.field_char = SCHAR_MIN; + break; + case DataType::Int8: + MinMax.MinUnion.field_int8 = INT8_MAX; + MinMax.MaxUnion.field_int8 = INT8_MIN; + break; + case DataType::Int16: + MinMax.MinUnion.field_int16 = INT16_MAX; + MinMax.MaxUnion.field_int16 = INT16_MIN; + break; + case DataType::Int32: + MinMax.MinUnion.field_int32 = INT32_MAX; + MinMax.MaxUnion.field_int32 = INT32_MIN; + break; + case DataType::Int64: + MinMax.MinUnion.field_int64 = INT64_MAX; + MinMax.MaxUnion.field_int64 = INT64_MIN; + break; + case DataType::UInt8: + MinMax.MinUnion.field_uint8 = UINT8_MAX; + MinMax.MaxUnion.field_uint8 = 0; + break; + case DataType::UInt16: + MinMax.MinUnion.field_uint16 = UINT16_MAX; + MinMax.MaxUnion.field_uint16 = 0; + break; + case DataType::UInt32: + MinMax.MinUnion.field_uint32 = UINT32_MAX; + MinMax.MaxUnion.field_uint32 = 0; + break; + case DataType::UInt64: + MinMax.MinUnion.field_uint64 = UINT64_MAX; + MinMax.MaxUnion.field_uint64 = 0; + break; + case DataType::Float: + MinMax.MinUnion.field_float = FLT_MAX; + MinMax.MaxUnion.field_float = -FLT_MAX; + break; + case DataType::Double: + MinMax.MinUnion.field_double = DBL_MAX; + MinMax.MaxUnion.field_double = -DBL_MAX; + case DataType::LongDouble: + MinMax.MinUnion.field_ldouble = LDBL_MAX; + MinMax.MaxUnion.field_ldouble = -LDBL_MAX; + break; + case DataType::FloatComplex: + case DataType::DoubleComplex: + case DataType::String: + case DataType::Compound: + break; + } +} + +void ApplyElementMinMax(Engine::MinMaxStruct &MinMax, DataType Type, + void *Element) +{ + switch (Type) + { + case DataType::None: + break; + case DataType::Char: + if (*(char *)Element < MinMax.MinUnion.field_char) + MinMax.MinUnion.field_char = *(char *)Element; + if (*(char *)Element > MinMax.MaxUnion.field_char) + MinMax.MaxUnion.field_char = *(char *)Element; + break; + case DataType::Int8: + if (*(int8_t *)Element < MinMax.MinUnion.field_int8) + MinMax.MinUnion.field_int8 = *(int8_t *)Element; + if (*(int8_t *)Element > MinMax.MaxUnion.field_int8) + MinMax.MaxUnion.field_int8 = *(int8_t *)Element; + break; + case DataType::Int16: + if (*(int16_t *)Element < MinMax.MinUnion.field_int16) + MinMax.MinUnion.field_int16 = *(int16_t *)Element; + if (*(int16_t *)Element > MinMax.MaxUnion.field_int16) + MinMax.MaxUnion.field_int16 = *(int16_t *)Element; + break; + case DataType::Int32: + if (*(int32_t *)Element < MinMax.MinUnion.field_int32) + MinMax.MinUnion.field_int32 = *(int32_t *)Element; + if (*(int32_t *)Element > MinMax.MaxUnion.field_int32) + MinMax.MaxUnion.field_int32 = *(int32_t *)Element; + break; + case DataType::Int64: + if (*(int64_t *)Element < MinMax.MinUnion.field_int64) + MinMax.MinUnion.field_int64 = *(int64_t *)Element; + if (*(int64_t *)Element > MinMax.MaxUnion.field_int64) + MinMax.MaxUnion.field_int64 = *(int64_t *)Element; + break; + case DataType::UInt8: + if (*(uint8_t *)Element < MinMax.MinUnion.field_uint8) + MinMax.MinUnion.field_uint8 = *(uint8_t *)Element; + if (*(uint8_t *)Element > MinMax.MaxUnion.field_uint8) + MinMax.MaxUnion.field_uint8 = *(uint8_t *)Element; + break; + case DataType::UInt16: + if (*(uint16_t *)Element < MinMax.MinUnion.field_uint16) + MinMax.MinUnion.field_uint16 = *(uint16_t *)Element; + if (*(uint16_t *)Element > MinMax.MaxUnion.field_uint16) + MinMax.MaxUnion.field_uint16 = *(uint16_t *)Element; + break; + case DataType::UInt32: + if (*(uint32_t *)Element < MinMax.MinUnion.field_uint32) + MinMax.MinUnion.field_uint32 = *(uint32_t *)Element; + if (*(uint32_t *)Element > MinMax.MaxUnion.field_uint32) + MinMax.MaxUnion.field_uint32 = *(uint32_t *)Element; + break; + case DataType::UInt64: + if (*(uint64_t *)Element < MinMax.MinUnion.field_uint64) + MinMax.MinUnion.field_uint64 = *(uint64_t *)Element; + if (*(uint64_t *)Element > MinMax.MaxUnion.field_uint64) + MinMax.MaxUnion.field_uint64 = *(uint64_t *)Element; + break; + case DataType::Float: + if (*(float *)Element < MinMax.MinUnion.field_float) + MinMax.MinUnion.field_float = *(float *)Element; + if (*(float *)Element > MinMax.MaxUnion.field_float) + MinMax.MaxUnion.field_float = *(float *)Element; + break; + case DataType::Double: + if (*(double *)Element < MinMax.MinUnion.field_double) + MinMax.MinUnion.field_double = *(double *)Element; + if (*(double *)Element > MinMax.MaxUnion.field_double) + MinMax.MaxUnion.field_double = *(double *)Element; + break; + case DataType::LongDouble: + if (*(long double *)Element < MinMax.MinUnion.field_ldouble) + MinMax.MinUnion.field_ldouble = *(long double *)Element; + if (*(long double *)Element > MinMax.MaxUnion.field_ldouble) + MinMax.MaxUnion.field_ldouble = *(long double *)Element; + break; + case DataType::FloatComplex: + case DataType::DoubleComplex: + case DataType::String: + case DataType::Compound: + break; + } +} + +size_t BP5Deserializer::RelativeToAbsoluteStep(const BP5VarRec *VarRec, + size_t RelStep) +{ + // Consider an optimization here. Track the number of timesteps + // available to the engine and the number of steps upon which a + // variable appears. If the first step it appears on plus the + // number of steps it appears adds up to the number of steps + // available to the engine, then there are no gaps and we can + // easily calculate the RelativeToAbsoluteStep transformation + // without checking. That's probably the most common case. + // But for now, the simple stupid solution + size_t AbsStep = VarRec->FirstTSSeen; + while (RelStep != 0) + { + int WriterRank = 0; + while (WriterRank < m_WriterCohortSize) + { + FFSMetadataInfoStruct *BaseData; + BaseData = (FFSMetadataInfoStruct + *)(*MetadataBaseArray[AbsStep])[WriterRank]; + if (FFSBitfieldTest((FFSMetadataInfoStruct *)BaseData, + VarRec->VarNum)) + { + // variable appeared on this step + RelStep--; + break; // exit while (WriterRank < m_WriterCohortSize) + } + WriterRank++; + } + AbsStep++; + } + return AbsStep; +} + +bool BP5Deserializer::VariableMinMax(const VariableBase &Var, const size_t Step, + Engine::MinMaxStruct &MinMax) +{ + BP5VarRec *VarRec = LookupVarByKey((void *)&Var); + InitMinMax(MinMax, VarRec->Type); + + size_t StartStep = Step, StopStep = Step + 1; + if (Step == DefaultSizeT) + { + StartStep = 0; + StopStep = m_ControlArray.size(); + if (!m_RandomAccessMode) + StopStep = 1; + } + for (size_t RelStep = StartStep; RelStep < StopStep; RelStep++) + { + if ((VarRec->OrigShapeID == ShapeID::LocalValue) || + (VarRec->OrigShapeID == ShapeID::GlobalValue)) + { + for (size_t WriterRank = 0; WriterRank < m_WriterCohortSize; + WriterRank++) + { + void *writer_meta_base; + FFSMetadataInfoStruct *BaseData; + if (m_RandomAccessMode) + { + size_t AbsStep = RelativeToAbsoluteStep(VarRec, RelStep); + if (AbsStep >= m_ControlArray.size()) + return true; // done + ControlInfo *CI = + m_ControlArray[AbsStep] + [WriterRank]; // writer 0 control array + size_t MetadataFieldOffset = + (*CI->MetaFieldOffset)[VarRec->VarNum]; + BaseData = (FFSMetadataInfoStruct + *)(*MetadataBaseArray[AbsStep])[WriterRank]; + writer_meta_base = + (MetaArrayRec *)(((char *)(*MetadataBaseArray[AbsStep]) + [WriterRank]) + + MetadataFieldOffset); + } + else + { + BaseData = (FFSMetadataInfoStruct + *)(*m_MetadataBaseAddrs)[WriterRank]; + writer_meta_base = + (MetaArrayRec + *)(((char *)(*m_MetadataBaseAddrs)[WriterRank]) + + VarRec->PerWriterMetaFieldOffset[WriterRank]); + } + if (FFSBitfieldTest(BaseData, VarRec->VarNum)) + { + ApplyElementMinMax(MinMax, VarRec->Type, writer_meta_base); + } + } + } + } + return true; +} + } } diff --git a/source/adios2/toolkit/format/bp5/BP5Deserializer.h b/source/adios2/toolkit/format/bp5/BP5Deserializer.h index 495827620b..17200bf186 100644 --- a/source/adios2/toolkit/format/bp5/BP5Deserializer.h +++ b/source/adios2/toolkit/format/bp5/BP5Deserializer.h @@ -65,6 +65,8 @@ class BP5Deserializer : virtual public BP5Base Engine::MinVarInfo *AllStepsMinBlocksInfo(const VariableBase &var); Engine::MinVarInfo *MinBlocksInfo(const VariableBase &Var, const size_t Step); + bool VariableMinMax(const VariableBase &var, const size_t Step, + Engine::MinMaxStruct &MinMax); bool m_WriterIsRowMajor = 1; bool m_ReaderIsRowMajor = 1; @@ -78,10 +80,12 @@ class BP5Deserializer : virtual public BP5Base void *Variable = NULL; char *VarName = NULL; size_t DimCount = 0; + ShapeID OrigShapeID; DataType Type; int ElementSize = 0; size_t *GlobalDims = NULL; size_t LastTSAdded = SIZE_MAX; + size_t FirstTSSeen = SIZE_MAX; size_t LastShapeAdded = SIZE_MAX; std::vector PerWriterMetaFieldOffset; std::vector PerWriterBlockStart; @@ -91,7 +95,7 @@ class BP5Deserializer : virtual public BP5Base { int FieldOffset; BP5VarRec *VarRec; - int IsArray; + ShapeID OrigShapeID; DataType Type; int ElementSize; }; @@ -157,7 +161,11 @@ class BP5Deserializer : virtual public BP5Base size_t *Start, size_t *Count); void MapGlobalToLocalIndex(size_t Dims, const size_t *GlobalIndex, const size_t *LocalOffsets, size_t *LocalIndex); + size_t RelativeToAbsoluteStep(const BP5VarRec *VarRec, size_t RelStep); int FindOffset(size_t Dims, const size_t *Size, const size_t *Index); + void GetSingleValueFromMetadata(core::VariableBase &variable, + BP5VarRec *VarRec, void *DestData, + size_t Step, size_t WriterRank); void ExtractSelectionFromPartialRM(int ElementSize, size_t Dims, const size_t *GlobalDims, const size_t *PartialOffsets, @@ -190,7 +198,7 @@ class BP5Deserializer : virtual public BP5Base void *Data; }; std::vector PendingRequests; - bool NeedWriter(BP5ArrayRequest Req, size_t i); + bool NeedWriter(BP5ArrayRequest Req, size_t i, size_t &NodeFirst); size_t CurTimestep = 0; }; diff --git a/source/adios2/toolkit/format/bp5/BP5Serializer.cpp b/source/adios2/toolkit/format/bp5/BP5Serializer.cpp index 9659d07194..e0403fa28f 100644 --- a/source/adios2/toolkit/format/bp5/BP5Serializer.cpp +++ b/source/adios2/toolkit/format/bp5/BP5Serializer.cpp @@ -182,11 +182,41 @@ FMField dcomplex_field_list[] = { {"imag", "float", sizeof(double), FMOffset(dcomplex_struct *, imag_part)}, {NULL, NULL, 0, 0}}; -char *BP5Serializer::ConcatName(const char *base_name, const char *postfix) +const char *BP5Serializer::NamePrefix(ShapeID Shape) +{ + const char *Prefix = "BP5"; + switch (Shape) + { + case ShapeID::Unknown: + Prefix = "BPU"; + break; + case ShapeID::GlobalValue: + Prefix = "BPg"; + break; + case ShapeID::GlobalArray: + Prefix = "BPG"; + break; + case ShapeID::JoinedArray: + Prefix = "BPJ"; + break; + case ShapeID::LocalValue: + Prefix = "BPl"; + break; + case ShapeID::LocalArray: + Prefix = "BPL"; + break; + } + return Prefix; +} + +char *BP5Serializer::ConcatName(const char *base_name, const char *postfix, + ShapeID Shape) { - char *Ret = (char *)malloc(strlen("SST_") + strlen(base_name) + - strlen(postfix) + 1); - strcpy(Ret, "SST_"); + const char *Prefix = NamePrefix(Shape); + char *Ret = (char *)malloc(strlen(Prefix) + strlen(base_name) + + strlen(postfix) + 2); + strcpy(Ret, Prefix); + strcat(Ret, "_"); strcat(Ret, base_name); strcat(Ret, postfix); return Ret; @@ -195,9 +225,10 @@ char *BP5Serializer::ConcatName(const char *base_name, const char *postfix) char *BP5Serializer::BuildVarName(const char *base_name, const int type, const int element_size) { - int Len = strlen(base_name) + 2 + strlen("SST_") + 16; + const char *Prefix = NamePrefix(ShapeID::GlobalValue); + int Len = strlen(base_name) + 2 + strlen(Prefix) + 16; char *Ret = (char *)malloc(Len); - sprintf(Ret, "SST%d_%d_", element_size, type); + sprintf(Ret, "%s%d_%d_", Prefix, element_size, type); strcat(Ret, base_name); return Ret; } @@ -208,7 +239,7 @@ void BP5Serializer::BreakdownVarName(const char *Name, char **base_name_p, int Type; int ElementSize; const char *NameStart = strchr(strchr(Name, '_') + 1, '_') + 1; - sscanf(Name, "SST%d_%d_", &ElementSize, &Type); + sscanf(Name + 3, "%d_%d_", &ElementSize, &Type); *element_size_p = ElementSize; *type_p = Type; *base_name_p = strdup(NameStart); @@ -217,9 +248,10 @@ void BP5Serializer::BreakdownVarName(const char *Name, char **base_name_p, char *BP5Serializer::BuildArrayDimsName(const char *base_name, const int type, const int element_size) { - int Len = strlen(base_name) + 3 + strlen("SST_") + 16; + const char *Prefix = NamePrefix(ShapeID::GlobalArray); + int Len = strlen(base_name) + 3 + strlen(Prefix) + 16; char *Ret = (char *)malloc(Len); - sprintf(Ret, "SST%d_%d_", element_size, type); + sprintf(Ret, "%s%d_%d_", Prefix, element_size, type); strcat(Ret, base_name); strcat(Ret, "Dims"); return Ret; @@ -229,9 +261,10 @@ char *BP5Serializer::BuildArrayDBCountName(const char *base_name, const int type, const int element_size) { - int Len = strlen(base_name) + 3 + strlen("SST_") + 16; + const char *Prefix = NamePrefix(ShapeID::GlobalArray); + int Len = strlen(base_name) + 3 + strlen(Prefix) + 16; char *Ret = (char *)malloc(Len); - sprintf(Ret, "SST%d_%d_", element_size, type); + sprintf(Ret, "%s%d_%d_", Prefix, element_size, type); strcat(Ret, base_name); strcat(Ret, "DBCount"); return Ret; @@ -241,9 +274,10 @@ char *BP5Serializer::BuildArrayBlockCountName(const char *base_name, const int type, const int element_size) { - int Len = strlen(base_name) + 3 + strlen("SST_") + 24; + const char *Prefix = NamePrefix(ShapeID::GlobalArray); + int Len = strlen(base_name) + 3 + strlen(Prefix) + 24; char *Ret = (char *)malloc(Len); - sprintf(Ret, "SST%d_%d_", element_size, type); + sprintf(Ret, "%s%d_%d_", Prefix, element_size, type); strcat(Ret, base_name); strcat(Ret, "BlockCount"); return Ret; @@ -320,6 +354,7 @@ BP5Serializer::BP5WriterRec BP5Serializer::CreateWriterRec(void *Variable, const char *Name, DataType Type, size_t ElemSize, size_t DimCount) { + core::VariableBase *VB = static_cast(Variable); Info.RecList = (BP5WriterRec)realloc( Info.RecList, (Info.RecCount + 1) * sizeof(Info.RecList[0])); BP5WriterRec Rec = &Info.RecList[Info.RecCount]; @@ -332,7 +367,7 @@ BP5Serializer::CreateWriterRec(void *Variable, const char *Name, DataType Type, if (DimCount == 0) { // simple field, only add base value FMField to metadata - char *SstName = ConcatName(Name, ""); + char *SstName = ConcatName(Name, "", VB->m_ShapeID); AddField(&Info.MetaFields, &Info.MetaFieldCount, SstName, Type, ElemSize); free(SstName); diff --git a/source/adios2/toolkit/format/bp5/BP5Serializer.h b/source/adios2/toolkit/format/bp5/BP5Serializer.h index f8335a53fa..502d6a5f8a 100644 --- a/source/adios2/toolkit/format/bp5/BP5Serializer.h +++ b/source/adios2/toolkit/format/bp5/BP5Serializer.h @@ -110,6 +110,7 @@ class BP5Serializer : virtual public BP5Base { void *Key; int FieldID; + ShapeID Shape; size_t DataOffset; size_t MetaOffset; int DimCount; @@ -169,7 +170,9 @@ class BP5Serializer : virtual public BP5Base void AddVarArrayField(FMFieldList *FieldP, int *CountP, const char *Name, const DataType Type, int ElementSize, char *SizeField); - char *ConcatName(const char *base_name, const char *postfix); + char *ConcatName(const char *base_name, const char *postfix, + ShapeID Shape = ShapeID::Unknown); + const char *NamePrefix(ShapeID Shape); char *BuildVarName(const char *base_name, const int type, const int element_size); void BreakdownVarName(const char *Name, char **base_name_p, int *type_p, diff --git a/testing/adios2/engine/bp/CMakeLists.txt b/testing/adios2/engine/bp/CMakeLists.txt index 8b63a067f9..71ef82888d 100644 --- a/testing/adios2/engine/bp/CMakeLists.txt +++ b/testing/adios2/engine/bp/CMakeLists.txt @@ -51,7 +51,7 @@ bp_gtest_add_tests_helper(WriteReadVector MPI_ALLOW) bp3_bp4_gtest_add_tests_helper(WriteReadAttributesMultirank MPI_ALLOW) bp_gtest_add_tests_helper(LargeMetadata MPI_ALLOW) bp_gtest_add_tests_helper(WriteMemorySelectionRead MPI_ALLOW) -bp3_bp4_gtest_add_tests_helper(WriteReadLocalVariables MPI_ALLOW) +bp_gtest_add_tests_helper(WriteReadLocalVariables MPI_ALLOW) bp3_bp4_gtest_add_tests_helper(WriteReadLocalVariablesSel MPI_ALLOW) bp3_bp4_gtest_add_tests_helper(WriteReadLocalVariablesSelHighLevel MPI_ALLOW) bp_gtest_add_tests_helper(ChangingShape MPI_ALLOW) diff --git a/testing/adios2/engine/bp/TestBPWriteReadLocalVariables.cpp b/testing/adios2/engine/bp/TestBPWriteReadLocalVariables.cpp index b3d5865b30..eb50719715 100644 --- a/testing/adios2/engine/bp/TestBPWriteReadLocalVariables.cpp +++ b/testing/adios2/engine/bp/TestBPWriteReadLocalVariables.cpp @@ -199,7 +199,6 @@ TEST_F(BPWriteReadLocalVariables, ADIOS2BPWriteReadLocal1D) EXPECT_TRUE(var_StepsGlobalValue); EXPECT_EQ(var_StepsGlobalValue.ShapeID(), adios2::ShapeID::GlobalValue); - EXPECT_EQ(var_StepsGlobalValue.Steps(), NSteps); EXPECT_EQ(var_StepsGlobalValue.Shape().size(), 0); EXPECT_EQ(var_StepsGlobalValue.Min(), static_cast(currentStep)); @@ -213,7 +212,6 @@ TEST_F(BPWriteReadLocalVariables, ADIOS2BPWriteReadLocal1D) EXPECT_TRUE(var_StepsGlobalValueString); EXPECT_EQ(var_StepsGlobalValueString.ShapeID(), adios2::ShapeID::GlobalValue); - EXPECT_EQ(var_StepsGlobalValueString.Steps(), NSteps); EXPECT_EQ(var_StepsGlobalValueString.Shape().size(), 0); std::string stepsGlobalValueStringDataString; bpReader.Get(var_StepsGlobalValueString, @@ -225,7 +223,6 @@ TEST_F(BPWriteReadLocalVariables, ADIOS2BPWriteReadLocal1D) EXPECT_TRUE(var_RanksLocalValue); EXPECT_EQ(var_RanksLocalValue.ShapeID(), adios2::ShapeID::GlobalArray); - EXPECT_EQ(var_RanksLocalValue.Steps(), NSteps); EXPECT_EQ(var_RanksLocalValue.Shape().size(), 1); EXPECT_EQ(var_RanksLocalValue.Shape()[0], mpiSize); EXPECT_EQ(var_RanksLocalValue.Min(), 0); @@ -241,7 +238,6 @@ TEST_F(BPWriteReadLocalVariables, ADIOS2BPWriteReadLocal1D) EXPECT_TRUE(var_RanksLocalValueString); EXPECT_EQ(var_RanksLocalValueString.ShapeID(), adios2::ShapeID::GlobalArray); - EXPECT_EQ(var_RanksLocalValue.Steps(), NSteps); EXPECT_EQ(var_RanksLocalValue.Shape().size(), 1); EXPECT_EQ(var_RanksLocalValue.Shape()[0], mpiSize); std::vector rankLocalValueDataString; @@ -265,49 +261,41 @@ TEST_F(BPWriteReadLocalVariables, ADIOS2BPWriteReadLocal1D) EXPECT_TRUE(var_cr64); EXPECT_EQ(var_i8.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_i8.Steps(), NSteps); EXPECT_EQ(var_i8.Shape().size(), 0); EXPECT_EQ(var_i8.Start().size(), 0); EXPECT_EQ(var_i8.Count()[0], Nx); // EXPECT_EQ(var_i16.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_i16.Steps(), NSteps); EXPECT_EQ(var_i16.Shape().size(), 0); EXPECT_EQ(var_i16.Start().size(), 0); EXPECT_EQ(var_i16.Count()[0], Nx); // EXPECT_EQ(var_i32.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_i32.Steps(), NSteps); EXPECT_EQ(var_i32.Shape().size(), 0); EXPECT_EQ(var_i32.Start().size(), 0); EXPECT_EQ(var_i32.Count()[0], Nx); EXPECT_EQ(var_i64.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_i64.Steps(), NSteps); EXPECT_EQ(var_i64.Shape().size(), 0); EXPECT_EQ(var_i64.Start().size(), 0); EXPECT_EQ(var_i64.Count()[0], Nx); EXPECT_EQ(var_r32.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_r32.Steps(), NSteps); EXPECT_EQ(var_r32.Shape().size(), 0); EXPECT_EQ(var_r32.Start().size(), 0); EXPECT_EQ(var_r32.Count()[0], Nx); EXPECT_EQ(var_r64.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_r64.Steps(), NSteps); EXPECT_EQ(var_r64.Shape().size(), 0); EXPECT_EQ(var_r64.Start().size(), 0); EXPECT_EQ(var_r64.Count()[0], Nx); EXPECT_EQ(var_cr32.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_cr32.Steps(), NSteps); EXPECT_EQ(var_cr32.Shape().size(), 0); EXPECT_EQ(var_cr32.Start().size(), 0); EXPECT_EQ(var_cr32.Count()[0], Nx); EXPECT_EQ(var_cr64.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_cr64.Steps(), NSteps); EXPECT_EQ(var_cr64.Shape().size(), 0); EXPECT_EQ(var_cr64.Start().size(), 0); EXPECT_EQ(var_cr64.Count()[0], Nx); @@ -608,7 +596,6 @@ TEST_F(BPWriteReadLocalVariables, ADIOS2BPWriteReadLocal2D2x4) EXPECT_TRUE(var_StepsGlobalValue); EXPECT_EQ(var_StepsGlobalValue.ShapeID(), adios2::ShapeID::GlobalValue); - EXPECT_EQ(var_StepsGlobalValue.Steps(), NSteps); EXPECT_EQ(var_StepsGlobalValue.Shape().size(), 0); EXPECT_EQ(var_StepsGlobalValue.Min(), static_cast(currentStep)); @@ -622,7 +609,6 @@ TEST_F(BPWriteReadLocalVariables, ADIOS2BPWriteReadLocal2D2x4) EXPECT_TRUE(var_StepsGlobalValueString); EXPECT_EQ(var_StepsGlobalValueString.ShapeID(), adios2::ShapeID::GlobalValue); - EXPECT_EQ(var_StepsGlobalValueString.Steps(), NSteps); EXPECT_EQ(var_StepsGlobalValueString.Shape().size(), 0); std::string stepsGlobalValueStringDataString; bpReader.Get(var_StepsGlobalValueString, @@ -634,7 +620,6 @@ TEST_F(BPWriteReadLocalVariables, ADIOS2BPWriteReadLocal2D2x4) EXPECT_TRUE(var_RanksLocalValue); EXPECT_EQ(var_RanksLocalValue.ShapeID(), adios2::ShapeID::GlobalArray); - EXPECT_EQ(var_RanksLocalValue.Steps(), NSteps); EXPECT_EQ(var_RanksLocalValue.Shape()[0], mpiSize); EXPECT_EQ(var_RanksLocalValue.Min(), 0); EXPECT_EQ(var_RanksLocalValue.Max(), mpiSize - 1); @@ -649,7 +634,6 @@ TEST_F(BPWriteReadLocalVariables, ADIOS2BPWriteReadLocal2D2x4) EXPECT_TRUE(var_RanksLocalValueString); EXPECT_EQ(var_RanksLocalValueString.ShapeID(), adios2::ShapeID::GlobalArray); - EXPECT_EQ(var_RanksLocalValue.Steps(), NSteps); EXPECT_EQ(var_RanksLocalValue.Shape()[0], mpiSize); std::vector rankLocalValueDataString; bpReader.Get(var_RanksLocalValueString, rankLocalValueDataString, @@ -672,56 +656,48 @@ TEST_F(BPWriteReadLocalVariables, ADIOS2BPWriteReadLocal2D2x4) EXPECT_TRUE(var_cr64); EXPECT_EQ(var_i8.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_i8.Steps(), NSteps); EXPECT_EQ(var_i8.Shape().size(), 0); EXPECT_EQ(var_i8.Start().size(), 0); EXPECT_EQ(var_i8.Count()[0], Ny); EXPECT_EQ(var_i8.Count()[1], Nx); // EXPECT_EQ(var_i16.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_i16.Steps(), NSteps); EXPECT_EQ(var_i16.Shape().size(), 0); EXPECT_EQ(var_i16.Start().size(), 0); EXPECT_EQ(var_i16.Count()[0], Ny); EXPECT_EQ(var_i16.Count()[1], Nx); // EXPECT_EQ(var_i32.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_i32.Steps(), NSteps); EXPECT_EQ(var_i32.Shape().size(), 0); EXPECT_EQ(var_i32.Start().size(), 0); EXPECT_EQ(var_i32.Count()[0], Ny); EXPECT_EQ(var_i32.Count()[1], Nx); EXPECT_EQ(var_i64.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_i64.Steps(), NSteps); EXPECT_EQ(var_i64.Shape().size(), 0); EXPECT_EQ(var_i64.Start().size(), 0); EXPECT_EQ(var_i64.Count()[0], Ny); EXPECT_EQ(var_i64.Count()[1], Nx); EXPECT_EQ(var_r32.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_r32.Steps(), NSteps); EXPECT_EQ(var_r32.Shape().size(), 0); EXPECT_EQ(var_r32.Start().size(), 0); EXPECT_EQ(var_r32.Count()[0], Ny); EXPECT_EQ(var_r32.Count()[1], Nx); EXPECT_EQ(var_r64.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_r64.Steps(), NSteps); EXPECT_EQ(var_r64.Shape().size(), 0); EXPECT_EQ(var_r64.Start().size(), 0); EXPECT_EQ(var_r64.Count()[0], Ny); EXPECT_EQ(var_r64.Count()[1], Nx); EXPECT_EQ(var_cr32.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_cr32.Steps(), NSteps); EXPECT_EQ(var_cr32.Shape().size(), 0); EXPECT_EQ(var_cr32.Start().size(), 0); EXPECT_EQ(var_cr32.Count()[0], Ny); EXPECT_EQ(var_cr32.Count()[1], Nx); EXPECT_EQ(var_cr64.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_cr64.Steps(), NSteps); EXPECT_EQ(var_cr64.Shape().size(), 0); EXPECT_EQ(var_cr64.Start().size(), 0); EXPECT_EQ(var_cr64.Count()[0], Ny); @@ -1022,7 +998,6 @@ TEST_F(BPWriteReadLocalVariables, ADIOS2BPWriteReadLocal2D4x2) EXPECT_TRUE(var_StepsGlobalValue); EXPECT_EQ(var_StepsGlobalValue.ShapeID(), adios2::ShapeID::GlobalValue); - EXPECT_EQ(var_StepsGlobalValue.Steps(), NSteps); EXPECT_EQ(var_StepsGlobalValue.Shape().size(), 0); EXPECT_EQ(var_StepsGlobalValue.Min(), static_cast(currentStep)); @@ -1036,7 +1011,6 @@ TEST_F(BPWriteReadLocalVariables, ADIOS2BPWriteReadLocal2D4x2) EXPECT_TRUE(var_StepsGlobalValueString); EXPECT_EQ(var_StepsGlobalValueString.ShapeID(), adios2::ShapeID::GlobalValue); - EXPECT_EQ(var_StepsGlobalValueString.Steps(), NSteps); EXPECT_EQ(var_StepsGlobalValueString.Shape().size(), 0); std::string stepsGlobalValueStringDataString; bpReader.Get(var_StepsGlobalValueString, @@ -1048,7 +1022,6 @@ TEST_F(BPWriteReadLocalVariables, ADIOS2BPWriteReadLocal2D4x2) EXPECT_TRUE(var_RanksLocalValue); EXPECT_EQ(var_RanksLocalValue.ShapeID(), adios2::ShapeID::GlobalArray); - EXPECT_EQ(var_RanksLocalValue.Steps(), NSteps); EXPECT_EQ(var_RanksLocalValue.Shape().size(), 1); EXPECT_EQ(var_RanksLocalValue.Shape()[0], mpiSize); EXPECT_EQ(var_RanksLocalValue.Min(), 0); @@ -1064,7 +1037,6 @@ TEST_F(BPWriteReadLocalVariables, ADIOS2BPWriteReadLocal2D4x2) EXPECT_TRUE(var_RanksLocalValueString); EXPECT_EQ(var_RanksLocalValueString.ShapeID(), adios2::ShapeID::GlobalArray); - EXPECT_EQ(var_RanksLocalValue.Steps(), NSteps); EXPECT_EQ(var_RanksLocalValue.Shape().size(), 1); EXPECT_EQ(var_RanksLocalValue.Shape()[0], mpiSize); std::vector rankLocalValueDataString; @@ -1088,56 +1060,48 @@ TEST_F(BPWriteReadLocalVariables, ADIOS2BPWriteReadLocal2D4x2) EXPECT_TRUE(var_cr64); EXPECT_EQ(var_i8.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_i8.Steps(), NSteps); EXPECT_EQ(var_i8.Shape().size(), 0); EXPECT_EQ(var_i8.Start().size(), 0); EXPECT_EQ(var_i8.Count()[0], Ny); EXPECT_EQ(var_i8.Count()[1], Nx); // EXPECT_EQ(var_i16.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_i16.Steps(), NSteps); EXPECT_EQ(var_i16.Shape().size(), 0); EXPECT_EQ(var_i16.Start().size(), 0); EXPECT_EQ(var_i16.Count()[0], Ny); EXPECT_EQ(var_i16.Count()[1], Nx); // EXPECT_EQ(var_i32.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_i32.Steps(), NSteps); EXPECT_EQ(var_i32.Shape().size(), 0); EXPECT_EQ(var_i32.Start().size(), 0); EXPECT_EQ(var_i32.Count()[0], Ny); EXPECT_EQ(var_i32.Count()[1], Nx); EXPECT_EQ(var_i64.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_i64.Steps(), NSteps); EXPECT_EQ(var_i64.Shape().size(), 0); EXPECT_EQ(var_i64.Start().size(), 0); EXPECT_EQ(var_i64.Count()[0], Ny); EXPECT_EQ(var_i64.Count()[1], Nx); EXPECT_EQ(var_r32.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_r32.Steps(), NSteps); EXPECT_EQ(var_r32.Shape().size(), 0); EXPECT_EQ(var_r32.Start().size(), 0); EXPECT_EQ(var_r32.Count()[0], Ny); EXPECT_EQ(var_r32.Count()[1], Nx); EXPECT_EQ(var_r64.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_r64.Steps(), NSteps); EXPECT_EQ(var_r64.Shape().size(), 0); EXPECT_EQ(var_r64.Start().size(), 0); EXPECT_EQ(var_r64.Count()[0], Ny); EXPECT_EQ(var_r64.Count()[1], Nx); EXPECT_EQ(var_cr32.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_cr32.Steps(), NSteps); EXPECT_EQ(var_cr32.Shape().size(), 0); EXPECT_EQ(var_cr32.Start().size(), 0); EXPECT_EQ(var_cr32.Count()[0], Ny); EXPECT_EQ(var_cr32.Count()[1], Nx); EXPECT_EQ(var_cr64.ShapeID(), adios2::ShapeID::LocalArray); - EXPECT_EQ(var_cr64.Steps(), NSteps); EXPECT_EQ(var_cr64.Shape().size(), 0); EXPECT_EQ(var_cr64.Start().size(), 0); EXPECT_EQ(var_cr64.Count()[0], Ny); @@ -1391,7 +1355,8 @@ TEST_F(BPWriteReadLocalVariables, ADIOS2BPWriteReadLocal1DAllSteps) io.SetEngine(engineName); } - adios2::Engine bpReader = io.Open(fname, adios2::Mode::Read); + adios2::Engine bpReader = + io.Open(fname, adios2::Mode::ReadRandomAccess); std::vector I8; std::vector I16; From de815ed4e2efbad796e5810c283f84a0e2bad5b6 Mon Sep 17 00:00:00 2001 From: Greg Eisenhauer Date: Fri, 8 Oct 2021 09:51:17 -0400 Subject: [PATCH 2/4] warning --- source/adios2/toolkit/format/bp5/BP5Deserializer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/adios2/toolkit/format/bp5/BP5Deserializer.cpp b/source/adios2/toolkit/format/bp5/BP5Deserializer.cpp index efe278396d..238a1219d7 100644 --- a/source/adios2/toolkit/format/bp5/BP5Deserializer.cpp +++ b/source/adios2/toolkit/format/bp5/BP5Deserializer.cpp @@ -1380,7 +1380,7 @@ Engine::MinVarInfo *BP5Deserializer::MinBlocksInfo(const VariableBase &Var, MV->IsReverseDims = ((MV->Dims > 1) && (m_WriterIsRowMajor != m_ReaderIsRowMajor)); - int Id = 0; + size_t Id = 0; for (size_t WriterRank = 0; WriterRank < m_WriterCohortSize; WriterRank++) { MetaArrayRec *writer_meta_base; @@ -1614,7 +1614,7 @@ size_t BP5Deserializer::RelativeToAbsoluteStep(const BP5VarRec *VarRec, size_t AbsStep = VarRec->FirstTSSeen; while (RelStep != 0) { - int WriterRank = 0; + size_t WriterRank = 0; while (WriterRank < m_WriterCohortSize) { FFSMetadataInfoStruct *BaseData; From e980d2ead4519e20fe6eb0bf0071827cea4b8e24 Mon Sep 17 00:00:00 2001 From: Greg Eisenhauer Date: Fri, 8 Oct 2021 11:07:34 -0400 Subject: [PATCH 3/4] template/macro conflict --- source/adios2/core/Variable.tcc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/adios2/core/Variable.tcc b/source/adios2/core/Variable.tcc index 1fae3b9a5d..2b1c33ff16 100644 --- a/source/adios2/core/Variable.tcc +++ b/source/adios2/core/Variable.tcc @@ -133,8 +133,8 @@ std::pair Variable::DoMinMax(const size_t step) const { if (false) ; -#define declare_assign(T, N) \ - else if (#T == ToString(helper::GetDataType())) \ +#define declare_assign(F, N) \ + else if (#F == ToString(helper::GetDataType())) \ { \ minMax.first = MM.MinUnion.field_##N; \ minMax.second = MM.MaxUnion.field_##N; \ From 15afd8d7f0857a2ee26d815299aeb5f5a9f878ec Mon Sep 17 00:00:00 2001 From: Greg Eisenhauer Date: Fri, 8 Oct 2021 12:19:09 -0400 Subject: [PATCH 4/4] Different approach to get from union --- source/adios2/core/Engine.h | 7 +++++++ source/adios2/core/Variable.tcc | 12 ++---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/source/adios2/core/Engine.h b/source/adios2/core/Engine.h index 5df8e340fb..a1c14b0832 100644 --- a/source/adios2/core/Engine.h +++ b/source/adios2/core/Engine.h @@ -455,6 +455,13 @@ class Engine #define declare_field(T, N) T field_##N; ADIOS2_FOREACH_MINMAX_STDTYPE_2ARGS(declare_field) #undef declare_field +#define declare_get(T, N) \ + T Get(T def) { return field_##N; } + ADIOS2_FOREACH_MINMAX_STDTYPE_2ARGS(declare_get) +#undef declare_get + std::string Get(std::string def) { return def; } + std::complex Get(std::complex def) { return def; } + std::complex Get(std::complex def) { return def; } }; struct MinBlockInfo diff --git a/source/adios2/core/Variable.tcc b/source/adios2/core/Variable.tcc index 2b1c33ff16..64b341762f 100644 --- a/source/adios2/core/Variable.tcc +++ b/source/adios2/core/Variable.tcc @@ -131,16 +131,8 @@ std::pair Variable::DoMinMax(const size_t step) const Engine::MinMaxStruct MM; if (m_Engine->VariableMinMax(*this, step, MM)) { - if (false) - ; -#define declare_assign(F, N) \ - else if (#F == ToString(helper::GetDataType())) \ - { \ - minMax.first = MM.MinUnion.field_##N; \ - minMax.second = MM.MaxUnion.field_##N; \ - } - ADIOS2_FOREACH_MINMAX_STDTYPE_2ARGS(declare_assign) - + minMax.first = MM.MinUnion.Get(minMax.first); + minMax.second = MM.MaxUnion.Get(minMax.second); return minMax; } }