Selection
The Selection class provides an explicit, self-contained specification for
Get() operations. It bundles all the parameters that describe what data to
read — bounding box, block ID, step range, memory layout, and accuracy — into a
single object that is passed to Engine::Get().
Motivation
The traditional ADIOS2 read pattern requires mutating a Variable object
before calling Get():
var.SetSelection({{0, 0}, {10, 20}});
var.SetStepSelection({0, 5});
engine.Get(var, data);
This works, but the selection state lives inside the Variable and can become
stale or unclear when the same variable is read with different selections in
different parts of the code. The Selection class makes each Get() call
self-documenting by specifying the selection explicitly at the call site:
auto sel = adios2::Selection::BoundingBox({0, 0}, {10, 20}).WithSteps(0, 5);
engine.Get(var, data, sel);
Creating Selections
Selections are created using static factory methods. A selection has two independent aspects:
Spatial selection —
All(the entire variable) orBoundingBox(a hyperslab with start offsets and counts).Block selection — optionally targets an individual write block by ID.
These are orthogonal: a block ID can be combined with either spatial type.
// All — select the entire variable (this is also the default)
auto sel = adios2::Selection::All();
// Bounding box (hyperslab) — specify start offsets and counts per dimension
auto sel = adios2::Selection::BoundingBox({0, 0}, {10, 20});
// Block selection — read an entire write block
// (equivalent to All().WithBlock(3))
auto sel = adios2::Selection::Block(3);
// Block + bounding box — read a sub-region within a specific block
auto sel = adios2::Selection::BoundingBox({0}, {10}).WithBlock(3);
// Using Box<Dims> convenience type
adios2::Box<adios2::Dims> box = {{0, 0}, {10, 20}};
auto sel = adios2::Selection::BoundingBox(box);
A default-constructed Selection is equivalent to Selection::All():
adios2::Selection sel;
engine.Get(var, data, sel); // reads the whole variable
Fluent Style (Immutable)
The With*() methods return a new Selection with the modification
applied, leaving the original unchanged. This is useful for one-shot
expressions:
auto sel = adios2::Selection::BoundingBox({0, 0}, {10, 20})
.WithBlock(2)
.WithSteps(0, 5)
.WithMemory({0, 0}, {10, 40})
.WithAccuracy({0.01, 0.0, false});
engine.Get(var, data, sel);
Mutable Style (Reuse)
The Set*() methods modify the Selection in place and return *this
for chaining. This is useful when reusing a selection across iterations:
adios2::Selection sel;
sel.SetBoundingBox({0, 0}, {10, 20});
sel.SetAccuracy({0.01, 0.0, false});
for (size_t step = 0; step < nsteps; ++step)
{
sel.SetSteps(step, 1);
engine.Get(var, buffers[step], sel);
}
Using Selections with Get()
New Engine::Get() overloads accept a Selection parameter:
// Raw pointer version
engine.Get(var, data_ptr, sel, adios2::Mode::Sync);
// std::vector version (auto-resized)
std::vector<double> data;
engine.Get(var, data, sel);
Buffer Pre-allocation with SelectionSize()
Variable::SelectionSize() now accepts a Selection to compute the
required buffer size without modifying the variable:
auto sel = adios2::Selection::BoundingBox({0, 0}, {10, 20});
size_t nelems = var.SelectionSize(sel);
double *buf = new double[nelems];
engine.Get(var, buf, sel);
Available Selection Parameters
Parameter |
Factory / Setter |
Non-mutating modifier |
Description |
|---|---|---|---|
All |
|
— |
Select the entire variable (default) |
Bounding Box |
|
— |
Hyperslab selection with start offsets and counts |
Block |
|
|
Select an individual write block by ID (can combine with any spatial type) |
Steps |
|
|
Step range to read (default: current step, count 1) |
Memory |
|
|
Memory layout specification for the destination buffer |
Accuracy |
|
|
Lossy accuracy requirements |
Other methods:
Clear()— reset the selection to default state (All, no block)ClearBlock()— remove block selectionClearMemory()— remove memory layout specificationToString()— human-readable string representation for debugging
auto sel = adios2::Selection::BoundingBox({0, 0}, {10, 20}).WithSteps(0, 5);
std::cout << sel.ToString() << std::endl;
// Output: Selection(BoundingBox start={0, 0} count={10, 20}, steps=[0, 5])
Engine Support
Selection-based Get() is currently supported by the BP5 and SST
(with BP5 marshalling) engines. Other engines will throw a runtime error if a
Selection is passed to Get().
Thread-Safe Concurrent Reads with GetContext
The Selection-based Get() shown above shares per-engine queue state with
every other Get() call on the same engine, so concurrent calls from
multiple threads are not safe. A second overload takes an explicit
GetContext so each thread (or each independent reader) can queue and drain
Get() requests on its own:
auto ctx = engine.NewGetContext();
if (!ctx) {
// Engine does not support concurrent contexts; fall back to the
// single-threaded Selection-based Get above.
}
auto sel = adios2::Selection::BoundingBox({0, 0}, {10, 20}).WithSteps(0, 1);
engine.Get(*ctx, var, data, sel);
engine.PerformGets(*ctx);
Each GetContext owns its own queue of pending requests, so
PerformGets(ctxA) drains only ctxA and leaves any requests queued on
ctxB untouched. A context is reusable after PerformGets; the queue is
cleared on the success path. Calls in ctx-form are always deferred — there is
no Mode::Sync variant.
NewGetContext() is a feature probe: it returns nullptr if the engine
does not support concurrent contexts. Currently only the BP5 reader
supports them, and only when:
the engine was opened in
Mode::ReadRandomAccess(no step lifecycle to race on), andthe underlying file transport is reentrant for
Read(the POSIX transport is;fstreamand others are not).
The legacy Selection-less Get()/PerformGets() API and the
single-threaded Selection-based Get() are unchanged; the ctx-form is an
additional API for callers that need concurrency.
Compatibility
The existing Variable::SetSelection(), SetBlockSelection(),
SetStepSelection(), and SetMemorySelection() APIs remain available and
are not deprecated. The Selection class is a convenience alternative that
makes the selection explicit at the Get() call site rather than relying on
state previously set on the Variable.