kernel_gpu_opencl_wrapper.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. // #ifdef __cplusplus
  2. // extern "C" {
  3. // #endif
  4. //========================================================================================================================================================================================================200
  5. // DEFINE/INCLUDE
  6. //========================================================================================================================================================================================================200
  7. //======================================================================================================================================================150
  8. // COMMON
  9. //======================================================================================================================================================150
  10. #include "../common.h" // (in directory)
  11. //======================================================================================================================================================150
  12. // UTILITIES
  13. //======================================================================================================================================================150
  14. #include "../util/timer/timer.h" // (in directory)
  15. //======================================================================================================================================================150
  16. // KERNEL
  17. //======================================================================================================================================================150
  18. #include "./solver.c" // (in directory)
  19. #include "../util/opencl/opencl.h" // (in directory)
  20. //======================================================================================================================================================150
  21. // LIBRARIES
  22. //======================================================================================================================================================150
  23. #include <stdio.h> // (in path known to compiler) needed by printf
  24. #include <string.h> // (in path known to compiler) needed by strlen
  25. #include <CL/cl.h> // (in path provided to compiler) needed by OpenCL types and functions
  26. //======================================================================================================================================================150
  27. // HEADER
  28. //======================================================================================================================================================150
  29. #include "kernel_gpu_opencl_wrapper.h" // (in directory)
  30. //======================================================================================================================================================150
  31. // END
  32. //======================================================================================================================================================150
  33. //========================================================================================================================================================================================================200
  34. // MAIN FUNCTION
  35. //========================================================================================================================================================================================================200
  36. int
  37. kernel_gpu_opencl_wrapper( int xmax,
  38. int workload,
  39. fp ***y,
  40. fp **x,
  41. fp **params,
  42. fp *com)
  43. {
  44. //======================================================================================================================================================150
  45. // VARIABLES
  46. //======================================================================================================================================================150
  47. long long time0;
  48. long long time1;
  49. long long time2;
  50. long long time3;
  51. long long time4;
  52. long long time5;
  53. long long timecopyin = 0;
  54. long long timekernel = 0;
  55. long long timecopyout = 0;
  56. long long timeother;
  57. time0 = get_time();
  58. int i;
  59. //======================================================================================================================================================150
  60. // GPU SETUP
  61. //======================================================================================================================================================150
  62. //====================================================================================================100
  63. // COMMON VARIABLES
  64. //====================================================================================================100
  65. // common variables
  66. cl_int error;
  67. //====================================================================================================100
  68. // GET PLATFORMS (Intel, AMD, NVIDIA, based on provided library), SELECT ONE
  69. //====================================================================================================100
  70. // Get the number of available platforms
  71. cl_uint num_platforms;
  72. error = clGetPlatformIDs( 0,
  73. NULL,
  74. &num_platforms);
  75. if (error != CL_SUCCESS)
  76. fatal_CL(error, __LINE__);
  77. // Get the list of available platforms
  78. cl_platform_id *platforms = (cl_platform_id *)malloc(sizeof(cl_platform_id) * num_platforms);
  79. error = clGetPlatformIDs( num_platforms,
  80. platforms,
  81. NULL);
  82. if (error != CL_SUCCESS)
  83. fatal_CL(error, __LINE__);
  84. // Select the 1st platform
  85. cl_platform_id platform = platforms[0];
  86. // Get the name of the selected platform and print it (if there are multiple platforms, choose the first one)
  87. char pbuf[100];
  88. error = clGetPlatformInfo( platform,
  89. CL_PLATFORM_VENDOR,
  90. sizeof(pbuf),
  91. pbuf,
  92. NULL);
  93. if (error != CL_SUCCESS)
  94. fatal_CL(error, __LINE__);
  95. printf("Platform: %s\n", pbuf);
  96. //====================================================================================================100
  97. // CREATE CONTEXT FOR THE PLATFORM
  98. //====================================================================================================100
  99. // Create context properties for selected platform
  100. cl_context_properties context_properties[3] = { CL_CONTEXT_PLATFORM,
  101. (cl_context_properties) platform,
  102. 0};
  103. // Create context for selected platform being GPU
  104. cl_context context;
  105. context = clCreateContextFromType( context_properties,
  106. CL_DEVICE_TYPE_GPU,
  107. NULL,
  108. NULL,
  109. &error);
  110. if (error != CL_SUCCESS)
  111. fatal_CL(error, __LINE__);
  112. //====================================================================================================100
  113. // GET DEVICES AVAILABLE FOR THE CONTEXT, SELECT ONE
  114. //====================================================================================================100
  115. // Get the number of devices (previousely selected for the context)
  116. size_t devices_size;
  117. error = clGetContextInfo( context,
  118. CL_CONTEXT_DEVICES,
  119. 0,
  120. NULL,
  121. &devices_size);
  122. if (error != CL_SUCCESS)
  123. fatal_CL(error, __LINE__);
  124. // Get the list of devices (previousely selected for the context)
  125. cl_device_id *devices = (cl_device_id *) malloc(devices_size);
  126. error = clGetContextInfo( context,
  127. CL_CONTEXT_DEVICES,
  128. devices_size,
  129. devices,
  130. NULL);
  131. if (error != CL_SUCCESS)
  132. fatal_CL(error, __LINE__);
  133. // Select the first device (previousely selected for the context) (if there are multiple devices, choose the first one)
  134. cl_device_id device;
  135. device = devices[0];
  136. // Get the name of the selected device (previousely selected for the context) and print it
  137. error = clGetDeviceInfo(device,
  138. CL_DEVICE_NAME,
  139. sizeof(pbuf),
  140. pbuf,
  141. NULL);
  142. if (error != CL_SUCCESS)
  143. fatal_CL(error, __LINE__);
  144. printf("Device: %s\n", pbuf);
  145. //====================================================================================================100
  146. // CREATE COMMAND QUEUE FOR THE DEVICE
  147. //====================================================================================================100
  148. // Create a command queue
  149. cl_command_queue command_queue;
  150. command_queue = clCreateCommandQueue( context,
  151. device,
  152. 0,
  153. &error);
  154. if (error != CL_SUCCESS)
  155. fatal_CL(error, __LINE__);
  156. //====================================================================================================100
  157. // CRATE PROGRAM, COMPILE IT
  158. //====================================================================================================100
  159. // Load kernel source code from file
  160. const char *source = load_kernel_source("./kernel/kernel_gpu_opencl.cl");
  161. size_t sourceSize = strlen(source);
  162. // Create the program
  163. cl_program program = clCreateProgramWithSource( context,
  164. 1,
  165. &source,
  166. &sourceSize,
  167. &error);
  168. if (error != CL_SUCCESS)
  169. fatal_CL(error, __LINE__);
  170. // Compile the program
  171. error = clBuildProgram( program,
  172. 1,
  173. &device,
  174. "-I./../",
  175. NULL,
  176. NULL);
  177. // Print warnings and errors from compilation
  178. static char log[65536];
  179. memset(log, 0, sizeof(log));
  180. clGetProgramBuildInfo( program,
  181. device,
  182. CL_PROGRAM_BUILD_LOG,
  183. sizeof(log)-1,
  184. log,
  185. NULL);
  186. printf("-----OpenCL Compiler Output-----\n");
  187. if (strstr(log,"warning:") || strstr(log, "error:"))
  188. printf("<<<<\n%s\n>>>>\n", log);
  189. printf("--------------------------------\n");
  190. if (error != CL_SUCCESS)
  191. fatal_CL(error, __LINE__);
  192. // Create kernel
  193. cl_kernel kernel;
  194. kernel = clCreateKernel(program,
  195. "kernel_gpu_opencl",
  196. &error);
  197. if (error != CL_SUCCESS)
  198. fatal_CL(error, __LINE__);
  199. //====================================================================================================100
  200. // INITIAL DRIVER OVERHEAD
  201. //====================================================================================================100
  202. // cudaThreadSynchronize();
  203. time1 = get_time();
  204. //======================================================================================================================================================150
  205. // ALLOCATE MEMORY
  206. //======================================================================================================================================================150
  207. //====================================================================================================100
  208. // d_initvalu_mem
  209. //====================================================================================================100
  210. int d_initvalu_mem;
  211. d_initvalu_mem = EQUATIONS * sizeof(fp);
  212. cl_mem d_initvalu;
  213. d_initvalu = clCreateBuffer(context, // context
  214. CL_MEM_READ_WRITE, // flags
  215. d_initvalu_mem, // size of buffer
  216. NULL, // host pointer (optional)
  217. &error ); // returned error
  218. if (error != CL_SUCCESS)
  219. fatal_CL(error, __LINE__);
  220. //====================================================================================================100
  221. // d_finavalu_mem
  222. //====================================================================================================100
  223. int d_finavalu_mem;
  224. d_finavalu_mem = EQUATIONS * sizeof(fp);
  225. cl_mem d_finavalu;
  226. d_finavalu = clCreateBuffer(context,
  227. CL_MEM_READ_WRITE,
  228. d_finavalu_mem,
  229. NULL,
  230. &error );
  231. if (error != CL_SUCCESS)
  232. fatal_CL(error, __LINE__);
  233. //====================================================================================================100
  234. // d_params_mem
  235. //====================================================================================================100
  236. int d_params_mem;
  237. d_params_mem = PARAMETERS * sizeof(fp);
  238. cl_mem d_params;
  239. d_params = clCreateBuffer( context,
  240. CL_MEM_READ_WRITE,
  241. d_params_mem,
  242. NULL,
  243. &error );
  244. if (error != CL_SUCCESS)
  245. fatal_CL(error, __LINE__);
  246. //====================================================================================================100
  247. // d_com_mem
  248. //====================================================================================================100
  249. int d_com_mem;
  250. d_com_mem = 3 * sizeof(fp);
  251. cl_mem d_com;
  252. d_com = clCreateBuffer( context,
  253. CL_MEM_READ_WRITE,
  254. d_com_mem,
  255. NULL,
  256. &error );
  257. if (error != CL_SUCCESS)
  258. fatal_CL(error, __LINE__);
  259. time2 = get_time();
  260. //======================================================================================================================================================150
  261. // EXECUTION
  262. //======================================================================================================================================================150
  263. int status;
  264. for(i=0; i<workload; i++){
  265. status = solver( y[i],
  266. x[i],
  267. xmax,
  268. params[i],
  269. com,
  270. d_initvalu,
  271. d_finavalu,
  272. d_params,
  273. d_com,
  274. command_queue,
  275. kernel,
  276. &timecopyin,
  277. &timekernel,
  278. &timecopyout);
  279. if(status !=0){
  280. printf("STATUS: %d\n", status);
  281. }
  282. }
  283. // // // print results
  284. // // int k;
  285. // // for(i=0; i<workload; i++){
  286. // // printf("WORKLOAD %d:\n", i);
  287. // // for(j=0; j<(xmax+1); j++){
  288. // // printf("\tTIME %d:\n", j);
  289. // // for(k=0; k<EQUATIONS; k++){
  290. // // printf("\t\ty[%d][%d][%d]=%13.10f\n", i, j, k, y[i][j][k]);
  291. // // }
  292. // // }
  293. // // }
  294. time3 = get_time();
  295. //======================================================================================================================================================150
  296. // FREE GPU MEMORY
  297. //======================================================================================================================================================150
  298. // Release kernels...
  299. clReleaseKernel(kernel);
  300. // Now the program...
  301. clReleaseProgram(program);
  302. // Clean up the device memory...
  303. clReleaseMemObject(d_initvalu);
  304. clReleaseMemObject(d_finavalu);
  305. clReleaseMemObject(d_params);
  306. clReleaseMemObject(d_com);
  307. // Flush the queue
  308. error = clFlush(command_queue);
  309. if (error != CL_SUCCESS)
  310. fatal_CL(error, __LINE__);
  311. // ...and finally, the queue and context.
  312. clReleaseCommandQueue(command_queue);
  313. // ???
  314. clReleaseContext(context);
  315. time4= get_time();
  316. //======================================================================================================================================================150
  317. // DISPLAY TIMING
  318. //======================================================================================================================================================150
  319. printf("Time spent in different stages of the application:\n");
  320. printf("%15.12f s, %15.12f % : CPU: GPU SETUP\n", (float) (time1-time0) / 1000000, (float) (time1-time0) / (float) (time4-time0) * 100);
  321. printf("%15.12f s, %15.12f % : CPU: ALLOCATE GPU MEMORY\n", (float) (time2-time1) / 1000000, (float) (time2-time1) / (float) (time4-time0) * 100);
  322. printf("%15.12f s, %15.12f % : GPU: COMPUTATION\n", (float) (time3-time2) / 1000000, (float) (time3-time2) / (float) (time4-time0) * 100);
  323. printf("\tGPU: COMPUTATION Components:\n");
  324. printf("\t%15.12f s, %15.12f % : GPU: COPY DATA IN\n", (float) (timecopyin) / 1000000, (float) (timecopyin) / (float) (time4-time0) * 100);
  325. printf("\t%15.12f s, %15.12f % : GPU: KERNEL\n", (float) (timekernel) / 1000000, (float) (timekernel) / (float) (time4-time0) * 100);
  326. printf("\t%15.12f s, %15.12f % : GPU: COPY DATA OUT\n", (float) (timecopyout) / 1000000, (float) (timecopyout) / (float) (time4-time0) * 100);
  327. timeother = time3-time2-timecopyin-timekernel-timecopyout;
  328. printf("\t%15.12f s, %15.12f % : GPU: OTHER\n", (float) (timeother) / 1000000, (float) (timeother) / (float) (time4-time0) * 100);
  329. printf("%15.12f s, %15.12f % : CPU: FREE GPU MEMORY\n", (float) (time4-time3) / 1000000, (float) (time4-time3) / (float) (time4-time0) * 100);
  330. printf("Total time:\n");
  331. printf("%.12f s\n", (float) (time4-time0) / 1000000);
  332. //======================================================================================================================================================150
  333. // RETURN
  334. //======================================================================================================================================================150
  335. return 0;
  336. //======================================================================================================================================================150
  337. // END
  338. //======================================================================================================================================================150
  339. }
  340. //========================================================================================================================================================================================================200
  341. // END
  342. //========================================================================================================================================================================================================200
  343. // #ifdef __cplusplus
  344. // }
  345. // #endif