Skip to content

Commit 0d8b785

Browse files
authored
Merge pull request #646 from teojgo/regression_test/kernel_latency
[test] Add benchmark measuring CUDA kernel launch latency
2 parents ab6a8bc + 42c8e33 commit 0d8b785

File tree

2 files changed

+143
-0
lines changed

2 files changed

+143
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import reframe as rfm
2+
import reframe.utility.sanity as sn
3+
4+
5+
@rfm.required_version('>=2.16-dev0')
6+
@rfm.parameterized_test(['sync'], ['async'])
7+
class KernelLatencyTest(rfm.RegressionTest):
8+
def __init__(self, kernel_version):
9+
super().__init__()
10+
self.sourcepath = 'kernel_latency.cu'
11+
self.build_system = 'SingleSource'
12+
self.valid_systems = ['daint:gpu', 'dom:gpu', 'kesch:cn']
13+
self.valid_prog_environs = ['PrgEnv-cray', 'PrgEnv-pgi']
14+
self.num_tasks = 0
15+
self.num_tasks_per_node = 1
16+
17+
if self.current_system.name in {'dom', 'daint'}:
18+
self.num_gpus_per_node = 1
19+
gpu_arch = '60'
20+
self.modules = ['craype-accel-nvidia60']
21+
self.valid_prog_environs += ['PrgEnv-gnu']
22+
else:
23+
self.num_gpus_per_node = 16
24+
self.modules = ['craype-accel-nvidia35']
25+
gpu_arch = '37'
26+
27+
self.build_system.cxxflags = ['-arch=compute_%s' % gpu_arch,
28+
'-code=sm_%s' % gpu_arch, '-std=c++11']
29+
30+
if kernel_version == 'sync':
31+
self.build_system.cppflags = ['-D SYNCKERNEL=1']
32+
else:
33+
self.build_system.cppflags = ['-D SYNCKERNEL=0']
34+
35+
self.sanity_patterns = sn.all([
36+
sn.assert_eq(
37+
sn.count(sn.findall(r'\[\S+\] Found \d+ gpu\(s\)',
38+
self.stdout)),
39+
self.num_tasks_assigned),
40+
sn.assert_eq(
41+
sn.count(sn.findall(r'\[\S+\] \[gpu \d+\] Kernel launch '
42+
r'latency: \S+ us', self.stdout)),
43+
self.num_tasks_assigned * self.num_gpus_per_node)
44+
])
45+
46+
self.perf_patterns = {
47+
'latency': sn.max(sn.extractall(
48+
r'\[\S+\] \[gpu \d+\] Kernel launch latency: '
49+
r'(?P<latency>\S+) us', self.stdout, 'latency', float))
50+
}
51+
self.sys_reference = {
52+
'sync': {
53+
'dom:gpu': {
54+
'latency': (6.6, None, 0.10, 's')
55+
},
56+
'daint:gpu': {
57+
'latency': (6.6, None, 0.10, 'us')
58+
},
59+
'kesch:cn': {
60+
'latency': (12.0, None, 0.10, 'us')
61+
},
62+
},
63+
'async': {
64+
'dom:gpu': {
65+
'latency': (2.2, None, 0.10, 'us')
66+
},
67+
'daint:gpu': {
68+
'latency': (2.2, None, 0.10, 's')
69+
},
70+
'kesch:cn': {
71+
'latency': (5.7, None, 0.10, 'us')
72+
},
73+
},
74+
}
75+
76+
self.reference = self.sys_reference[kernel_version]
77+
78+
self.maintainers = ['TM']
79+
self.tags = {'benchmark', 'diagnostic'}
80+
81+
@property
82+
@sn.sanity_function
83+
def num_tasks_assigned(self):
84+
return self.job.num_tasks
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include <iostream>
2+
#include <chrono>
3+
#include <ratio>
4+
#include <unistd.h>
5+
#include <cuda.h>
6+
7+
__global__ void null_kernel() {
8+
};
9+
10+
int main(int argc, char* argv[]) {
11+
12+
char hostname[256];
13+
hostname[255]='\0';
14+
gethostname(hostname, 255);
15+
16+
cudaError_t error;
17+
int gpu_count = 0;
18+
19+
error = cudaGetDeviceCount(&gpu_count);
20+
21+
if (error == cudaSuccess) {
22+
if (gpu_count <= 0) {
23+
std::cout << "[" << hostname << "] " << "Could not find any gpu\n";
24+
return 1;
25+
}
26+
std::cout << "[" << hostname << "] " << "Found " << gpu_count << " gpu(s)\n";
27+
}
28+
else{
29+
std::cout << "[" << hostname << "] " << "Error getting gpu count, exiting...\n";
30+
return 1;
31+
}
32+
33+
for (int i = 0; i < gpu_count; i++) {
34+
35+
cudaSetDevice(i);
36+
// Single kernel launch to initialize cuda runtime
37+
null_kernel<<<1, 1>>>();
38+
39+
auto t_start = std::chrono::system_clock::now();
40+
const int kernel_count = 1000;
41+
42+
for (int i = 0; i < kernel_count; ++i) {
43+
null_kernel<<<1, 1>>>();
44+
#if SYNCKERNEL == 1
45+
cudaDeviceSynchronize();
46+
#endif
47+
}
48+
49+
#if SYNCKERNEL != 1
50+
cudaDeviceSynchronize();
51+
#endif
52+
53+
auto t_end = std::chrono::system_clock::now();
54+
std::cout << "[" << hostname << "] " << "[gpu " << i << "] " << "Kernel launch latency: " << std::chrono::duration_cast<std::chrono::duration<double, std::micro>>(t_end - t_start).count() / kernel_count << " us\n";
55+
}
56+
57+
return 0;
58+
}
59+

0 commit comments

Comments
 (0)