diff --git a/bindings/CXX11/adios2/cxx11/Engine.tcc b/bindings/CXX11/adios2/cxx11/Engine.tcc index fb68a13a6a..1c6f07ac78 100644 --- a/bindings/CXX11/adios2/cxx11/Engine.tcc +++ b/bindings/CXX11/adios2/cxx11/Engine.tcc @@ -59,6 +59,58 @@ ToBlocksInfo(const std::vector +static std::vector::Info> +ToBlocksInfo(const core::Engine::MinVarInfo *coreVarInfo) +{ + using IOType = typename TypeInfo::IOType; + + auto coreBlocksInfo = coreVarInfo->BlocksInfo; + + std::vector::Info> blocksInfo; + blocksInfo.reserve(coreBlocksInfo.size()); + + for (auto &coreBlockInfo : coreBlocksInfo) + { + typename Variable::Info blockInfo; + + if (coreVarInfo->Shape) + { + blockInfo.Start.reserve(coreVarInfo->Dims); + blockInfo.Count.reserve(coreVarInfo->Dims); + for (int i = 0; i < coreVarInfo->Dims; i++) + { + blockInfo.Start.push_back(coreBlockInfo.Start[i]); + blockInfo.Count.push_back(coreBlockInfo.Count[i]); + } + } + else + { + blockInfo.Count.reserve(coreVarInfo->Dims); + for (int i = 0; i < coreVarInfo->Dims; i++) + { + blockInfo.Count.push_back(coreBlockInfo.Count[i]); + } + } + blockInfo.WriterID = coreBlockInfo.WriterID; + + blockInfo.IsValue = coreVarInfo->IsValue; + blockInfo.IsReverseDims = coreVarInfo->IsReverseDims; + if (blockInfo.IsValue) + { + blockInfo.Value = *((T *)coreBlockInfo.BufferP); + } + else + { + blockInfo.Min = *((T *)&coreBlockInfo.MinUnion); + blockInfo.Max = *((T *)&coreBlockInfo.MaxUnion); + } + blockInfo.BlockID = coreBlockInfo.BlockID; + blocksInfo.push_back(blockInfo); + } + + return blocksInfo; +} } // end empty namespace template @@ -333,6 +385,14 @@ Engine::BlocksInfo(const Variable variable, const size_t step) const adios2::helper::CheckForNullptr( variable.m_Variable, "for variable in call to Engine::BlocksInfo"); + const auto minBlocksInfo = + m_Engine->MinBlocksInfo(*variable.m_Variable, step); + + if (minBlocksInfo) + { + return ToBlocksInfo(minBlocksInfo); + } + const auto blocksInfo = m_Engine->BlocksInfo(*variable.m_Variable, step); return ToBlocksInfo(blocksInfo); diff --git a/source/adios2/core/Engine.h b/source/adios2/core/Engine.h index 76aec1c3bb..b92a2a735e 100644 --- a/source/adios2/core/Engine.h +++ b/source/adios2/core/Engine.h @@ -450,6 +450,51 @@ class Engine /* for adios2 internal testing */ virtual size_t DebugGetDataBufferSize() const; + 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; + }; + + struct MinBlockInfo + { + int WriterID = 0; + size_t BlockID = 0; + size_t *Start; + size_t *Count; + union PrimitiveStdtypeUnion MinUnion; + union PrimitiveStdtypeUnion MaxUnion; + void *BufferP = NULL; + }; + struct MinVarInfo + { + int Dims; + size_t *Shape; + bool IsValue = false; + bool IsReverseDims = false; + std::vector BlocksInfo; + MinVarInfo(int D, size_t *S) + : Dims(D), Shape(S), IsValue(false), IsReverseDims(false), + BlocksInfo({}) + { + } + }; + + virtual MinVarInfo *MinBlocksInfo(const VariableBase &, + const size_t Step) const + { + return nullptr; + } + protected: /** from ADIOS class passed to Engine created with Open * if no communicator is passed */ diff --git a/source/adios2/core/Variable.h b/source/adios2/core/Variable.h index 25ebe3f87b..832d669eb7 100644 --- a/source/adios2/core/Variable.h +++ b/source/adios2/core/Variable.h @@ -159,6 +159,8 @@ class Variable : public VariableBase DoAllStepsBlocksInfo() const; void CheckRandomAccess(const size_t step, const std::string hint) const; + + size_t WriterIndex; }; } // end namespace core diff --git a/source/adios2/engine/sst/SstReader.cpp b/source/adios2/engine/sst/SstReader.cpp index 1aa964324b..7ec61f8778 100644 --- a/source/adios2/engine/sst/SstReader.cpp +++ b/source/adios2/engine/sst/SstReader.cpp @@ -120,42 +120,42 @@ SstReader::SstReader(IO &io, const std::string &name, const Mode mode, return; }; - auto arrayFFSCallback = [](void *reader, const char *variableName, - const int type, int DimCount, size_t *Shape, - size_t *Start, size_t *Count) { - std::vector VecShape; - std::vector VecStart; - std::vector VecCount; - adios2::DataType Type = (adios2::DataType)type; - class SstReader::SstReader *Reader = - reinterpret_cast(reader); - /* - * setup shape of array variable as global (I.E. Count == Shape, - * Start == 0) - */ - if (Shape) - { - for (int i = 0; i < DimCount; i++) + auto arrayFFSCallback = + [](void *reader, const char *variableName, const int type, int DimCount, + size_t *Shape, size_t *Start, size_t *Count, void **MinVarInfoP) { + std::vector VecShape; + std::vector VecStart; + std::vector VecCount; + adios2::DataType Type = (adios2::DataType)type; + class SstReader::SstReader *Reader = + reinterpret_cast(reader); + /* + * setup shape of array variable as global (I.E. Count == Shape, + * Start == 0) + */ + if (Shape) { - VecShape.push_back(Shape[i]); - VecStart.push_back(0); - VecCount.push_back(Shape[i]); + for (int i = 0; i < DimCount; i++) + { + VecShape.push_back(Shape[i]); + VecStart.push_back(0); + VecCount.push_back(Shape[i]); + } } - } - else - { - VecShape = {}; - VecStart = {}; - for (int i = 0; i < DimCount; i++) + else { - VecCount.push_back(Count[i]); + VecShape = {}; + VecStart = {}; + for (int i = 0; i < DimCount; i++) + { + VecCount.push_back(Count[i]); + } } - } - if (Type == adios2::DataType::Compound) - { - return (void *)NULL; - } + if (Type == adios2::DataType::Compound) + { + return (void *)NULL; + } #define declare_type(T) \ else if (Type == helper::GetDataType()) \ { \ @@ -164,10 +164,10 @@ SstReader::SstReader(IO &io, const std::string &name, const Mode mode, variable->m_AvailableStepsCount = 1; \ return (void *)variable; \ } - ADIOS2_FOREACH_STDTYPE_1ARG(declare_type) + ADIOS2_FOREACH_STDTYPE_1ARG(declare_type) #undef declare_type - return (void *)NULL; - }; + return (void *)NULL; + }; auto arrayBlocksInfoCallback = [](void *reader, void *variable, const int type, int WriterRank, @@ -179,6 +179,7 @@ SstReader::SstReader(IO &io, const std::string &name, const Mode mode, class SstReader::SstReader *Reader = reinterpret_cast(reader); size_t currentStep = SstCurrentStep(Reader->m_Input); + struct MinBlockInfo BI; /* * setup shape of array variable as global (I.E. Count == Shape, * Start == 0) @@ -226,8 +227,99 @@ SstReader::SstReader(IO &io, const std::string &name, const Mode mode, return; }; - SstReaderInitFFSCallback(m_Input, this, varFFSCallback, arrayFFSCallback, - attrFFSCallback, arrayBlocksInfoCallback); + auto arrayMinFFSCallback = + [](void *reader, const char *variableName, const int type, int DimCount, + size_t *Shape, size_t *Start, size_t *Count, void **MinVarInfoP) { + std::vector VecShape; + std::vector VecStart; + std::vector VecCount; + adios2::DataType Type = (adios2::DataType)type; + class SstReader::SstReader *Reader = + reinterpret_cast(reader); + struct MinVarInfo *MV = new MinVarInfo(DimCount, Shape); + /* + * setup shape of array variable as global (I.E. Count == Shape, + * Start == 0) + */ + if (Shape) + { + for (int i = 0; i < DimCount; i++) + { + VecShape.push_back(Shape[i]); + VecStart.push_back(0); + VecCount.push_back(Shape[i]); + } + } + else + { + VecShape = {}; + VecStart = {}; + for (int i = 0; i < DimCount; i++) + { + VecCount.push_back(Count[i]); + } + } + if (Type == adios2::DataType::Compound) + { + return (void *)NULL; + } +#define declare_type(T) \ + else if (Type == helper::GetDataType()) \ + { \ + Variable *variable = &(Reader->m_IO.DefineVariable( \ + variableName, VecShape, VecStart, VecCount)); \ + variable->m_AvailableStepsCount = 1; \ + Reader->m_InfoMap.emplace(variable, MV); \ + *MinVarInfoP = (void *)MV; \ + return (void *)variable; \ + } + ADIOS2_FOREACH_STDTYPE_1ARG(declare_type) +#undef declare_type + return (void *)NULL; + }; + + auto arrayMinBlocksInfoCallback = + [](void *reader, void *MV, const int type, int WriterRank, int DimCount, + size_t *Shape, size_t *Start, size_t *Count) { + std::vector VecShape; + std::vector VecStart; + std::vector VecCount; + adios2::DataType Type = (adios2::DataType)type; + struct MinBlockInfo MBI; + class SstReader::SstReader *Reader = + reinterpret_cast(reader); + size_t currentStep = SstCurrentStep(Reader->m_Input); + struct MinVarInfo *MinVar = (struct MinVarInfo *)MV; + + MBI.WriterID = WriterRank; + MBI.BlockID = 0; + MBI.Start = Start; + MBI.Count = Count; + + MinVar->BlocksInfo.push_back(MBI); + return; + }; + + static int UseMin = -1; + if (UseMin == -1) + { + if (getenv("MinBlocksInfo") == NULL) + { + UseMin = 0; + } + else + { + UseMin = 1; + } + } + if (UseMin) + SstReaderInitFFSCallback(m_Input, this, varFFSCallback, + arrayMinFFSCallback, attrFFSCallback, + arrayMinBlocksInfoCallback); + else + SstReaderInitFFSCallback(m_Input, this, varFFSCallback, + arrayFFSCallback, attrFFSCallback, + arrayBlocksInfoCallback); delete[] cstr; } @@ -397,6 +489,7 @@ void SstReader::EndStep() // unknown marshaling method, shouldn't happen } SstReleaseStep(m_Input); + m_InfoMap.clear(); } void SstReader::Flush(const int transportIndex) {} @@ -603,6 +696,16 @@ void SstReader::PerformGets() void SstReader::DoClose(const int transportIndex) { SstReaderClose(m_Input); } +Engine::MinVarInfo *SstReader::MinBlocksInfo(const VariableBase &Var, + const size_t Step) const +{ + auto it = m_InfoMap.find(&Var); + if (it == m_InfoMap.end()) + return nullptr; + else + return it->second; +} + #define declare_type(T) \ std::map::BPInfo>> \ SstReader::DoAllStepsBlocksInfo(const Variable &variable) const \ diff --git a/source/adios2/engine/sst/SstReader.h b/source/adios2/engine/sst/SstReader.h index 3931c6b963..d4dabc88d3 100644 --- a/source/adios2/engine/sst/SstReader.h +++ b/source/adios2/engine/sst/SstReader.h @@ -49,6 +49,7 @@ class SstReader : public Engine void EndStep(); void PerformGets(); void Flush(const int transportIndex = -1) final; + MinVarInfo *MinBlocksInfo(const VariableBase &, const size_t Step) const; private: template @@ -76,6 +77,7 @@ class SstReader : public Engine struct _SstParams Params; + std::unordered_map m_InfoMap; #define declare_type(T) \ void DoGetSync(Variable &, T *) final; \ void DoGetDeferred(Variable &, T *) final; \ diff --git a/source/adios2/toolkit/sst/cp/ffs_marshal.c b/source/adios2/toolkit/sst/cp/ffs_marshal.c index 56d2bd8477..9f2a212d1f 100644 --- a/source/adios2/toolkit/sst/cp/ffs_marshal.c +++ b/source/adios2/toolkit/sst/cp/ffs_marshal.c @@ -1988,10 +1988,11 @@ static void BuildVarList(SstStream Stream, TSMetadataMsg MetaData, } if (!VarRec->Variable) { + VarRec->MinVarInfo = NULL; VarRec->Variable = Stream->ArraySetupUpcall( Stream->SetupUpcallReader, VarRec->VarName, VarRec->Type, meta_base->Dims, meta_base->Shape, meta_base->Offsets, - meta_base->Count); + meta_base->Count, &VarRec->MinVarInfo); } VarRec->DimCount = meta_base->Dims; VarRec->PerWriterBlockCount[WriterRank] = @@ -2013,8 +2014,13 @@ static void BuildVarList(SstStream Stream, TSMetadataMsg MetaData, size_t *Offsets = NULL; if (meta_base->Offsets) Offsets = meta_base->Offsets + (i * meta_base->Dims); + void *Variable = VarRec->Variable; + if (VarRec->MinVarInfo) + { + Variable = VarRec->MinVarInfo; + } Stream->ArrayBlocksInfoUpcall( - Stream->SetupUpcallReader, VarRec->Variable, VarRec->Type, + Stream->SetupUpcallReader, Variable, VarRec->Type, WriterRank, meta_base->Dims, meta_base->Shape, Offsets, meta_base->Count); } diff --git a/source/adios2/toolkit/sst/cp/ffs_marshal.h b/source/adios2/toolkit/sst/cp/ffs_marshal.h index 9969480d46..317f640fb4 100644 --- a/source/adios2/toolkit/sst/cp/ffs_marshal.h +++ b/source/adios2/toolkit/sst/cp/ffs_marshal.h @@ -56,6 +56,7 @@ typedef struct FFSVarRec size_t DimCount; int Type; int ElementSize; + void *MinVarInfo; size_t *GlobalDims; size_t *PerWriterBlockStart; size_t *PerWriterBlockCount; diff --git a/source/adios2/toolkit/sst/sst.h b/source/adios2/toolkit/sst/sst.h index 6f4fb64562..e8e40081d5 100644 --- a/source/adios2/toolkit/sst/sst.h +++ b/source/adios2/toolkit/sst/sst.h @@ -123,7 +123,7 @@ typedef void (*AttrSetupUpcallFunc)(void *Reader, const char *Name, typedef void *(*ArraySetupUpcallFunc)(void *Reader, const char *Name, const int Type, int DimsCount, size_t *Shape, size_t *Start, - size_t *Count); + size_t *Count, void **MinVarInfoP); typedef void (*ArrayBlocksInfoUpcallFunc)(void *Reader, void *Variable, const int Type, int WriterRank, int DimsCount, size_t *Shape,