@@ -7258,28 +7258,123 @@ TEST_CASE("groupbased_read_write", "[serial]")
72587258void joined_dim (std::string const &ext)
72597259{
72607260 using type = float ;
7261- Series s (" ../samples/joinedDim." + ext, Access::CREATE);
7262- std::vector<UniquePtrWithLambda<type>> writeFrom (5 );
7263- for (size_t i = 0 ; i < 5 ; ++i)
7261+ using patchType = uint64_t ;
7262+ constexpr size_t patches_per_rank = 5 ;
7263+ constexpr size_t length_of_patch = 10 ;
7264+
72647265 {
7265- writeFrom[i] = UniquePtrWithLambda<type>(
7266- new type[10 ], [](auto const *ptr) { delete[] ptr; });
7267- std::iota (writeFrom[i].get (), writeFrom[i].get () + 10 , 10 * i);
7268- }
7266+ Series s (" ../samples/joinedDimParallel." + ext, Access::CREATE);
7267+ std::vector<UniquePtrWithLambda<type>> writeFrom (patches_per_rank);
72697268
7270- auto it = s.writeIterations ()[100 ];
7271- auto epx = it.particles [" e" ][" position" ][" x" ];
7272- Dataset ds (determineDatatype<type>(), {1 });
7273- ds.joinedDimension = 0 ;
7274- epx.resetDataset (ds);
7269+ auto it = s.writeIterations ()[100 ];
7270+
7271+ Dataset numParticlesDS (determineDatatype<patchType>(), {1 });
7272+ numParticlesDS.joinedDimension = 0 ;
7273+ auto numParticles =
7274+ it.particles [" e" ]
7275+ .particlePatches [" numParticles" ][RecordComponent::SCALAR];
7276+ auto numParticlesOffset =
7277+ it.particles [" e" ]
7278+ .particlePatches [" numParticlesOffset" ][RecordComponent::SCALAR];
7279+ numParticles.resetDataset (numParticlesDS);
7280+ numParticlesOffset.resetDataset (numParticlesDS);
7281+
7282+ auto patchOffset = it.particles [" e" ].particlePatches [" offset" ][" x" ];
7283+ auto patchExtent = it.particles [" e" ].particlePatches [" extent" ][" x" ];
7284+ Dataset particlePatchesDS (determineDatatype<float >(), {1 });
7285+ particlePatchesDS.joinedDimension = 0 ;
7286+ patchOffset.resetDataset (particlePatchesDS);
7287+ patchExtent.resetDataset (particlePatchesDS);
7288+
7289+ for (size_t i = 0 ; i < 5 ; ++i)
7290+ {
7291+ writeFrom[i] = UniquePtrWithLambda<type>(
7292+ new type[length_of_patch],
7293+ [](auto const *ptr) { delete[] ptr; });
7294+ std::iota (
7295+ writeFrom[i].get (),
7296+ writeFrom[i].get () + 10 ,
7297+ length_of_patch * i);
7298+ patchOffset.store <type>(length_of_patch * i);
7299+ }
7300+
7301+ auto epx = it.particles [" e" ][" position" ][" x" ];
7302+ Dataset ds (determineDatatype<type>(), {1 });
7303+ ds.joinedDimension = 0 ;
7304+ epx.resetDataset (ds);
7305+
7306+ size_t counter = 0 ;
7307+ for (auto &chunk : writeFrom)
7308+ {
7309+ epx.storeChunk (std::move (chunk), {}, {length_of_patch});
7310+ numParticles.store <patchType>(length_of_patch);
7311+ /*
7312+ * For the sake of the test case, we know that the
7313+ * numParticlesOffset has this value. In general, the purpose of the
7314+ * joined array is that we don't need to know these values, so the
7315+ * specification of particle patches is somewhat difficult.
7316+ */
7317+ numParticlesOffset.store <patchType>(counter++ * length_of_patch);
7318+ patchExtent.store <type>(10 );
7319+ }
7320+ writeFrom.clear ();
7321+ it.close ();
7322+ s.close ();
7323+ }
72757324
7276- for (auto &chunk : writeFrom)
72777325 {
7278- epx.storeChunk (std::move (chunk), {}, {10 });
7326+ Series s (" ../samples/joinedDimParallel." + ext, Access::READ_ONLY);
7327+ auto it = s.iterations [100 ];
7328+ auto e = it.particles [" e" ];
7329+
7330+ auto particleData = e[" position" ][" x" ].loadChunk <type>();
7331+ auto numParticles =
7332+ e.particlePatches [" numParticles" ][RecordComponent::SCALAR]
7333+ .load <patchType>();
7334+ auto numParticlesOffset =
7335+ e.particlePatches [" numParticlesOffset" ][RecordComponent::SCALAR]
7336+ .load <patchType>();
7337+ auto patchOffset = e.particlePatches [" offset" ][" x" ].load <type>();
7338+ auto patchExtent = e.particlePatches [" extent" ][" x" ].load <type>();
7339+
7340+ it.close ();
7341+
7342+ // check validity of particle patches
7343+ auto numPatches =
7344+ e.particlePatches [" numParticlesOffset" ][RecordComponent::SCALAR]
7345+ .getExtent ()[0 ];
7346+ REQUIRE (
7347+ e.particlePatches [" numParticles" ][RecordComponent::SCALAR]
7348+ .getExtent ()[0 ] == numPatches);
7349+ for (size_t i = 0 ; i < numPatches; ++i)
7350+ {
7351+ for (size_t j = 0 ; j < numParticles.get ()[i]; ++j)
7352+ {
7353+ REQUIRE (
7354+ patchOffset.get ()[i] <=
7355+ particleData.get ()[numParticlesOffset.get ()[i] + j]);
7356+ REQUIRE (
7357+ particleData.get ()[numParticlesOffset.get ()[i] + j] <
7358+ patchOffset.get ()[i] + patchExtent.get ()[i]);
7359+ }
7360+ }
7361+
7362+ /*
7363+ * Check that:
7364+ * 1. Joined array joins writes from lower ranks before higher ranks
7365+ * 2. Joined array joins early writes before later writes from the same
7366+ * rank
7367+ */
7368+ for (size_t i = 0 ; i < length_of_patch * patches_per_rank; ++i)
7369+ {
7370+ REQUIRE (float (i) == particleData.get ()[i]);
7371+ }
7372+ for (size_t i = 0 ; i < patches_per_rank; ++i)
7373+ {
7374+ REQUIRE (length_of_patch * i == numParticlesOffset.get ()[i]);
7375+ REQUIRE (type (length_of_patch * i) == patchOffset.get ()[i]);
7376+ }
72797377 }
7280- writeFrom.clear ();
7281- it.close ();
7282- s.close ();
72837378}
72847379
72857380TEST_CASE (" joined_dim" , " [serial]" )
0 commit comments