CLHelper.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814
  1. //------------------------------------------
  2. //--cambine:helper function for OpenCL
  3. //--programmer: Jianbin Fang
  4. //--date: 27/12/2010
  5. //------------------------------------------
  6. #ifndef _CL_HELPER_
  7. #define _CL_HELPER_
  8. #include <CL/cl.h>
  9. #include <vector>
  10. #include <iostream>
  11. #include <fstream>
  12. #include <string>
  13. using std::string;
  14. using std::ifstream;
  15. using std::cerr;
  16. using std::endl;
  17. using std::cout;
  18. //#pragma OPENCL EXTENSION cl_nv_compiler_options:enable
  19. #define WORK_DIM 2 //work-items dimensions
  20. struct oclHandleStruct
  21. {
  22. cl_context context;
  23. cl_device_id *devices;
  24. cl_command_queue queue;
  25. cl_program program;
  26. cl_int cl_status;
  27. std::string error_str;
  28. std::vector<cl_kernel> kernel;
  29. };
  30. struct oclHandleStruct oclHandles;
  31. char kernel_file[100] = "Kernels.cl";
  32. int total_kernels = 2;
  33. string kernel_names[2] = {"BFS_1", "BFS_2"};
  34. int work_group_size = 512;
  35. int device_id_inused = 0; //deviced id used (default : 0)
  36. /*
  37. * Converts the contents of a file into a string
  38. */
  39. string FileToString(const string fileName)
  40. {
  41. ifstream f(fileName.c_str(), ifstream::in | ifstream::binary);
  42. try
  43. {
  44. size_t size;
  45. char* str;
  46. string s;
  47. if(f.is_open())
  48. {
  49. size_t fileSize;
  50. f.seekg(0, ifstream::end);
  51. size = fileSize = f.tellg();
  52. f.seekg(0, ifstream::beg);
  53. str = new char[size+1];
  54. if (!str) throw(string("Could not allocate memory"));
  55. f.read(str, fileSize);
  56. f.close();
  57. str[size] = '\0';
  58. s = str;
  59. delete [] str;
  60. return s;
  61. }
  62. }
  63. catch(std::string msg)
  64. {
  65. cerr << "Exception caught in FileToString(): " << msg << endl;
  66. if(f.is_open())
  67. f.close();
  68. }
  69. catch(...)
  70. {
  71. cerr << "Exception caught in FileToString()" << endl;
  72. if(f.is_open())
  73. f.close();
  74. }
  75. string errorMsg = "FileToString()::Error: Unable to open file "
  76. + fileName;
  77. throw(errorMsg);
  78. }
  79. //---------------------------------------
  80. //Read command line parameters
  81. //
  82. void _clCmdParams(int argc, char* argv[]){
  83. for (int i =0; i < argc; ++i)
  84. {
  85. switch (argv[i][1])
  86. {
  87. case 'g': //--g stands for size of work group
  88. if (++i < argc)
  89. {
  90. sscanf(argv[i], "%u", &work_group_size);
  91. }
  92. else
  93. {
  94. std::cerr << "Could not read argument after option " << argv[i-1] << std::endl;
  95. throw;
  96. }
  97. break;
  98. case 'd': //--d stands for device id used in computaion
  99. if (++i < argc)
  100. {
  101. sscanf(argv[i], "%u", &device_id_inused);
  102. }
  103. else
  104. {
  105. std::cerr << "Could not read argument after option " << argv[i-1] << std::endl;
  106. throw;
  107. }
  108. break;
  109. default:
  110. ;
  111. }
  112. }
  113. }
  114. //---------------------------------------
  115. //Initlize CL objects
  116. //--description: there are 5 steps to initialize all the OpenCL objects needed
  117. //--revised on 04/01/2011: get the number of devices and
  118. // devices have no relationship with context
  119. void _clInit()
  120. {
  121. int DEVICE_ID_INUSED = device_id_inused;
  122. cl_int resultCL;
  123. oclHandles.context = NULL;
  124. oclHandles.devices = NULL;
  125. oclHandles.queue = NULL;
  126. oclHandles.program = NULL;
  127. cl_uint deviceListSize;
  128. //-----------------------------------------------
  129. //--cambine-1: find the available platforms and select one
  130. cl_uint numPlatforms;
  131. cl_platform_id targetPlatform = NULL;
  132. resultCL = clGetPlatformIDs(0, NULL, &numPlatforms);
  133. if (resultCL != CL_SUCCESS)
  134. throw (string("InitCL()::Error: Getting number of platforms (clGetPlatformIDs)"));
  135. //printf("number of platforms:%d\n",numPlatforms); //by cambine
  136. if (!(numPlatforms > 0))
  137. throw (string("InitCL()::Error: No platforms found (clGetPlatformIDs)"));
  138. cl_platform_id* allPlatforms = (cl_platform_id*) malloc(numPlatforms * sizeof(cl_platform_id));
  139. resultCL = clGetPlatformIDs(numPlatforms, allPlatforms, NULL);
  140. if (resultCL != CL_SUCCESS)
  141. throw (string("InitCL()::Error: Getting platform ids (clGetPlatformIDs)"));
  142. /* Select the target platform. Default: first platform */
  143. targetPlatform = allPlatforms[1];
  144. for (int i = 0; i < numPlatforms; i++)
  145. {
  146. char pbuff[128];
  147. resultCL = clGetPlatformInfo( allPlatforms[i],
  148. CL_PLATFORM_VENDOR,
  149. sizeof(pbuff),
  150. pbuff,
  151. NULL);
  152. if (resultCL != CL_SUCCESS)
  153. throw (string("InitCL()::Error: Getting platform info (clGetPlatformInfo)"));
  154. //printf("vedor is %s\n",pbuff);
  155. }
  156. free(allPlatforms);
  157. //-----------------------------------------------
  158. //--cambine-2: create an OpenCL context
  159. cl_context_properties cprops[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)targetPlatform, 0 };
  160. oclHandles.context = clCreateContextFromType(cprops,
  161. CL_DEVICE_TYPE_CPU,
  162. NULL,
  163. NULL,
  164. &resultCL);
  165. if ((resultCL != CL_SUCCESS) || (oclHandles.context == NULL))
  166. throw (string("InitCL()::Error: Creating Context (clCreateContextFromType)"));
  167. //-----------------------------------------------
  168. //--cambine-3: detect OpenCL devices
  169. /* First, get the size of device list */
  170. oclHandles.cl_status = clGetDeviceIDs(targetPlatform, CL_DEVICE_TYPE_CPU, 0, NULL, &deviceListSize);
  171. if(oclHandles.cl_status!=CL_SUCCESS){
  172. throw(string("exception in _clInit -> clGetDeviceIDs"));
  173. }
  174. if (deviceListSize == 0)
  175. throw(string("InitCL()::Error: No devices found."));
  176. //std::cout<<"device number:"<<deviceListSize<<std::endl;
  177. /* Now, allocate the device list */
  178. oclHandles.devices = (cl_device_id *)malloc(deviceListSize * sizeof(cl_device_id));
  179. if (oclHandles.devices == 0)
  180. throw(string("InitCL()::Error: Could not allocate memory."));
  181. /* Next, get the device list data */
  182. oclHandles.cl_status = clGetDeviceIDs(targetPlatform, CL_DEVICE_TYPE_CPU, deviceListSize, \
  183. oclHandles.devices, NULL);
  184. if(oclHandles.cl_status!=CL_SUCCESS){
  185. throw(string("exception in _clInit -> clGetDeviceIDs-2"));
  186. }
  187. //-----------------------------------------------
  188. //--cambine-4: Create an OpenCL command queue
  189. oclHandles.queue = clCreateCommandQueue(oclHandles.context,
  190. oclHandles.devices[DEVICE_ID_INUSED],
  191. 0,
  192. &resultCL);
  193. if ((resultCL != CL_SUCCESS) || (oclHandles.queue == NULL))
  194. throw(string("InitCL()::Creating Command Queue. (clCreateCommandQueue)"));
  195. //-----------------------------------------------
  196. //--cambine-5: Load CL file, build CL program object, create CL kernel object
  197. std::string source_str = FileToString(kernel_file);
  198. const char * source = source_str.c_str();
  199. size_t sourceSize[] = { source_str.length() };
  200. oclHandles.program = clCreateProgramWithSource(oclHandles.context,
  201. 1,
  202. &source,
  203. sourceSize,
  204. &resultCL);
  205. if ((resultCL != CL_SUCCESS) || (oclHandles.program == NULL))
  206. throw(string("InitCL()::Error: Loading Binary into cl_program. (clCreateProgramWithBinary)"));
  207. //insert debug information
  208. //std::string options= "-cl-nv-verbose"; //Doesn't work on AMD machines
  209. //options += " -cl-nv-opt-level=3";
  210. resultCL = clBuildProgram(oclHandles.program, deviceListSize, oclHandles.devices, NULL, NULL,NULL);
  211. if ((resultCL != CL_SUCCESS) || (oclHandles.program == NULL))
  212. {
  213. cerr << "InitCL()::Error: In clBuildProgram" << endl;
  214. size_t length;
  215. resultCL = clGetProgramBuildInfo(oclHandles.program,
  216. oclHandles.devices[DEVICE_ID_INUSED],
  217. CL_PROGRAM_BUILD_LOG,
  218. 0,
  219. NULL,
  220. &length);
  221. if(resultCL != CL_SUCCESS)
  222. throw(string("InitCL()::Error: Getting Program build info(clGetProgramBuildInfo)"));
  223. char* buffer = (char*)malloc(length);
  224. resultCL = clGetProgramBuildInfo(oclHandles.program,
  225. oclHandles.devices[DEVICE_ID_INUSED],
  226. CL_PROGRAM_BUILD_LOG,
  227. length,
  228. buffer,
  229. NULL);
  230. if(resultCL != CL_SUCCESS)
  231. throw(string("InitCL()::Error: Getting Program build info(clGetProgramBuildInfo)"));
  232. cerr << buffer << endl;
  233. free(buffer);
  234. throw(string("InitCL()::Error: Building Program (clBuildProgram)"));
  235. }
  236. //get program information in intermediate representation
  237. #ifdef PTX_MSG
  238. size_t binary_sizes[deviceListSize];
  239. char * binaries[deviceListSize];
  240. //figure out number of devices and the sizes of the binary for each device.
  241. oclHandles.cl_status = clGetProgramInfo(oclHandles.program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t)*deviceListSize, &binary_sizes, NULL );
  242. if(oclHandles.cl_status!=CL_SUCCESS){
  243. throw(string("--cambine:exception in _InitCL -> clGetProgramInfo-2"));
  244. }
  245. std::cout<<"--cambine:"<<binary_sizes<<std::endl;
  246. //copy over all of the generated binaries.
  247. for(int i=0;i<deviceListSize;i++)
  248. binaries[i] = (char *)malloc( sizeof(char)*(binary_sizes[i]+1));
  249. oclHandles.cl_status = clGetProgramInfo(oclHandles.program, CL_PROGRAM_BINARIES, sizeof(char *)*deviceListSize, binaries, NULL );
  250. if(oclHandles.cl_status!=CL_SUCCESS){
  251. throw(string("--cambine:exception in _InitCL -> clGetProgramInfo-3"));
  252. }
  253. for(int i=0;i<deviceListSize;i++)
  254. binaries[i][binary_sizes[i]] = '\0';
  255. std::cout<<"--cambine:writing ptd information..."<<std::endl;
  256. FILE * ptx_file = fopen("cl.ptx","w");
  257. if(ptx_file==NULL){
  258. throw(string("exceptions in allocate ptx file."));
  259. }
  260. fprintf(ptx_file,"%s",binaries[DEVICE_ID_INUSED]);
  261. fclose(ptx_file);
  262. std::cout<<"--cambine:writing ptd information done."<<std::endl;
  263. for(int i=0;i<deviceListSize;i++)
  264. free(binaries[i]);
  265. #endif
  266. for (int nKernel = 0; nKernel < total_kernels; nKernel++)
  267. {
  268. /* get a kernel object handle for a kernel with the given name */
  269. cl_kernel kernel = clCreateKernel(oclHandles.program,
  270. (kernel_names[nKernel]).c_str(),
  271. &resultCL);
  272. if ((resultCL != CL_SUCCESS) || (kernel == NULL))
  273. {
  274. string errorMsg = "InitCL()::Error: Creating Kernel (clCreateKernel) \"" + kernel_names[nKernel] + "\"";
  275. throw(errorMsg);
  276. }
  277. oclHandles.kernel.push_back(kernel);
  278. }
  279. //get resource alocation information
  280. #ifdef RES_MSG
  281. char * build_log;
  282. size_t ret_val_size;
  283. oclHandles.cl_status = clGetProgramBuildInfo(oclHandles.program, oclHandles.devices[DEVICE_ID_INUSED], CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
  284. if(oclHandles.cl_status!=CL_SUCCESS){
  285. throw(string("exceptions in _InitCL -> getting resource information"));
  286. }
  287. build_log = (char *)malloc(ret_val_size+1);
  288. oclHandles.cl_status = clGetProgramBuildInfo(oclHandles.program, oclHandles.devices[DEVICE_ID_INUSED], CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
  289. if(oclHandles.cl_status!=CL_SUCCESS){
  290. throw(string("exceptions in _InitCL -> getting resources allocation information-2"));
  291. }
  292. build_log[ret_val_size] = '\0';
  293. std::cout<<"--cambine:"<<build_log<<std::endl;
  294. free(build_log);
  295. #endif
  296. }
  297. //---------------------------------------
  298. //release CL objects
  299. void _clRelease()
  300. {
  301. char errorFlag = false;
  302. for (int nKernel = 0; nKernel < oclHandles.kernel.size(); nKernel++)
  303. {
  304. if (oclHandles.kernel[nKernel] != NULL)
  305. {
  306. cl_int resultCL = clReleaseKernel(oclHandles.kernel[nKernel]);
  307. if (resultCL != CL_SUCCESS)
  308. {
  309. cerr << "ReleaseCL()::Error: In clReleaseKernel" << endl;
  310. errorFlag = true;
  311. }
  312. oclHandles.kernel[nKernel] = NULL;
  313. }
  314. oclHandles.kernel.clear();
  315. }
  316. if (oclHandles.program != NULL)
  317. {
  318. cl_int resultCL = clReleaseProgram(oclHandles.program);
  319. if (resultCL != CL_SUCCESS)
  320. {
  321. cerr << "ReleaseCL()::Error: In clReleaseProgram" << endl;
  322. errorFlag = true;
  323. }
  324. oclHandles.program = NULL;
  325. }
  326. if (oclHandles.queue != NULL)
  327. {
  328. cl_int resultCL = clReleaseCommandQueue(oclHandles.queue);
  329. if (resultCL != CL_SUCCESS)
  330. {
  331. cerr << "ReleaseCL()::Error: In clReleaseCommandQueue" << endl;
  332. errorFlag = true;
  333. }
  334. oclHandles.queue = NULL;
  335. }
  336. free(oclHandles.devices);
  337. if (oclHandles.context != NULL)
  338. {
  339. cl_int resultCL = clReleaseContext(oclHandles.context);
  340. if (resultCL != CL_SUCCESS)
  341. {
  342. cerr << "ReleaseCL()::Error: In clReleaseContext" << endl;
  343. errorFlag = true;
  344. }
  345. oclHandles.context = NULL;
  346. }
  347. if (errorFlag) throw(string("ReleaseCL()::Error encountered."));
  348. }
  349. //--------------------------------------------------------
  350. //--cambine:create buffer and then copy data from host to device
  351. cl_mem _clCreateAndCpyMem(int size, void * h_mem_source) throw(string){
  352. cl_mem d_mem;
  353. d_mem = clCreateBuffer(oclHandles.context, CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR, \
  354. size, h_mem_source, &oclHandles.cl_status);
  355. #ifdef ERRMSG
  356. if(oclHandles.cl_status != CL_SUCCESS)
  357. throw(string("excpetion in _clCreateAndCpyMem()"));
  358. #endif
  359. return d_mem;
  360. }
  361. //-------------------------------------------------------
  362. //--cambine: create read only buffer for devices
  363. //--date: 17/01/2011
  364. cl_mem _clMallocRW(int size, void * h_mem_ptr) throw(string){
  365. cl_mem d_mem;
  366. d_mem = clCreateBuffer(oclHandles.context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, size, h_mem_ptr, &oclHandles.cl_status);
  367. #ifdef ERRMSG
  368. if(oclHandles.cl_status != CL_SUCCESS)
  369. throw(string("excpetion in _clMallocRW"));
  370. #endif
  371. return d_mem;
  372. }
  373. //-------------------------------------------------------
  374. //--cambine: create read and write buffer for devices
  375. //--date: 17/01/2011
  376. cl_mem _clMalloc(int size, void * h_mem_ptr) throw(string){
  377. cl_mem d_mem;
  378. d_mem = clCreateBuffer(oclHandles.context, CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, size, h_mem_ptr, &oclHandles.cl_status);
  379. #ifdef ERRMSG
  380. if(oclHandles.cl_status != CL_SUCCESS)
  381. throw(string("excpetion in _clMalloc"));
  382. #endif
  383. return d_mem;
  384. }
  385. //-------------------------------------------------------
  386. //--cambine: transfer data from host to device
  387. //--date: 17/01/2011
  388. void _clMemcpyH2D(cl_mem d_mem, int size, const void *h_mem_ptr) throw(string){
  389. oclHandles.cl_status = clEnqueueWriteBuffer(oclHandles.queue, d_mem, CL_TRUE, 0, size, h_mem_ptr, 0, NULL, NULL);
  390. #ifdef ERRMSG
  391. if(oclHandles.cl_status != CL_SUCCESS)
  392. throw(string("excpetion in _clMemcpyH2D"));
  393. #endif
  394. }
  395. //--------------------------------------------------------
  396. //--cambine:create buffer and then copy data from host to device with pinned
  397. // memory
  398. cl_mem _clCreateAndCpyPinnedMem(int size, float* h_mem_source) throw(string){
  399. cl_mem d_mem, d_mem_pinned;
  400. float * h_mem_pinned = NULL;
  401. d_mem_pinned = clCreateBuffer(oclHandles.context, CL_MEM_READ_ONLY|CL_MEM_ALLOC_HOST_PTR, \
  402. size, NULL, &oclHandles.cl_status);
  403. #ifdef ERRMSG
  404. if(oclHandles.cl_status != CL_SUCCESS)
  405. throw(string("excpetion in _clCreateAndCpyMem()->d_mem_pinned"));
  406. #endif
  407. //------------
  408. d_mem = clCreateBuffer(oclHandles.context, CL_MEM_READ_ONLY, \
  409. size, NULL, &oclHandles.cl_status);
  410. #ifdef ERRMSG
  411. if(oclHandles.cl_status != CL_SUCCESS)
  412. throw(string("excpetion in _clCreateAndCpyMem() -> d_mem "));
  413. #endif
  414. //----------
  415. h_mem_pinned = (cl_float *)clEnqueueMapBuffer(oclHandles.queue, d_mem_pinned, CL_TRUE, \
  416. CL_MAP_WRITE, 0, size, 0, NULL, \
  417. NULL, &oclHandles.cl_status);
  418. #ifdef ERRMSG
  419. if(oclHandles.cl_status != CL_SUCCESS)
  420. throw(string("excpetion in _clCreateAndCpyMem() -> clEnqueueMapBuffer"));
  421. #endif
  422. int element_number = size/sizeof(float);
  423. #pragma omp parallel for
  424. for(int i=0;i<element_number;i++){
  425. h_mem_pinned[i] = h_mem_source[i];
  426. }
  427. //----------
  428. oclHandles.cl_status = clEnqueueWriteBuffer(oclHandles.queue, d_mem, \
  429. CL_TRUE, 0, size, h_mem_pinned, \
  430. 0, NULL, NULL);
  431. #ifdef ERRMSG
  432. if(oclHandles.cl_status != CL_SUCCESS)
  433. throw(string("excpetion in _clCreateAndCpyMem() -> clEnqueueWriteBuffer"));
  434. #endif
  435. return d_mem;
  436. }
  437. //--------------------------------------------------------
  438. //--cambine:create write only buffer on device
  439. cl_mem _clMallocWO(int size) throw(string){
  440. cl_mem d_mem;
  441. d_mem = clCreateBuffer(oclHandles.context, CL_MEM_WRITE_ONLY, size, 0, &oclHandles.cl_status);
  442. #ifdef ERRMSG
  443. if(oclHandles.cl_status != CL_SUCCESS)
  444. throw(string("excpetion in _clCreateMem()"));
  445. #endif
  446. return d_mem;
  447. }
  448. //--------------------------------------------------------
  449. //transfer data from device to host
  450. void _clMemcpyD2H(cl_mem d_mem, int size, void * h_mem) throw(string){
  451. oclHandles.cl_status = clEnqueueReadBuffer(oclHandles.queue, d_mem, CL_TRUE, 0, size, h_mem, 0,0,0);
  452. #ifdef ERRMSG
  453. oclHandles.error_str = "excpetion in _clCpyMemD2H -> ";
  454. switch(oclHandles.cl_status){
  455. case CL_INVALID_COMMAND_QUEUE:
  456. oclHandles.error_str += "CL_INVALID_COMMAND_QUEUE";
  457. break;
  458. case CL_INVALID_CONTEXT:
  459. oclHandles.error_str += "CL_INVALID_CONTEXT";
  460. break;
  461. case CL_INVALID_MEM_OBJECT:
  462. oclHandles.error_str += "CL_INVALID_MEM_OBJECT";
  463. break;
  464. case CL_INVALID_VALUE:
  465. oclHandles.error_str += "CL_INVALID_VALUE";
  466. break;
  467. case CL_INVALID_EVENT_WAIT_LIST:
  468. oclHandles.error_str += "CL_INVALID_EVENT_WAIT_LIST";
  469. break;
  470. case CL_MEM_OBJECT_ALLOCATION_FAILURE:
  471. oclHandles.error_str += "CL_MEM_OBJECT_ALLOCATION_FAILURE";
  472. break;
  473. case CL_OUT_OF_HOST_MEMORY:
  474. oclHandles.error_str += "CL_OUT_OF_HOST_MEMORY";
  475. break;
  476. default:
  477. oclHandles.error_str += "Unknown reason";
  478. break;
  479. }
  480. if(oclHandles.cl_status != CL_SUCCESS)
  481. throw(oclHandles.error_str);
  482. #endif
  483. }
  484. //--------------------------------------------------------
  485. //set kernel arguments
  486. void _clSetArgs(int kernel_id, int arg_idx, void * d_mem, int size = 0) throw(string){
  487. if(!size){
  488. oclHandles.cl_status = clSetKernelArg(oclHandles.kernel[kernel_id], arg_idx, sizeof(d_mem), &d_mem);
  489. #ifdef ERRMSG
  490. oclHandles.error_str = "excpetion in _clSetKernelArg() ";
  491. switch(oclHandles.cl_status){
  492. case CL_INVALID_KERNEL:
  493. oclHandles.error_str += "CL_INVALID_KERNEL";
  494. break;
  495. case CL_INVALID_ARG_INDEX:
  496. oclHandles.error_str += "CL_INVALID_ARG_INDEX";
  497. break;
  498. case CL_INVALID_ARG_VALUE:
  499. oclHandles.error_str += "CL_INVALID_ARG_VALUE";
  500. break;
  501. case CL_INVALID_MEM_OBJECT:
  502. oclHandles.error_str += "CL_INVALID_MEM_OBJECT";
  503. break;
  504. case CL_INVALID_SAMPLER:
  505. oclHandles.error_str += "CL_INVALID_SAMPLER";
  506. break;
  507. case CL_INVALID_ARG_SIZE:
  508. oclHandles.error_str += "CL_INVALID_ARG_SIZE";
  509. break;
  510. case CL_OUT_OF_RESOURCES:
  511. oclHandles.error_str += "CL_OUT_OF_RESOURCES";
  512. break;
  513. case CL_OUT_OF_HOST_MEMORY:
  514. oclHandles.error_str += "CL_OUT_OF_HOST_MEMORY";
  515. break;
  516. default:
  517. oclHandles.error_str += "Unknown reason";
  518. break;
  519. }
  520. if(oclHandles.cl_status != CL_SUCCESS)
  521. throw(oclHandles.error_str);
  522. #endif
  523. }
  524. else{
  525. oclHandles.cl_status = clSetKernelArg(oclHandles.kernel[kernel_id], arg_idx, size, d_mem);
  526. #ifdef ERRMSG
  527. oclHandles.error_str = "excpetion in _clSetKernelArg() ";
  528. switch(oclHandles.cl_status){
  529. case CL_INVALID_KERNEL:
  530. oclHandles.error_str += "CL_INVALID_KERNEL";
  531. break;
  532. case CL_INVALID_ARG_INDEX:
  533. oclHandles.error_str += "CL_INVALID_ARG_INDEX";
  534. break;
  535. case CL_INVALID_ARG_VALUE:
  536. oclHandles.error_str += "CL_INVALID_ARG_VALUE";
  537. break;
  538. case CL_INVALID_MEM_OBJECT:
  539. oclHandles.error_str += "CL_INVALID_MEM_OBJECT";
  540. break;
  541. case CL_INVALID_SAMPLER:
  542. oclHandles.error_str += "CL_INVALID_SAMPLER";
  543. break;
  544. case CL_INVALID_ARG_SIZE:
  545. oclHandles.error_str += "CL_INVALID_ARG_SIZE";
  546. break;
  547. case CL_OUT_OF_RESOURCES:
  548. oclHandles.error_str += "CL_OUT_OF_RESOURCES";
  549. break;
  550. case CL_OUT_OF_HOST_MEMORY:
  551. oclHandles.error_str += "CL_OUT_OF_HOST_MEMORY";
  552. break;
  553. default:
  554. oclHandles.error_str += "Unknown reason";
  555. break;
  556. }
  557. if(oclHandles.cl_status != CL_SUCCESS)
  558. throw(oclHandles.error_str);
  559. #endif
  560. }
  561. }
  562. void _clFinish() throw(string){
  563. oclHandles.cl_status = clFinish(oclHandles.queue);
  564. #ifdef ERRMSG
  565. oclHandles.error_str = "excpetion in _clFinish";
  566. switch(oclHandles.cl_status){
  567. case CL_INVALID_COMMAND_QUEUE:
  568. oclHandles.error_str += "CL_INVALID_COMMAND_QUEUE";
  569. break;
  570. case CL_OUT_OF_RESOURCES:
  571. oclHandles.error_str += "CL_OUT_OF_RESOURCES";
  572. break;
  573. case CL_OUT_OF_HOST_MEMORY:
  574. oclHandles.error_str += "CL_OUT_OF_HOST_MEMORY";
  575. break;
  576. default:
  577. oclHandles.error_str += "Unknown reasons";
  578. break;
  579. }
  580. if(oclHandles.cl_status!=CL_SUCCESS){
  581. throw(oclHandles.error_str);
  582. }
  583. #endif
  584. }
  585. //--------------------------------------------------------
  586. //--cambine:enqueue kernel
  587. void _clInvokeKernel(int kernel_id, int work_items, int work_group_size) throw(string){
  588. cl_uint work_dim = WORK_DIM;
  589. cl_event e[1];
  590. if(work_items%work_group_size != 0) //process situations that work_items cannot be divided by work_group_size
  591. work_items = work_items + (work_group_size-(work_items%work_group_size));
  592. size_t local_work_size[] = {work_group_size, 1};
  593. size_t global_work_size[] = {work_items, 1};
  594. oclHandles.cl_status = clEnqueueNDRangeKernel(oclHandles.queue, oclHandles.kernel[kernel_id], work_dim, 0, \
  595. global_work_size, local_work_size, 0 , 0, &(e[0]) );
  596. #ifdef ERRMSG
  597. oclHandles.error_str = "excpetion in _clInvokeKernel() -> ";
  598. switch(oclHandles.cl_status)
  599. {
  600. case CL_INVALID_PROGRAM_EXECUTABLE:
  601. oclHandles.error_str += "CL_INVALID_PROGRAM_EXECUTABLE";
  602. break;
  603. case CL_INVALID_COMMAND_QUEUE:
  604. oclHandles.error_str += "CL_INVALID_COMMAND_QUEUE";
  605. break;
  606. case CL_INVALID_KERNEL:
  607. oclHandles.error_str += "CL_INVALID_KERNEL";
  608. break;
  609. case CL_INVALID_CONTEXT:
  610. oclHandles.error_str += "CL_INVALID_CONTEXT";
  611. break;
  612. case CL_INVALID_KERNEL_ARGS:
  613. oclHandles.error_str += "CL_INVALID_KERNEL_ARGS";
  614. break;
  615. case CL_INVALID_WORK_DIMENSION:
  616. oclHandles.error_str += "CL_INVALID_WORK_DIMENSION";
  617. break;
  618. case CL_INVALID_GLOBAL_WORK_SIZE:
  619. oclHandles.error_str += "CL_INVALID_GLOBAL_WORK_SIZE";
  620. break;
  621. case CL_INVALID_WORK_GROUP_SIZE:
  622. oclHandles.error_str += "CL_INVALID_WORK_GROUP_SIZE";
  623. break;
  624. case CL_INVALID_WORK_ITEM_SIZE:
  625. oclHandles.error_str += "CL_INVALID_WORK_ITEM_SIZE";
  626. break;
  627. case CL_INVALID_GLOBAL_OFFSET:
  628. oclHandles.error_str += "CL_INVALID_GLOBAL_OFFSET";
  629. break;
  630. case CL_OUT_OF_RESOURCES:
  631. oclHandles.error_str += "CL_OUT_OF_RESOURCES";
  632. break;
  633. case CL_MEM_OBJECT_ALLOCATION_FAILURE:
  634. oclHandles.error_str += "CL_MEM_OBJECT_ALLOCATION_FAILURE";
  635. break;
  636. case CL_INVALID_EVENT_WAIT_LIST:
  637. oclHandles.error_str += "CL_INVALID_EVENT_WAIT_LIST";
  638. break;
  639. case CL_OUT_OF_HOST_MEMORY:
  640. oclHandles.error_str += "CL_OUT_OF_HOST_MEMORY";
  641. break;
  642. default:
  643. oclHandles.error_str += "Unkown reseason";
  644. break;
  645. }
  646. if(oclHandles.cl_status != CL_SUCCESS)
  647. throw(oclHandles.error_str);
  648. #endif
  649. //_clFinish();
  650. // oclHandles.cl_status = clWaitForEvents(1, &e[0]);
  651. // #ifdef ERRMSG
  652. // if (oclHandles.cl_status!= CL_SUCCESS)
  653. // throw(string("excpetion in _clEnqueueNDRange() -> clWaitForEvents"));
  654. // #endif
  655. }
  656. void _clInvokeKernel2D(int kernel_id, int range_x, int range_y, int group_x, int group_y) throw(string){
  657. cl_uint work_dim = WORK_DIM;
  658. size_t local_work_size[] = {group_x, group_y};
  659. size_t global_work_size[] = {range_x, range_y};
  660. cl_event e[1];
  661. /*if(work_items%work_group_size != 0) //process situations that work_items cannot be divided by work_group_size
  662. work_items = work_items + (work_group_size-(work_items%work_group_size));*/
  663. oclHandles.cl_status = clEnqueueNDRangeKernel(oclHandles.queue, oclHandles.kernel[kernel_id], work_dim, 0, \
  664. global_work_size, local_work_size, 0 , 0, &(e[0]) );
  665. #ifdef ERRMSG
  666. oclHandles.error_str = "excpetion in _clInvokeKernel() -> ";
  667. switch(oclHandles.cl_status)
  668. {
  669. case CL_INVALID_PROGRAM_EXECUTABLE:
  670. oclHandles.error_str += "CL_INVALID_PROGRAM_EXECUTABLE";
  671. break;
  672. case CL_INVALID_COMMAND_QUEUE:
  673. oclHandles.error_str += "CL_INVALID_COMMAND_QUEUE";
  674. break;
  675. case CL_INVALID_KERNEL:
  676. oclHandles.error_str += "CL_INVALID_KERNEL";
  677. break;
  678. case CL_INVALID_CONTEXT:
  679. oclHandles.error_str += "CL_INVALID_CONTEXT";
  680. break;
  681. case CL_INVALID_KERNEL_ARGS:
  682. oclHandles.error_str += "CL_INVALID_KERNEL_ARGS";
  683. break;
  684. case CL_INVALID_WORK_DIMENSION:
  685. oclHandles.error_str += "CL_INVALID_WORK_DIMENSION";
  686. break;
  687. case CL_INVALID_GLOBAL_WORK_SIZE:
  688. oclHandles.error_str += "CL_INVALID_GLOBAL_WORK_SIZE";
  689. break;
  690. case CL_INVALID_WORK_GROUP_SIZE:
  691. oclHandles.error_str += "CL_INVALID_WORK_GROUP_SIZE";
  692. break;
  693. case CL_INVALID_WORK_ITEM_SIZE:
  694. oclHandles.error_str += "CL_INVALID_WORK_ITEM_SIZE";
  695. break;
  696. case CL_INVALID_GLOBAL_OFFSET:
  697. oclHandles.error_str += "CL_INVALID_GLOBAL_OFFSET";
  698. break;
  699. case CL_OUT_OF_RESOURCES:
  700. oclHandles.error_str += "CL_OUT_OF_RESOURCES";
  701. break;
  702. case CL_MEM_OBJECT_ALLOCATION_FAILURE:
  703. oclHandles.error_str += "CL_MEM_OBJECT_ALLOCATION_FAILURE";
  704. break;
  705. case CL_INVALID_EVENT_WAIT_LIST:
  706. oclHandles.error_str += "CL_INVALID_EVENT_WAIT_LIST";
  707. break;
  708. case CL_OUT_OF_HOST_MEMORY:
  709. oclHandles.error_str += "CL_OUT_OF_HOST_MEMORY";
  710. break;
  711. default:
  712. oclHandles.error_str += "Unkown reseason";
  713. break;
  714. }
  715. if(oclHandles.cl_status != CL_SUCCESS)
  716. throw(oclHandles.error_str);
  717. #endif
  718. //_clFinish();
  719. /*oclHandles.cl_status = clWaitForEvents(1, &e[0]);
  720. #ifdef ERRMSG
  721. if (oclHandles.cl_status!= CL_SUCCESS)
  722. throw(string("excpetion in _clEnqueueNDRange() -> clWaitForEvents"));
  723. #endif*/
  724. }
  725. //--------------------------------------------------------
  726. //release OpenCL objects
  727. void _clFree(cl_mem ob) throw(string){
  728. if(ob!=NULL)
  729. oclHandles.cl_status = clReleaseMemObject(ob);
  730. #ifdef ERRMSG
  731. oclHandles.error_str = "excpetion in _clFree() ->";
  732. switch(oclHandles.cl_status)
  733. {
  734. case CL_INVALID_MEM_OBJECT:
  735. oclHandles.error_str += "CL_INVALID_MEM_OBJECT";
  736. break;
  737. case CL_OUT_OF_RESOURCES:
  738. oclHandles.error_str += "CL_OUT_OF_RESOURCES";
  739. break;
  740. case CL_OUT_OF_HOST_MEMORY:
  741. oclHandles.error_str += "CL_OUT_OF_HOST_MEMORY";
  742. break;
  743. default:
  744. oclHandles.error_str += "Unkown reseason";
  745. break;
  746. }
  747. if (oclHandles.cl_status!= CL_SUCCESS)
  748. throw(oclHandles.error_str);
  749. #endif
  750. }
  751. #endif //_CL_HELPER_