run all available OpenCL devices
Change-Id: I6d18be3f6178003eb5153d32d4b618101ddcb3d9
Reviewed-on: https://skia-review.googlesource.com/c/191297
Auto-Submit: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/tools/hello-opencl.cpp b/tools/hello-opencl.cpp
index 9b1be82..12b51f5 100644
--- a/tools/hello-opencl.cpp
+++ b/tools/hello-opencl.cpp
@@ -22,128 +22,96 @@
}
#define cl_ok(err) assert_cl(err, __FILE__, __LINE__)
-int main(int argc, char** argv) {
- // Find any OpenCL platform+device with these substrings.
- const char* platform_match = argc > 1 ? argv[1] : "";
- const char* device_match = argc > 2 ? argv[2] : "";
+int main(int, char**) {
+ std::vector<cl::Platform> platforms;
+ cl_ok(cl::Platform::get(&platforms));
- cl::Platform platform;
- {
- std::vector<cl::Platform> platforms;
- cl_ok(cl::Platform::get(&platforms));
-
- bool found = false;
- for (cl::Platform p : platforms) {
- std::string name;
- cl_ok(p.getInfo(CL_PLATFORM_NAME, &name));
-
- fprintf(stdout, "Available platform %s\n", name.c_str());
-
- if (name.find(platform_match) != std::string::npos) {
- platform = p;
- found = true;
- }
- }
- if (!found) {
- fprintf(stderr, "No platform containing '%s' found.\n", platform_match);
- exit(1);
- }
+ std::vector<cl::Device> devices;
+ for (cl::Platform platform : platforms) {
+ std::vector<cl::Device> platform_devices;
+ cl_ok(platform.getDevices(CL_DEVICE_TYPE_ALL, &platform_devices));
+ devices.insert(devices.end(), platform_devices.begin(), platform_devices.end());
}
- cl::Device device;
- {
- std::vector<cl::Device> devices;
- cl_ok(platform.getDevices(CL_DEVICE_TYPE_ALL, &devices));
-
- bool found = false;
- for (cl::Device d : devices) {
- std::string name,
- version,
- driver;
- cl_ok(d.getInfo(CL_DEVICE_NAME, &name));
- cl_ok(d.getInfo(CL_DEVICE_VERSION, &version));
- cl_ok(d.getInfo(CL_DRIVER_VERSION, &driver));
-
- fprintf(stdout, "Available device %s%s, driver version %s\n"
- , version.c_str(), name.c_str(), driver.c_str());
-
- if (name.find(device_match) != std::string::npos) {
- device = d;
- found = true;
- }
- }
- if (!found) {
- fprintf(stderr, "No device containing '%s' found.\n", device_match);
- exit(2);
- }
+ if (devices.empty()) {
+ fprintf(stderr, "No OpenCL devices available. :(\n");
+ return 1;
}
- std::string name,
- vendor,
- extensions;
- cl_ok(device.getInfo(CL_DEVICE_NAME, &name));
- cl_ok(device.getInfo(CL_DEVICE_VENDOR, &vendor));
- cl_ok(device.getInfo(CL_DEVICE_EXTENSIONS, &extensions));
+ // To keep things simple we'll only create single-device cl::Contexts.
+ for (cl::Device device : devices) {
+ std::string name,
+ version,
+ driver,
+ vendor,
+ extensions;
+ cl_ok(device.getInfo(CL_DEVICE_NAME, &name));
+ cl_ok(device.getInfo(CL_DEVICE_VERSION, &version));
+ cl_ok(device.getInfo(CL_DEVICE_VENDOR, &vendor));
+ cl_ok(device.getInfo(CL_DEVICE_EXTENSIONS, &extensions));
+ cl_ok(device.getInfo(CL_DRIVER_VERSION, &driver));
- fprintf(stdout, "Using %s, vendor %s, extensions:\n%s\n",
- name.c_str(), vendor.c_str(), extensions.c_str());
+ fprintf(stdout, "Using %s%s, vendor %s, version %s, extensions:\n%s\n",
+ version.c_str(), name.c_str(), vendor.c_str(), driver.c_str(), extensions.c_str());
- std::vector<cl::Device> devices = { device };
+ std::vector<cl::Device> devices = { device };
- // Some APIs can't return their cl_int error but might still fail,
- // so they take a pointer. cl_ok() is really handy here too.
- cl_int ok;
- cl::Context ctx(devices,
- nullptr/*optional cl_context_properties*/,
- nullptr/*optional error reporting callback*/,
- nullptr/*context arguement for error reporting callback*/,
- &ok);
- cl_ok(ok);
-
- cl::Program program(ctx,
- "__kernel void mul(__global const float* a, "
- " __global const float* b, "
- " __global float* dst) {"
- " int i = get_global_id(0); "
- " dst[i] = a[i] * b[i]; "
- "} ",
- /*and build now*/true,
+ // Some APIs can't return their cl_int error but might still fail,
+ // so they take a pointer. cl_ok() is really handy here too.
+ cl_int ok;
+ cl::Context ctx(devices,
+ nullptr/*optional cl_context_properties*/,
+ nullptr/*optional error reporting callback*/,
+ nullptr/*context argument for error reporting callback*/,
&ok);
- cl_ok(ok);
+ cl_ok(ok);
- std::vector<float> a,b,p;
- for (int i = 0; i < 1000; i++) {
- a.push_back(+i);
- b.push_back(-i);
- p.push_back( 0);
- }
+ cl::Program program(ctx,
+ "__kernel void mul(__global const float* a, "
+ " __global const float* b, "
+ " __global float* dst) {"
+ " int i = get_global_id(0); "
+ " dst[i] = a[i] * b[i]; "
+ "} ",
+ /*and build now*/true,
+ &ok);
+ cl_ok(ok);
- cl::Buffer A(ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR , sizeof(float)*a.size(), a.data()),
- B(ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR , sizeof(float)*b.size(), b.data()),
- P(ctx, CL_MEM_WRITE_ONLY| CL_MEM_HOST_READ_ONLY, sizeof(float)*p.size());
+ std::vector<float> a,b,p;
+ for (int i = 0; i < 1000; i++) {
+ a.push_back(+i);
+ b.push_back(-i);
+ p.push_back( 0);
+ }
- cl::Kernel mul(program, "mul", &ok);
- cl_ok(ok);
- cl_ok(mul.setArg(0, A));
- cl_ok(mul.setArg(1, B));
- cl_ok(mul.setArg(2, P));
+ cl::Buffer
+ A(ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR , sizeof(float)*a.size(), a.data()),
+ B(ctx, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR , sizeof(float)*b.size(), b.data()),
+ P(ctx, CL_MEM_WRITE_ONLY| CL_MEM_HOST_READ_ONLY, sizeof(float)*p.size());
- cl::CommandQueue queue(ctx, device);
+ cl::Kernel mul(program, "mul", &ok);
+ cl_ok(ok);
+ cl_ok(mul.setArg(0, A));
+ cl_ok(mul.setArg(1, B));
+ cl_ok(mul.setArg(2, P));
- cl_ok(queue.enqueueNDRangeKernel(mul, cl::NDRange(0) /*offset*/
- , cl::NDRange(1000) /*size*/));
+ cl::CommandQueue queue(ctx, device);
- cl_ok(queue.enqueueReadBuffer(P, true/*block until read is done*/
- , 0 /*offset in bytes*/
- , sizeof(float)*p.size() /*size in bytes*/
- , p.data()));
+ cl_ok(queue.enqueueNDRangeKernel(mul, cl::NDRange(0) /*offset*/
+ , cl::NDRange(1000) /*size*/));
- for (int i = 0; i < 1000; i++) {
- if (p[i] != a[i]*b[i]) {
- return 1;
+ cl_ok(queue.enqueueReadBuffer(P, true/*block until read is done*/
+ , 0 /*offset in bytes*/
+ , sizeof(float)*p.size() /*size in bytes*/
+ , p.data()));
+
+ fprintf(stdout, "OpenCL sez: %g x %g = %g\n", a[42], b[42], p[42]);
+ for (int i = 0; i < 1000; i++) {
+ if (p[i] != a[i]*b[i]) {
+ return 1;
+ }
}
}
- fprintf(stdout, "OpenCL sez: %g x %g = %g\n", a[42], b[42], p[42]);
return 0;
}