Skip to content

Commit

Permalink
new attempt to commit query support of local array. (ornladios#3868)
Browse files Browse the repository at this point in the history
  • Loading branch information
guj authored Oct 23, 2023
1 parent e53a1bf commit 2af5482
Show file tree
Hide file tree
Showing 14 changed files with 448 additions and 154 deletions.
8 changes: 7 additions & 1 deletion bindings/CXX11/adios2/cxx11/Query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ QueryWorker::QueryWorker(const std::string &configFile, adios2::Engine &reader)
delete m;
}

void QueryWorker::GetResultCoverage(std::vector<size_t> &touched_blockIDs)
{
m_Worker->GetResultCoverage(touched_blockIDs);
}

void QueryWorker::GetResultCoverage(std::vector<adios2::Box<adios2::Dims>> &touched_blocks)
{
adios2::Box<adios2::Dims> empty;
Expand All @@ -26,4 +31,5 @@ void QueryWorker::GetResultCoverage(const adios2::Box<adios2::Dims> &outputSelec
if (m_Worker)
return m_Worker->GetResultCoverage(outputSelection, touched_blocks);
}
}

} // namespace
1 change: 1 addition & 0 deletions bindings/CXX11/adios2/cxx11/Query.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class QueryWorker
// configFile has query, can be either xml or json
QueryWorker(const std::string &configFile, adios2::Engine &engine);

void GetResultCoverage(std::vector<size_t> &touched_block_ids);
// touched_blocks is a list of regions specified by (start, count),
// that contains data that satisfies the query file
void GetResultCoverage(std::vector<adios2::Box<adios2::Dims>> &touched_blocks);
Expand Down
7 changes: 7 additions & 0 deletions bindings/Python/py11Query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,12 @@ std::vector<Box<Dims>> Query::GetResult()
return touched_blocks;
}

std::vector<size_t> Query::GetBlockIDs()
{
std::vector<size_t> touched_block_ids;
m_QueryWorker->GetResultCoverage(touched_block_ids);
return touched_block_ids;
}

} // py11
} // adios2
1 change: 1 addition & 0 deletions bindings/Python/py11Query.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class Query
explicit operator bool() const noexcept;

std::vector<Box<Dims>> GetResult();
std::vector<size_t> GetBlockIDs();

private:
Query(adios2::query::Worker *qw);
Expand Down
3 changes: 2 additions & 1 deletion bindings/Python/py11glue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,8 @@ PYBIND11_MODULE(ADIOS2_PYTHON_MODULE_NAME, m)
"adios2 query construction, a xml query File and a read engine",
pybind11::arg("queryFile"), pybind11::arg("reader") = true)

.def("GetResult", &adios2::py11::Query::GetResult);
.def("GetResult", &adios2::py11::Query::GetResult)
.def("GetBlockIDs", &adios2::py11::Query::GetBlockIDs);

pybind11::class_<adios2::py11::Variable>(m, "Variable")
// Python 2
Expand Down
54 changes: 41 additions & 13 deletions examples/basics/queryWorker/queryWorker.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,39 @@
/*
* Distributed under the OSI-approved Apache License, Version 2.0. See
* accompanying file Copyright.txt for details.
*/

#include "adios2.h"
#include <mpi.h>

#include <cstdint>
#include <iomanip>
#include <iostream>
#include <math.h>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>

// touched block ids are printed.
void queryIDs(adios2::IO &queryIO, std::string &dataFileName, std::string &queryFile)
{
adios2::Engine reader = queryIO.Open(dataFileName, adios2::Mode::Read, MPI_COMM_WORLD);
// adios2::QueryWorker* worker = NULL;
queryIO.SetParameter("StreamReader", "true");
std::vector<size_t> touched_blockIDs;

while (reader.BeginStep() == adios2::StepStatus::OK)
{
adios2::QueryWorker w = adios2::QueryWorker(queryFile, reader);
w.GetResultCoverage(touched_blockIDs);

std::cout << " Num touched blocks =" << touched_blockIDs.size() << std::endl;
for (auto n : touched_blockIDs)
{
std::cout << "\t[" << n << "] " << std::endl;
}

reader.EndStep();
}
reader.Close();
}

void queryWithStreaming(adios2::IO &queryIO, std::string &dataFileName, std::string &queryFile)
{
adios2::Engine reader = queryIO.Open(dataFileName, adios2::Mode::Read, MPI_COMM_WORLD);
Expand All @@ -23,7 +46,10 @@ void queryWithStreaming(adios2::IO &queryIO, std::string &dataFileName, std::str
adios2::QueryWorker w = adios2::QueryWorker(queryFile, reader);
w.GetResultCoverage(touched_blocks);

std::cout << " ... now can read out touched blocks ... size=" << touched_blocks.size()
std::cout << " Num touched regions ="
<< touched_blocks.size()
// std::cout << " ... now can read out touched blocks ... size=" <<
// touched_blocks.size()
<< std::endl;
for (auto n : touched_blocks)
{
Expand Down Expand Up @@ -67,12 +93,6 @@ int main(int argc, char *argv[])
configFileName = argv[1];
dataFileName = argv[2];

if (rank == 0)
{
std::cout << " using config file = " << configFileName << std::endl;
std::cout << " data file = " << dataFileName << std::endl;
}

adios2::ADIOS ad = adios2::ADIOS(configFileName, MPI_COMM_WORLD);

adios2::IO queryIO = ad.DeclareIO("query");
Expand All @@ -82,8 +102,16 @@ int main(int argc, char *argv[])
{
queryFile = argv[3];
}
std::cout << "Testing query file ..." << queryFile << std::endl;
if (rank == 0)
{
std::cout << " using config file = " << configFileName << std::endl;
std::cout << " data file = " << dataFileName << std::endl;
std::cout << " queryfile = " << queryFile << std::endl;
}

queryIDs(queryIO, dataFileName, queryFile);

std::cout << "\n" << std::endl;
queryWithStreaming(queryIO, dataFileName, queryFile);

return 0;
Expand Down
134 changes: 81 additions & 53 deletions source/adios2/toolkit/query/BlockIndex.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,6 @@ namespace query
template <class T>
class BlockIndex
{
struct Tree
{
//
// ** no need to keep the original block. might be smaller than
// blockIndex typename Variable<T>::BPInfo& m_BlockInfo;
//
std::vector<typename adios2::core::Variable<T>::BPInfo> m_SubBlockInfo;
};

public:
BlockIndex<T>(adios2::core::Variable<T> *var, adios2::core::IO &io,
adios2::core::Engine &reader)
Expand All @@ -30,15 +21,20 @@ class BlockIndex

void Generate(std::string &fromBPFile, const adios2::Params &inputs) {}

void Evaluate(const QueryVar &query, std::vector<adios2::Box<adios2::Dims>> &resultSubBlocks)
void Evaluate(const QueryVar &query, std::vector<BlockHit> &resultBlockIDs)
{
if (nullptr == m_VarPtr)
{
throw std::runtime_error("Unable to evaluate query! Invalid Variable detected");
}

if (m_IdxReader.m_EngineType.find("5") != std::string::npos) // a bp5 reader
RunBP5Stat(query, resultSubBlocks);
RunBP5Stat(query, resultBlockIDs);
else
RunBP4Stat(query, resultSubBlocks);
RunBP4Stat(query, resultBlockIDs);
}

void RunBP5Stat(const QueryVar &query, std::vector<adios2::Box<adios2::Dims>> &hitBlocks)
void RunBP5Stat(const QueryVar &query, std::vector<BlockHit> &hitBlocks)
{
size_t currStep = m_IdxReader.CurrentStep();
adios2::Dims currShape = m_VarPtr->Shape();
Expand All @@ -52,29 +48,40 @@ class BlockIndex
}
for (auto &blockInfo : MinBlocksInfo->BlocksInfo)
{
Dims ss(MinBlocksInfo->Dims);
Dims cc(MinBlocksInfo->Dims);
for (std::vector<int>::size_type i = 0; i < ss.size(); i++)
{
ss[i] = blockInfo.Start[i];
cc[i] = blockInfo.Count[i];
}
if (!query.TouchSelection(ss, cc))
continue;

T bmin = *(T *)&blockInfo.MinMax.MinUnion;
T bmax = *(T *)&blockInfo.MinMax.MaxUnion;
bool isHit = query.m_RangeTree.CheckInterval(bmin, bmax);
if (isHit)

if (!isHit)
continue;

if (m_VarPtr->m_ShapeID != adios2::ShapeID::LocalArray)
{
adios2::Box<adios2::Dims> box = {ss, cc};
hitBlocks.push_back(box);
Dims ss(MinBlocksInfo->Dims);
Dims cc(MinBlocksInfo->Dims);
for (std::vector<int>::size_type i = 0; i < ss.size(); i++)
{
ss[i] = blockInfo.Start[i];
cc[i] = blockInfo.Count[i];
}
if (!query.TouchSelection(ss, cc))
continue;

if (isHit)
{
adios2::Box<adios2::Dims> box = {ss, cc};
hitBlocks.push_back(BlockHit(blockInfo.BlockID, box));
}
}
else
{ // local array
hitBlocks.push_back(BlockHit(blockInfo.BlockID));
}
}
delete MinBlocksInfo;
}

void RunBP4Stat(const QueryVar &query, std::vector<adios2::Box<adios2::Dims>> &hitBlocks)
void RunBP4Stat(const QueryVar &query, std::vector<BlockHit> &hitBlocks)
{
size_t currStep = m_IdxReader.CurrentStep();
adios2::Dims currShape = m_VarPtr->Shape();
Expand All @@ -86,45 +93,66 @@ class BlockIndex

for (auto &blockInfo : varBlocksInfo)
{
if (!query.TouchSelection(blockInfo.Start, blockInfo.Count))
bool isHit = query.m_RangeTree.CheckInterval(blockInfo.Min, blockInfo.Max);
if (!isHit)
continue;

if (blockInfo.MinMaxs.size() > 0)
if (m_VarPtr->m_ShapeID == adios2::ShapeID::LocalArray)
{
adios2::helper::CalculateSubblockInfo(blockInfo.Count, blockInfo.SubBlockInfo);
unsigned int numSubBlocks = static_cast<unsigned int>(blockInfo.MinMaxs.size() / 2);
for (unsigned int i = 0; i < numSubBlocks; i++)
if (isHit)
hitBlocks.push_back(BlockHit(blockInfo.BlockID));
}
else
{
// global array
if (!query.TouchSelection(blockInfo.Start, blockInfo.Count))
continue;

BlockHit tmp(blockInfo.BlockID);
if (blockInfo.MinMaxs.size() > 0)
{
bool isHit = query.m_RangeTree.CheckInterval(blockInfo.MinMaxs[2 * i],
blockInfo.MinMaxs[2 * i + 1]);
if (isHit)
// Consolidate to whole block If all subblocks are hits, then return the whole
// block
bool allCovered = true;

adios2::helper::CalculateSubblockInfo(blockInfo.Count, blockInfo.SubBlockInfo);
unsigned int numSubBlocks =
static_cast<unsigned int>(blockInfo.MinMaxs.size() / 2);
for (unsigned int i = 0; i < numSubBlocks; i++)
{
adios2::Box<adios2::Dims> currSubBlock =
adios2::helper::GetSubBlock(blockInfo.Count, blockInfo.SubBlockInfo, i);
for (size_t d = 0; d < blockInfo.Count.size(); ++d)
bool isSubblockHit = query.m_RangeTree.CheckInterval(
blockInfo.MinMaxs[2 * i], blockInfo.MinMaxs[2 * i + 1]);
if (isSubblockHit)
{
adios2::Box<adios2::Dims> currSubBlock = adios2::helper::GetSubBlock(
blockInfo.Count, blockInfo.SubBlockInfo, i);
for (size_t d = 0; d < blockInfo.Count.size(); ++d)
currSubBlock.first[d] += blockInfo.Start[d];

if (!query.TouchSelection(currSubBlock.first, currSubBlock.second))
continue;
tmp.m_Regions.push_back(currSubBlock);
}
else
{
currSubBlock.first[d] += blockInfo.Start[d];
allCovered = false;
}
if (!query.TouchSelection(currSubBlock.first, currSubBlock.second))
continue;
hitBlocks.push_back(currSubBlock);
} // for num subblocks

if (!allCovered)
{
hitBlocks.push_back(tmp);
continue;
}
}
}
else
{ // default
bool isHit = query.m_RangeTree.CheckInterval(blockInfo.Min, blockInfo.Max);
if (isHit)
{
adios2::Box<adios2::Dims> box = {blockInfo.Start, blockInfo.Count};
hitBlocks.push_back(box);
}

// no subblock info or (allCovered = true)
adios2::Box<adios2::Dims> box = {blockInfo.Start, blockInfo.Count};
hitBlocks.push_back(BlockHit(blockInfo.BlockID, box));
}
}
}

Tree m_Content;

// can not be unique_ptr as it changes with bp5 through steps
// as BP5Deserializer::SetupForStep calls io.RemoveVariables()
// must use ptr as bp5 associates ptrs with blockinfo, see MinBlocksInfo() in bp5
Expand Down
Loading

0 comments on commit 2af5482

Please sign in to comment.