24#include "openPMD/config.hpp"
27#include "RandomDatasetFiller.hpp"
29#include "openPMD/DatatypeHelpers.hpp"
30#include "openPMD/benchmark/mpi/BlockSlicer.hpp"
31#include "openPMD/benchmark/mpi/DatasetFiller.hpp"
32#include "openPMD/benchmark/mpi/MPIBenchmarkReport.hpp"
33#include "openPMD/openPMD.hpp"
56template <
typename DatasetFillerProv
ider>
61 using extentT = Extent::value_type;
62 MPI_Comm communicator = MPI_COMM_WORLD;
69 std::shared_ptr<BlockSlicer> m_blockSlicer;
71 DatasetFillerProvider m_dfp;
90 std::shared_ptr<BlockSlicer> blockSlicer,
91 DatasetFillerProvider dfp,
92 MPI_Comm comm = MPI_COMM_WORLD);
105 std::string jsonConfig,
123 std::string jsonConfig,
128 void resetConfigurations();
138 template <
typename Clock>
143 std::string m_basePath;
144 std::vector<std::tuple<
161 std::pair<Offset, Extent> slice(
int size);
169 template <
typename Clock>
170 struct BenchmarkExecution
174 explicit BenchmarkExecution(
176 : m_benchmark{benchmark}
190 template <
typename T>
191 typename Clock::duration writeBenchmark(
192 std::string
const &jsonConfig,
195 std::string
const &extension,
196 std::shared_ptr<DatasetFiller<T>> datasetFiller,
208 template <
typename T>
209 typename Clock::duration readBenchmark(
212 std::string extension,
215 template <
typename T>
217 BenchmarkExecution<Clock> &,
218 MPIBenchmarkReport<typename Clock::duration> &report,
221 static constexpr char const *errorMsg =
"BenchmarkExecution";
227template <
typename DatasetFillerProv
ider>
228template <
typename Clock>
233 BenchmarkExecution<Clock> exec{
this};
235 std::set<Datatype> datatypes;
236 for (
auto const &conf : m_configurations)
238 datatypes.insert(std::get<DTYPE>(conf));
248template <
typename DatasetFillerProv
ider>
250 std::string basePath,
252 std::shared_ptr<BlockSlicer> blockSlicer,
253 DatasetFillerProvider dfp,
257 , m_blockSlicer{
std::move(blockSlicer)}
259 , m_basePath{
std::move(basePath)}
261 if (m_blockSlicer ==
nullptr)
262 throw std::runtime_error(
"Argument blockSlicer cannot be a nullptr!");
265template <
typename DatasetFillerProv
ider>
266std::pair<Offset, Extent> MPIBenchmark<DatasetFillerProvider>::slice(
int size)
269 MPI_Comm_size(this->communicator, &actualSize);
271 MPI_Comm_rank(this->communicator, &rank);
272 size = std::min(size, actualSize);
273 return m_blockSlicer->sliceBlock(totalExtent, size, rank);
276template <
typename DatasetFillerProv
ider>
278 std::string jsonConfig,
284 this->m_configurations.emplace_back(
285 std::move(jsonConfig), backend, threadSize, dt, iterations);
288template <
typename DatasetFillerProv
ider>
290 std::string jsonConfig,
296 MPI_Comm_size(communicator, &size);
300template <
typename DatasetFillerProv
ider>
301void MPIBenchmark<DatasetFillerProvider>::resetConfigurations()
303 this->m_configurations.clear();
306template <
typename DatasetFillerProv
ider>
307template <
typename Clock>
309typename Clock::duration
310MPIBenchmark<DatasetFillerProvider>::BenchmarkExecution<Clock>::writeBenchmark(
311 std::string
const &jsonConfig,
314 std::string
const &extension,
315 std::shared_ptr<DatasetFiller<T>> datasetFiller,
318 MPI_Barrier(m_benchmark->communicator);
319 auto start = Clock::now();
322 Series series = Series(
323 m_benchmark->m_basePath +
"." + extension,
325 m_benchmark->communicator,
328 typename Clock::duration ignore{};
332 auto ignore_start = Clock::now();
333 auto writeData = datasetFiller->produceData();
334 auto ignore_end = Clock::now();
335 ignore += ignore_end - ignore_start;
338 .meshes[
"id"][MeshRecordComponent::SCALAR];
340 Datatype datatype = determineDatatype(writeData);
343 id.resetDataset(dataset);
347 id.storeChunk<
T>(writeData, offset, extent);
351 MPI_Barrier(m_benchmark->communicator);
352 auto end = Clock::now();
354 return (end - start) - ignore;
357template <
typename DatasetFillerProv
ider>
358template <
typename Clock>
360typename Clock::duration
361MPIBenchmark<DatasetFillerProvider>::BenchmarkExecution<Clock>::readBenchmark(
364 std::string extension,
367 MPI_Barrier(m_benchmark->communicator);
369 auto start = Clock::now();
372 m_benchmark->m_basePath +
"." + extension,
374 m_benchmark->communicator);
379 series.snapshots()[i].meshes[
"id"][MeshRecordComponent::SCALAR];
381 auto chunk_data =
id.
loadChunk<
T>(offset, extent);
385 MPI_Barrier(m_benchmark->communicator);
386 auto end = Clock::now();
390template <
typename DatasetFillerProv
ider>
391template <
typename Clock>
393void MPIBenchmark<DatasetFillerProvider>::BenchmarkExecution<Clock>::call(
394 BenchmarkExecution<Clock> &exec,
398 Datatype dt = determineDatatype<T>();
399 auto dsf = std::dynamic_pointer_cast<DatasetFiller<T>>(
400 exec.m_benchmark->m_dfp.template operator()<
T>());
401 for (
auto const &config : exec.m_benchmark->m_configurations)
403 std::string jsonConfig;
408 std::tie(jsonConfig, backend, size, dt2, iterations) = config;
415 auto localCuboid = exec.m_benchmark->slice(size);
417 extentT blockSize = 1;
418 for (
auto ext : localCuboid.second)
422 dsf->setNumberOfItems(blockSize);
424 auto writeTime = exec.writeBenchmark<
T>(
431 auto readTime = exec.readBenchmark<
T>(
432 localCuboid.first, localCuboid.second, backend, iterations);
440 std::make_pair(writeTime, readTime));
Definition Dataset.hpp:38
Class representing a benchmark.
Definition MPIBenchmark.hpp:58
void addConfiguration(std::string jsonConfig, std::string backend, Datatype dt, Series::IterationIndex_t iterations, int threadSize)
Definition MPIBenchmark.hpp:277
Extent totalExtent
Total extent of the hypercuboid used in the benchmark.
Definition MPIBenchmark.hpp:67
MPIBenchmark(std::string basePath, Extent tExtent, std::shared_ptr< BlockSlicer > blockSlicer, DatasetFillerProvider dfp, MPI_Comm comm=MPI_COMM_WORLD)
Construct an MPI benchmark manually.
Definition MPIBenchmark.hpp:249
MPIBenchmarkReport< typename Clock::duration > runBenchmark(int rootThread=0)
Main function for running a benchmark.
Definition MPIBenchmark.hpp:230
Definition MeshRecordComponent.hpp:36
std::shared_ptr< T > loadChunk(Offset={0u}, Extent={-1u})
Load and allocate a chunk of data.
Definition RecordComponent.cpp:754
Implementation for the root level of the openPMD hierarchy.
Definition Series.hpp:288
Iteration::IterationIndex_t IterationIndex_t
An unsigned integer type, used to identify Iterations in a Series.
Definition Series.hpp:383
Public definitions of openPMD-api.
Definition Date.cpp:29
@ T
time
Definition UnitDimension.hpp:41
Datatype
Concrete datatype of an object available at runtime.
Definition Datatype.hpp:51
constexpr auto switchDatasetType(Datatype dt, Args &&...args) -> decltype(Action::template call< char >(std::forward< Args >(args)...))
Generalizes switching over an openPMD datatype.
The report for a single benchmark produced by <openPMD/benchmark/mpi/MPIBenchmark>.
Definition MPIBenchmarkReport.hpp:45