PLSSVM - Parallel Least Squares Support Vector Machine  2.0.0
A Least Squares Support Vector Machine implementation using different backends.
utility.hpp
Go to the documentation of this file.
1 
12 #ifndef PLSSVM_BACKENDS_OPENCL_DETAIL_UTILITY_HPP_
13 #define PLSSVM_BACKENDS_OPENCL_DETAIL_UTILITY_HPP_
14 #pragma once
15 
16 #include "plssvm/backends/OpenCL/detail/command_queue.hpp" // plssvm::opencl::detail::command_queue
17 #include "plssvm/backends/OpenCL/detail/context.hpp" // plssvm::opencl::detail::context
18 #include "plssvm/backends/OpenCL/detail/error_code.hpp" // plssvm::opencl::detail::error_code
19 #include "plssvm/backends/OpenCL/detail/kernel.hpp" // plssvm::opencl::detail::compute_kernel_name
20 #include "plssvm/detail/assert.hpp" // PLSSVM_ASSERT
21 #include "plssvm/kernel_function_types.hpp" // plssvm::kernel_function_type
22 #include "plssvm/target_platforms.hpp" // plssvm::target_platform
23 
24 #include "CL/cl.h" // cl_uint, cl_int, clSetKernelArg, clEnqueueNDRangeKernel, clFinish
25 
26 #include "fmt/core.h" // fmt::format
27 
28 #include <cstddef> // std::size_t
29 #include <string> // std::string
30 #include <string_view> // std::string_view
31 #include <utility> // std::forward, std::pair
32 #include <vector> // std::vector
33 
38 #define PLSSVM_OPENCL_ERROR_CHECK(err, ...) plssvm::opencl::detail::device_assert((err), ##__VA_ARGS__)
39 
40 namespace plssvm::opencl::detail {
41 
49 void device_assert(error_code code, std::string_view msg = "");
50 
58 [[nodiscard]] std::pair<std::vector<context>, target_platform> get_contexts(target_platform target);
59 
64 void device_synchronize(const command_queue &queue);
65 
71 [[nodiscard]] std::string get_device_name(const command_queue &queue);
72 
78 [[nodiscard]] std::vector<std::pair<compute_kernel_name, std::string>> kernel_type_to_function_names(kernel_function_type kernel);
79 
100 [[nodiscard]] std::vector<command_queue> create_command_queues(const std::vector<context> &contexts, target_platform target, const std::vector<std::pair<compute_kernel_name, std::string>> &kernel_names);
101 
108 template <typename... Args>
109 inline void set_kernel_args(cl_kernel kernel, Args... args) {
110  cl_uint i = 0;
111  // iterate over parameter pack and set OpenCL kernel
112  ([&](auto &arg) {
113  const error_code ec = clSetKernelArg(kernel, i++, sizeof(decltype(arg)), &arg);
114  PLSSVM_OPENCL_ERROR_CHECK(ec, fmt::format("error setting OpenCL kernel argument {}", i - 1));
115  }(args),
116  ...);
117 }
118 
128 template <typename... Args>
129 inline void run_kernel(const command_queue &queue, cl_kernel kernel, const std::vector<std::size_t> &grid_size, const std::vector<std::size_t> &block_size, Args &&...args) {
130  PLSSVM_ASSERT(grid_size.size() == block_size.size(), "grid_size and block_size must have the same number of dimensions!: {} != {}", grid_size.size(), block_size.size());
131  PLSSVM_ASSERT(grid_size.size() <= 3, "The number of dimensions must be less or equal than 3!: {} > 3", grid_size.size());
132 
133  // set kernel arguments
134  set_kernel_args(kernel, std::forward<Args>(args)...);
135 
136  // enqueue kernel in command queue
137  PLSSVM_OPENCL_ERROR_CHECK(clEnqueueNDRangeKernel(queue, kernel, static_cast<cl_int>(grid_size.size()), nullptr, grid_size.data(), block_size.data(), 0, nullptr, nullptr), "error enqueuing OpenCL kernel");
138  // wait until kernel computation finished
139  PLSSVM_OPENCL_ERROR_CHECK(clFinish(queue), "error running OpenCL kernel");
140 }
141 
151 template <typename... Args>
152 inline void run_kernel(const command_queue &queue, cl_kernel kernel, std::size_t grid_size, std::size_t block_size, Args &&...args) {
153  run_kernel(queue, kernel, std::vector<std::size_t>{ grid_size }, std::vector<std::size_t>{ block_size }, std::forward<Args>(args)...);
154 }
155 
156 } // namespace plssvm::opencl::detail
157 
158 #endif // PLSSVM_BACKENDS_OPENCL_DETAIL_UTILITY_HPP_
Implements a custom assert macro PLSSVM_ASSERT.
#define PLSSVM_ASSERT(cond, msg,...)
Defines the PLSSVM_ASSERT macro if PLSSVM_ASSERT_ENABLED is defined.
Definition: assert.hpp:74
#define PLSSVM_OPENCL_ERROR_CHECK(err,...)
Macro used for error checking OpenCL runtime functions.
Definition: utility.hpp:38
RAII wrapper class around a cl_command_queue.
Definition: command_queue.hpp:28
Class wrapping an OpenCL error code.
Definition: error_code.hpp:27
RAII wrapper class around a cl_kernel.
Definition: kernel.hpp:38
Defines a very small RAII wrapper around a cl_command_queue including information about its associate...
Defines a very small RAII wrapper around a cl_context including all associated devices and one comman...
Small wrapper around OpenCL's error codes.
Defines a very small RAII wrapper around a cl_kernel.
Defines an enumeration holding all possible kernel function types.
Namespace containing OpenCL backend specific implementation details. Should not directly be used by u...
Definition: command_queue.hpp:22
void set_kernel_args(cl_kernel kernel, Args... args)
Set all arguments in the parameter pack args for the kernel kernel.
Definition: utility.hpp:109
void run_kernel(const command_queue &queue, cl_kernel kernel, const std::vector< std::size_t > &grid_size, const std::vector< std::size_t > &block_size, Args &&...args)
Run the 1D kernel on the queue with the additional parameters args.
Definition: utility.hpp:129
std::pair< std::vector< context >, target_platform > get_contexts(target_platform target)
Returns the context listing all devices matching the target platform target and the actually used tar...
std::string get_device_name(const command_queue &queue)
Get the name of the device associated with the OpenCL command queue queue.
std::vector< std::pair< compute_kernel_name, std::string > > kernel_type_to_function_names(kernel_function_type kernel)
Convert the kernel type kernel to the device function names and return the plssvm::opencl::detail::co...
std::vector< command_queue > create_command_queues(const std::vector< context > &contexts, target_platform target, const std::vector< std::pair< compute_kernel_name, std::string >> &kernel_names)
Create command queues for all devices in the OpenCL contexts with respect to target given and the ass...
void device_assert(error_code code, std::string_view msg="")
Check the OpenCL error code. If code signals an error, throw a plssvm::opencl::backend_exception.
void device_synchronize(const command_queue &queue)
Wait for the compute device associated with queue to finish.
target_platform
Enum class for all possible targets.
Definition: target_platforms.hpp:25
kernel_function_type
Enum class for all implemented kernel functions.
Definition: kernel_function_types.hpp:31
Defines an enumeration holding all possible target platforms. Can also include targets not available ...