77 get_device(
unsigned int platform_i,
unsigned int device_i);
96 run_example(
unsigned int nb_work_group,
unsigned int nb_work_items_by_work_group,
97 cl::Device device,
bool debug,
const std::string& path);
117 std::ifstream infile(filename, std::ios::in);
118 const std::string
s((std::istreambuf_iterator<char>(infile)),
119 std::istreambuf_iterator<char>());
123 std::cerr <<
"! Impossible to read file \"" << filename <<
'"' << std::endl;
128 return "#line 1 \"" + filename +
"\"\n" +
s;
133 get_device(
unsigned int platform_i,
unsigned int device_i) {
134 std::vector<cl::Platform> platforms;
136 cl::Platform::get(&platforms);
137 if (platform_i >= platforms.size()) {
141 std::vector<cl::Device> devices;
143 platforms[platform_i].getDevices(CL_DEVICE_TYPE_ALL, &devices);
144 if (device_i >= devices.size()) {
148 return devices[device_i];
154 const char sep =
'/';
156 if (path.empty() || (path.back() == sep)) {
160 const size_t j = path.rfind(sep);
162 return (j == std::string::npos
164 : path.substr(0, j + 1));
172 if (!message.empty()) {
173 message =
" " + message;
176 std::cerr <<
"! OpenCL error " 186 run_example(
unsigned int nb_work_group,
unsigned int nb_work_items_by_work_group,
187 cl::Device device,
bool debug,
const std::string& path) {
190 const size_t h_outs_byte_size =
sizeof(h_outs[0])*2;
192 uint64_t h_asserts[2] = {0, 0};
193 const size_t h_asserts_byte_size =
sizeof(h_asserts[0])*2;
195 float h_assert_float[1] = {0};
196 const size_t h_assert_float_byte_size =
sizeof(h_assert_float[0]);
198 assert(
sizeof(
float) == 4);
202 const cl::Context context{device};
206 std::string options =
"-I" + path +
"../../OpenCL/";
209 std::cerr <<
"OpenCL in DEBUG mode!" << std::endl;
213 options +=
" -DNDEBUG";
216 const std::string kernel_filename = path +
"../kernel/example.cl";
218 const cl::Program program{context, kernel_src};
219 const VECTOR_CLASS<cl::Device> devices = {device};
220 cl_int error = program.build(devices, options.c_str());
224 cl::Kernel kernel{program,
"example"};
228 const cl::CommandQueue queue{context, device, CL_QUEUE_PROFILING_ENABLE};
232 cl::Buffer d_outs{context, CL_MEM_WRITE_ONLY, h_outs_byte_size};
234 cl::Buffer d_asserts{context, CL_MEM_READ_WRITE, h_asserts_byte_size};
235 cl::Buffer d_assert_float{context, CL_MEM_READ_WRITE, h_assert_float_byte_size};
238 error = queue.enqueueWriteBuffer(d_asserts, CL_TRUE, 0, h_asserts_byte_size, h_asserts);
239 print_error(error,
"clEnqueueWriteBuffer(d_asserts, ...)");
241 error = queue.enqueueWriteBuffer(d_assert_float, CL_TRUE, 0, h_assert_float_byte_size, h_assert_float);
242 print_error(error,
"clEnqueueWriteBuffer(d_assert_float, ...)");
247 error = kernel.setArg(0, 666);
250 error = kernel.setArg(1, d_outs);
254 const unsigned int nb_args = 2;
256 error = kernel.setArg(nb_args, d_asserts);
259 error = kernel.setArg(nb_args + 1, d_assert_float);
260 print_error(error,
"clSetKernelArg(..., d_assert_float)");
265 const unsigned int global_size = nb_work_items_by_work_group * nb_work_group;
267 std::cout <<
"===== run kernel =====" << std::endl;
270 queue.enqueueNDRangeKernel(kernel,
272 cl::NDRange(global_size),
273 cl::NDRange(nb_work_items_by_work_group),
281 std::cout <<
"===== end kernel =====" << std::endl;
286 error = queue.enqueueReadBuffer(d_outs, CL_TRUE, 0, h_outs_byte_size, h_outs);
287 print_error(error,
"clEnqueueReadBuffer(d_outs, ...)");
290 error = queue.enqueueReadBuffer(d_asserts, CL_TRUE, 0, h_asserts_byte_size, h_asserts);
291 print_error(error,
"clEnqueueReadBuffer(d_asserts, ...)");
293 error = queue.enqueueReadBuffer(d_assert_float, CL_TRUE, 0, h_assert_float_byte_size, h_assert_float);
294 print_error(error,
"clEnqueueReadBuffer(d_assert_float, ...)");
296 const uint64_t line = h_asserts[0];
299 const uint64_t uint64_value = h_asserts[1];
300 const int64_t sint64_value =
static_cast<int64_t
>(h_asserts[1]);
301 const float float_value = h_assert_float[0];
303 std::cerr << kernel_filename <<
':' << line <<
"\tAssertion failed | Maybe\t" 304 << uint64_value <<
'\t' << sint64_value <<
" | Maybe\t" << float_value << std::endl;
313 std::cout <<
"Results: (" << h_outs[0] <<
", " << h_outs[1] <<
')' << std::endl;
327 main(
int argc,
const char*
const argv[]) {
334 signed int device_i = 0;
335 signed int platform_i = 0;
342 const std::string arg = argv[i];
344 if ((arg ==
"--debug") || (arg ==
"--ndebug")) {
345 debug = (arg ==
"--debug");
347 else if (arg ==
"--device") {
353 const std::string both_i = argv[i];
354 const size_t j = both_i.find(
':');
356 if (j == std::string::npos) {
357 platform_i = std::stoi(both_i);
360 platform_i = std::stoi(both_i.substr(0, j));
361 device_i = std::stoi(both_i.substr(j + 1));
364 if ((platform_i < 0) || (device_i < 0)) {
374 const cl::Device device =
get_device(static_cast<unsigned int>(platform_i),
375 static_cast<unsigned int>(device_i));
379 std::string device_name;
381 device.getInfo(CL_DEVICE_NAME, &device_name);
382 if (device_name[device_name.size() - 1] ==
'\0') {
383 device_name = device_name.substr(0, device_name.size() - 1);
385 std::cout <<
"Device " << platform_i <<
':' << device_i <<
' ' << device_name << std::endl;
std::string dirname(std::string path)
Return the directory part of path.
void print_error(cl_int code, std::string message="")
If code != 0 then print an error message corresponding to the error code.
int main(int argc, const char *const argv[])
Get the optional parameter –device platform:device and run the kernel ../kernel/example.cl.
cl::Device get_device(unsigned int platform_i, unsigned int device_i)
Return the given device of the given platform OpenCL, or exit if doesn't exists.
const std::map< int32_t, std::string > errors_map
List of all error codes and names extracted from /usr/include/CL/cl.h.
List of all error codes and names extracted from /usr/include/CL/cl.h.
#define assert(test)
If test is true then do nothing. Else init (if they are still null) assert_result and assert_result_f...
void run_example(unsigned int nb_work_group, unsigned int nb_work_items_by_work_group, cl::Device device, bool debug, const std::string &path)
Run the kernel ../kernel/example.cl.
std::string file_to_string(std::string filename)
Read the file and return its content to a string. If failed then print a error message and exit...
std::string error_name(cl_int code)
Return the error name corresponding to the error code.