openPMD-api
 
Loading...
Searching...
No Matches
MPIBenchmarkReport.hpp
1/* Copyright 2018-2025 Franz Poeschel, Axel Huebl
2 *
3 * This file is part of openPMD-api.
4 *
5 * openPMD-api is free software: you can redistribute it and/or modify
6 * it under the terms of of either the GNU General Public License or
7 * the GNU Lesser General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * openPMD-api is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License and the GNU Lesser General Public License
15 * for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * and the GNU Lesser General Public License along with openPMD-api.
19 * If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#pragma once
23
24#include "openPMD/config.hpp"
25#if openPMD_HAVE_MPI
26
27#include "openPMD/Datatype.hpp"
28#include "openPMD/Series.hpp"
29
30#include "string.h"
31#include <map>
32#include <mpi.h>
33#include <tuple>
34#include <vector>
35
36namespace openPMD
37{
43template <typename Duration>
44struct MPIBenchmarkReport
45{
46 MPI_Comm communicator;
47
48 MPIBenchmarkReport(MPI_Comm);
49
53 std::map<
54 std::tuple<
55 int, // rank
56 std::string, // jsonConfig
57 std::string, // extension
58 int, // thread size
61 std::pair<Duration, Duration> >
63
64 enum Selector
65 {
66 RANK = 0,
67 COMPRESSION,
68 COMPRESSION_LEVEL,
69 BACKEND,
70 NRANKS,
71 DTYPE,
72 ITERATIONS
73 };
74
86 void addReport(
87 int rootThread,
88 std::string jsonConfig,
89 std::string extension,
90 int threadSize,
91 Datatype dt,
92 Series::IterationIndex_t iterations,
93 std::pair<Duration, Duration> const &report);
94
105 std::pair<Duration, Duration> getReport(
106 int rank,
107 std::string jsonConfig,
108 std::string extension,
109 int threadSize,
110 Datatype dt,
111 Series::IterationIndex_t iterations);
112
113private:
114 template <typename D, typename Dummy = D>
115 struct MPIDatatype
116 {};
117
118 template <typename Dummy>
119 struct MPIDatatype<char, Dummy>
120 {
121 MPI_Datatype dt = MPI_CHAR;
122 };
123 template <typename Dummy>
124 struct MPIDatatype<unsigned char, Dummy>
125 {
126 MPI_Datatype dt = MPI_UNSIGNED_CHAR;
127 };
128 template <typename Dummy>
129 struct MPIDatatype<short, Dummy>
130 {
131 MPI_Datatype dt = MPI_SHORT;
132 };
133 template <typename Dummy>
134 struct MPIDatatype<int, Dummy>
135 {
136 MPI_Datatype dt = MPI_INT;
137 };
138 template <typename Dummy>
139 struct MPIDatatype<long, Dummy>
140 {
141 MPI_Datatype dt = MPI_LONG;
142 };
143 template <typename Dummy>
144 struct MPIDatatype<float, Dummy>
145 {
146 MPI_Datatype dt = MPI_FLOAT;
147 };
148 template <typename Dummy>
149 struct MPIDatatype<double, Dummy>
150 {
151 MPI_Datatype dt = MPI_DOUBLE;
152 };
153 template <typename Dummy>
154 struct MPIDatatype<unsigned short, Dummy>
155 {
156 MPI_Datatype dt = MPI_UNSIGNED_SHORT;
157 };
158 template <typename Dummy>
159 struct MPIDatatype<unsigned int, Dummy>
160 {
161 MPI_Datatype dt = MPI_UNSIGNED;
162 };
163 template <typename Dummy>
164 struct MPIDatatype<unsigned long, Dummy>
165 {
166 MPI_Datatype dt = MPI_UNSIGNED_LONG;
167 };
168 template <typename Dummy>
169 struct MPIDatatype<long double, Dummy>
170 {
171 MPI_Datatype dt = MPI_LONG_DOUBLE;
172 };
173 template <typename Dummy>
174 struct MPIDatatype<long long, Dummy>
175 {
176 MPI_Datatype dt = MPI_LONG_LONG_INT;
177 };
178
179 MPIDatatype<typename Duration::rep> m_mpiDatatype;
180 MPI_Datatype mpiType = m_mpiDatatype.dt;
181};
182
183// implementation
184
185template <typename Duration>
187 int rootThread,
188 std::string jsonConfig,
189 std::string extension,
190 int threadSize,
191 Datatype dt,
192 Series::IterationIndex_t iterations,
193 std::pair<Duration, Duration> const &report)
194{
195 using rep = typename Duration::rep;
196 // auto mpi_dt = MPIDatatype<rep>::dt;
197 int rank;
198 MPI_Comm_rank(communicator, &rank);
199 int size;
200 MPI_Comm_size(communicator, &size);
201 MPI_Comm restricted;
202 MPI_Comm_split(
203 communicator, rank < threadSize ? 0 : MPI_UNDEFINED, rank, &restricted);
204 rep readWrite[2];
205 if (rank < threadSize)
206 {
207 readWrite[0] = report.first.count();
208 readWrite[1] = report.second.count();
209 }
210 rep *recv = nullptr;
211 if (rank == rootThread)
212 {
213 recv = new rep[2 * threadSize];
214 }
215
216 if (restricted != MPI_COMM_NULL)
217 {
218 MPI_Gather(
219 readWrite,
220 2, // should be 2 but doesnt work then..
221 this->mpiType,
222 recv,
223 2,
224 this->mpiType,
225 rootThread,
226 restricted);
227 }
228
229 if (rank == rootThread)
230 {
231 for (int i = 0; i < threadSize; i++)
232 {
233 Duration dWrite{recv[2 * i]};
234 Duration dRead{recv[2 * i + 1]};
235 this->durations.emplace(
236 std::make_tuple(
237 i, jsonConfig, extension, threadSize, dt, iterations),
238 std::make_pair(dWrite, dRead));
239 }
240 delete[] recv;
241 }
242 if (restricted != MPI_COMM_NULL)
243 {
244 MPI_Comm_free(&restricted);
245 }
246}
247
248template <typename Duration>
249MPIBenchmarkReport<Duration>::MPIBenchmarkReport(MPI_Comm comm)
250 : communicator{comm}
251{}
252
253template <typename Duration>
254std::pair<Duration, Duration> MPIBenchmarkReport<Duration>::getReport(
255 int rank,
256 std::string jsonConfig,
257 std::string extension,
258 int threadSize,
259 Datatype dt,
260 Series::IterationIndex_t iterations)
261{
262 auto it = this->durations.find(
263 std::make_tuple(
264 rank, jsonConfig, extension, threadSize, dt, iterations));
265 if (it == this->durations.end())
266 {
267 throw std::runtime_error(
268 "Requested report not found. (Reports are available on the root "
269 "thread only)");
270 }
271 else
272 {
273 return it->second;
274 }
275}
276
277} // namespace openPMD
278
279#endif
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
Datatype
Concrete datatype of an object available at runtime.
Definition Datatype.hpp:51
std::map< std::tuple< int, std::string, std::string, int, Datatype, Series::IterationIndex_t >, std::pair< Duration, Duration > > durations
Time needed for writing and reading per compression strategy and level.
Definition MPIBenchmarkReport.hpp:62
void addReport(int rootThread, std::string jsonConfig, std::string extension, int threadSize, Datatype dt, Series::IterationIndex_t iterations, std::pair< Duration, Duration > const &report)
Add results for a certain compression strategy and level.
Definition MPIBenchmarkReport.hpp:186
std::pair< Duration, Duration > getReport(int rank, std::string jsonConfig, std::string extension, int threadSize, Datatype dt, Series::IterationIndex_t iterations)
Retrieve the time measured for a certain compression strategy.
Definition MPIBenchmarkReport.hpp:254