From 8a1f15df81018a33f993cca934da8fadb2f2bdda Mon Sep 17 00:00:00 2001 From: Mike Klein Date: Mon, 11 Feb 2019 11:59:41 -0500 Subject: [PATCH] update hello-opencl - break dependency on code from src/compute - port away from C APIs to friendlier C++ wrapper APIs - add DEPS for OpenCL C++ wrapper headers so we can build on Mac - factor out a //third_party/opencl GN target Change-Id: I9e37c6677cfb779021e66f2bd10f97570c450746 Reviewed-on: https://skia-review.googlesource.com/c/191281 Auto-Submit: Mike Klein Reviewed-by: Brian Osman Commit-Queue: Mike Klein --- BUILD.gn | 11 ++--- DEPS | 1 + third_party/opencl/BUILD.gn | 15 +++++++ tools/hello-opencl.cpp | 85 +++++++++++++++++++++++++------------ 4 files changed, 77 insertions(+), 35 deletions(-) create mode 100644 third_party/opencl/BUILD.gn diff --git a/BUILD.gn b/BUILD.gn index 96fdf86c9d..bfad8d584b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -2404,16 +2404,11 @@ if (skia_enable_tools) { if (skia_use_opencl) { test_app("hello-opencl") { sources = [ - "src/compute/common/cl/assert_cl.c", - "src/compute/common/cl/find_cl.c", "tools/hello-opencl.cpp", ] - include_dirs = [ "src/compute/common" ] - if (is_linux) { - libs = [ "OpenCL" ] - } else if (is_win) { - libs = [ "OpenCL.lib" ] - } + deps = [ + "//third_party/opencl", + ] } } } diff --git a/DEPS b/DEPS index e341ad1127..e7d08d3c13 100644 --- a/DEPS +++ b/DEPS @@ -21,6 +21,7 @@ deps = { "third_party/externals/lua" : "https://skia.googlesource.com/external/github.com/lua/lua.git@v5-3-4", "third_party/externals/microhttpd" : "https://android.googlesource.com/platform/external/libmicrohttpd@748945ec6f1c67b7efc934ab0808e1d32f2fb98d", "third_party/externals/opencl-lib" : "https://skia.googlesource.com/external/github.com/GPUOpen-Tools/common-lib-amd-APPSDK-3.0@4e6d30e406d2e5a65e1d65e404fe6df5f772a32b", + "third_party/externals/opencl-registry" : "https://github.com/KhronosGroup/OpenCL-Registry@932ed55c85f887041291cef8019e54280c033c35", "third_party/externals/opengl-registry" : "https://skia.googlesource.com/external/github.com/KhronosGroup/OpenGL-Registry@14b80ebeab022b2c78f84a573f01028c96075553", "third_party/externals/piex" : "https://android.googlesource.com/platform/external/piex.git@bb217acdca1cc0c16b704669dd6f91a1b509c406", "third_party/externals/sdl" : "https://skia.googlesource.com/third_party/sdl@5d7cfcca344034aff9327f77fc181ae3754e7a90", diff --git a/third_party/opencl/BUILD.gn b/third_party/opencl/BUILD.gn new file mode 100644 index 0000000000..03b2a90c6f --- /dev/null +++ b/third_party/opencl/BUILD.gn @@ -0,0 +1,15 @@ +import("../third_party.gni") + +third_party("opencl") { + # OpenCL C++ wrapper API, cl.hpp. + # (Some platforms only ship the C APIs, which cl.hpp builds on.) + public_include_dirs = [ "../externals/opencl-registry/api/2.1" ] + + if (is_linux) { + libs = [ "OpenCL" ] + } else if (is_mac) { + libs = [ "OpenCL.framework" ] + } else if (is_win) { + libs = [ "OpenCL.lib" ] + } +} diff --git a/tools/hello-opencl.cpp b/tools/hello-opencl.cpp index 7e57f0b977..9b1be8252b 100644 --- a/tools/hello-opencl.cpp +++ b/tools/hello-opencl.cpp @@ -7,45 +7,76 @@ // This is a simple OpenCL Hello World that tests you have a functioning OpenCL setup. -#include +#include "cl.hpp" #include +#include +#include +#include +#include -extern "C" { - #include "cl/assert_cl.h" // for cl(), cl_ok() macros - #include "cl/find_cl.h" // for clFindIdsByName +static inline void assert_cl(cl_int rc, const char* file, int line) { + if (rc != CL_SUCCESS) { + fprintf(stderr, "%s:%d, got OpenCL error code %d\n", file,line,rc); + exit(1); + } } +#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] : ""; - cl_platform_id platform_id; - cl_device_id device_id; + cl::Platform platform; + { + std::vector platforms; + cl_ok(cl::Platform::get(&platforms)); - char device_name[256]; - size_t device_name_len; + bool found = false; + for (cl::Platform p : platforms) { + std::string name; + cl_ok(p.getInfo(CL_PLATFORM_NAME, &name)); - // clFindIdsByName will narrate what it's doing when this is set. - bool verbose = true; + fprintf(stdout, "Available platform %s\n", name.c_str()); - // The cl() macro prepends cl to its argument, calls it, and asserts that it succeeded, - // printing out the file, line, and somewhat readable version of the error code on failure. - // - // It's generally used to call OpenCL APIs, but here we've written clFindIdsByName to match - // the convention, as its error conditions are just going to be passed along from OpenCL. - cl(FindIdsByName(platform_match, device_match, - &platform_id, &device_id, - sizeof(device_name), device_name, &device_name_len, - verbose)); + 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); + } + } - printf("picked %.*s\n", (int)device_name_len, device_name); + cl::Device device; + { + std::vector devices; + cl_ok(platform.getDevices(CL_DEVICE_TYPE_ALL, &devices)); - // Allan's code is all C using OpenCL's C API, - // but we can mix that freely with the C++ API found in cl.hpp. - // cl_ok() comes in handy here, which is cl() without the extra cl- prefix. + 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)); - cl::Device device(device_id); + 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); + } + } std::string name, vendor, @@ -54,8 +85,8 @@ int main(int argc, char** argv) { cl_ok(device.getInfo(CL_DEVICE_VENDOR, &vendor)); cl_ok(device.getInfo(CL_DEVICE_EXTENSIONS, &extensions)); - printf("name %s, vendor %s, extensions:\n%s\n", - name.c_str(), vendor.c_str(), extensions.c_str()); + fprintf(stdout, "Using %s, vendor %s, extensions:\n%s\n", + name.c_str(), vendor.c_str(), extensions.c_str()); std::vector devices = { device }; @@ -113,6 +144,6 @@ int main(int argc, char** argv) { } } - printf("OpenCL sez: %g x %g = %g\n", a[42], b[42], p[42]); + fprintf(stdout, "OpenCL sez: %g x %g = %g\n", a[42], b[42], p[42]); return 0; }