Skip to content

Commit 0e8c784

Browse files
committed
add SVM offset examples
1 parent 196d94c commit 0e8c784

File tree

7 files changed

+398
-0
lines changed

7 files changed

+398
-0
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright (c) 2026 Ben Ashbaugh
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
add_opencl_sample(
6+
TEST
7+
NUMBER 102
8+
TARGET cgsvmoffset
9+
VERSION 200
10+
CATEGORY svm
11+
SOURCES main.cpp)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# cgsvmoffset
2+
3+
## Sample Purpose
4+
5+
TODO
6+
7+
## Key APIs and Concepts
8+
9+
TODO
10+
11+
## Command Line Options
12+
13+
| Option | Default Value | Description |
14+
|:--|:-:|:--|
15+
| `-d <index>` | 0 | Specify the index of the OpenCL device in the platform to execute on the sample on.
16+
| `-p <index>` | 0 | Specify the index of the OpenCL platform to execute the sample on.
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
/*
2+
// Copyright (c) 2026 Ben Ashbaugh
3+
//
4+
// SPDX-License-Identifier: MIT
5+
*/
6+
7+
#include <memory>
8+
#include <popl/popl.hpp>
9+
10+
#include <CL/opencl.hpp>
11+
12+
#include "util.hpp"
13+
14+
const size_t gwx = 1024*1024;
15+
16+
static const char kernelString[] = R"CLC(
17+
kernel void CopyBuffer( global uint* dst, global uint* src )
18+
{
19+
uint id = get_global_id(0);
20+
dst[id] = src[id];
21+
}
22+
)CLC";
23+
24+
struct SVMDeleter
25+
{
26+
SVMDeleter(cl::Context& _c) : context(_c) {}
27+
void operator()(void* ptr) {
28+
clSVMFree(context(), ptr);
29+
}
30+
cl::Context context;
31+
};
32+
33+
int main(
34+
int argc,
35+
char** argv )
36+
{
37+
int platformIndex = 0;
38+
int deviceIndex = 0;
39+
40+
{
41+
popl::OptionParser op("Supported Options");
42+
op.add<popl::Value<int>>("p", "platform", "Platform Index", platformIndex, &platformIndex);
43+
op.add<popl::Value<int>>("d", "device", "Device Index", deviceIndex, &deviceIndex);
44+
bool printUsage = false;
45+
try {
46+
op.parse(argc, argv);
47+
} catch (std::exception& e) {
48+
fprintf(stderr, "Error: %s\n\n", e.what());
49+
printUsage = true;
50+
}
51+
52+
if (printUsage || !op.unknown_options().empty() || !op.non_option_args().empty()) {
53+
fprintf(stderr,
54+
"Usage: dmemhelloworld [options]\n"
55+
"%s", op.help().c_str());
56+
return -1;
57+
}
58+
}
59+
60+
std::vector<cl::Platform> platforms;
61+
cl::Platform::get(&platforms);
62+
63+
if (!checkPlatformIndex(platforms, platformIndex)) {
64+
return -1;
65+
}
66+
67+
printf("Running on platform: %s\n",
68+
platforms[platformIndex].getInfo<CL_PLATFORM_NAME>().c_str() );
69+
70+
std::vector<cl::Device> devices;
71+
platforms[platformIndex].getDevices(CL_DEVICE_TYPE_ALL, &devices);
72+
73+
printf("Running on device: %s\n",
74+
devices[deviceIndex].getInfo<CL_DEVICE_NAME>().c_str() );
75+
76+
cl_device_svm_capabilities svmcaps = devices[deviceIndex].getInfo<CL_DEVICE_SVM_CAPABILITIES>();
77+
if( svmcaps & CL_DEVICE_SVM_COARSE_GRAIN_BUFFER ) {
78+
printf("Device supports CL_DEVICE_SVM_COARSE_GRAIN_BUFFER.\n");
79+
} else {
80+
printf("Device does not support CL_DEVICE_SVM_COARSE_GRAIN_BUFFER, exiting.\n");
81+
return -1;
82+
}
83+
84+
cl::Context context{devices[deviceIndex]};
85+
cl::CommandQueue commandQueue{context, devices[deviceIndex]};
86+
87+
cl::Program program{ context, kernelString };
88+
program.build();
89+
cl::Kernel kernel = cl::Kernel{ program, "CopyBuffer" };
90+
91+
{
92+
constexpr size_t count = gwx + 4;
93+
94+
std::unique_ptr<cl_int[], SVMDeleter> src(
95+
(cl_int*)clSVMAlloc(
96+
context(),
97+
CL_MEM_READ_WRITE,
98+
count * sizeof(cl_int),
99+
0),
100+
SVMDeleter(context));
101+
std::unique_ptr<cl_int[], SVMDeleter> dst(
102+
(cl_int*)clSVMAlloc(
103+
context(),
104+
CL_MEM_READ_WRITE,
105+
count * sizeof(cl_int),
106+
0),
107+
SVMDeleter(context));
108+
109+
if (src && dst) {
110+
// initialization
111+
{
112+
commandQueue.enqueueMapSVM(
113+
src,
114+
CL_TRUE,
115+
CL_MAP_WRITE_INVALIDATE_REGION,
116+
count * sizeof(cl_int) );
117+
for( size_t i = 0; i < count; i++ )
118+
{
119+
auto val = static_cast<cl_int>(i);
120+
src[i] = val;
121+
dst[i] = -val;
122+
}
123+
124+
commandQueue.enqueueUnmapSVM( src );
125+
}
126+
127+
// execution
128+
constexpr size_t dstOffset = 1;
129+
constexpr size_t srcOffset = 2;
130+
printf("Setting dst argument with offset: %zu\n", dstOffset);
131+
kernel.setArg( 0, dst.get() + dstOffset );
132+
printf("Setting src argument with offset: %zu\n", srcOffset);
133+
kernel.setArg( 1, src.get() + srcOffset );
134+
commandQueue.enqueueNDRangeKernel(
135+
kernel,
136+
cl::NullRange,
137+
cl::NDRange{gwx} );
138+
139+
// verification
140+
{
141+
commandQueue.enqueueMapSVM(
142+
dst,
143+
CL_TRUE,
144+
CL_MAP_READ,
145+
count * sizeof(cl_uint) );
146+
147+
size_t mismatches = 0;
148+
149+
for (size_t i = 0; i < dstOffset; i++) {
150+
if (dst[i] != i) {
151+
fprintf(stderr, "MisMatch at dst buffer start! dst[%zu] = %08X, want %08X\n",
152+
i,
153+
dst[i],
154+
(cl_int)i );
155+
mismatches++;
156+
}
157+
}
158+
159+
160+
for (size_t i = 0; i < gwx; i++) {
161+
auto ci = i + dstOffset;
162+
auto cv = i + srcOffset;
163+
if (dst[ci] != cv) {
164+
if (mismatches < 16) {
165+
fprintf(stderr, "MisMatch! dst[%zu] == %08X, want %08X\n",
166+
ci,
167+
dst[ci],
168+
(cl_int)cv );
169+
}
170+
mismatches++;
171+
}
172+
}
173+
174+
commandQueue.enqueueUnmapSVM( dst );
175+
176+
if (mismatches) {
177+
fprintf(stderr, "Error: Found %zu mismatches / %zu values!!!\n",
178+
mismatches,
179+
count );
180+
} else {
181+
printf("Success.\n");
182+
}
183+
}
184+
} else {
185+
printf("Allocation failed - does this device support SVM?\n");
186+
}
187+
188+
printf("Cleaning up...\n");
189+
}
190+
191+
return 0;
192+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Copyright (c) 2026 Ben Ashbaugh
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
add_opencl_sample(
6+
TEST
7+
NUMBER 102
8+
TARGET cgsvmoffset2
9+
VERSION 200
10+
CATEGORY svm
11+
SOURCES main.cpp)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# cgsvmoffset
2+
3+
## Sample Purpose
4+
5+
TODO
6+
7+
## Key APIs and Concepts
8+
9+
TODO
10+
11+
## Command Line Options
12+
13+
| Option | Default Value | Description |
14+
|:--|:-:|:--|
15+
| `-d <index>` | 0 | Specify the index of the OpenCL device in the platform to execute on the sample on.
16+
| `-p <index>` | 0 | Specify the index of the OpenCL platform to execute the sample on.

0 commit comments

Comments
 (0)