Skip to content

Commit 5dd673c

Browse files
committed
initial google benchmark test for api times
1 parent e261e8e commit 5dd673c

6 files changed

Lines changed: 353 additions & 0 deletions

File tree

CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,24 @@ else()
3636
message(STATUS "OpenCL Extension Loader is not found.")
3737
endif()
3838

39+
if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/external/benchmark)
40+
# Disable Benchmark testing to avoid Google Test dependency.
41+
set(BENCHMARK_ENABLE_TESTING NO)
42+
add_subdirectory(external/benchmark)
43+
set_target_properties(benchmark PROPERTIES FOLDER "Google-Benchmark")
44+
set_target_properties(benchmark_main PROPERTIES FOLDER "Google-Benchmark")
45+
else()
46+
message(STATUS "Google Benchmark is not found.")
47+
endif()
48+
49+
#if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/external/google)
50+
# add_subdirectory(external/google)
51+
# set_target_properties(benchmark PROPERTIES FOLDER "Google-Benchmark")
52+
# set_target_properties(benchmark_main PROPERTIES FOLDER "Google-Benchmark")
53+
#else()
54+
# message(STATUS "Google Benchmark is not found.")
55+
#endif()
56+
3957
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
4058
enable_testing()
4159
endif()

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ Many samples that use extensions additionally require the OpenCL Extension Loade
3939

4040
git clone https://github.com/bashbaug/opencl-extension-loader external/opencl-extension-loader
4141

42+
Some benchmark samples use Google Benchmark:
43+
44+
git clone https://github.com/google/benchmark external/benchmark
45+
4246
After satisfying the external dependencies create build files using CMake. For example:
4347

4448
mkdir build && cd build

samples/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ function(add_opencl_sample)
5151
endif()
5252
endfunction()
5353

54+
add_subdirectory( benchmarks )
5455
add_subdirectory( images )
5556
add_subdirectory( opengl )
5657
add_subdirectory( python )
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright (c) 2022 Ben Ashbaugh
2+
#
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy
4+
# of this software and associated documentation files (the "Software"), to deal
5+
# in the Software without restriction, including without limitation the rights
6+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
# copies of the Software, and to permit persons to whom the Software is
8+
# furnished to do so, subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in all
11+
# copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
# SOFTWARE.
20+
21+
add_opencl_sample(
22+
TEST
23+
NUMBER 00
24+
TARGET apibenchmark
25+
VERSION 200
26+
CATEGORY benchmarks
27+
SOURCES main.cpp
28+
LIBS benchmark::benchmark OpenCLExt)
Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
/*
2+
// Copyright (c) 2019-2021 Ben Ashbaugh
3+
//
4+
// Permission is hereby granted, free of charge, to any person obtaining a copy
5+
// of this software and associated documentation files (the "Software"), to deal
6+
// in the Software without restriction, including without limitation the rights
7+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
// copies of the Software, and to permit persons to whom the Software is
9+
// furnished to do so, subject to the following conditions:
10+
//
11+
// The above copyright notice and this permission notice shall be included in all
12+
// copies or substantial portions of the Software.
13+
//
14+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20+
// SOFTWARE.
21+
*/
22+
23+
#include <benchmark/benchmark.h>
24+
#include <popl/popl.hpp>
25+
26+
#include <CL/opencl.hpp>
27+
#include "util.hpp"
28+
29+
struct OpenCLBenchmarkEnvironment
30+
{
31+
void ParseArgs(int argc, char** argv)
32+
{
33+
int platformIndex = 0;
34+
int deviceIndex = 0;
35+
36+
bool printHelp = false;
37+
38+
popl::OptionParser op("OpenCL Fixture Options");
39+
op.add<popl::Value<int>>("p", "platform", "Platform Index", platformIndex, &platformIndex);
40+
op.add<popl::Value<int>>("d", "device", "Device Index", deviceIndex, &deviceIndex);
41+
op.add<popl::Switch, popl::Attribute::hidden>("h", "help", "Print Help", &printHelp);
42+
bool printUsage = false;
43+
try {
44+
op.parse(argc, argv);
45+
} catch (std::exception& e) {
46+
fprintf(stderr, "Error: %s\n\n", e.what());
47+
printUsage = true;
48+
}
49+
if (printUsage || printHelp) {
50+
fprintf(stderr, "%s", op.help().c_str());
51+
}
52+
53+
std::vector<cl::Platform> platforms;
54+
cl::Platform::get(&platforms);
55+
56+
platform = platforms[platformIndex];
57+
printf("Running on platform: %s\n",
58+
platform.getInfo<CL_PLATFORM_NAME>().c_str() );
59+
60+
std::vector<cl::Device> devices;
61+
platform.getDevices(CL_DEVICE_TYPE_ALL, &devices);
62+
63+
device = devices[deviceIndex];
64+
printf("Running on device: %s\n",
65+
device.getInfo<CL_DEVICE_NAME>().c_str() );
66+
67+
context = cl::Context{device};
68+
69+
ioq = cl::CommandQueue{context};
70+
ooq = cl::CommandQueue{context, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE};
71+
}
72+
73+
cl::Platform platform;
74+
cl::Device device;
75+
cl::Context context;
76+
cl::CommandQueue ioq;
77+
cl::CommandQueue ooq;
78+
};
79+
80+
OpenCLBenchmarkEnvironment env;
81+
82+
struct Platform : public benchmark::Fixture
83+
{
84+
cl::Platform platform;
85+
86+
virtual void SetUp(benchmark::State& state) override {
87+
platform = env.platform;
88+
}
89+
virtual void TearDown(benchmark::State& state) override {
90+
platform = NULL;
91+
}
92+
};
93+
94+
BENCHMARK_DEFINE_F(Platform, clGetDeviceIDs)(benchmark::State& state)
95+
{
96+
while(state.KeepRunning()) {
97+
cl_uint numDevices = 0;
98+
clGetDeviceIDs(
99+
platform(),
100+
CL_DEVICE_TYPE_ALL,
101+
0,
102+
NULL,
103+
&numDevices);
104+
}
105+
}
106+
BENCHMARK_REGISTER_F(Platform, clGetDeviceIDs);
107+
108+
struct Device : public benchmark::Fixture
109+
{
110+
cl::Device device;
111+
112+
virtual void SetUp(benchmark::State& state) override {
113+
device = env.device;
114+
}
115+
virtual void TearDown(benchmark::State& state) override {
116+
device = NULL;
117+
}
118+
};
119+
120+
BENCHMARK_DEFINE_F(Device, clGetDeviceInfo)(benchmark::State& state)
121+
{
122+
while(state.KeepRunning()) {
123+
cl_device_type type = 0;
124+
clGetDeviceInfo(
125+
device(),
126+
CL_DEVICE_TYPE,
127+
sizeof(type),
128+
&type,
129+
NULL);
130+
}
131+
}
132+
BENCHMARK_REGISTER_F(Device, clGetDeviceInfo);
133+
134+
struct Kernel : public benchmark::Fixture
135+
{
136+
cl::Program program;
137+
cl::Kernel kernel;
138+
139+
virtual void SetUp(benchmark::State& state) override {
140+
static const char kernelString[] = R"CLC( kernel void Empty(int a) {} )CLC";
141+
142+
program = cl::Program{env.context, kernelString};
143+
144+
program.build();
145+
kernel = cl::Kernel{program, "Empty"};
146+
}
147+
virtual void TearDown(benchmark::State& state) override {
148+
program = NULL;
149+
kernel = NULL;
150+
}
151+
};
152+
153+
BENCHMARK_DEFINE_F(Kernel, clSetKernelArg)(benchmark::State& state)
154+
{
155+
while(state.KeepRunning()) {
156+
int x = 0;
157+
clSetKernelArg(
158+
kernel(),
159+
0,
160+
sizeof(x),
161+
&x);
162+
}
163+
}
164+
BENCHMARK_REGISTER_F(Kernel, clSetKernelArg);
165+
166+
struct SVMKernel : public benchmark::Fixture
167+
{
168+
cl::Program program;
169+
cl::Kernel kernel;
170+
171+
std::vector<void*> ptrs;
172+
173+
virtual void SetUp(benchmark::State& state) override {
174+
static const char kernelString[] = R"CLC( kernel void Empty(global int* a) {} )CLC";
175+
176+
program = cl::Program{env.context, kernelString};
177+
178+
program.build();
179+
kernel = cl::Kernel{program, "Empty"};
180+
181+
for (int i = 0; i < 16; i++) {
182+
ptrs.push_back(clSVMAlloc(env.context(), CL_MEM_READ_WRITE, 128, 0));
183+
}
184+
}
185+
virtual void TearDown(benchmark::State& state) override {
186+
program = NULL;
187+
kernel = NULL;
188+
189+
for(auto ptr : ptrs) {
190+
clSVMFree(env.context(), ptr);
191+
}
192+
}
193+
};
194+
195+
BENCHMARK_DEFINE_F(SVMKernel, clSetKernelArgSVMPointer)(benchmark::State& state)
196+
{
197+
const int mask = (int)state.range(0) - 1;
198+
int i = 0;
199+
while(state.KeepRunning()) {
200+
clSetKernelArgSVMPointer(
201+
kernel(),
202+
0,
203+
ptrs[i&mask]);
204+
++i;
205+
}
206+
}
207+
BENCHMARK_REGISTER_F(SVMKernel, clSetKernelArgSVMPointer)->Arg(1)->Arg(2)->Arg(4);
208+
209+
struct USMMemCpy : public benchmark::Fixture
210+
{
211+
bool hasSupport = false;
212+
213+
cl::CommandQueue queue;
214+
215+
std::vector<void*> dptrs;
216+
std::vector<void*> hptrs;
217+
std::vector<void*> sptrs;
218+
219+
virtual void SetUp(benchmark::State& state) override {
220+
queue = env.ioq;
221+
222+
for (int i = 0; i < 16; i++) {
223+
dptrs.push_back(clDeviceMemAllocINTEL(env.context(), env.device(), NULL, 128, 0, NULL));
224+
hptrs.push_back(clHostMemAllocINTEL(env.context(), NULL, 128, 0, NULL));
225+
sptrs.push_back(clSharedMemAllocINTEL(env.context(), env.device(), NULL, 128, 0, NULL));
226+
}
227+
}
228+
virtual void TearDown(benchmark::State& state) override {
229+
queue = NULL;
230+
231+
for(auto ptr : dptrs) {
232+
clMemBlockingFreeINTEL(env.context(), ptr);
233+
}
234+
for(auto ptr : hptrs) {
235+
clMemBlockingFreeINTEL(env.context(), ptr);
236+
}
237+
for(auto ptr : sptrs) {
238+
clMemBlockingFreeINTEL(env.context(), ptr);
239+
}
240+
}
241+
};
242+
243+
BENCHMARK_DEFINE_F(USMMemCpy, clEnqueueMemcpyINTEL_device_blocking)(benchmark::State& state)
244+
{
245+
if (dptrs[0] == NULL || dptrs[1] == NULL) {
246+
state.SkipWithError("unsupported");
247+
}
248+
while(state.KeepRunning()) {
249+
clEnqueueMemcpyINTEL(
250+
queue(),
251+
CL_TRUE,
252+
dptrs[0],
253+
dptrs[1],
254+
128,
255+
0,
256+
NULL,
257+
NULL);
258+
}
259+
}
260+
BENCHMARK_REGISTER_F(USMMemCpy, clEnqueueMemcpyINTEL_device_blocking);
261+
262+
int main(int argc, char** argv)
263+
{
264+
env.ParseArgs(argc, argv);
265+
266+
::benchmark::Initialize(&argc, argv);
267+
//if (::benchmark::ReportUnrecognizedArguments(argc, argv)) {
268+
// return 1;
269+
//}
270+
::benchmark::RunSpecifiedBenchmarks();
271+
::benchmark::Shutdown();
272+
return 0;
273+
}

samples/benchmarks/CMakeLists.txt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright (c) 2022 Ben Ashbaugh
2+
#
3+
# Permission is hereby granted, free of charge, to any person obtaining a copy
4+
# of this software and associated documentation files (the "Software"), to deal
5+
# in the Software without restriction, including without limitation the rights
6+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
# copies of the Software, and to permit persons to whom the Software is
8+
# furnished to do so, subject to the following conditions:
9+
#
10+
# The above copyright notice and this permission notice shall be included in all
11+
# copies or substantial portions of the Software.
12+
#
13+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
# SOFTWARE.
20+
21+
set(BUILD_BENCHMARK_SAMPLES TRUE)
22+
if(NOT TARGET benchmark::benchmark)
23+
message(STATUS "Skipping Benchmark Samples - Google Benchmark is not found.")
24+
set(BUILD_BENCHMARK_SAMPLES FALSE)
25+
endif()
26+
27+
if(BUILD_BENCHMARK_SAMPLES)
28+
add_subdirectory( 00_apibenchmark )
29+
endif()

0 commit comments

Comments
 (0)