CLHelper.h 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  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(int platform_num, int device_num, int use_gpu)
  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[platform_num];
  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. // Select device type on the basis of the passed parameter
  160. static cl_device_type device_type = use_gpu ? CL_DEVICE_TYPE_GPU : CL_DEVICE_TYPE_CPU;
  161. cl_context_properties cprops[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)targetPlatform, 0 };
  162. oclHandles.context = clCreateContextFromType(cprops,
  163. device_type,
  164. NULL,
  165. NULL,
  166. &resultCL);
  167. if ((resultCL != CL_SUCCESS) || (oclHandles.context == NULL))
  168. throw (string("InitCL()::Error: Creating Context (clCreateContextFromType)"));
  169. //-----------------------------------------------
  170. //--cambine-3: detect OpenCL devices
  171. /* First, get the size of device list */
  172. oclHandles.cl_status = clGetDeviceIDs(targetPlatform, device_type, 0, NULL, &deviceListSize);
  173. if(oclHandles.cl_status!=CL_SUCCESS){
  174. throw(string("exception in _clInit -> clGetDeviceIDs"));
  175. }
  176. if (deviceListSize == 0)
  177. throw(string("InitCL()::Error: No devices found."));
  178. //std::cout<<"device number:"<<deviceListSize<<std::endl;
  179. /* Now, allocate the device list */
  180. oclHandles.devices = (cl_device_id *)malloc(deviceListSize * sizeof(cl_device_id));
  181. if (oclHandles.devices == 0)
  182. throw(string("InitCL()::Error: Could not allocate memory."));
  183. /* Next, get the device list data */
  184. oclHandles.cl_status = clGetDeviceIDs(targetPlatform, device_type, deviceListSize, \
  185. oclHandles.devices, NULL);
  186. if(oclHandles.cl_status!=CL_SUCCESS){
  187. throw(string("exception in _clInit -> clGetDeviceIDs-2"));
  188. }
  189. //-----------------------------------------------
  190. //--cambine-4: Create an OpenCL command queue
  191. oclHandles.queue = clCreateCommandQueue(oclHandles.context,
  192. oclHandles.devices[device_num],
  193. 0,
  194. &resultCL);
  195. if ((resultCL != CL_SUCCESS) || (oclHandles.queue == NULL))
  196. throw(string("InitCL()::Creating Command Queue. (clCreateCommandQueue)"));
  197. //-----------------------------------------------
  198. //--cambine-5: Load CL file, build CL program object, create CL kernel object
  199. std::string source_str = FileToString(kernel_file);
  200. const char * source = source_str.c_str();
  201. size_t sourceSize[] = { source_str.length() };
  202. oclHandles.program = clCreateProgramWithSource(oclHandles.context,
  203. 1,
  204. &source,
  205. sourceSize,
  206. &resultCL);
  207. if ((resultCL != CL_SUCCESS) || (oclHandles.program == NULL))
  208. throw(string("InitCL()::Error: Loading Binary into cl_program. (clCreateProgramWithBinary)"));
  209. //insert debug information
  210. //std::string options= "-cl-nv-verbose"; //Doesn't work on AMD machines
  211. //options += " -cl-nv-opt-level=3";
  212. resultCL = clBuildProgram(oclHandles.program, deviceListSize, oclHandles.devices, NULL, NULL,NULL);
  213. if ((resultCL != CL_SUCCESS) || (oclHandles.program == NULL))
  214. {
  215. cerr << "InitCL()::Error: In clBuildProgram" << endl;
  216. size_t length;
  217. resultCL = clGetProgramBuildInfo(oclHandles.program,
  218. oclHandles.devices[device_num],
  219. CL_PROGRAM_BUILD_LOG,
  220. 0,
  221. NULL,
  222. &length);
  223. if(resultCL != CL_SUCCESS)
  224. throw(string("InitCL()::Error: Getting Program build info(clGetProgramBuildInfo)"));
  225. char* buffer = (char*)malloc(length);
  226. resultCL = clGetProgramBuildInfo(oclHandles.program,
  227. oclHandles.devices[device_num],
  228. CL_PROGRAM_BUILD_LOG,
  229. length,
  230. buffer,
  231. NULL);
  232. if(resultCL != CL_SUCCESS)
  233. throw(string("InitCL()::Error: Getting Program build info(clGetProgramBuildInfo)"));
  234. cerr << buffer << endl;
  235. free(buffer);
  236. throw(string("InitCL()::Error: Building Program (clBuildProgram)"));
  237. }
  238. //get program information in intermediate representation
  239. #ifdef PTX_MSG
  240. size_t binary_sizes[deviceListSize];
  241. char * binaries[deviceListSize];
  242. //figure out number of devices and the sizes of the binary for each device.
  243. oclHandles.cl_status = clGetProgramInfo(oclHandles.program, CL_PROGRAM_BINARY_SIZES, sizeof(size_t)*deviceListSize, &binary_sizes, NULL );
  244. if(oclHandles.cl_status!=CL_SUCCESS){
  245. throw(string("--cambine:exception in _InitCL -> clGetProgramInfo-2"));
  246. }
  247. std::cout<<"--cambine:"<<binary_sizes<<std::endl;
  248. //copy over all of the generated binaries.
  249. for(int i=0;i<deviceListSize;i++)
  250. binaries[i] = (char *)malloc( sizeof(char)*(binary_sizes[i]+1));
  251. oclHandles.cl_status = clGetProgramInfo(oclHandles.program, CL_PROGRAM_BINARIES, sizeof(char *)*deviceListSize, binaries, NULL );
  252. if(oclHandles.cl_status!=CL_SUCCESS){
  253. throw(string("--cambine:exception in _InitCL -> clGetProgramInfo-3"));
  254. }
  255. for(int i=0;i<deviceListSize;i++)
  256. binaries[i][binary_sizes[i]] = '\0';
  257. std::cout<<"--cambine:writing ptd information..."<<std::endl;
  258. FILE * ptx_file = fopen("cl.ptx","w");
  259. if(ptx_file==NULL){
  260. throw(string("exceptions in allocate ptx file."));
  261. }
  262. fprintf(ptx_file,"%s",binaries[DEVICE_ID_INUSED]);
  263. fclose(ptx_file);
  264. std::cout<<"--cambine:writing ptd information done."<<std::endl;
  265. for(int i=0;i<deviceListSize;i++)
  266. free(binaries[i]);
  267. #endif
  268. for (int nKernel = 0; nKernel < total_kernels; nKernel++)
  269. {
  270. /* get a kernel object handle for a kernel with the given name */
  271. cl_kernel kernel = clCreateKernel(oclHandles.program,
  272. (kernel_names[nKernel]).c_str(),
  273. &resultCL);
  274. if ((resultCL != CL_SUCCESS) || (kernel == NULL))
  275. {
  276. string errorMsg = "InitCL()::Error: Creating Kernel (clCreateKernel) \"" + kernel_names[nKernel] + "\"";
  277. throw(errorMsg);
  278. }
  279. oclHandles.kernel.push_back(kernel);
  280. }
  281. //get resource alocation information
  282. #ifdef RES_MSG
  283. char * build_log;
  284. size_t ret_val_size;
  285. oclHandles.cl_status = clGetProgramBuildInfo(oclHandles.program, oclHandles.devices[DEVICE_ID_INUSED], CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
  286. if(oclHandles.cl_status!=CL_SUCCESS){
  287. throw(string("exceptions in _InitCL -> getting resource information"));
  288. }
  289. build_log = (char *)malloc(ret_val_size+1);
  290. oclHandles.cl_status = clGetProgramBuildInfo(oclHandles.program, oclHandles.devices[DEVICE_ID_INUSED], CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
  291. if(oclHandles.cl_status!=CL_SUCCESS){
  292. throw(string("exceptions in _InitCL -> getting resources allocation information-2"));
  293. }
  294. build_log[ret_val_size] = '\0';
  295. std::cout<<"--cambine:"<<build_log<<std::endl;
  296. free(build_log);
  297. #endif
  298. }
  299. //---------------------------------------
  300. //release CL objects
  301. void _clRelease()
  302. {
  303. char errorFlag = false;
  304. for (int nKernel = 0; nKernel < oclHandles.kernel.size(); nKernel++)
  305. {
  306. if (oclHandles.kernel[nKernel] != NULL)
  307. {
  308. cl_int resultCL = clReleaseKernel(oclHandles.kernel[nKernel]);
  309. if (resultCL != CL_SUCCESS)
  310. {
  311. cerr << "ReleaseCL()::Error: In clReleaseKernel" << endl;
  312. errorFlag = true;
  313. }
  314. oclHandles.kernel[nKernel] = NULL;
  315. }
  316. oclHandles.kernel.clear();
  317. }
  318. if (oclHandles.program != NULL)
  319. {
  320. cl_int resultCL = clReleaseProgram(oclHandles.program);
  321. if (resultCL != CL_SUCCESS)
  322. {
  323. cerr << "ReleaseCL()::Error: In clReleaseProgram" << endl;
  324. errorFlag = true;
  325. }
  326. oclHandles.program = NULL;
  327. }
  328. if (oclHandles.queue != NULL)
  329. {
  330. cl_int resultCL = clReleaseCommandQueue(oclHandles.queue);
  331. if (resultCL != CL_SUCCESS)
  332. {
  333. cerr << "ReleaseCL()::Error: In clReleaseCommandQueue" << endl;
  334. errorFlag = true;
  335. }
  336. oclHandles.queue = NULL;
  337. }
  338. free(oclHandles.devices);
  339. if (oclHandles.context != NULL)
  340. {
  341. cl_int resultCL = clReleaseContext(oclHandles.context);
  342. if (resultCL != CL_SUCCESS)
  343. {
  344. cerr << "ReleaseCL()::Error: In clReleaseContext" << endl;
  345. errorFlag = true;
  346. }
  347. oclHandles.context = NULL;
  348. }
  349. if (errorFlag) throw(string("ReleaseCL()::Error encountered."));
  350. }
  351. //--------------------------------------------------------
  352. //--cambine:create buffer and then copy data from host to device
  353. cl_mem _clCreateAndCpyMem(int size, void * h_mem_source) throw(string){
  354. cl_mem d_mem;
  355. d_mem = clCreateBuffer(oclHandles.context, CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR, \
  356. size, h_mem_source, &oclHandles.cl_status);
  357. #ifdef ERRMSG
  358. if(oclHandles.cl_status != CL_SUCCESS)
  359. throw(string("excpetion in _clCreateAndCpyMem()"));
  360. #endif
  361. return d_mem;
  362. }
  363. //-------------------------------------------------------
  364. //--cambine: create read only buffer for devices
  365. //--date: 17/01/2011
  366. cl_mem _clMallocRW(int size, void * h_mem_ptr) throw(string){
  367. cl_mem d_mem;
  368. d_mem = clCreateBuffer(oclHandles.context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, size, h_mem_ptr, &oclHandles.cl_status);
  369. #ifdef ERRMSG
  370. if(oclHandles.cl_status != CL_SUCCESS)
  371. throw(string("excpetion in _clMallocRW"));
  372. #endif
  373. return d_mem;
  374. }
  375. //-------------------------------------------------------
  376. //--cambine: create read and write buffer for devices
  377. //--date: 17/01/2011
  378. cl_mem _clMalloc(int size, void * h_mem_ptr) throw(string){
  379. cl_mem d_mem;
  380. d_mem = clCreateBuffer(oclHandles.context, CL_MEM_WRITE_ONLY | CL_MEM_COPY_HOST_PTR, size, h_mem_ptr, &oclHandles.cl_status);
  381. #ifdef ERRMSG
  382. if(oclHandles.cl_status != CL_SUCCESS)
  383. throw(string("excpetion in _clMalloc"));
  384. #endif
  385. return d_mem;
  386. }
  387. //-------------------------------------------------------
  388. //--cambine: transfer data from host to device
  389. //--date: 17/01/2011
  390. void _clMemcpyH2D(cl_mem d_mem, int size, const void *h_mem_ptr) throw(string){
  391. oclHandles.cl_status = clEnqueueWriteBuffer(oclHandles.queue, d_mem, CL_TRUE, 0, size, h_mem_ptr, 0, NULL, NULL);
  392. #ifdef ERRMSG
  393. if(oclHandles.cl_status != CL_SUCCESS)
  394. throw(string("excpetion in _clMemcpyH2D"));
  395. #endif
  396. }
  397. //--------------------------------------------------------
  398. //--cambine:create buffer and then copy data from host to device with pinned
  399. // memory
  400. cl_mem _clCreateAndCpyPinnedMem(int size, float* h_mem_source) throw(string){
  401. cl_mem d_mem, d_mem_pinned;
  402. float * h_mem_pinned = NULL;
  403. d_mem_pinned = clCreateBuffer(oclHandles.context, CL_MEM_READ_ONLY|CL_MEM_ALLOC_HOST_PTR, \
  404. size, NULL, &oclHandles.cl_status);
  405. #ifdef ERRMSG
  406. if(oclHandles.cl_status != CL_SUCCESS)
  407. throw(string("excpetion in _clCreateAndCpyMem()->d_mem_pinned"));
  408. #endif
  409. //------------
  410. d_mem = clCreateBuffer(oclHandles.context, CL_MEM_READ_ONLY, \
  411. size, NULL, &oclHandles.cl_status);
  412. #ifdef ERRMSG
  413. if(oclHandles.cl_status != CL_SUCCESS)
  414. throw(string("excpetion in _clCreateAndCpyMem() -> d_mem "));
  415. #endif
  416. //----------
  417. h_mem_pinned = (cl_float *)clEnqueueMapBuffer(oclHandles.queue, d_mem_pinned, CL_TRUE, \
  418. CL_MAP_WRITE, 0, size, 0, NULL, \
  419. NULL, &oclHandles.cl_status);
  420. #ifdef ERRMSG
  421. if(oclHandles.cl_status != CL_SUCCESS)
  422. throw(string("excpetion in _clCreateAndCpyMem() -> clEnqueueMapBuffer"));
  423. #endif
  424. int element_number = size/sizeof(float);
  425. #pragma omp parallel for
  426. for(int i=0;i<element_number;i++){
  427. h_mem_pinned[i] = h_mem_source[i];
  428. }
  429. //----------
  430. oclHandles.cl_status = clEnqueueWriteBuffer(oclHandles.queue, d_mem, \
  431. CL_TRUE, 0, size, h_mem_pinned, \
  432. 0, NULL, NULL);
  433. #ifdef ERRMSG
  434. if(oclHandles.cl_status != CL_SUCCESS)
  435. throw(string("excpetion in _clCreateAndCpyMem() -> clEnqueueWriteBuffer"));
  436. #endif
  437. return d_mem;
  438. }
  439. //--------------------------------------------------------
  440. //--cambine:create write only buffer on device
  441. cl_mem _clMallocWO(int size) throw(string){
  442. cl_mem d_mem;
  443. d_mem = clCreateBuffer(oclHandles.context, CL_MEM_WRITE_ONLY, size, 0, &oclHandles.cl_status);
  444. #ifdef ERRMSG
  445. if(oclHandles.cl_status != CL_SUCCESS)
  446. throw(string("excpetion in _clCreateMem()"));
  447. #endif
  448. return d_mem;
  449. }
  450. //--------------------------------------------------------
  451. //transfer data from device to host
  452. void _clMemcpyD2H(cl_mem d_mem, int size, void * h_mem) throw(string){
  453. oclHandles.cl_status = clEnqueueReadBuffer(oclHandles.queue, d_mem, CL_TRUE, 0, size, h_mem, 0,0,0);
  454. #ifdef ERRMSG
  455. oclHandles.error_str = "excpetion in _clCpyMemD2H -> ";
  456. switch(oclHandles.cl_status){
  457. case CL_INVALID_COMMAND_QUEUE:
  458. oclHandles.error_str += "CL_INVALID_COMMAND_QUEUE";
  459. break;
  460. case CL_INVALID_CONTEXT:
  461. oclHandles.error_str += "CL_INVALID_CONTEXT";
  462. break;
  463. case CL_INVALID_MEM_OBJECT:
  464. oclHandles.error_str += "CL_INVALID_MEM_OBJECT";
  465. break;
  466. case CL_INVALID_VALUE:
  467. oclHandles.error_str += "CL_INVALID_VALUE";
  468. break;
  469. case CL_INVALID_EVENT_WAIT_LIST:
  470. oclHandles.error_str += "CL_INVALID_EVENT_WAIT_LIST";
  471. break;
  472. case CL_MEM_OBJECT_ALLOCATION_FAILURE:
  473. oclHandles.error_str += "CL_MEM_OBJECT_ALLOCATION_FAILURE";
  474. break;
  475. case CL_OUT_OF_HOST_MEMORY:
  476. oclHandles.error_str += "CL_OUT_OF_HOST_MEMORY";
  477. break;
  478. default:
  479. oclHandles.error_str += "Unknown reason";
  480. break;
  481. }
  482. if(oclHandles.cl_status != CL_SUCCESS)
  483. throw(oclHandles.error_str);
  484. #endif
  485. }
  486. //--------------------------------------------------------
  487. //set kernel arguments
  488. void _clSetArgs(int kernel_id, int arg_idx, void * d_mem, int size = 0) throw(string){
  489. if(!size){
  490. oclHandles.cl_status = clSetKernelArg(oclHandles.kernel[kernel_id], arg_idx, sizeof(d_mem), &d_mem);
  491. #ifdef ERRMSG
  492. oclHandles.error_str = "excpetion in _clSetKernelArg() ";
  493. switch(oclHandles.cl_status){
  494. case CL_INVALID_KERNEL:
  495. oclHandles.error_str += "CL_INVALID_KERNEL";
  496. break;
  497. case CL_INVALID_ARG_INDEX:
  498. oclHandles.error_str += "CL_INVALID_ARG_INDEX";
  499. break;
  500. case CL_INVALID_ARG_VALUE:
  501. oclHandles.error_str += "CL_INVALID_ARG_VALUE";
  502. break;
  503. case CL_INVALID_MEM_OBJECT:
  504. oclHandles.error_str += "CL_INVALID_MEM_OBJECT";
  505. break;
  506. case CL_INVALID_SAMPLER:
  507. oclHandles.error_str += "CL_INVALID_SAMPLER";
  508. break;
  509. case CL_INVALID_ARG_SIZE:
  510. oclHandles.error_str += "CL_INVALID_ARG_SIZE";
  511. break;
  512. case CL_OUT_OF_RESOURCES:
  513. oclHandles.error_str += "CL_OUT_OF_RESOURCES";
  514. break;
  515. case CL_OUT_OF_HOST_MEMORY:
  516. oclHandles.error_str += "CL_OUT_OF_HOST_MEMORY";
  517. break;
  518. default:
  519. oclHandles.error_str += "Unknown reason";
  520. break;
  521. }
  522. if(oclHandles.cl_status != CL_SUCCESS)
  523. throw(oclHandles.error_str);
  524. #endif
  525. }
  526. else{
  527. oclHandles.cl_status = clSetKernelArg(oclHandles.kernel[kernel_id], arg_idx, size, d_mem);
  528. #ifdef ERRMSG
  529. oclHandles.error_str = "excpetion in _clSetKernelArg() ";
  530. switch(oclHandles.cl_status){
  531. case CL_INVALID_KERNEL:
  532. oclHandles.error_str += "CL_INVALID_KERNEL";
  533. break;
  534. case CL_INVALID_ARG_INDEX:
  535. oclHandles.error_str += "CL_INVALID_ARG_INDEX";
  536. break;
  537. case CL_INVALID_ARG_VALUE:
  538. oclHandles.error_str += "CL_INVALID_ARG_VALUE";
  539. break;
  540. case CL_INVALID_MEM_OBJECT:
  541. oclHandles.error_str += "CL_INVALID_MEM_OBJECT";
  542. break;
  543. case CL_INVALID_SAMPLER:
  544. oclHandles.error_str += "CL_INVALID_SAMPLER";
  545. break;
  546. case CL_INVALID_ARG_SIZE:
  547. oclHandles.error_str += "CL_INVALID_ARG_SIZE";
  548. break;
  549. case CL_OUT_OF_RESOURCES:
  550. oclHandles.error_str += "CL_OUT_OF_RESOURCES";
  551. break;
  552. case CL_OUT_OF_HOST_MEMORY:
  553. oclHandles.error_str += "CL_OUT_OF_HOST_MEMORY";
  554. break;
  555. default:
  556. oclHandles.error_str += "Unknown reason";
  557. break;
  558. }
  559. if(oclHandles.cl_status != CL_SUCCESS)
  560. throw(oclHandles.error_str);
  561. #endif
  562. }
  563. }
  564. void _clFinish() throw(string){
  565. oclHandles.cl_status = clFinish(oclHandles.queue);
  566. #ifdef ERRMSG
  567. oclHandles.error_str = "excpetion in _clFinish";
  568. switch(oclHandles.cl_status){
  569. case CL_INVALID_COMMAND_QUEUE:
  570. oclHandles.error_str += "CL_INVALID_COMMAND_QUEUE";
  571. break;
  572. case CL_OUT_OF_RESOURCES:
  573. oclHandles.error_str += "CL_OUT_OF_RESOURCES";
  574. break;
  575. case CL_OUT_OF_HOST_MEMORY:
  576. oclHandles.error_str += "CL_OUT_OF_HOST_MEMORY";
  577. break;
  578. default:
  579. oclHandles.error_str += "Unknown reasons";
  580. break;
  581. }
  582. if(oclHandles.cl_status!=CL_SUCCESS){
  583. throw(oclHandles.error_str);
  584. }
  585. #endif
  586. }
  587. //--------------------------------------------------------
  588. //--cambine:enqueue kernel
  589. void _clInvokeKernel(int kernel_id, int work_items, int work_group_size) throw(string){
  590. cl_uint work_dim = WORK_DIM;
  591. cl_event e[1];
  592. if(work_items%work_group_size != 0) //process situations that work_items cannot be divided by work_group_size
  593. work_items = work_items + (work_group_size-(work_items%work_group_size));
  594. size_t local_work_size[] = {work_group_size, 1};
  595. size_t global_work_size[] = {work_items, 1};
  596. oclHandles.cl_status = clEnqueueNDRangeKernel(oclHandles.queue, oclHandles.kernel[kernel_id], work_dim, 0, \
  597. global_work_size, local_work_size, 0 , 0, &(e[0]) );
  598. #ifdef ERRMSG
  599. oclHandles.error_str = "excpetion in _clInvokeKernel() -> ";
  600. switch(oclHandles.cl_status)
  601. {
  602. case CL_INVALID_PROGRAM_EXECUTABLE:
  603. oclHandles.error_str += "CL_INVALID_PROGRAM_EXECUTABLE";
  604. break;
  605. case CL_INVALID_COMMAND_QUEUE:
  606. oclHandles.error_str += "CL_INVALID_COMMAND_QUEUE";
  607. break;
  608. case CL_INVALID_KERNEL:
  609. oclHandles.error_str += "CL_INVALID_KERNEL";
  610. break;
  611. case CL_INVALID_CONTEXT:
  612. oclHandles.error_str += "CL_INVALID_CONTEXT";
  613. break;
  614. case CL_INVALID_KERNEL_ARGS:
  615. oclHandles.error_str += "CL_INVALID_KERNEL_ARGS";
  616. break;
  617. case CL_INVALID_WORK_DIMENSION:
  618. oclHandles.error_str += "CL_INVALID_WORK_DIMENSION";
  619. break;
  620. case CL_INVALID_GLOBAL_WORK_SIZE:
  621. oclHandles.error_str += "CL_INVALID_GLOBAL_WORK_SIZE";
  622. break;
  623. case CL_INVALID_WORK_GROUP_SIZE:
  624. oclHandles.error_str += "CL_INVALID_WORK_GROUP_SIZE";
  625. break;
  626. case CL_INVALID_WORK_ITEM_SIZE:
  627. oclHandles.error_str += "CL_INVALID_WORK_ITEM_SIZE";
  628. break;
  629. case CL_INVALID_GLOBAL_OFFSET:
  630. oclHandles.error_str += "CL_INVALID_GLOBAL_OFFSET";
  631. break;
  632. case CL_OUT_OF_RESOURCES:
  633. oclHandles.error_str += "CL_OUT_OF_RESOURCES";
  634. break;
  635. case CL_MEM_OBJECT_ALLOCATION_FAILURE:
  636. oclHandles.error_str += "CL_MEM_OBJECT_ALLOCATION_FAILURE";
  637. break;
  638. case CL_INVALID_EVENT_WAIT_LIST:
  639. oclHandles.error_str += "CL_INVALID_EVENT_WAIT_LIST";
  640. break;
  641. case CL_OUT_OF_HOST_MEMORY:
  642. oclHandles.error_str += "CL_OUT_OF_HOST_MEMORY";
  643. break;
  644. default:
  645. oclHandles.error_str += "Unkown reseason";
  646. break;
  647. }
  648. if(oclHandles.cl_status != CL_SUCCESS)
  649. throw(oclHandles.error_str);
  650. #endif
  651. //_clFinish();
  652. // oclHandles.cl_status = clWaitForEvents(1, &e[0]);
  653. // #ifdef ERRMSG
  654. // if (oclHandles.cl_status!= CL_SUCCESS)
  655. // throw(string("excpetion in _clEnqueueNDRange() -> clWaitForEvents"));
  656. // #endif
  657. }
  658. void _clInvokeKernel2D(int kernel_id, int range_x, int range_y, int group_x, int group_y) throw(string){
  659. cl_uint work_dim = WORK_DIM;
  660. size_t local_work_size[] = {group_x, group_y};
  661. size_t global_work_size[] = {range_x, range_y};
  662. cl_event e[1];
  663. /*if(work_items%work_group_size != 0) //process situations that work_items cannot be divided by work_group_size
  664. work_items = work_items + (work_group_size-(work_items%work_group_size));*/
  665. oclHandles.cl_status = clEnqueueNDRangeKernel(oclHandles.queue, oclHandles.kernel[kernel_id], work_dim, 0, \
  666. global_work_size, local_work_size, 0 , 0, &(e[0]) );
  667. #ifdef ERRMSG
  668. oclHandles.error_str = "excpetion in _clInvokeKernel() -> ";
  669. switch(oclHandles.cl_status)
  670. {
  671. case CL_INVALID_PROGRAM_EXECUTABLE:
  672. oclHandles.error_str += "CL_INVALID_PROGRAM_EXECUTABLE";
  673. break;
  674. case CL_INVALID_COMMAND_QUEUE:
  675. oclHandles.error_str += "CL_INVALID_COMMAND_QUEUE";
  676. break;
  677. case CL_INVALID_KERNEL:
  678. oclHandles.error_str += "CL_INVALID_KERNEL";
  679. break;
  680. case CL_INVALID_CONTEXT:
  681. oclHandles.error_str += "CL_INVALID_CONTEXT";
  682. break;
  683. case CL_INVALID_KERNEL_ARGS:
  684. oclHandles.error_str += "CL_INVALID_KERNEL_ARGS";
  685. break;
  686. case CL_INVALID_WORK_DIMENSION:
  687. oclHandles.error_str += "CL_INVALID_WORK_DIMENSION";
  688. break;
  689. case CL_INVALID_GLOBAL_WORK_SIZE:
  690. oclHandles.error_str += "CL_INVALID_GLOBAL_WORK_SIZE";
  691. break;
  692. case CL_INVALID_WORK_GROUP_SIZE:
  693. oclHandles.error_str += "CL_INVALID_WORK_GROUP_SIZE";
  694. break;
  695. case CL_INVALID_WORK_ITEM_SIZE:
  696. oclHandles.error_str += "CL_INVALID_WORK_ITEM_SIZE";
  697. break;
  698. case CL_INVALID_GLOBAL_OFFSET:
  699. oclHandles.error_str += "CL_INVALID_GLOBAL_OFFSET";
  700. break;
  701. case CL_OUT_OF_RESOURCES:
  702. oclHandles.error_str += "CL_OUT_OF_RESOURCES";
  703. break;
  704. case CL_MEM_OBJECT_ALLOCATION_FAILURE:
  705. oclHandles.error_str += "CL_MEM_OBJECT_ALLOCATION_FAILURE";
  706. break;
  707. case CL_INVALID_EVENT_WAIT_LIST:
  708. oclHandles.error_str += "CL_INVALID_EVENT_WAIT_LIST";
  709. break;
  710. case CL_OUT_OF_HOST_MEMORY:
  711. oclHandles.error_str += "CL_OUT_OF_HOST_MEMORY";
  712. break;
  713. default:
  714. oclHandles.error_str += "Unkown reseason";
  715. break;
  716. }
  717. if(oclHandles.cl_status != CL_SUCCESS)
  718. throw(oclHandles.error_str);
  719. #endif
  720. //_clFinish();
  721. /*oclHandles.cl_status = clWaitForEvents(1, &e[0]);
  722. #ifdef ERRMSG
  723. if (oclHandles.cl_status!= CL_SUCCESS)
  724. throw(string("excpetion in _clEnqueueNDRange() -> clWaitForEvents"));
  725. #endif*/
  726. }
  727. //--------------------------------------------------------
  728. //release OpenCL objects
  729. void _clFree(cl_mem ob) throw(string){
  730. if(ob!=NULL)
  731. oclHandles.cl_status = clReleaseMemObject(ob);
  732. #ifdef ERRMSG
  733. oclHandles.error_str = "excpetion in _clFree() ->";
  734. switch(oclHandles.cl_status)
  735. {
  736. case CL_INVALID_MEM_OBJECT:
  737. oclHandles.error_str += "CL_INVALID_MEM_OBJECT";
  738. break;
  739. case CL_OUT_OF_RESOURCES:
  740. oclHandles.error_str += "CL_OUT_OF_RESOURCES";
  741. break;
  742. case CL_OUT_OF_HOST_MEMORY:
  743. oclHandles.error_str += "CL_OUT_OF_HOST_MEMORY";
  744. break;
  745. default:
  746. oclHandles.error_str += "Unkown reseason";
  747. break;
  748. }
  749. if (oclHandles.cl_status!= CL_SUCCESS)
  750. throw(oclHandles.error_str);
  751. #endif
  752. }
  753. #endif //_CL_HELPER_