|
| 1 | +#pragma once |
| 2 | + |
| 3 | +#include <algorithm> |
| 4 | +#include <array> |
| 5 | +#include <initializer_list> |
| 6 | +#include <iostream> |
| 7 | + |
| 8 | +// Array values |
| 9 | +#define startA (0.1) |
| 10 | +#define startB (0.2) |
| 11 | +#define startC (0.0) |
| 12 | +#define startScalar (0.4) |
| 13 | + |
| 14 | +// Benchmark Identifier: identifies individual & groups of benchmarks: |
| 15 | +// - Classic: 5 classic kernels: Copy, Mul, Add, Triad, Dot. |
| 16 | +// - All: all kernels. |
| 17 | +// - Individual kernels only. |
| 18 | +enum class BenchId : int {Copy, Mul, Add, Triad, Nstream, Dot, Classic, All}; |
| 19 | + |
| 20 | +struct Benchmark { |
| 21 | + BenchId id; |
| 22 | + char const* label; |
| 23 | + // Weight counts data elements of original arrays moved each loop iteration - used to calculate achieved BW: |
| 24 | + // bytes = weight * sizeof(T) * ARRAY_SIZE -> bw = bytes / dur |
| 25 | + size_t weight; |
| 26 | + // Is it one of: Copy, Mul, Add, Triad, Dot? |
| 27 | + bool classic = false; |
| 28 | +}; |
| 29 | + |
| 30 | +// Benchmarks in the order in which - if present - should be run for validation purposes: |
| 31 | +constexpr size_t num_benchmarks = 6; |
| 32 | +constexpr std::array<Benchmark, num_benchmarks> bench = { |
| 33 | + Benchmark { .id = BenchId::Copy, .label = "Copy", .weight = 2, .classic = true }, |
| 34 | + Benchmark { .id = BenchId::Mul, .label = "Mul", .weight = 2, .classic = true }, |
| 35 | + Benchmark { .id = BenchId::Add, .label = "Add", .weight = 3, .classic = true }, |
| 36 | + Benchmark { .id = BenchId::Triad, .label = "Triad", .weight = 3, .classic = true }, |
| 37 | + Benchmark { .id = BenchId::Dot, .label = "Dot", .weight = 2, .classic = true }, |
| 38 | + Benchmark { .id = BenchId::Nstream, .label = "Nstream", .weight = 4, .classic = false } |
| 39 | +}; |
| 40 | + |
| 41 | +// Which buffers are needed by each benchmark |
| 42 | +inline bool needs_buffer(BenchId id, char n) { |
| 43 | + auto in = [n](std::initializer_list<char> values) { |
| 44 | + return std::find(values.begin(), values.end(), n) != values.end(); |
| 45 | + }; |
| 46 | + switch(id) { |
| 47 | + case BenchId::All: return in({'a','b','c'}); |
| 48 | + case BenchId::Classic: return in({'a','b','c'}); |
| 49 | + case BenchId::Copy: return in({'a','c'}); |
| 50 | + case BenchId::Mul: return in({'b','c'}); |
| 51 | + case BenchId::Add: return in({'a','b','c'}); |
| 52 | + case BenchId::Triad: return in({'a','b','c'}); |
| 53 | + case BenchId::Dot: return in({'a','b'}); |
| 54 | + case BenchId::Nstream: return in({'a','b','c'}); |
| 55 | + default: |
| 56 | + std::cerr << "Unknown benchmark" << std::endl; |
| 57 | + abort(); |
| 58 | + } |
| 59 | +} |
| 60 | + |
| 61 | +// Returns true if the benchmark needs to be run: |
| 62 | +inline bool run_benchmark(BenchId selection, Benchmark const& b) { |
| 63 | + if (selection == BenchId::All) return true; |
| 64 | + if (selection == BenchId::Classic && b.classic) return true; |
| 65 | + return selection == b.id; |
| 66 | +} |
0 commit comments