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>
0 commit comments