Skip to content

Commit efc72b0

Browse files
committed
Go through AdiosAttributes for attribute reading
1 parent 72be3cb commit efc72b0

File tree

5 files changed

+143
-28
lines changed

5 files changed

+143
-28
lines changed

include/openPMD/IO/ADIOS/ADIOS2File.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,11 @@ class ADIOS2File
411411
void setStepSelection(std::optional<size_t>);
412412
[[nodiscard]] std::optional<size_t> stepSelection() const;
413413

414+
[[nodiscard]] detail::AdiosAttributes const &attributes() const
415+
{
416+
return m_attributes;
417+
}
418+
414419
private:
415420
ADIOS2IOHandlerImpl *m_impl;
416421
std::optional<adios2::Engine> m_engine; //! ADIOS engine

include/openPMD/IO/ADIOS/ADIOS2IOHandler.hpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "openPMD/Error.hpp"
2424
#include "openPMD/IO/ADIOS/ADIOS2Auxiliary.hpp"
2525
#include "openPMD/IO/ADIOS/ADIOS2FilePosition.hpp"
26+
#include "openPMD/IO/ADIOS/ADIOS2PreloadAttributes.hpp"
2627
#include "openPMD/IO/ADIOS/macros.hpp"
2728
#include "openPMD/IO/AbstractIOHandler.hpp"
2829
#include "openPMD/IO/AbstractIOHandlerImpl.hpp"
@@ -541,9 +542,26 @@ namespace detail
541542

542543
struct AttributeReader
543544
{
545+
struct GetAttribute
546+
{
547+
size_t step;
548+
adios2::IO &IO;
549+
detail::AdiosAttributes const &attributes;
550+
template <typename AdiosType>
551+
auto call(std::string const &name) const
552+
-> detail::AttributeWithShapeAndResource<AdiosType>
553+
{
554+
return attributes.getAttribute<AdiosType>(step, IO, name);
555+
}
556+
};
557+
544558
template <typename T>
545-
static Datatype
546-
call(adios2::IO &IO, std::string name, Attribute::resource &resource);
559+
static Datatype call(
560+
size_t step,
561+
adios2::IO &IO,
562+
std::string name,
563+
Attribute::resource &resource,
564+
detail::AdiosAttributes const &);
547565

548566
template <int n, typename... Params>
549567
static Datatype call(Params &&...);

include/openPMD/IO/ADIOS/ADIOS2PreloadAttributes.hpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,41 @@ class PreloadAdiosAttributes
143143
}
144144
};
145145

146+
template <typename T>
147+
struct AttributeWithShapeAndResource : AttributeWithShape<T>
148+
{
149+
AttributeWithShapeAndResource(AttributeWithShape<T> parent)
150+
: AttributeWithShape<T>(std::move(parent))
151+
{}
152+
AttributeWithShapeAndResource(
153+
size_t len_in,
154+
T const *data_in,
155+
std::optional<std::vector<T>> resource_in)
156+
: AttributeWithShape<T>{len_in, data_in}
157+
, resource{std::move(resource_in)}
158+
{}
159+
explicit AttributeWithShapeAndResource() : AttributeWithShape<T>(0, nullptr)
160+
{}
161+
AttributeWithShapeAndResource(adios2::Attribute<T> attr)
162+
{
163+
if (!attr)
164+
{
165+
this->data = nullptr;
166+
this->len = 0;
167+
return;
168+
}
169+
auto vec = attr.Data();
170+
this->len = vec.size();
171+
this->data = vec.data();
172+
this->resource = std::move(vec);
173+
}
174+
operator bool() const
175+
{
176+
return this->data;
177+
}
178+
std::optional<std::vector<T>> resource;
179+
};
180+
146181
struct AdiosAttributes
147182
{
148183
using RandomAccess_t = std::vector<PreloadAdiosAttributes>;
@@ -178,6 +213,10 @@ struct AdiosAttributes
178213
}},
179214
m_data);
180215
}
216+
217+
template <typename T>
218+
AttributeWithShapeAndResource<T>
219+
getAttribute(size_t step, adios2::IO &IO, std::string const &name) const;
181220
};
182221
} // namespace openPMD::detail
183222

src/IO/ADIOS/ADIOS2IOHandler.cpp

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "openPMD/IO/ADIOS/ADIOS2Auxiliary.hpp"
2828
#include "openPMD/IO/ADIOS/ADIOS2FilePosition.hpp"
2929
#include "openPMD/IO/ADIOS/ADIOS2IOHandler.hpp"
30+
#include "openPMD/IO/ADIOS/ADIOS2PreloadAttributes.hpp"
3031
#include "openPMD/IO/IOTask.hpp"
3132
#include "openPMD/IterationEncoding.hpp"
3233
#include "openPMD/Streaming.hpp"
@@ -1236,7 +1237,12 @@ void ADIOS2IOHandlerImpl::readAttribute(
12361237
}
12371238

12381239
Datatype ret = switchType<detail::AttributeReader>(
1239-
type, ba.m_IO, name, *parameters.resource);
1240+
type,
1241+
ba.currentStep(),
1242+
ba.m_IO,
1243+
name,
1244+
*parameters.resource,
1245+
ba.attributes());
12401246
*parameters.dtype = ret;
12411247
}
12421248

@@ -1246,9 +1252,12 @@ namespace
12461252
Functor fun will be called with the value of the retrieved attribute;
12471253
both functions use different logic for processing the retrieved values.
12481254
*/
1249-
template <typename T, typename Functor>
1250-
Datatype
1251-
genericReadAttribute(Functor &&fun, adios2::IO &IO, std::string const &name)
1255+
template <typename T, typename Functor, typename GetAttribute>
1256+
Datatype genericReadAttribute(
1257+
Functor &&fun,
1258+
adios2::IO &IO,
1259+
std::string const &name,
1260+
GetAttribute const &getAttribute)
12521261
{
12531262
/*
12541263
* If we store an attribute of boolean type, we store an additional
@@ -1259,7 +1268,7 @@ namespace
12591268

12601269
if constexpr (std::is_same<T, rep>::value)
12611270
{
1262-
auto attr = IO.InquireAttribute<rep>(name);
1271+
auto attr = getAttribute.template call<rep>(name);
12631272
if (!attr)
12641273
{
12651274
throw std::runtime_error(
@@ -1286,11 +1295,11 @@ namespace
12861295
if (meta.Data().size() == 1 && meta.Data()[0] == 1)
12871296
{
12881297
std::forward<Functor>(fun)(
1289-
detail::bool_repr::fromRep(attr.Data()[0]));
1298+
detail::bool_repr::fromRep(attr.data[0]));
12901299
return determineDatatype<bool>();
12911300
}
12921301
}
1293-
std::forward<Functor>(fun)(attr.Data()[0]);
1302+
std::forward<Functor>(fun)(attr.data[0]);
12941303
}
12951304
else if constexpr (detail::IsUnsupportedComplex_v<T>)
12961305
{
@@ -1300,27 +1309,30 @@ namespace
13001309
}
13011310
else if constexpr (auxiliary::IsVector_v<T>)
13021311
{
1303-
auto attr = IO.InquireAttribute<typename T::value_type>(name);
1312+
auto attr =
1313+
getAttribute.template call<typename T::value_type>(name);
13041314
if (!attr)
13051315
{
13061316
throw std::runtime_error(
13071317
"[ADIOS2] Internal error: Failed reading attribute '" +
13081318
name + "'.");
13091319
}
1310-
std::forward<Functor>(fun)(attr.Data());
1320+
std::forward<Functor>(fun)(std::vector<typename T::value_type>(
1321+
attr.data, attr.data + attr.len));
13111322
}
13121323
else if constexpr (auxiliary::IsArray_v<T>)
13131324
{
1314-
auto attr = IO.InquireAttribute<typename T::value_type>(name);
1325+
auto attr =
1326+
getAttribute.template call<typename T::value_type>(name);
13151327
if (!attr)
13161328
{
13171329
throw std::runtime_error(
13181330
"[ADIOS2] Internal error: Failed reading attribute '" +
13191331
name + "'.");
13201332
}
1321-
auto data = attr.Data();
1333+
auto data = attr.data;
13221334
T res;
1323-
for (size_t i = 0; i < data.size(); i++)
1335+
for (size_t i = 0; i < attr.len; i++)
13241336
{
13251337
res[i] = data[i];
13261338
}
@@ -1333,21 +1345,32 @@ namespace
13331345
}
13341346
else
13351347
{
1336-
auto attr = IO.InquireAttribute<T>(name);
1348+
auto attr = getAttribute.template call<T>(name);
13371349
if (!attr)
13381350
{
13391351
throw std::runtime_error(
13401352
"[ADIOS2] Internal error: Failed reading attribute '" +
13411353
name + "'.");
13421354
}
1343-
std::forward<Functor>(fun)(attr.Data()[0]);
1355+
std::forward<Functor>(fun)(attr.data[0]);
13441356
}
13451357

13461358
return determineDatatype<T>();
13471359
}
13481360

13491361
struct ReadAttributeAllsteps
13501362
{
1363+
struct GetAttribute
1364+
{
1365+
adios2::IO &IO;
1366+
template <typename AdiosType>
1367+
[[nodiscard]] auto call(std::string const &name) const
1368+
-> detail::AttributeWithShapeAndResource<AdiosType>
1369+
{
1370+
return {IO.InquireAttribute<AdiosType>(name)};
1371+
}
1372+
};
1373+
13511374
template <typename T>
13521375
static void call(
13531376
adios2::IO &IO,
@@ -1379,7 +1402,8 @@ namespace
13791402
}
13801403
},
13811404
IO,
1382-
name);
1405+
name,
1406+
GetAttribute{IO});
13831407
engine.EndStep();
13841408
status = engine.BeginStep();
13851409
}
@@ -1657,11 +1681,12 @@ void ADIOS2IOHandlerImpl::listPaths(
16571681
detail::ADIOS2File::StreamStatus::DuringStep)
16581682
{
16591683
auto currentStep = fileData.currentStep();
1684+
auto &IO = fileData.m_IO;
16601685
for (auto const &attrName : attrs)
16611686
{
16621687
using table_t = unsigned long long;
1663-
auto attr = fileData.m_IO.InquireAttribute<table_t>(
1664-
tablePrefix + attrName);
1688+
auto attr = fileData.attributes().getAttribute<table_t>(
1689+
currentStep, IO, tablePrefix + attrName);
16651690
if (!attr)
16661691
{
16671692
std::cerr << "[ADIOS2 backend] Unable to inquire group "
@@ -1671,7 +1696,7 @@ void ADIOS2IOHandlerImpl::listPaths(
16711696
<< std::endl;
16721697
continue;
16731698
}
1674-
if (attr.Data()[0] != currentStep)
1699+
if (attr.data[0] != currentStep)
16751700
{
16761701
// group wasn't defined in current step
16771702
continue;
@@ -2113,14 +2138,19 @@ namespace detail
21132138
{
21142139
template <typename T>
21152140
Datatype AttributeReader::call(
2116-
adios2::IO &IO, std::string name, Attribute::resource &resource)
2141+
size_t step,
2142+
adios2::IO &IO,
2143+
std::string name,
2144+
Attribute::resource &resource,
2145+
detail::AdiosAttributes const &attributes)
21172146
{
21182147
return genericReadAttribute<T>(
21192148
[&resource](auto &&value) {
21202149
resource = static_cast<decltype(value)>(value);
21212150
},
21222151
IO,
2123-
name);
2152+
name,
2153+
GetAttribute{step, IO, attributes});
21242154
}
21252155

21262156
template <int n, typename... Params>

src/IO/ADIOS/ADIOS2PreloadAttributes.cpp

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -260,12 +260,6 @@ PreloadAdiosAttributes::getAttribute(std::string const &name) const
260260
return res;
261261
}
262262

263-
#define OPENPMD_INSTANTIATE_GETATTRIBUTE(type) \
264-
template AttributeWithShape<type> PreloadAdiosAttributes::getAttribute( \
265-
std::string const &name) const;
266-
ADIOS2_FOREACH_ATTRIBUTE_STDTYPE_1ARG(OPENPMD_INSTANTIATE_GETATTRIBUTE)
267-
#undef OPENPMD_INSTANTIATE_GETATTRIBUTE
268-
269263
Datatype PreloadAdiosAttributes::attributeType(std::string const &name) const
270264
{
271265
auto it = m_offsets.find(name);
@@ -275,6 +269,35 @@ Datatype PreloadAdiosAttributes::attributeType(std::string const &name) const
275269
}
276270
return it->second.dt;
277271
}
272+
273+
template <typename T>
274+
auto AdiosAttributes::getAttribute(
275+
size_t step, adios2::IO &IO, std::string const &name) const
276+
-> AttributeWithShapeAndResource<T>
277+
{
278+
return std::visit(
279+
auxiliary::overloaded{
280+
[step, &name](
281+
RandomAccess_t const &ra) -> AttributeWithShapeAndResource<T> {
282+
auto &attribute_data = ra.at(step);
283+
return attribute_data.getAttribute<T>(name);
284+
},
285+
[&name,
286+
&IO](StreamAccess_t const &) -> AttributeWithShapeAndResource<T> {
287+
auto attr = IO.InquireAttribute<T>(name);
288+
return {std::move(attr)};
289+
}},
290+
m_data);
291+
}
292+
293+
#define OPENPMD_INSTANTIATE_GETATTRIBUTE(type) \
294+
template AttributeWithShape<type> PreloadAdiosAttributes::getAttribute( \
295+
std::string const &name) const; \
296+
template auto AdiosAttributes::getAttribute( \
297+
size_t step, adios2::IO &IO, std::string const &name) const \
298+
-> AttributeWithShapeAndResource<type>;
299+
ADIOS2_FOREACH_TYPE_1ARG(OPENPMD_INSTANTIATE_GETATTRIBUTE)
300+
#undef OPENPMD_INSTANTIATE_GETATTRIBUTE
278301
} // namespace openPMD::detail
279302

280303
#endif // openPMD_HAVE_ADIOS2

0 commit comments

Comments
 (0)