Skip to content

Commit c833209

Browse files
committed
Test memory selection
1 parent d815cc5 commit c833209

5 files changed

Lines changed: 117 additions & 3 deletions

File tree

include/openPMD/IO/ADIOS/ADIOS2IOHandler.hpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "openPMD/Error.hpp"
2525
#include "openPMD/IO/ADIOS/ADIOS2Auxiliary.hpp"
2626
#include "openPMD/IO/ADIOS/ADIOS2FilePosition.hpp"
27+
#include "openPMD/IO/ADIOS/macros.hpp"
2728
#include "openPMD/IO/AbstractIOHandler.hpp"
2829
#include "openPMD/IO/AbstractIOHandlerImpl.hpp"
2930
#include "openPMD/IO/AbstractIOHandlerImplCommon.hpp"
@@ -481,6 +482,7 @@ class ADIOS2IOHandlerImpl
481482
var.SetSelection(
482483
{adios2::Dims(offset.begin(), offset.end()),
483484
adios2::Dims(extent.begin(), extent.end())});
485+
484486
if (memorySelection.has_value())
485487
{
486488
var.SetMemorySelection(
@@ -490,14 +492,38 @@ class ADIOS2IOHandlerImpl
490492
adios2::Dims(
491493
memorySelection->extent.begin(),
492494
memorySelection->extent.end())});
495+
if constexpr (!CanTheMemorySelectionBeReset)
496+
{
497+
if (!printedWarningsAlready.memorySelection)
498+
{
499+
std::cerr
500+
<< "[Warning] Using a version of ADIOS2 that cannot "
501+
"reset memory selections on a variable, once "
502+
"specified. When using memory selections, then "
503+
"please specify it explicitly on all storeChunk() "
504+
"calls. Further info: "
505+
"https://github.com/ornladios/ADIOS2/pull/4169."
506+
<< std::endl;
507+
printedWarningsAlready.memorySelection = true;
508+
}
509+
}
493510
}
511+
else
512+
{
513+
if constexpr (CanTheMemorySelectionBeReset)
514+
{
515+
var.SetMemorySelection();
516+
}
517+
}
518+
494519
return var;
495520
}
496521

497522
struct
498523
{
499524
bool noGroupBased = false;
500525
bool blosc2bp5 = false;
526+
bool memorySelection = false;
501527
} printedWarningsAlready;
502528
}; // ADIOS2IOHandlerImpl
503529

include/openPMD/IO/ADIOS/macros.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,26 @@
2626
#define openPMD_HAVE_ADIOS2_BP5 0
2727
#endif
2828

29+
namespace detail
30+
{
31+
template <typename Variable, typename SFINAE = void>
32+
struct CanTheMemorySelectionBeReset
33+
{
34+
static constexpr bool value = false;
35+
};
36+
37+
template <typename Variable>
38+
struct CanTheMemorySelectionBeReset<
39+
Variable,
40+
decltype(std::declval<Variable>().SetMemorySelection())>
41+
{
42+
static constexpr bool value = true;
43+
};
44+
} // namespace detail
45+
46+
constexpr bool CanTheMemorySelectionBeReset =
47+
detail::CanTheMemorySelectionBeReset<adios2::Variable<int>>::value;
48+
2949
#else
3050

3151
#define openPMD_HAS_ADIOS_2_8 0

include/openPMD/LoadStoreChunk.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ class ConfigureStoreChunkFromBuffer
120120
auto storeChunkConfig() const -> internal::StoreChunkConfigFromBuffer;
121121

122122
public:
123-
auto memorySelection(MemorySelection) & -> ConfigureStoreChunkFromBuffer &;
123+
auto memorySelection(MemorySelection) -> ConfigureStoreChunkFromBuffer &;
124124

125125
auto as_parent() && -> parent_t &&;
126126
auto as_parent() & -> parent_t &;

src/LoadStoreChunk.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "openPMD/DatatypeMacros.hpp"
1414

1515
#include <memory>
16+
#include <optional>
1617
#include <stdexcept>
1718

1819
namespace openPMD
@@ -151,6 +152,14 @@ auto ConfigureStoreChunkFromBuffer<Ptr_Type>::storeChunkConfig() const
151152
this->getOffset(), this->getExtent(), m_mem_select};
152153
}
153154

155+
template <typename Ptr_Type>
156+
auto ConfigureStoreChunkFromBuffer<Ptr_Type>::memorySelection(
157+
MemorySelection sel) -> ConfigureStoreChunkFromBuffer &
158+
{
159+
this->m_mem_select = std::make_optional<MemorySelection>(std::move(sel));
160+
return *this;
161+
}
162+
154163
template <typename Ptr_Type>
155164
auto ConfigureStoreChunkFromBuffer<Ptr_Type>::enqueue() -> void
156165
{

test/ParallelIOTest.cpp

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,13 +421,42 @@ void available_chunks_test(std::string const &file_ending)
421421
}
422422
)END";
423423

424-
std::vector<int> data{2, 4, 6, 8};
424+
std::vector<int> xdata{2, 4, 6, 8};
425+
std::vector<int> ydata{0, 0, 0, 0, 0, //
426+
0, 1, 2, 3, 0, //
427+
0, 4, 5, 6, 0, //
428+
0, 7, 8, 9, 0, //
429+
0, 0, 0, 0, 0};
430+
std::vector<int> ydata_firstandlastrow{-1, -1, -1};
425431
{
426432
Series write(name, Access::CREATE, MPI_COMM_WORLD, parameters.str());
427433
Iteration it0 = write.iterations[0];
428434
auto E_x = it0.meshes["E"]["x"];
429435
E_x.resetDataset({Datatype::INT, {mpi_size, 4}});
430-
E_x.storeChunk(data, {mpi_rank, 0}, {1, 4});
436+
E_x.storeChunk(xdata, {mpi_rank, 0}, {1, 4});
437+
auto E_y = it0.meshes["E"]["y"];
438+
E_y.resetDataset({Datatype::INT, {5, 3ul * mpi_size}});
439+
E_y.prepareStoreChunk()
440+
.fromContiguousContainer(ydata_firstandlastrow)
441+
.offset({0, 3ul * mpi_rank})
442+
.extent({1, 3})
443+
.enqueue();
444+
E_y.prepareStoreChunk()
445+
.offset({1, 3ul * mpi_rank})
446+
.extent({3, 3})
447+
.fromContiguousContainer(ydata)
448+
.memorySelection({{1, 1}, {5, 5}})
449+
.enqueue();
450+
// if condition checks if this PR is available in ADIOS2:
451+
// https://github.com/ornladios/ADIOS2/pull/4169
452+
if constexpr (CanTheMemorySelectionBeReset)
453+
{
454+
E_y.prepareStoreChunk()
455+
.fromContiguousContainer(ydata_firstandlastrow)
456+
.offset({4, 3ul * mpi_rank})
457+
.extent({1, 3})
458+
.enqueue();
459+
}
431460
it0.close();
432461
}
433462

@@ -459,6 +488,36 @@ void available_chunks_test(std::string const &file_ending)
459488
{
460489
REQUIRE(ranks[i] == i);
461490
}
491+
492+
auto E_y = it0.meshes["E"]["y"];
493+
auto width = E_y.getExtent()[1];
494+
auto first_row = E_y.loadChunk<int>({0, 0}, {1, width});
495+
auto middle_rows = E_y.loadChunk<int>({1, 0}, {3, width});
496+
auto last_row = E_y.loadChunk<int>({4, 0}, {1, width});
497+
read.flush();
498+
499+
for (auto row : [&]() -> std::vector<std::shared_ptr<int> *> {
500+
if constexpr (CanTheMemorySelectionBeReset)
501+
{
502+
return {&first_row, &last_row};
503+
}
504+
else
505+
{
506+
return {&first_row};
507+
}
508+
}())
509+
{
510+
for (size_t i = 0; i < width; ++i)
511+
{
512+
REQUIRE(row->get()[i] == -1);
513+
}
514+
}
515+
for (size_t i = 0; i < width * 3; ++i)
516+
{
517+
size_t row = i / width;
518+
int required_value = row * 3 + (i % 3) + 1;
519+
REQUIRE(middle_rows.get()[i] == required_value);
520+
}
462521
}
463522
}
464523

0 commit comments

Comments
 (0)