1515#ifndef GPU_BENCHMARK_UTILS_H
1616#define GPU_BENCHMARK_UTILS_H
1717
18+ #if defined(__HIPCC__)
19+ #include " hip/hip_runtime.h"
20+ #endif
21+
1822#include < iostream>
1923#include < iomanip>
2024#include < typeinfo>
2125#include < boost/program_options.hpp>
2226#include < vector>
27+ #include < string>
2328#include < TTree.h>
2429#include < TFile.h>
2530
2631#define KNRM " \x1B [0m"
2732#define KRED " \x1B [31m"
2833#define KGRN " \x1B [32m"
2934#define KYEL " \x1B [33m"
30- #define KBLU " \x1B [34m"
35+ #define configLU " \x1B [34m"
3136#define KMAG " \x1B [35m"
3237#define KCYN " \x1B [36m"
3338#define KWHT " \x1B [37m"
@@ -48,16 +53,116 @@ enum class Test {
4853 Copy
4954};
5055
56+ inline std::ostream& operator <<(std::ostream& os, Test test)
57+ {
58+ switch (test) {
59+ case Test::Read:
60+ os << " read" ;
61+ break ;
62+ case Test::Write:
63+ os << " write" ;
64+ break ;
65+ case Test::Copy:
66+ os << " copy" ;
67+ break ;
68+ }
69+ return os;
70+ }
71+
5172enum class Mode {
5273 Sequential,
5374 Concurrent
5475};
5576
56- enum class SplitLevel {
57- Blocks,
58- Threads
77+ inline std::ostream& operator <<(std::ostream& os, Mode mode)
78+ {
79+ switch (mode) {
80+ case Mode::Sequential:
81+ os << " sequential" ;
82+ break ;
83+ case Mode::Concurrent:
84+ os << " concurrent" ;
85+ break ;
86+ }
87+ return os;
88+ }
89+
90+ enum class KernelConfig {
91+ Single,
92+ Multi
5993};
6094
95+ inline std::ostream& operator <<(std::ostream& os, KernelConfig config)
96+ {
97+ switch (config) {
98+ case KernelConfig::Single:
99+ os << " single" ;
100+ break ;
101+ case KernelConfig::Multi:
102+ os << " multiple" ;
103+ break ;
104+ }
105+ return os;
106+ }
107+
108+ template <class T >
109+ inline std::string getType ()
110+ {
111+ if (typeid (T).name () == typeid (char ).name ()) {
112+ return std::string{" char" };
113+ }
114+ if (typeid (T).name () == typeid (size_t ).name ()) {
115+ return std::string{" unsigned_long" };
116+ }
117+ if (typeid (T).name () == typeid (int ).name ()) {
118+ return std::string{" int" };
119+ }
120+ if (typeid (T).name () == typeid (int4).name ()) {
121+ return std::string{" int4" };
122+ }
123+ return std::string{" unknown" };
124+ }
125+
126+ inline std::string getTestName (Mode mode, Test test, KernelConfig blocks)
127+ {
128+ std::string tname;
129+ tname += (mode == Mode::Sequential) ? " seq_" : " conc_" ;
130+ tname += (test == Test::Read) ? " read_" : (test == Test::Write) ? " write_"
131+ : " copy_" ;
132+ tname += (blocks == KernelConfig::Single) ? " SB" : " MB" ;
133+ return tname;
134+ }
135+
136+ template <class chunk_t >
137+ inline chunk_t * getPartPtr (chunk_t * scratchPtr, float chunkReservedGB, int partNumber)
138+ {
139+ return reinterpret_cast <chunk_t *>(reinterpret_cast <char *>(scratchPtr) + static_cast <size_t >(GB * chunkReservedGB) * partNumber);
140+ }
141+
142+ inline float computeThroughput (Test test, float result, float chunkSizeGB, int ntests)
143+ {
144+ // https://docs.nvidia.com/cuda/cuda-c-best-practices-guide/index.html
145+ // Eff_bandwidth (GB/s) = (B_r + B_w) / (~1e9 * Time (s))
146+
147+ float throughput;
148+ switch (test) {
149+ case Test::Read: {
150+ throughput = 1e3 * chunkSizeGB * ntests / result;
151+ break ;
152+ }
153+ case Test::Write: {
154+ throughput = 1e3 * chunkSizeGB * ntests / result;
155+ break ;
156+ }
157+ case Test::Copy: {
158+ throughput = 2 * 1e3 * chunkSizeGB * ntests / result;
159+ break ;
160+ }
161+ }
162+
163+ return throughput;
164+ }
165+
61166namespace o2
62167{
63168namespace benchmark
@@ -69,7 +174,7 @@ struct benchmarkOpts {
69174 int deviceId = 0 ;
70175 std::vector<Test> tests = {Test::Read, Test::Write, Test::Copy};
71176 std::vector<Mode> modes = {Mode::Sequential, Mode::Concurrent};
72- std::vector<SplitLevel > pools = {SplitLevel::Blocks, SplitLevel::Threads };
177+ std::vector<KernelConfig > pools = {KernelConfig::Single, KernelConfig::Multi };
73178 std::vector<std::string> dtypes = {" char" , " int" , " ulong" };
74179 float chunkReservedGB = 1 .f;
75180 int nRegions = 2 ;
@@ -177,23 +282,8 @@ inline void ResultWriter::addBenchmarkEntry(const std::string bName, const std::
177282
178283inline void ResultWriter::storeBenchmarkEntry (Test test, int chunk, float entry, float chunkSizeGB, int nLaunches)
179284{
180- // https://docs.nvidia.com/cuda/cuda-c-best-practices-guide/index.html
181- // Eff_bandwidth (GB/s) = (B_r + B_w) / (~1e9 * Time (s))
182285 mTimeResults [chunk] = entry;
183- switch (test) {
184- case Test::Read: {
185- mThroughputResults [chunk] = 1e3 * chunkSizeGB * nLaunches / entry;
186- break ;
187- }
188- case Test::Write: {
189- mThroughputResults [chunk] = 1e3 * chunkSizeGB * nLaunches / entry;
190- break ;
191- }
192- case Test::Copy: {
193- mThroughputResults [chunk] = 2 * 1e3 * chunkSizeGB * nLaunches / entry;
194- break ;
195- }
196- }
286+ mThroughputResults [chunk] = computeThroughput (test, entry, chunkSizeGB, nLaunches);
197287}
198288
199289inline void ResultWriter::snapshotBenchmark ()
0 commit comments