Skip to content

Commit 83a441c

Browse files
committed
Testing
Only test if ADIOS2 version at least 2.9
1 parent e86addc commit 83a441c

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
@@ -7276,3 +7276,147 @@ TEST_CASE("groupbased_read_write", "[serial]")
72767276
groupbased_read_write("toml");
72777277
}
72787278
}
7279+
7280+
void joined_dim(std::string const &ext)
7281+
{
7282+
using type = float;
7283+
using patchType = uint64_t;
7284+
constexpr size_t patches_per_rank = 5;
7285+
constexpr size_t length_of_patch = 10;
7286+
7287+
{
7288+
Series s("../samples/joinedDimParallel." + ext, Access::CREATE);
7289+
std::vector<UniquePtrWithLambda<type>> writeFrom(patches_per_rank);
7290+
7291+
auto it = s.writeIterations()[100];
7292+
7293+
Dataset numParticlesDS(
7294+
determineDatatype<patchType>(), {Dataset::JOINED_DIMENSION});
7295+
auto numParticles =
7296+
it.particles["e"]
7297+
.particlePatches["numParticles"][RecordComponent::SCALAR];
7298+
auto numParticlesOffset =
7299+
it.particles["e"]
7300+
.particlePatches["numParticlesOffset"][RecordComponent::SCALAR];
7301+
numParticles.resetDataset(numParticlesDS);
7302+
numParticlesOffset.resetDataset(numParticlesDS);
7303+
7304+
auto patchOffset = it.particles["e"].particlePatches["offset"]["x"];
7305+
auto patchExtent = it.particles["e"].particlePatches["extent"]["x"];
7306+
Dataset particlePatchesDS(
7307+
determineDatatype<float>(), {Dataset::JOINED_DIMENSION});
7308+
patchOffset.resetDataset(particlePatchesDS);
7309+
patchExtent.resetDataset(particlePatchesDS);
7310+
7311+
for (size_t i = 0; i < 5; ++i)
7312+
{
7313+
writeFrom[i] = UniquePtrWithLambda<type>(
7314+
new type[length_of_patch],
7315+
[](auto const *ptr) { delete[] ptr; });
7316+
std::iota(
7317+
writeFrom[i].get(),
7318+
writeFrom[i].get() + 10,
7319+
length_of_patch * i);
7320+
patchOffset.store<type>(length_of_patch * i);
7321+
}
7322+
7323+
auto epx = it.particles["e"]["position"]["x"];
7324+
Dataset ds(determineDatatype<type>(), {Dataset::JOINED_DIMENSION});
7325+
epx.resetDataset(ds);
7326+
7327+
size_t counter = 0;
7328+
for (auto &chunk : writeFrom)
7329+
{
7330+
epx.storeChunk(std::move(chunk), {}, {length_of_patch});
7331+
numParticles.store<patchType>(length_of_patch);
7332+
/*
7333+
* For the sake of the test case, we know that the
7334+
* numParticlesOffset has this value. In general, the purpose of the
7335+
* joined array is that we don't need to know these values, so the
7336+
* specification of particle patches is somewhat difficult.
7337+
*/
7338+
numParticlesOffset.store<patchType>(counter++ * length_of_patch);
7339+
patchExtent.store<type>(10);
7340+
}
7341+
writeFrom.clear();
7342+
it.close();
7343+
s.close();
7344+
}
7345+
7346+
{
7347+
Series s("../samples/joinedDimParallel." + ext, Access::READ_ONLY);
7348+
auto it = s.iterations[100];
7349+
auto e = it.particles["e"];
7350+
7351+
auto particleData = e["position"]["x"].loadChunk<type>();
7352+
auto numParticles =
7353+
e.particlePatches["numParticles"][RecordComponent::SCALAR]
7354+
.load<patchType>();
7355+
auto numParticlesOffset =
7356+
e.particlePatches["numParticlesOffset"][RecordComponent::SCALAR]
7357+
.load<patchType>();
7358+
auto patchOffset = e.particlePatches["offset"]["x"].load<type>();
7359+
auto patchExtent = e.particlePatches["extent"]["x"].load<type>();
7360+
7361+
it.close();
7362+
7363+
// check validity of particle patches
7364+
auto numPatches =
7365+
e.particlePatches["numParticlesOffset"][RecordComponent::SCALAR]
7366+
.getExtent()[0];
7367+
REQUIRE(
7368+
e.particlePatches["numParticles"][RecordComponent::SCALAR]
7369+
.getExtent()[0] == numPatches);
7370+
for (size_t i = 0; i < numPatches; ++i)
7371+
{
7372+
for (size_t j = 0; j < numParticles.get()[i]; ++j)
7373+
{
7374+
REQUIRE(
7375+
patchOffset.get()[i] <=
7376+
particleData.get()[numParticlesOffset.get()[i] + j]);
7377+
REQUIRE(
7378+
particleData.get()[numParticlesOffset.get()[i] + j] <
7379+
patchOffset.get()[i] + patchExtent.get()[i]);
7380+
}
7381+
}
7382+
7383+
/*
7384+
* Check that:
7385+
* 1. Joined array joins writes from lower ranks before higher ranks
7386+
* 2. Joined array joins early writes before later writes from the same
7387+
* rank
7388+
*/
7389+
for (size_t i = 0; i < length_of_patch * patches_per_rank; ++i)
7390+
{
7391+
REQUIRE(float(i) == particleData.get()[i]);
7392+
}
7393+
for (size_t i = 0; i < patches_per_rank; ++i)
7394+
{
7395+
REQUIRE(length_of_patch * i == numParticlesOffset.get()[i]);
7396+
REQUIRE(type(length_of_patch * i) == patchOffset.get()[i]);
7397+
}
7398+
}
7399+
}
7400+
7401+
TEST_CASE("joined_dim", "[serial]")
7402+
{
7403+
#if 100000000 * ADIOS2_VERSION_MAJOR + 1000000 * ADIOS2_VERSION_MINOR + \
7404+
10000 * ADIOS2_VERSION_PATCH + 100 * ADIOS2_VERSION_TWEAK >= \
7405+
209000000
7406+
constexpr char const *supportsJoinedDims[] = {"bp", "bp4", "bp5"};
7407+
#else
7408+
// no zero-size arrays
7409+
std::vector<char const *> supportsJoinedDims;
7410+
#endif
7411+
for (auto const &t : testedFileExtensions())
7412+
{
7413+
for (auto const supported : supportsJoinedDims)
7414+
{
7415+
if (t == supported)
7416+
{
7417+
joined_dim(t);
7418+
break;
7419+
}
7420+
}
7421+
}
7422+
}

0 commit comments

Comments
 (0)