39 std::unordered_map<std::string, double> microbench_results = {};
43namespace shamsys::microbench {
59 template<
typename T, sham::benchmarks::IntChainOp op>
114 u64 length = 1024UL * 1014UL * 8UL;
118 std::vector<MPI_Request> rqs;
122 bool is_used =
false;
126 mpi::barrier(MPI_COMM_WORLD);
127 f64 t_start = MPI_Wtime();
129 if (wr == wr_sender) {
130 rqs.push_back(MPI_Request{});
131 u32 rq_index = rqs.size() - 1;
132 auto &rq = rqs[rq_index];
134 buf_send.get_ptr(), length, MPI_BYTE, wr_receiv, 0, MPI_COMM_WORLD, &rq);
138 if (wr == wr_receiv) {
141 buf_recv.get_ptr(), length, MPI_BYTE, wr_sender, 0, MPI_COMM_WORLD, &s);
148 std::vector<MPI_Status> st_lst(rqs.size());
149 if (rqs.size() > 0) {
152 f64 t_end = MPI_Wtime();
153 t += t_end - t_start;
155 }
while (shamalgs::collective::allreduce_min(t) < 1);
157 f64 bw =
f64(length * loops) / t;
159 microbench_results[
"p2p_bandwidth"] = bw;
165 " - p2p bandwidth : {:.2f} {}B.s^-1 (ranks : {} -> {}) (loops : {})",
179 "can not launch this test with same ranks");
193 bool is_used =
false;
197 mpi::barrier(MPI_COMM_WORLD);
198 f64 t_start = MPI_Wtime();
217 f64 t_end = MPI_Wtime();
218 t += t_end - t_start;
222 }
while (shamalgs::collective::allreduce_min(bench_timer.
elapsed_sec()) < 1);
224 f64 latency = t /
f64(loops);
225 microbench_results[
"p2p_latency"] = latency;
230 " - p2p latency : {:.4e} s (ranks : {} <-> {}) (loops : {})",
240 int Tsize =
sizeof(T);
242 std::string type_name;
244 if constexpr (std::is_same_v<T, f32>) {
249 }
else if constexpr (std::is_same_v<T, f64>) {
254 }
else if constexpr (std::is_same_v<T, f32_2>) {
256 init_x = {1.0f, 1.0f};
257 init_y = {2.0f, 2.0f};
259 }
else if constexpr (std::is_same_v<T, f64_2>) {
264 }
else if constexpr (std::is_same_v<T, f32_3>) {
266 init_x = {1.0f, 1.0f, 1.0f};
267 init_y = {2.0f, 2.0f, 2.0f};
268 a = {2.0f, 2.0f, 2.0f};
269 }
else if constexpr (std::is_same_v<T, f64_3>) {
271 init_x = {1.0, 1.0, 1.0};
272 init_y = {2.0, 2.0, 2.0};
274 }
else if constexpr (std::is_same_v<T, f32_4>) {
276 init_x = {1.0f, 1.0f, 1.0f, 1.0f};
277 init_y = {2.0f, 2.0f, 2.0f, 2.0f};
278 a = {2.0f, 2.0f, 2.0f, 2.0f};
279 }
else if constexpr (std::is_same_v<T, f64_4>) {
281 init_x = {1.0, 1.0, 1.0, 1.0};
282 init_y = {2.0, 2.0, 2.0, 2.0};
283 a = {2.0, 2.0, 2.0, 2.0};
288 auto bench_step = [&](
int N) {
290 instance::get_compute_scheduler_ptr(), N, init_x, init_y, a, Tsize, N < (1 << 17));
293 auto benchmark = [&]() {
294 size_t N = (1 << 15);
297 auto &dev_ptr = dev_ctx.device;
301 = std::min<size_t>(dev.prop.max_mem_alloc_size_dev, dev.prop.global_mem_size);
302 double max_size = double(max_alloc) / (Tsize * 4);
303 if (max_size >= (1 << 30)) {
304 max_size = (1 << 30);
307 auto result = bench_step(shambase::narrow_or_throw<i32>(N));
309 for (; N <= (1 << 30) && static_cast<double>(N) <= max_size; N *= 2) {
310 result = bench_step(shambase::narrow_or_throw<i32>(N));
315 if (result.seconds > 1e-3) {
323 auto result = benchmark();
325 f64 bw = result.bandwidth * 1e9;
327 f64 min_bw = shamalgs::collective::allreduce_min(bw);
328 f64 max_bw = shamalgs::collective::allreduce_max(bw);
329 f64 sum_bw = shamalgs::collective::allreduce_sum(bw);
332 microbench_results[
"saxpy_" + type_name] = sum_bw;
338 " - saxpy ({}) : {:.2f} {}B.s^-1 (min = {:.1e}, max = {:.1e}, avg = {:.1e}) "
346 result.seconds * 1e3,
358 std::string type_name;
359 f64 flops_multiplier = 1;
360 if constexpr (std::is_same_v<T, f32>) {
362 flops_multiplier = 1;
363 }
else if constexpr (std::is_same_v<T, f64>) {
365 flops_multiplier = 1;
366 }
else if constexpr (std::is_same_v<T, f32_2>) {
368 flops_multiplier = 2;
369 }
else if constexpr (std::is_same_v<T, f64_2>) {
371 flops_multiplier = 2;
372 }
else if constexpr (std::is_same_v<T, f32_3>) {
374 flops_multiplier = 3;
375 }
else if constexpr (std::is_same_v<T, f64_3>) {
377 flops_multiplier = 3;
378 }
else if constexpr (std::is_same_v<T, f32_4>) {
380 flops_multiplier = 4;
381 }
else if constexpr (std::is_same_v<T, f64_4>) {
383 flops_multiplier = 4;
388 f64 min_flop = shamalgs::collective::allreduce_min(result.flops);
389 f64 max_flop = shamalgs::collective::allreduce_max(result.flops);
390 f64 sum_flop = shamalgs::collective::allreduce_sum(result.flops);
393 microbench_results[
"fma_chains_" + type_name] = sum_flop * flops_multiplier;
399 " - fma_chains ({}) : {:.2f} {}flops (min = {:.1e}, max = {:.1e}, avg = {:.1e}) "
400 "({:.1e} ms, rotations = {})",
404 min_flop * flops_multiplier,
405 max_flop * flops_multiplier,
406 avg_flop * flops_multiplier,
407 result.seconds * 1e3,
412template<
typename T, sham::benchmarks::IntChainOp op>
419 std::string type_name;
420 if constexpr (std::is_same_v<T, u32>) {
422 }
else if constexpr (std::is_same_v<T, u64>) {
430 f64 min_iops = shamalgs::collective::allreduce_min(result.iops);
431 f64 max_iops = shamalgs::collective::allreduce_max(result.iops);
432 f64 sum_iops = shamalgs::collective::allreduce_sum(result.iops);
435 microbench_results[
"int_" + op_name +
"_chains_" + type_name] = sum_iops;
441 " - int_{}_chains ({}) : {:.2f} {}iops (min = {:.1e}, max = {:.1e}, avg = {:.1e}) "
442 "({:.1e} ms, rotations = {})",
450 result.seconds * 1e3,
458 std::vector<u64> send_data(el_per_rank);
460 std::vector<u64> recv_data;
465 auto benchmark_step = [&]() {
467 f64 t_start = MPI_Wtime();
469 f64 t_end = MPI_Wtime();
470 t += t_end - t_start;
476 }
while (shamalgs::collective::allreduce_min(t) < 0.1);
480 f64 min_t = shamalgs::collective::allreduce_min(t);
481 f64 max_t = shamalgs::collective::allreduce_max(t);
482 f64 sum_t = shamalgs::collective::allreduce_sum(t);
485 microbench_results[
"vector_allgather_u64_" + std::to_string(el_per_rank)] = avg_t;
490 " - vector_allgather (u64, n={:4}) : {:.3e} s (min = {:.2e}, max = {:.2e}, loops = "
501 if (allow_run && microbench_results.empty()) {
504 return microbench_results;
Shamrock communication buffers.
void vector_allgather(u32 el_per_rank)
Vector allgather benchmark.
void p2p_latency(u32 wr1, u32 wr2)
MPI point-to-point latency benchmark.
void p2p_bandwidth(u32 wr_sender, u32 wr_receiv)
MPI point-to-point bandwidth benchmark.
void int_chains_rotation()
Integer chains benchmark to get the maximum integer performance.
void saxpy()
SAXPY benchmark, to get the maximum bandwidth.
void fma_chains_rotation()
FMA chains benchmark to get the maximum floating point performance.
This header does the MPI include and wrap MPI calls.
Header file describing a Node Instance.
double f64
Alias for double.
std::uint32_t u32
32 bit unsigned integer
std::uint64_t u64
64 bit unsigned integer
Class Timer measures the time elapsed since the timer was started.
f64 elapsed_sec() const
Converts the stored nanosecond time to a floating point representation in seconds.
void start()
Starts the timer.
void stop()
Stops the timer and stores the elapsed time in nanoseconds.
Shamrock communication buffers.
This header file contains utility functions related to exception handling in the code.
std::vector< int > vector_allgatherv(const std::vector< T > &send_vec, const MPI_Datatype &send_type, std::vector< T > &recv_vec, const MPI_Datatype &recv_type, const MPI_Comm comm)
allgatherv on vector with size query (size querying variant of vector_allgatherv_ks) //TODO add fault...
Port of Argonne National Laboratory's FMA chains benchmark flops.cpp.
fma_chains_result fma_chains_bench(DeviceScheduler_ptr sched, int N, f64 time_threshold)
Run the fma_chains benchmark.
Convert raw numeric values to human-readable SI-formatted pairs.
Integer ALU throughput benchmark (multiply chains vs add chains).
int_chains_result int_chains_bench(DeviceScheduler_ptr sched, int N, f64 time_threshold)
Run the int_chains benchmark.
@ Mul
multiply-add chains, 16 multiplies + 16 adds per rotation
human_readable_t to_human_readable(double value)
Convert a raw value to a human-readable scaled form with an SI prefix.
std::string readable_sizeof(double size)
given a sizeof value return a readble string Example : readable_sizeof(1e9) -> "1....
T & get_check_ref(const std::unique_ptr< T > &ptr, SourceLocation loc=SourceLocation())
Takes a std::unique_ptr and returns a reference to the object it holds. It throws a std::runtime_erro...
ExcptTypes make_except_with_loc(std::string message, SourceLocation loc=SourceLocation{})
Create an exception with a message and a location.
i32 world_rank()
Gives the rank of the current process in the MPI communicator.
i32 world_size()
Gives the size of the MPI communicator.
void run_micro_benchmark()
Run latency & bandwidth benchmark those benchmark where adapted from osu_microbenchmark.
const std::unordered_map< std::string, double > & get_microbench_results(bool allow_run=false)
Get the microbench results.
saxpy_result saxpy_bench(DeviceScheduler_ptr sched, int N, T init_x, T init_y, T a, int load_size, bool check_correctness)
saxpy function for benchmarking.
void raw_ln(Types... var2)
Prints a log message with multiple arguments followed by a newline.
This file contains the definition for the stacktrace related functionality.
shambase::details::BasicStackEntry StackEntry
Alias for shambase::details::BasicStackEntry.
void Recv(void *buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)
MPI wrapper for MPI_Recv.
void Barrier(MPI_Comm comm)
MPI wrapper for MPI_Barrier.
void Waitall(int count, MPI_Request array_of_requests[], MPI_Status *array_of_statuses)
MPI wrapper for MPI_Waitall.
void Send(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm)
MPI wrapper for MPI_Send.
void Isend(const void *buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request)
MPI wrapper for MPI_Isend.