Guest User

Untitled

a guest
May 21st, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.63 KB | None | 0 0
  1. #include <CL/cl.h>
  2. #include <array>
  3.  
  4.  
  5. const char *source = R"(
  6. kernel void mult(global float *data) {
  7. const int id = get_global_id(0);
  8. data[id] *= 2.f;
  9. }
  10. )";
  11.  
  12.  
  13. struct cl_impl_t {
  14.  
  15. bool init();
  16.  
  17. auto &get_data() {
  18. return data;
  19. }
  20.  
  21. bool run() {
  22. if (!write_buffers()) {
  23. return false;
  24. }
  25. if (!run_kernel()) {
  26. return false;
  27. }
  28. if (!read_buffers()) {
  29. return false;
  30. }
  31. if (!sync()) {
  32. return false;
  33. }
  34. return true;
  35. }
  36.  
  37. protected:
  38.  
  39. bool create_kernel();
  40. bool create_buffers();
  41. bool write_buffers();
  42. bool read_buffers();
  43. bool run_kernel();
  44. bool sync();
  45.  
  46. std::array<float, 512> data;
  47.  
  48. std::array<cl_platform_id, 32> platforms;
  49. cl_context context;
  50. cl_device_id device;
  51. cl_command_queue queue;
  52. cl_program program;
  53. cl_kernel kernel;
  54. cl_mem buffer;
  55. };
  56.  
  57.  
  58. bool cl_impl_t::init() {
  59.  
  60. cl_int ret = CL_SUCCESS;
  61.  
  62. cl_uint num_platforms = 0;
  63. ret = clGetPlatformIDs(
  64. platforms.size(),
  65. platforms.data(),
  66. &num_platforms);
  67. if (CL_SUCCESS != ret)
  68. return false;
  69.  
  70. ret = clGetDeviceIDs(
  71. platforms[0], // platform selection
  72. CL_DEVICE_TYPE_CPU,
  73. 1, // number of devices
  74. &device, // device pointer
  75. nullptr);
  76. if (CL_SUCCESS != ret)
  77. return false;
  78.  
  79. context = clCreateContext(
  80. nullptr,
  81. 1,
  82. &device,
  83. nullptr,
  84. nullptr,
  85. nullptr);
  86. if (!context)
  87. return false;
  88.  
  89. queue = clCreateCommandQueue(
  90. context,
  91. device,
  92. cl_command_queue_properties(0),
  93. nullptr);
  94. if (!queue)
  95. return false;
  96.  
  97. if (!create_kernel()) {
  98. return false;
  99. }
  100.  
  101. if (!create_buffers()) {
  102. return false;
  103. }
  104.  
  105. return true;
  106. }
  107.  
  108. bool cl_impl_t::create_kernel() {
  109.  
  110. cl_int ret = CL_SUCCESS;
  111.  
  112. program = clCreateProgramWithSource(
  113. context,
  114. 1, // number of source buffers
  115. &source, // source code
  116. nullptr, // source length
  117. nullptr); // error code ret
  118. if (!program)
  119. return false;
  120.  
  121. ret = clBuildProgram(
  122. program,
  123. 0, // num devices
  124. nullptr, // device list
  125. nullptr, // options
  126. nullptr, // notify callback
  127. nullptr); // user data
  128. kernel = clCreateKernel(
  129. program,
  130. "mult", // kernel name
  131. nullptr);
  132. if (!kernel)
  133. return false;
  134.  
  135. return true;
  136. }
  137.  
  138. bool cl_impl_t::create_buffers() {
  139.  
  140. cl_int ret = CL_SUCCESS;
  141.  
  142. buffer = clCreateBuffer(
  143. context,
  144. CL_MEM_READ_WRITE, // memory usage flags
  145. data.size() * sizeof(float), // buffer size in bytes
  146. nullptr,
  147. nullptr);
  148. if (!buffer)
  149. return false;
  150.  
  151. return true;
  152. }
  153.  
  154. bool cl_impl_t::write_buffers() {
  155.  
  156. cl_int ret = CL_SUCCESS;
  157.  
  158. ret = clEnqueueWriteBuffer(
  159. queue,
  160. buffer,
  161. CL_FALSE,
  162. 0,
  163. data.size() * sizeof(float), // buffer size in bytes
  164. data.data(), // buffer contents
  165. 0,
  166. nullptr,
  167. nullptr);
  168. if (CL_SUCCESS != ret)
  169. return false;
  170.  
  171. return true;
  172. }
  173.  
  174. bool cl_impl_t::run_kernel() {
  175.  
  176. cl_int ret = CL_SUCCESS;
  177. const size_t dimensions[] = {data.size(), 0, 0};
  178.  
  179. ret = clSetKernelArg(
  180. kernel, // kernel
  181. 0, // argument index
  182. sizeof(buffer), // size of the memory object
  183. &buffer); // pointer to memory object
  184. if (CL_SUCCESS != ret)
  185. return false;
  186.  
  187. ret = clEnqueueNDRangeKernel(
  188. queue,
  189. kernel,
  190. 1, // work dimensions
  191. nullptr, // global work offset
  192. dimensions, // global work size
  193. nullptr, // local work size
  194. 0, // num events
  195. nullptr, // event wait list
  196. nullptr); // event
  197. if (CL_SUCCESS != ret)
  198. return false;
  199.  
  200. return true;
  201. }
  202.  
  203. bool cl_impl_t::read_buffers() {
  204.  
  205. cl_int ret = CL_SUCCESS;
  206.  
  207. ret = clEnqueueReadBuffer(
  208. queue,
  209. buffer,
  210. CL_FALSE,
  211. 0,
  212. sizeof(float) * data.size(), // buffer size in bytes
  213. data.data(), // destination
  214. 0,
  215. nullptr,
  216. nullptr);
  217. if (CL_SUCCESS != ret)
  218. return false;
  219.  
  220. return true;
  221. }
  222.  
  223. bool cl_impl_t::sync() {
  224.  
  225. cl_int ret = CL_SUCCESS;
  226.  
  227. ret = clFinish(queue);
  228. if (CL_SUCCESS != ret)
  229. return false;
  230.  
  231. return true;
  232. }
  233.  
  234. int main() {
  235.  
  236. cl_impl_t cl;
  237. if (!cl.init()) {
  238. return 1;
  239. }
  240.  
  241. auto &data = cl.get_data();
  242. for (uint32_t i = 0; i < data.size(); ++i)
  243. data[i] = float(i);
  244.  
  245. if (!cl.run()) {
  246. return 1;
  247. }
  248.  
  249. return 0;
  250. }
Add Comment
Please, Sign In to add comment