@@ -7219,28 +7219,123 @@ TEST_CASE("groupbased_read_write", "[serial]")
72197219void joined_dim (std::string const &ext)
72207220{
72217221 using type = float ;
7222- Series s (" ../samples/joinedDim." + ext, Access::CREATE);
7223- std::vector<UniquePtrWithLambda<type>> writeFrom (5 );
7224- for (size_t i = 0 ; i < 5 ; ++i)
7222+ using patchType = uint64_t ;
7223+ constexpr size_t patches_per_rank = 5 ;
7224+ constexpr size_t length_of_patch = 10 ;
7225+
72257226 {
7226- writeFrom[i] = UniquePtrWithLambda<type>(
7227- new type[10 ], [](auto const *ptr) { delete[] ptr; });
7228- std::iota (writeFrom[i].get (), writeFrom[i].get () + 10 , 10 * i);
7229- }
7227+ Series s (" ../samples/joinedDimParallel." + ext, Access::CREATE);
7228+ std::vector<UniquePtrWithLambda<type>> writeFrom (patches_per_rank);
72307229
7231- auto it = s.writeIterations ()[100 ];
7232- auto epx = it.particles [" e" ][" position" ][" x" ];
7233- Dataset ds (determineDatatype<type>(), {1 });
7234- ds.joinedDimension = 0 ;
7235- epx.resetDataset (ds);
7230+ auto it = s.writeIterations ()[100 ];
7231+
7232+ Dataset numParticlesDS (determineDatatype<patchType>(), {1 });
7233+ numParticlesDS.joinedDimension = 0 ;
7234+ auto numParticles =
7235+ it.particles [" e" ]
7236+ .particlePatches [" numParticles" ][RecordComponent::SCALAR];
7237+ auto numParticlesOffset =
7238+ it.particles [" e" ]
7239+ .particlePatches [" numParticlesOffset" ][RecordComponent::SCALAR];
7240+ numParticles.resetDataset (numParticlesDS);
7241+ numParticlesOffset.resetDataset (numParticlesDS);
7242+
7243+ auto patchOffset = it.particles [" e" ].particlePatches [" offset" ][" x" ];
7244+ auto patchExtent = it.particles [" e" ].particlePatches [" extent" ][" x" ];
7245+ Dataset particlePatchesDS (determineDatatype<float >(), {1 });
7246+ particlePatchesDS.joinedDimension = 0 ;
7247+ patchOffset.resetDataset (particlePatchesDS);
7248+ patchExtent.resetDataset (particlePatchesDS);
7249+
7250+ for (size_t i = 0 ; i < 5 ; ++i)
7251+ {
7252+ writeFrom[i] = UniquePtrWithLambda<type>(
7253+ new type[length_of_patch],
7254+ [](auto const *ptr) { delete[] ptr; });
7255+ std::iota (
7256+ writeFrom[i].get (),
7257+ writeFrom[i].get () + 10 ,
7258+ length_of_patch * i);
7259+ patchOffset.store <type>(length_of_patch * i);
7260+ }
7261+
7262+ auto epx = it.particles [" e" ][" position" ][" x" ];
7263+ Dataset ds (determineDatatype<type>(), {1 });
7264+ ds.joinedDimension = 0 ;
7265+ epx.resetDataset (ds);
7266+
7267+ size_t counter = 0 ;
7268+ for (auto &chunk : writeFrom)
7269+ {
7270+ epx.storeChunk (std::move (chunk), {}, {length_of_patch});
7271+ numParticles.store <patchType>(length_of_patch);
7272+ /*
7273+ * For the sake of the test case, we know that the
7274+ * numParticlesOffset has this value. In general, the purpose of the
7275+ * joined array is that we don't need to know these values, so the
7276+ * specification of particle patches is somewhat difficult.
7277+ */
7278+ numParticlesOffset.store <patchType>(counter++ * length_of_patch);
7279+ patchExtent.store <type>(10 );
7280+ }
7281+ writeFrom.clear ();
7282+ it.close ();
7283+ s.close ();
7284+ }
72367285
7237- for (auto &chunk : writeFrom)
72387286 {
7239- epx.storeChunk (std::move (chunk), {}, {10 });
7287+ Series s (" ../samples/joinedDimParallel." + ext, Access::READ_ONLY);
7288+ auto it = s.iterations [100 ];
7289+ auto e = it.particles [" e" ];
7290+
7291+ auto particleData = e[" position" ][" x" ].loadChunk <type>();
7292+ auto numParticles =
7293+ e.particlePatches [" numParticles" ][RecordComponent::SCALAR]
7294+ .load <patchType>();
7295+ auto numParticlesOffset =
7296+ e.particlePatches [" numParticlesOffset" ][RecordComponent::SCALAR]
7297+ .load <patchType>();
7298+ auto patchOffset = e.particlePatches [" offset" ][" x" ].load <type>();
7299+ auto patchExtent = e.particlePatches [" extent" ][" x" ].load <type>();
7300+
7301+ it.close ();
7302+
7303+ // check validity of particle patches
7304+ auto numPatches =
7305+ e.particlePatches [" numParticlesOffset" ][RecordComponent::SCALAR]
7306+ .getExtent ()[0 ];
7307+ REQUIRE (
7308+ e.particlePatches [" numParticles" ][RecordComponent::SCALAR]
7309+ .getExtent ()[0 ] == numPatches);
7310+ for (size_t i = 0 ; i < numPatches; ++i)
7311+ {
7312+ for (size_t j = 0 ; j < numParticles.get ()[i]; ++j)
7313+ {
7314+ REQUIRE (
7315+ patchOffset.get ()[i] <=
7316+ particleData.get ()[numParticlesOffset.get ()[i] + j]);
7317+ REQUIRE (
7318+ particleData.get ()[numParticlesOffset.get ()[i] + j] <
7319+ patchOffset.get ()[i] + patchExtent.get ()[i]);
7320+ }
7321+ }
7322+
7323+ /*
7324+ * Check that:
7325+ * 1. Joined array joins writes from lower ranks before higher ranks
7326+ * 2. Joined array joins early writes before later writes from the same
7327+ * rank
7328+ */
7329+ for (size_t i = 0 ; i < length_of_patch * patches_per_rank; ++i)
7330+ {
7331+ REQUIRE (float (i) == particleData.get ()[i]);
7332+ }
7333+ for (size_t i = 0 ; i < patches_per_rank; ++i)
7334+ {
7335+ REQUIRE (length_of_patch * i == numParticlesOffset.get ()[i]);
7336+ REQUIRE (type (length_of_patch * i) == patchOffset.get ()[i]);
7337+ }
72407338 }
7241- writeFrom.clear ();
7242- it.close ();
7243- s.close ();
72447339}
72457340
72467341TEST_CASE (" joined_dim" , " [serial]" )
0 commit comments