Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new attempt to commit query support of local array. #3868

Merged
merged 3 commits into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading