Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <CL/cl.h>
- #include <array>
- const char *source = R"(
- kernel void mult(global float *data) {
- const int id = get_global_id(0);
- data[id] *= 2.f;
- }
- )";
- struct cl_impl_t {
- bool init();
- auto &get_data() {
- return data;
- }
- bool run() {
- if (!write_buffers()) {
- return false;
- }
- if (!run_kernel()) {
- return false;
- }
- if (!read_buffers()) {
- return false;
- }
- if (!sync()) {
- return false;
- }
- return true;
- }
- protected:
- bool create_kernel();
- bool create_buffers();
- bool write_buffers();
- bool read_buffers();
- bool run_kernel();
- bool sync();
- std::array<float, 512> data;
- std::array<cl_platform_id, 32> platforms;
- cl_context context;
- cl_device_id device;
- cl_command_queue queue;
- cl_program program;
- cl_kernel kernel;
- cl_mem buffer;
- };
- bool cl_impl_t::init() {
- cl_int ret = CL_SUCCESS;
- cl_uint num_platforms = 0;
- ret = clGetPlatformIDs(
- platforms.size(),
- platforms.data(),
- &num_platforms);
- if (CL_SUCCESS != ret)
- return false;
- ret = clGetDeviceIDs(
- platforms[0], // platform selection
- CL_DEVICE_TYPE_CPU,
- 1, // number of devices
- &device, // device pointer
- nullptr);
- if (CL_SUCCESS != ret)
- return false;
- context = clCreateContext(
- nullptr,
- 1,
- &device,
- nullptr,
- nullptr,
- nullptr);
- if (!context)
- return false;
- queue = clCreateCommandQueue(
- context,
- device,
- cl_command_queue_properties(0),
- nullptr);
- if (!queue)
- return false;
- if (!create_kernel()) {
- return false;
- }
- if (!create_buffers()) {
- return false;
- }
- return true;
- }
- bool cl_impl_t::create_kernel() {
- cl_int ret = CL_SUCCESS;
- program = clCreateProgramWithSource(
- context,
- 1, // number of source buffers
- &source, // source code
- nullptr, // source length
- nullptr); // error code ret
- if (!program)
- return false;
- ret = clBuildProgram(
- program,
- 0, // num devices
- nullptr, // device list
- nullptr, // options
- nullptr, // notify callback
- nullptr); // user data
- kernel = clCreateKernel(
- program,
- "mult", // kernel name
- nullptr);
- if (!kernel)
- return false;
- return true;
- }
- bool cl_impl_t::create_buffers() {
- cl_int ret = CL_SUCCESS;
- buffer = clCreateBuffer(
- context,
- CL_MEM_READ_WRITE, // memory usage flags
- data.size() * sizeof(float), // buffer size in bytes
- nullptr,
- nullptr);
- if (!buffer)
- return false;
- return true;
- }
- bool cl_impl_t::write_buffers() {
- cl_int ret = CL_SUCCESS;
- ret = clEnqueueWriteBuffer(
- queue,
- buffer,
- CL_FALSE,
- 0,
- data.size() * sizeof(float), // buffer size in bytes
- data.data(), // buffer contents
- 0,
- nullptr,
- nullptr);
- if (CL_SUCCESS != ret)
- return false;
- return true;
- }
- bool cl_impl_t::run_kernel() {
- cl_int ret = CL_SUCCESS;
- const size_t dimensions[] = {data.size(), 0, 0};
- ret = clSetKernelArg(
- kernel, // kernel
- 0, // argument index
- sizeof(buffer), // size of the memory object
- &buffer); // pointer to memory object
- if (CL_SUCCESS != ret)
- return false;
- ret = clEnqueueNDRangeKernel(
- queue,
- kernel,
- 1, // work dimensions
- nullptr, // global work offset
- dimensions, // global work size
- nullptr, // local work size
- 0, // num events
- nullptr, // event wait list
- nullptr); // event
- if (CL_SUCCESS != ret)
- return false;
- return true;
- }
- bool cl_impl_t::read_buffers() {
- cl_int ret = CL_SUCCESS;
- ret = clEnqueueReadBuffer(
- queue,
- buffer,
- CL_FALSE,
- 0,
- sizeof(float) * data.size(), // buffer size in bytes
- data.data(), // destination
- 0,
- nullptr,
- nullptr);
- if (CL_SUCCESS != ret)
- return false;
- return true;
- }
- bool cl_impl_t::sync() {
- cl_int ret = CL_SUCCESS;
- ret = clFinish(queue);
- if (CL_SUCCESS != ret)
- return false;
- return true;
- }
- int main() {
- cl_impl_t cl;
- if (!cl.init()) {
- return 1;
- }
- auto &data = cl.get_data();
- for (uint32_t i = 0; i < data.size(); ++i)
- data[i] = float(i);
- if (!cl.run()) {
- return 1;
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment