Skip to content

Commit f0249c3

Browse files
committed
Testing
Only test if ADIOS2 version at least 2.9
1 parent b469847 commit f0249c3

File tree

2 files changed

+300
-0
lines changed

2 files changed

+300
-0
lines changed

test/ParallelIOTest.cpp

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,4 +1778,160 @@ TEST_CASE("unavailable_backend", "[core][parallel]")
17781778
}
17791779
#endif
17801780
}
1781+
1782+
void joined_dim(std::string const &ext)
1783+
{
1784+
using type = float;
1785+
using patchType = uint64_t;
1786+
constexpr size_t patches_per_rank = 5;
1787+
constexpr size_t length_of_patch = 10;
1788+
1789+
int size{-1};
1790+
int rank{-1};
1791+
MPI_Comm_size(MPI_COMM_WORLD, &size);
1792+
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
1793+
1794+
{
1795+
Series s(
1796+
"../samples/joinedDimParallel." + ext,
1797+
Access::CREATE,
1798+
MPI_COMM_WORLD);
1799+
std::vector<UniquePtrWithLambda<type>> writeFrom(patches_per_rank);
1800+
1801+
auto it = s.writeIterations()[100];
1802+
1803+
Dataset numParticlesDS(
1804+
determineDatatype<patchType>(), {Dataset::JOINED_DIMENSION});
1805+
auto numParticles =
1806+
it.particles["e"]
1807+
.particlePatches["numParticles"][RecordComponent::SCALAR];
1808+
auto numParticlesOffset =
1809+
it.particles["e"]
1810+
.particlePatches["numParticlesOffset"][RecordComponent::SCALAR];
1811+
numParticles.resetDataset(numParticlesDS);
1812+
numParticlesOffset.resetDataset(numParticlesDS);
1813+
1814+
auto patchOffset = it.particles["e"].particlePatches["offset"]["x"];
1815+
auto patchExtent = it.particles["e"].particlePatches["extent"]["x"];
1816+
Dataset particlePatchesDS(
1817+
determineDatatype<float>(), {Dataset::JOINED_DIMENSION});
1818+
patchOffset.resetDataset(particlePatchesDS);
1819+
patchExtent.resetDataset(particlePatchesDS);
1820+
1821+
float start_value = rank * patches_per_rank * length_of_patch;
1822+
for (size_t i = 0; i < 5; ++i)
1823+
{
1824+
writeFrom[i] = UniquePtrWithLambda<type>(
1825+
new type[length_of_patch],
1826+
[](auto const *ptr) { delete[] ptr; });
1827+
std::iota(
1828+
writeFrom[i].get(),
1829+
writeFrom[i].get() + 10,
1830+
start_value + length_of_patch * i);
1831+
patchOffset.store<type>(start_value + length_of_patch * i);
1832+
}
1833+
1834+
auto epx = it.particles["e"]["position"]["x"];
1835+
Dataset ds(determineDatatype<type>(), {Dataset::JOINED_DIMENSION});
1836+
epx.resetDataset(ds);
1837+
1838+
size_t counter = 0;
1839+
for (auto &chunk : writeFrom)
1840+
{
1841+
epx.storeChunk(std::move(chunk), {}, {length_of_patch});
1842+
numParticles.store<patchType>(length_of_patch);
1843+
/*
1844+
* For the sake of the test case, we know that the
1845+
* numParticlesOffset has this value. In general, the purpose of the
1846+
* joined array is that we don't need to know these values, so the
1847+
* specification of particle patches is somewhat difficult.
1848+
*/
1849+
numParticlesOffset.store<patchType>(
1850+
start_value + counter++ * length_of_patch);
1851+
patchExtent.store<type>(10);
1852+
}
1853+
writeFrom.clear();
1854+
it.close();
1855+
s.close();
1856+
}
1857+
1858+
{
1859+
Series s(
1860+
"../samples/joinedDimParallel." + ext,
1861+
Access::READ_ONLY,
1862+
MPI_COMM_WORLD);
1863+
auto it = s.iterations[100];
1864+
auto e = it.particles["e"];
1865+
1866+
auto particleData = e["position"]["x"].loadChunk<type>();
1867+
auto numParticles =
1868+
e.particlePatches["numParticles"][RecordComponent::SCALAR]
1869+
.load<patchType>();
1870+
auto numParticlesOffset =
1871+
e.particlePatches["numParticlesOffset"][RecordComponent::SCALAR]
1872+
.load<patchType>();
1873+
auto patchOffset = e.particlePatches["offset"]["x"].load<type>();
1874+
auto patchExtent = e.particlePatches["extent"]["x"].load<type>();
1875+
1876+
it.close();
1877+
1878+
// check validity of particle patches
1879+
auto numPatches =
1880+
e.particlePatches["numParticlesOffset"][RecordComponent::SCALAR]
1881+
.getExtent()[0];
1882+
REQUIRE(
1883+
e.particlePatches["numParticles"][RecordComponent::SCALAR]
1884+
.getExtent()[0] == numPatches);
1885+
for (size_t i = 0; i < numPatches; ++i)
1886+
{
1887+
for (size_t j = 0; j < numParticles.get()[i]; ++j)
1888+
{
1889+
REQUIRE(
1890+
patchOffset.get()[i] <=
1891+
particleData.get()[numParticlesOffset.get()[i] + j]);
1892+
REQUIRE(
1893+
particleData.get()[numParticlesOffset.get()[i] + j] <
1894+
patchOffset.get()[i] + patchExtent.get()[i]);
1895+
}
1896+
}
1897+
1898+
/*
1899+
* Check that joined array joins early writes before later writes from
1900+
* the same rank
1901+
*/
1902+
for (size_t i = 0; i < size * length_of_patch * patches_per_rank; ++i)
1903+
{
1904+
REQUIRE(float(i) == particleData.get()[i]);
1905+
}
1906+
for (size_t i = 0; i < size * patches_per_rank; ++i)
1907+
{
1908+
REQUIRE(length_of_patch * i == numParticlesOffset.get()[i]);
1909+
REQUIRE(type(length_of_patch * i) == patchOffset.get()[i]);
1910+
}
1911+
}
1912+
}
1913+
1914+
TEST_CASE("joined_dim", "[parallel]")
1915+
{
1916+
#if 100000000 * ADIOS2_VERSION_MAJOR + 1000000 * ADIOS2_VERSION_MINOR + \
1917+
10000 * ADIOS2_VERSION_PATCH + 100 * ADIOS2_VERSION_TWEAK >= \
1918+
209000000
1919+
constexpr char const *supportsJoinedDims[] = {"bp", "bp4", "bp5"};
1920+
#else
1921+
// no zero-size arrays
1922+
std::vector<char const *> supportsJoinedDims;
1923+
#endif
1924+
for (auto const &t : testedFileExtensions())
1925+
{
1926+
for (auto const supported : supportsJoinedDims)
1927+
{
1928+
if (t == supported)
1929+
{
1930+
joined_dim(t);
1931+
break;
1932+
}
1933+
}
1934+
}
1935+
}
1936+
17811937
#endif // openPMD_HAVE_ADIOS2 && openPMD_HAVE_MPI

test/SerialIOTest.cpp

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7371,3 +7371,147 @@ TEST_CASE("groupbased_read_write", "[serial]")
73717371
groupbased_read_write("toml");
73727372
}
73737373
}
7374+
7375+
void joined_dim(std::string const &ext)
7376+
{
7377+
using type = float;
7378+
using patchType = uint64_t;
7379+
constexpr size_t patches_per_rank = 5;
7380+
constexpr size_t length_of_patch = 10;
7381+
7382+
{
7383+
Series s("../samples/joinedDimParallel." + ext, Access::CREATE);
7384+
std::vector<UniquePtrWithLambda<type>> writeFrom(patches_per_rank);
7385+
7386+
auto it = s.writeIterations()[100];
7387+
7388+
Dataset numParticlesDS(
7389+
determineDatatype<patchType>(), {Dataset::JOINED_DIMENSION});
7390+
auto numParticles =
7391+
it.particles["e"]
7392+
.particlePatches["numParticles"][RecordComponent::SCALAR];
7393+
auto numParticlesOffset =
7394+
it.particles["e"]
7395+
.particlePatches["numParticlesOffset"][RecordComponent::SCALAR];
7396+
numParticles.resetDataset(numParticlesDS);
7397+
numParticlesOffset.resetDataset(numParticlesDS);
7398+
7399+
auto patchOffset = it.particles["e"].particlePatches["offset"]["x"];
7400+
auto patchExtent = it.particles["e"].particlePatches["extent"]["x"];
7401+
Dataset particlePatchesDS(
7402+
determineDatatype<float>(), {Dataset::JOINED_DIMENSION});
7403+
patchOffset.resetDataset(particlePatchesDS);
7404+
patchExtent.resetDataset(particlePatchesDS);
7405+
7406+
for (size_t i = 0; i < 5; ++i)
7407+
{
7408+
writeFrom[i] = UniquePtrWithLambda<type>(
7409+
new type[length_of_patch],
7410+
[](auto const *ptr) { delete[] ptr; });
7411+
std::iota(
7412+
writeFrom[i].get(),
7413+
writeFrom[i].get() + 10,
7414+
length_of_patch * i);
7415+
patchOffset.store<type>(length_of_patch * i);
7416+
}
7417+
7418+
auto epx = it.particles["e"]["position"]["x"];
7419+
Dataset ds(determineDatatype<type>(), {Dataset::JOINED_DIMENSION});
7420+
epx.resetDataset(ds);
7421+
7422+
size_t counter = 0;
7423+
for (auto &chunk : writeFrom)
7424+
{
7425+
epx.storeChunk(std::move(chunk), {}, {length_of_patch});
7426+
numParticles.store<patchType>(length_of_patch);
7427+
/*
7428+
* For the sake of the test case, we know that the
7429+
* numParticlesOffset has this value. In general, the purpose of the
7430+
* joined array is that we don't need to know these values, so the
7431+
* specification of particle patches is somewhat difficult.
7432+
*/
7433+
numParticlesOffset.store<patchType>(counter++ * length_of_patch);
7434+
patchExtent.store<type>(10);
7435+
}
7436+
writeFrom.clear();
7437+
it.close();
7438+
s.close();
7439+
}
7440+
7441+
{
7442+
Series s("../samples/joinedDimParallel." + ext, Access::READ_ONLY);
7443+
auto it = s.iterations[100];
7444+
auto e = it.particles["e"];
7445+
7446+
auto particleData = e["position"]["x"].loadChunk<type>();
7447+
auto numParticles =
7448+
e.particlePatches["numParticles"][RecordComponent::SCALAR]
7449+
.load<patchType>();
7450+
auto numParticlesOffset =
7451+
e.particlePatches["numParticlesOffset"][RecordComponent::SCALAR]
7452+
.load<patchType>();
7453+
auto patchOffset = e.particlePatches["offset"]["x"].load<type>();
7454+
auto patchExtent = e.particlePatches["extent"]["x"].load<type>();
7455+
7456+
it.close();
7457+
7458+
// check validity of particle patches
7459+
auto numPatches =
7460+
e.particlePatches["numParticlesOffset"][RecordComponent::SCALAR]
7461+
.getExtent()[0];
7462+
REQUIRE(
7463+
e.particlePatches["numParticles"][RecordComponent::SCALAR]
7464+
.getExtent()[0] == numPatches);
7465+
for (size_t i = 0; i < numPatches; ++i)
7466+
{
7467+
for (size_t j = 0; j < numParticles.get()[i]; ++j)
7468+
{
7469+
REQUIRE(
7470+
patchOffset.get()[i] <=
7471+
particleData.get()[numParticlesOffset.get()[i] + j]);
7472+
REQUIRE(
7473+
particleData.get()[numParticlesOffset.get()[i] + j] <
7474+
patchOffset.get()[i] + patchExtent.get()[i]);
7475+
}
7476+
}
7477+
7478+
/*
7479+
* Check that:
7480+
* 1. Joined array joins writes from lower ranks before higher ranks
7481+
* 2. Joined array joins early writes before later writes from the same
7482+
* rank
7483+
*/
7484+
for (size_t i = 0; i < length_of_patch * patches_per_rank; ++i)
7485+
{
7486+
REQUIRE(float(i) == particleData.get()[i]);
7487+
}
7488+
for (size_t i = 0; i < patches_per_rank; ++i)
7489+
{
7490+
REQUIRE(length_of_patch * i == numParticlesOffset.get()[i]);
7491+
REQUIRE(type(length_of_patch * i) == patchOffset.get()[i]);
7492+
}
7493+
}
7494+
}
7495+
7496+
TEST_CASE("joined_dim", "[serial]")
7497+
{
7498+
#if 100000000 * ADIOS2_VERSION_MAJOR + 1000000 * ADIOS2_VERSION_MINOR + \
7499+
10000 * ADIOS2_VERSION_PATCH + 100 * ADIOS2_VERSION_TWEAK >= \
7500+
209000000
7501+
constexpr char const *supportsJoinedDims[] = {"bp", "bp4", "bp5"};
7502+
#else
7503+
// no zero-size arrays
7504+
std::vector<char const *> supportsJoinedDims;
7505+
#endif
7506+
for (auto const &t : testedFileExtensions())
7507+
{
7508+
for (auto const supported : supportsJoinedDims)
7509+
{
7510+
if (t == supported)
7511+
{
7512+
joined_dim(t);
7513+
break;
7514+
}
7515+
}
7516+
}
7517+
}

0 commit comments

Comments
 (0)