clutils.cpp 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339
  1. /****************************************************************************\
  2. * Copyright (c) 2011, Advanced Micro Devices, Inc. *
  3. * All rights reserved. *
  4. * *
  5. * Redistribution and use in source and binary forms, with or without *
  6. * modification, are permitted provided that the following conditions *
  7. * are met: *
  8. * *
  9. * Redistributions of source code must retain the above copyright notice, *
  10. * this list of conditions and the following disclaimer. *
  11. * *
  12. * Redistributions in binary form must reproduce the above copyright notice, *
  13. * this list of conditions and the following disclaimer in the documentation *
  14. * and/or other materials provided with the distribution. *
  15. * *
  16. * Neither the name of the copyright holder nor the names of its contributors *
  17. * may be used to endorse or promote products derived from this software *
  18. * without specific prior written permission. *
  19. * *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
  22. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR *
  23. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR *
  24. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
  25. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
  26. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
  27. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
  28. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
  29. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
  30. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
  31. * *
  32. * If you use the software (in whole or in part), you shall adhere to all *
  33. * applicable U.S., European, and other export laws, including but not *
  34. * limited to the U.S. Export Administration Regulations (“EAR”), (15 C.F.R. *
  35. * Sections 730 through 774), and E.U. Council Regulation (EC) No 1334/2000 *
  36. * of 22 June 2000. Further, pursuant to Section 740.6 of the EAR, you *
  37. * hereby certify that, except pursuant to a license granted by the United *
  38. * States Department of Commerce Bureau of Industry and Security or as *
  39. * otherwise permitted pursuant to a License Exception under the U.S. Export *
  40. * Administration Regulations ("EAR"), you will not (1) export, re-export or *
  41. * release to a national of a country in Country Groups D:1, E:1 or E:2 any *
  42. * restricted technology, software, or source code you receive hereunder, *
  43. * or (2) export to Country Groups D:1, E:1 or E:2 the direct product of such *
  44. * technology or software, if such foreign produced direct product is subject *
  45. * to national security controls as identified on the Commerce Control List *
  46. *(currently found in Supplement 1 to Part 774 of EAR). For the most current *
  47. * Country Group listings, or for additional information about the EAR or *
  48. * your obligations under those regulations, please refer to the U.S. Bureau *
  49. * of Industry and Security’s website at http://www.bis.doc.gov/. *
  50. \****************************************************************************/
  51. #include <stdlib.h>
  52. #include <stdio.h>
  53. #include <string.h>
  54. #include <math.h>
  55. #include <CL/cl.h>
  56. #include "clutils.h"
  57. #include "utils.h"
  58. // The following variables have file scope to simplify
  59. // the utility functions
  60. //! All discoverable OpenCL platforms
  61. static cl_platform_id* platforms = NULL;
  62. static cl_uint numPlatforms;
  63. //! All discoverable OpenCL devices (one pointer per platform)
  64. static cl_device_id** devices = NULL;
  65. static cl_uint* numDevices;
  66. //! The chosen OpenCL platform
  67. static cl_platform_id platform = NULL;
  68. //! The chosen OpenCL device
  69. static cl_device_id device = NULL;
  70. //! OpenCL context
  71. static cl_context context = NULL;
  72. //! OpenCL command queue
  73. static cl_command_queue commandQueue = NULL;
  74. static cl_command_queue commandQueueProf = NULL;
  75. static cl_command_queue commandQueueNoProf = NULL;
  76. //! Global status of events
  77. static bool eventsEnabled = false;
  78. //-------------------------------------------------------
  79. // Initialization and Cleanup
  80. //-------------------------------------------------------
  81. //! Initialize OpenCl environment on one device
  82. /*!
  83. Init function for one device. Looks for supported devices and creates a context
  84. \return returns a context initialized
  85. */
  86. cl_context cl_init(char devicePreference)
  87. {
  88. cl_int status;
  89. // Discover and populate the platforms
  90. status = clGetPlatformIDs(0, NULL, &numPlatforms);
  91. cl_errChk(status, "Getting platform IDs", true);
  92. if (numPlatforms > 0)
  93. {
  94. // Get all the platforms
  95. platforms = (cl_platform_id*)alloc(numPlatforms *
  96. sizeof(cl_platform_id));
  97. status = clGetPlatformIDs(numPlatforms, platforms, NULL);
  98. cl_errChk(status, "Getting platform IDs", true);
  99. }
  100. else
  101. {
  102. // If no platforms are available, we shouldn't continue
  103. printf("No OpenCL platforms found\n");
  104. exit(-1);
  105. }
  106. // Allocate space for the device lists and lengths
  107. numDevices = (cl_uint*)alloc(sizeof(cl_uint)*numPlatforms);
  108. devices = (cl_device_id**)alloc(sizeof(cl_device_id*)*numPlatforms);
  109. // If a device preference was supplied, we'll limit the search of devices
  110. // based on type
  111. cl_device_type deviceType = CL_DEVICE_TYPE_ALL;
  112. if(devicePreference == 'c') {
  113. deviceType = CL_DEVICE_TYPE_CPU;
  114. }
  115. if(devicePreference == 'g') {
  116. deviceType = CL_DEVICE_TYPE_GPU;
  117. }
  118. // Traverse the platforms array printing information and
  119. // populating devices
  120. for(unsigned int i = 0; i < numPlatforms ; i++)
  121. {
  122. // Print out some basic info about the platform
  123. char* platformName = NULL;
  124. char* platformVendor = NULL;
  125. platformName = cl_getPlatformName(platforms[i]);
  126. platformVendor = cl_getPlatformVendor(platforms[i]);
  127. status = clGetDeviceIDs(platforms[i], deviceType, 0, NULL, &numDevices[i]);
  128. cl_errChk(status, "Getting device IDs", false);
  129. if(status != CL_SUCCESS) {
  130. printf("This is a known NVIDIA bug (if platform == AMD then die)\n");
  131. printf("Setting number of devices to 0 and continuing\n");
  132. numDevices[i] = 0;
  133. }
  134. printf("Platform %d (%d devices):\n", i, numDevices[i]);
  135. printf("\tName: %s\n", platformName);
  136. printf("\tVendor: %s\n", platformVendor);
  137. free(platformName);
  138. free(platformVendor);
  139. // Populate OpenCL devices if any exist
  140. if(numDevices[i] != 0)
  141. {
  142. // Allocate an array of devices of size "numDevices"
  143. devices[i] = (cl_device_id*)alloc(sizeof(cl_device_id)*numDevices[i]);
  144. // Populate Arrray with devices
  145. status = clGetDeviceIDs(platforms[i], deviceType, numDevices[i],
  146. devices[i], NULL);
  147. cl_errChk(status, "Getting device IDs", true);
  148. }
  149. // Print some information about each device
  150. for( unsigned int j = 0; j < numDevices[i]; j++)
  151. {
  152. char* deviceName = NULL;
  153. char* deviceVendor = NULL;
  154. printf("\tDevice %d:\n", j);
  155. deviceName = cl_getDeviceName(devices[i][j]);
  156. deviceVendor = cl_getDeviceVendor(devices[i][j]);
  157. printf("\t\tName: %s\n", deviceName);
  158. printf("\t\tVendor: %s\n", deviceVendor);
  159. free(deviceName);
  160. free(deviceVendor);
  161. }
  162. }
  163. // Hard-code in the platform/device to use, or uncomment 'scanf'
  164. // to decide at runtime
  165. cl_uint chosen_platform, chosen_device;
  166. // UNCOMMENT the following two lines to manually select device each time
  167. //printf("Enter Platform and Device No (Seperated by Space) \n");
  168. //scanf("%d %d", &chosen_platform, &chosen_device);
  169. chosen_platform = 0;
  170. chosen_device = 0;
  171. printf("Using Platform %d, Device %d \n", chosen_platform, chosen_device);
  172. // Do a sanity check of platform/device selection
  173. if(chosen_platform >= numPlatforms ||
  174. chosen_device >= numDevices[chosen_platform]) {
  175. printf("Invalid platform/device combination\n");
  176. exit(-1);
  177. }
  178. // Set the selected platform and device
  179. platform = platforms[chosen_platform];
  180. device = devices[chosen_platform][chosen_device];
  181. // Create the context
  182. cl_context_properties cps[3] = {CL_CONTEXT_PLATFORM,
  183. (cl_context_properties)(platform), 0};
  184. context = clCreateContext(cps, 1, &device, NULL, NULL, &status);
  185. cl_errChk(status, "Creating context", true);
  186. // Create the command queue
  187. commandQueueProf = clCreateCommandQueue(context, device,
  188. CL_QUEUE_PROFILING_ENABLE, &status);
  189. cl_errChk(status, "creating command queue", true);
  190. commandQueueNoProf = clCreateCommandQueue(context, device, 0, &status);
  191. cl_errChk(status, "creating command queue", true);
  192. if(eventsEnabled) {
  193. printf("Profiling enabled\n");
  194. commandQueue = commandQueueProf;
  195. }
  196. else {
  197. printf("Profiling disabled\n");
  198. commandQueue = commandQueueNoProf;
  199. }
  200. return context;
  201. }
  202. cl_context cl_init_context(int platform, int dev,int quiet) {
  203. int printInfo=1;
  204. if (platform >= 0 && dev >= 0) printInfo = 0;
  205. cl_int status;
  206. // Used to iterate through the platforms and devices, respectively
  207. cl_uint numPlatforms;
  208. cl_uint numDevices;
  209. // These will hold the platform and device we select (can potentially be
  210. // multiple, but we're just doing one for now)
  211. // cl_platform_id platform = NULL;
  212. status = clGetPlatformIDs(0, NULL, &numPlatforms);
  213. if (printInfo) printf("Number of platforms detected:%d\n", numPlatforms);
  214. // Print some information about the available platforms
  215. cl_platform_id *platforms = NULL;
  216. cl_device_id * devices = NULL;
  217. if (numPlatforms > 0)
  218. {
  219. // get all the platforms
  220. platforms = (cl_platform_id*)malloc(numPlatforms *
  221. sizeof(cl_platform_id));
  222. status = clGetPlatformIDs(numPlatforms, platforms, NULL);
  223. // Traverse the platforms array
  224. if (printInfo) printf("Checking For OpenCl Compatible Devices\n");
  225. for(unsigned int i = 0; i < numPlatforms ; i++)
  226. {
  227. char pbuf[100];
  228. if (printInfo) printf("Platform %d:\t", i);
  229. status = clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR,
  230. sizeof(pbuf), pbuf, NULL);
  231. if (printInfo) printf("Vendor: %s\n", pbuf);
  232. //unsigned int numDevices;
  233. status = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, 0, NULL, &numDevices);
  234. if(cl_errChk(status, "checking for devices",true))
  235. exit(1);
  236. if(numDevices == 0) {
  237. printf("There are no devices for Platform %d\n",i);
  238. exit(0);
  239. }
  240. else
  241. {
  242. if (printInfo) printf("\tNo of devices for Platform %d is %u\n",i, numDevices);
  243. //! Allocate an array of devices of size "numDevices"
  244. devices = (cl_device_id*)malloc(sizeof(cl_device_id)*numDevices);
  245. //! Populate Arrray with devices
  246. status = clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, numDevices,
  247. devices, NULL);
  248. if(cl_errChk(status, "getting device IDs",true)) {
  249. exit(1);
  250. }
  251. }
  252. for( unsigned int j = 0; j < numDevices; j++)
  253. {
  254. char dbuf[100];
  255. char deviceStr[100];
  256. if (printInfo) printf("\tDevice: %d\t", j);
  257. status = clGetDeviceInfo(devices[j], CL_DEVICE_VENDOR, sizeof(dbuf),
  258. deviceStr, NULL);
  259. cl_errChk(status, "Getting Device Info\n",true);
  260. if (printInfo) printf("Vendor: %s", deviceStr);
  261. status = clGetDeviceInfo(devices[j], CL_DEVICE_NAME, sizeof(dbuf),
  262. dbuf, NULL);
  263. if (printInfo) printf("\n\t\tName: %s\n", dbuf);
  264. }
  265. }
  266. }
  267. else
  268. {
  269. // If no platforms are available, we're sunk!
  270. printf("No OpenCL platforms found\n");
  271. exit(0);
  272. }
  273. int platform_touse;
  274. unsigned int device_touse;
  275. if (printInfo) printf("Enter Platform and Device No (Seperated by Space) \n");
  276. if (printInfo) scanf("%d %d", &platform_touse, &device_touse);
  277. else {
  278. platform_touse = platform;
  279. device_touse = dev;
  280. }
  281. if (!quiet) printf("Using Platform %d \t Device No %d \n",platform_touse, device_touse);
  282. //! Recheck how many devices does our chosen platform have
  283. status = clGetDeviceIDs(platforms[platform_touse], CL_DEVICE_TYPE_ALL, 0, NULL, &numDevices);
  284. if(device_touse > numDevices)
  285. {
  286. printf("Invalid Device Number\n");
  287. exit(1);
  288. }
  289. //! Populate devices array with all the visible devices of our chosen platform
  290. devices = (cl_device_id *)malloc(sizeof(cl_device_id)*numDevices);
  291. status = clGetDeviceIDs(platforms[platform_touse],
  292. CL_DEVICE_TYPE_ALL, numDevices,
  293. devices, NULL);
  294. if(cl_errChk(status,"Error in Getting Devices\n",true)) exit(1);
  295. //!Check if Device requested is a CPU or a GPU
  296. cl_device_type dtype;
  297. device = devices[device_touse];
  298. status = clGetDeviceInfo(devices[device_touse],
  299. CL_DEVICE_TYPE,
  300. sizeof(dtype),
  301. (void *)&dtype,
  302. NULL);
  303. if(cl_errChk(status,"Error in Getting Device Info\n",true)) exit(1);
  304. if(dtype == CL_DEVICE_TYPE_GPU) {
  305. if (!quiet) printf("Creating GPU Context\n\n");
  306. }
  307. else if (dtype == CL_DEVICE_TYPE_CPU) {
  308. if (!quiet) printf("Creating CPU Context\n\n");
  309. }
  310. else perror("This Context Type Not Supported\n");
  311. cl_context_properties cps[3] = {CL_CONTEXT_PLATFORM,
  312. (cl_context_properties)(platforms[platform_touse]), 0};
  313. cl_context_properties *cprops = cps;
  314. context = clCreateContextFromType(
  315. cprops, (cl_device_type)dtype,
  316. NULL, NULL, &status);
  317. if(cl_errChk(status, "creating Context",true)) {
  318. exit(1);
  319. }
  320. #define PROFILING
  321. #ifdef PROFILING
  322. commandQueue = clCreateCommandQueue(context,
  323. devices[device_touse], CL_QUEUE_PROFILING_ENABLE, &status);
  324. #else
  325. clCommandQueue = clCreateCommandQueue(clGPUContext,
  326. devices[device_touse], NULL, &status);
  327. #endif // PROFILING
  328. if(cl_errChk(status, "creating command queue",true)) {
  329. exit(1);
  330. }
  331. return context;
  332. }
  333. /*!
  334. Release all resources that the user doesn't have access to.
  335. */
  336. void cl_cleanup()
  337. {
  338. // Free the command queue
  339. if(commandQueue) {
  340. clReleaseCommandQueue(commandQueue);
  341. }
  342. // Free the context
  343. if(context) {
  344. clReleaseContext(context);
  345. }
  346. free(devices);
  347. free(numDevices);
  348. // Free the platforms
  349. free(platforms);
  350. }
  351. //! Release a kernel object
  352. /*!
  353. \param mem The kernel object to release
  354. */
  355. void cl_freeKernel(cl_kernel kernel)
  356. {
  357. cl_int status;
  358. if(kernel != NULL) {
  359. status = clReleaseKernel(kernel);
  360. cl_errChk(status, "Releasing kernel object", true);
  361. }
  362. }
  363. //! Release memory allocated on the device
  364. /*!
  365. \param mem The device pointer to release
  366. */
  367. void cl_freeMem(cl_mem mem)
  368. {
  369. cl_int status;
  370. if(mem != NULL) {
  371. status = clReleaseMemObject(mem);
  372. cl_errChk(status, "Releasing mem object", true);
  373. }
  374. }
  375. //! Release a program object
  376. /*!
  377. \param mem The program object to release
  378. */
  379. void cl_freeProgram(cl_program program)
  380. {
  381. cl_int status;
  382. if(program != NULL) {
  383. status = clReleaseProgram(program);
  384. cl_errChk(status, "Releasing program object", true);
  385. }
  386. }
  387. //! Returns a reference to the command queue
  388. /*!
  389. Returns a reference to the command queue \n
  390. Used for any OpenCl call that needs the command queue declared in clutils.cpp
  391. */
  392. cl_command_queue cl_getCommandQueue()
  393. {
  394. return commandQueue;
  395. }
  396. //-------------------------------------------------------
  397. // Synchronization functions
  398. //-------------------------------------------------------
  399. /*!
  400. Wait till all pending commands in queue are finished
  401. */
  402. void cl_sync()
  403. {
  404. clFinish(commandQueue);
  405. }
  406. //-------------------------------------------------------
  407. // Memory allocation
  408. //-------------------------------------------------------
  409. //! Allocate a buffer on a device
  410. /*!
  411. \param mem_size Size of memory in bytes
  412. \param flags Optional cl_mem_flags
  413. \return Returns a cl_mem object that points to device memory
  414. */
  415. cl_mem cl_allocBuffer(size_t mem_size, cl_mem_flags flags)
  416. {
  417. cl_mem mem;
  418. cl_int status;
  419. /*!
  420. Logging information for keeping track of device memory
  421. */
  422. static int allocationCount = 1;
  423. static size_t allocationSize = 0;
  424. allocationCount++;
  425. allocationSize += mem_size;
  426. mem = clCreateBuffer(context, flags, mem_size, NULL, &status);
  427. cl_errChk(status, "creating buffer", true);
  428. return mem;
  429. }
  430. //! Allocate constant memory on device
  431. /*!
  432. \param mem_size Size of memory in bytes
  433. \param host_ptr Host pointer that contains the data
  434. \return Returns a cl_mem object that points to device memory
  435. */
  436. cl_mem cl_allocBufferConst(size_t mem_size, void* host_ptr)
  437. {
  438. cl_mem mem;
  439. cl_int status;
  440. mem = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,
  441. mem_size, host_ptr, &status);
  442. cl_errChk(status, "Error creating const mem buffer", true);
  443. return mem;
  444. }
  445. //! Allocate a buffer on device pinning the host memory at host_ptr
  446. /*!
  447. \param mem_size Size of memory in bytes
  448. \return Returns a cl_mem object that points to pinned memory on the host
  449. */
  450. cl_mem cl_allocBufferPinned(size_t mem_size)
  451. {
  452. cl_mem mem;
  453. cl_int status;
  454. mem = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR,
  455. mem_size, NULL, &status);
  456. cl_errChk(status, "Error allocating pinned memory", true);
  457. return mem;
  458. }
  459. //! Allocate an image on a device
  460. /*!
  461. \param height Number of rows in the image
  462. \param width Number of columns in the image
  463. \param elemSize Size of the elements in the image
  464. \param flags Optional cl_mem_flags
  465. \return Returns a cl_mem object that points to device memory
  466. */
  467. cl_mem cl_allocImage(size_t height, size_t width, char type, cl_mem_flags flags)
  468. {
  469. cl_mem mem;
  470. cl_int status;
  471. size_t elemSize = 0;
  472. cl_image_format format;
  473. format.image_channel_order = CL_R;
  474. switch(type) {
  475. case 'f':
  476. elemSize = sizeof(float);
  477. format.image_channel_data_type = CL_FLOAT;
  478. break;
  479. case 'i':
  480. elemSize = sizeof(int);
  481. format.image_channel_data_type = CL_SIGNED_INT32;
  482. break;
  483. default:
  484. printf("Error creating image: Unsupported image type.\n");
  485. exit(-1);
  486. }
  487. /*!
  488. Logging information for keeping track of device memory
  489. */
  490. static int allocationCount = 1;
  491. static size_t allocationSize = 0;
  492. allocationCount++;
  493. allocationSize += height*width*elemSize;
  494. // Create the image
  495. mem = clCreateImage2D(context, flags, &format, width, height, 0, NULL, &status);
  496. //cl_errChk(status, "creating image", true);
  497. if(status != CL_SUCCESS) {
  498. printf("Error creating image: Images may not be supported for this device.\n");
  499. printSupportedImageFormats();
  500. getchar();
  501. exit(-1);
  502. }
  503. return mem;
  504. }
  505. //-------------------------------------------------------
  506. // Data transfers
  507. //-------------------------------------------------------
  508. // Copy and map a buffer
  509. void* cl_copyAndMapBuffer(cl_mem dst, cl_mem src, size_t size) {
  510. void* ptr; // Pointer to the pinned memory that will be returned
  511. cl_copyBufferToBuffer(dst, src, size);
  512. ptr = cl_mapBuffer(dst, size, CL_MAP_READ);
  513. return ptr;
  514. }
  515. // Copy a buffer
  516. void cl_copyBufferToBuffer(cl_mem dst, cl_mem src, size_t size)
  517. {
  518. cl_int status;
  519. status = clEnqueueCopyBuffer(commandQueue, src, dst, 0, 0, size, 0, NULL,
  520. NULL);
  521. cl_errChk(status, "Copying buffer", true);
  522. }
  523. //! Copy a buffer to the device
  524. /*!
  525. \param dst Valid device pointer
  526. \param src Host pointer that contains the data
  527. \param mem_size Size of data to copy
  528. \param blocking Blocking or non-blocking operation
  529. */
  530. void cl_copyBufferToDevice(cl_mem dst, void* src, size_t mem_size, cl_bool blocking)
  531. {
  532. cl_int status;
  533. status = clEnqueueWriteBuffer(commandQueue, dst, blocking, 0,
  534. mem_size, src, 0, NULL, NULL);
  535. cl_errChk(status, "Writing buffer", true);
  536. }
  537. //! Copy a buffer to the host
  538. /*!
  539. \param dst Valid host pointer
  540. \param src Device pointer that contains the data
  541. \param mem_size Size of data to copy
  542. \param blocking Blocking or non-blocking operation
  543. */
  544. void cl_copyBufferToHost(void* dst, cl_mem src, size_t mem_size, cl_bool blocking)
  545. {
  546. cl_int status;
  547. status = clEnqueueReadBuffer(commandQueue, src, blocking, 0,
  548. mem_size, dst, 0, NULL, NULL);
  549. cl_errChk(status, "Reading buffer", true);
  550. }
  551. //! Copy a buffer to a 2D image
  552. /*!
  553. \param src Valid device buffer
  554. \param dst Empty device image
  555. \param mem_size Size of data to copy
  556. */
  557. void cl_copyBufferToImage(cl_mem buffer, cl_mem image, int height, int width)
  558. {
  559. size_t origin[3] = {0, 0, 0};
  560. size_t region[3] = {width, height, 1};
  561. cl_int status;
  562. status = clEnqueueCopyBufferToImage(commandQueue, buffer, image, 0,
  563. origin, region, 0, NULL, NULL);
  564. cl_errChk(status, "Copying buffer to image", true);
  565. }
  566. // Copy data to an image on the device
  567. /*!
  568. \param dst Valid device pointer
  569. \param src Host pointer that contains the data
  570. \param height Height of the image
  571. \param width Width of the image
  572. */
  573. void cl_copyImageToDevice(cl_mem dst, void* src, size_t height, size_t width)
  574. {
  575. cl_int status;
  576. size_t origin[3] = {0, 0, 0};
  577. size_t region[3] = {width, height, 1};
  578. status = clEnqueueWriteImage(commandQueue, dst, CL_TRUE, origin,
  579. region, 0, 0, src, 0, NULL, NULL);
  580. cl_errChk(status, "Writing image", true);
  581. }
  582. //! Copy an image to the host
  583. /*!
  584. \param dst Valid host pointer
  585. \param src Device pointer that contains the data
  586. \param height Height of the image
  587. \param width Width of the image
  588. */
  589. void cl_copyImageToHost(void* dst, cl_mem src, size_t height, size_t width)
  590. {
  591. cl_int status;
  592. size_t origin[3] = {0, 0, 0};
  593. size_t region[3] = {width, height, 1};
  594. status = clEnqueueReadImage(commandQueue, src, CL_TRUE, origin,
  595. region, 0, 0, dst, 0, NULL, NULL);
  596. cl_errChk(status, "Reading image", true);
  597. }
  598. //! Map a buffer into a host address
  599. /*!
  600. \param mem cl_mem object
  601. \param mem_size Size of memory in bytes
  602. \param flags Optional cl_mem_flags
  603. \return Returns a host pointer that points to the mapped region
  604. */
  605. void *cl_mapBuffer(cl_mem mem, size_t mem_size, cl_mem_flags flags)
  606. {
  607. cl_int status;
  608. void *ptr;
  609. ptr = (void *)clEnqueueMapBuffer(commandQueue, mem, CL_TRUE, flags,
  610. 0, mem_size, 0, NULL, NULL, &status);
  611. cl_errChk(status, "Error mapping a buffer", true);
  612. return ptr;
  613. }
  614. //! Unmap a buffer or image
  615. /*!
  616. \param mem cl_mem object
  617. \param ptr A host pointer that points to the mapped region
  618. */
  619. void cl_unmapBuffer(cl_mem mem, void *ptr)
  620. {
  621. // TODO It looks like AMD doesn't support profiling unmapping yet. Leaving the
  622. // commented code here until it's supported
  623. cl_int status;
  624. status = clEnqueueUnmapMemObject(commandQueue, mem, ptr, 0, NULL, NULL);
  625. cl_errChk(status, "Error unmapping a buffer or image", true);
  626. }
  627. void cl_writeToZCBuffer(cl_mem mem, void* data, size_t size)
  628. {
  629. void* ptr;
  630. ptr = cl_mapBuffer(mem, size, CL_MAP_WRITE);
  631. memcpy(ptr, data, size);
  632. cl_unmapBuffer(mem, ptr);
  633. }
  634. //-------------------------------------------------------
  635. // Program and kernels
  636. //-------------------------------------------------------
  637. //! Convert source code file into cl_program
  638. /*!
  639. Compile Opencl source file into a cl_program. The cl_program will be made into a kernel in PrecompileKernels()
  640. \param kernelPath Filename of OpenCl code
  641. \param compileoptions Compilation options
  642. \param verbosebuild Switch to enable verbose Output
  643. */
  644. cl_program cl_compileProgram(char* kernelPath, char* compileoptions, bool verbosebuild )
  645. {
  646. cl_int status;
  647. FILE *fp = NULL;
  648. char *source = NULL;
  649. long int size;
  650. printf("\t%s\n", kernelPath);
  651. // Determine the size of the source file
  652. #ifdef _WIN32
  653. fopen_s(&fp, kernelPath, "rb");
  654. #else
  655. fp = fopen(kernelPath, "rb");
  656. #endif
  657. if(!fp) {
  658. printf("Could not open kernel file\n");
  659. exit(-1);
  660. }
  661. status = fseek(fp, 0, SEEK_END);
  662. if(status != 0) {
  663. printf("Error seeking to end of file\n");
  664. exit(-1);
  665. }
  666. size = ftell(fp);
  667. if(size < 0) {
  668. printf("Error getting file position\n");
  669. exit(-1);
  670. }
  671. rewind(fp);
  672. // Allocate enough space for the source code
  673. source = (char *)alloc(size + 1);
  674. // fill with NULLs (just for fun)
  675. for (int i = 0; i < size+1; i++) {
  676. source[i] = '\0';
  677. }
  678. // Read in the source code
  679. fread(source, 1, size, fp);
  680. source[size] = '\0';
  681. // Create the program object
  682. cl_program clProgramReturn = clCreateProgramWithSource(context, 1,
  683. (const char **)&source, NULL, &status);
  684. cl_errChk(status, "Creating program", true);
  685. free(source);
  686. fclose(fp);
  687. // Try to compile the program
  688. status = clBuildProgram(clProgramReturn, 0, NULL, compileoptions, NULL, NULL);
  689. if(cl_errChk(status, "Building program", false) || verbosebuild == 1)
  690. {
  691. cl_build_status build_status;
  692. clGetProgramBuildInfo(clProgramReturn, device, CL_PROGRAM_BUILD_STATUS,
  693. sizeof(cl_build_status), &build_status, NULL);
  694. if(build_status == CL_SUCCESS && verbosebuild == 0) {
  695. return clProgramReturn;
  696. }
  697. //char *build_log;
  698. size_t ret_val_size;
  699. printf("Device: %p",device);
  700. clGetProgramBuildInfo(clProgramReturn, device, CL_PROGRAM_BUILD_LOG, 0,
  701. NULL, &ret_val_size);
  702. char *build_log = (char*)alloc(ret_val_size+1);
  703. clGetProgramBuildInfo(clProgramReturn, device, CL_PROGRAM_BUILD_LOG,
  704. ret_val_size+1, build_log, NULL);
  705. // to be careful, terminate with \0
  706. // there's no information in the reference whether the string is 0
  707. // terminated or not
  708. build_log[ret_val_size] = '\0';
  709. printf("Build log:\n %s...\n", build_log);
  710. if(build_status != CL_SUCCESS) {
  711. getchar();
  712. exit(-1);
  713. }
  714. else
  715. return clProgramReturn;
  716. }
  717. // print the ptx information
  718. // printBinaries(clProgram);
  719. return clProgramReturn;
  720. }
  721. //! Create a kernel from compiled source
  722. /*!
  723. Create a kernel from compiled source
  724. \param program Compiled OpenCL program
  725. \param kernel_name Name of the kernel in the program
  726. \return Returns a cl_kernel object for the specified kernel
  727. */
  728. cl_kernel cl_createKernel(cl_program program, const char* kernel_name) {
  729. cl_kernel kernel;
  730. cl_int status;
  731. kernel = clCreateKernel(program, kernel_name, &status);
  732. cl_errChk(status, "Creating kernel", true);
  733. return kernel;
  734. }
  735. //! Set an argument for a OpenCL kernel
  736. /*!
  737. Set an argument for a OpenCL kernel
  738. \param kernel The kernel for which the argument is being set
  739. \param index The argument index
  740. \param size The size of the argument
  741. \param data A pointer to the argument
  742. */
  743. void cl_setKernelArg(cl_kernel kernel, unsigned int index, size_t size,
  744. void* data)
  745. {
  746. cl_int status;
  747. status = clSetKernelArg(kernel, index, size, data);
  748. cl_errChk(status, "Setting kernel arg", true);
  749. }
  750. //-------------------------------------------------------
  751. // Profiling/events
  752. //-------------------------------------------------------
  753. //! Time kernel execution using cl_event
  754. /*!
  755. Prints out the time taken between the start and end of an event
  756. \param event_time
  757. */
  758. double cl_computeExecTime(cl_event event_time)
  759. {
  760. cl_int status;
  761. cl_ulong starttime;
  762. cl_ulong endtime;
  763. double elapsed;
  764. status = clGetEventProfilingInfo(event_time, CL_PROFILING_COMMAND_START,
  765. sizeof(cl_ulong), &starttime, NULL);
  766. cl_errChk(status, "profiling start", true);
  767. status = clGetEventProfilingInfo(event_time, CL_PROFILING_COMMAND_END,
  768. sizeof(cl_ulong), &endtime, NULL);
  769. cl_errChk(status, "profiling end", true);
  770. // Convert to ms
  771. elapsed = (double)(endtime-starttime)/1000000.0;
  772. return elapsed;
  773. }
  774. //! Compute the elapsed time between two timer values
  775. double cl_computeTime(cl_time start, cl_time end)
  776. {
  777. #ifdef _WIN32
  778. __int64 freq;
  779. int status;
  780. status = QueryPerformanceFrequency((LARGE_INTEGER*)&freq);
  781. if(status == 0) {
  782. perror("QueryPerformanceFrequency");
  783. exit(-1);
  784. }
  785. // Return time in ms
  786. return double(end-start)/(double(freq)/1000.0);
  787. #else
  788. return end-start;
  789. #endif
  790. }
  791. //! Grab the current time using a system-specific timer
  792. void cl_getTime(cl_time* time)
  793. {
  794. #ifdef _WIN32
  795. int status = QueryPerformanceCounter((LARGE_INTEGER*)time);
  796. if(status == 0) {
  797. perror("QueryPerformanceCounter");
  798. exit(-1);
  799. }
  800. #else
  801. // Use gettimeofday to get the current time
  802. struct timeval curTime;
  803. gettimeofday(&curTime, NULL);
  804. // Convert timeval into double
  805. *time = curTime.tv_sec * 1000 + (double)curTime.tv_usec/1000;
  806. #endif
  807. }
  808. //-------------------------------------------------------
  809. // Error handling
  810. //-------------------------------------------------------
  811. //! OpenCl error code list
  812. /*!
  813. An array of character strings used to give the error corresponding to the error code \n
  814. The error code is the index within this array
  815. */
  816. char *cl_errs[MAX_ERR_VAL] = {
  817. (char *)"CL_SUCCESS", // 0
  818. (char *)"CL_DEVICE_NOT_FOUND", //-1
  819. (char *)"CL_DEVICE_NOT_AVAILABLE", //-2
  820. (char *)"CL_COMPILER_NOT_AVAILABLE", //-3
  821. (char *)"CL_MEM_OBJECT_ALLOCATION_FAILURE", //-4
  822. (char *)"CL_OUT_OF_RESOURCES", //-5
  823. (char *)"CL_OUT_OF_HOST_MEMORY", //-6
  824. (char *)"CL_PROFILING_INFO_NOT_AVAILABLE", //-7
  825. (char *)"CL_MEM_COPY_OVERLAP", //-8
  826. (char *)"CL_IMAGE_FORMAT_MISMATCH", //-9
  827. (char *)"CL_IMAGE_FORMAT_NOT_SUPPORTED", //-10
  828. (char *)"CL_BUILD_PROGRAM_FAILURE", //-11
  829. (char *)"CL_MAP_FAILURE", //-12
  830. (char *)"", //-13
  831. (char *)"", //-14
  832. (char *)"", //-15
  833. (char *)"", //-16
  834. (char *)"", //-17
  835. (char *)"", //-18
  836. (char *)"", //-19
  837. (char *)"", //-20
  838. (char *)"", //-21
  839. (char *)"", //-22
  840. (char *)"", //-23
  841. (char *)"", //-24
  842. (char *)"", //-25
  843. (char *)"", //-26
  844. (char *)"", //-27
  845. (char *)"", //-28
  846. (char *)"", //-29
  847. (char *)"CL_INVALID_VALUE", //-30
  848. (char *)"CL_INVALID_DEVICE_TYPE", //-31
  849. (char *)"CL_INVALID_PLATFORM", //-32
  850. (char *)"CL_INVALID_DEVICE", //-33
  851. (char *)"CL_INVALID_CONTEXT", //-34
  852. (char *)"CL_INVALID_QUEUE_PROPERTIES", //-35
  853. (char *)"CL_INVALID_COMMAND_QUEUE", //-36
  854. (char *)"CL_INVALID_HOST_PTR", //-37
  855. (char *)"CL_INVALID_MEM_OBJECT", //-38
  856. (char *)"CL_INVALID_IMAGE_FORMAT_DESCRIPTOR", //-39
  857. (char *)"CL_INVALID_IMAGE_SIZE", //-40
  858. (char *)"CL_INVALID_SAMPLER", //-41
  859. (char *)"CL_INVALID_BINARY", //-42
  860. (char *)"CL_INVALID_BUILD_OPTIONS", //-43
  861. (char *)"CL_INVALID_PROGRAM", //-44
  862. (char *)"CL_INVALID_PROGRAM_EXECUTABLE", //-45
  863. (char *)"CL_INVALID_KERNEL_NAME", //-46
  864. (char *)"CL_INVALID_KERNEL_DEFINITION", //-47
  865. (char *)"CL_INVALID_KERNEL", //-48
  866. (char *)"CL_INVALID_ARG_INDEX", //-49
  867. (char *)"CL_INVALID_ARG_VALUE", //-50
  868. (char *)"CL_INVALID_ARG_SIZE", //-51
  869. (char *)"CL_INVALID_KERNEL_ARGS", //-52
  870. (char *)"CL_INVALID_WORK_DIMENSION ", //-53
  871. (char *)"CL_INVALID_WORK_GROUP_SIZE", //-54
  872. (char *)"CL_INVALID_WORK_ITEM_SIZE", //-55
  873. (char *)"CL_INVALID_GLOBAL_OFFSET", //-56
  874. (char *)"CL_INVALID_EVENT_WAIT_LIST", //-57
  875. (char *)"CL_INVALID_EVENT", //-58
  876. (char *)"CL_INVALID_OPERATION", //-59
  877. (char *)"CL_INVALID_GL_OBJECT", //-60
  878. (char *)"CL_INVALID_BUFFER_SIZE", //-61
  879. (char *)"CL_INVALID_MIP_LEVEL", //-62
  880. (char *)"CL_INVALID_GLOBAL_WORK_SIZE"}; //-63
  881. //! OpenCl Error checker
  882. /*!
  883. Checks for error code as per cl_int returned by OpenCl
  884. \param status Error value as cl_int
  885. \param msg User provided error message
  886. \return True if Error Seen, False if no error
  887. */
  888. int cl_errChk(const cl_int status, const char * msg, bool exitOnErr)
  889. {
  890. if(status != CL_SUCCESS) {
  891. printf("OpenCL Error: %d %s %s\n", status, cl_errs[-status], msg);
  892. if(exitOnErr) {
  893. exit(-1);
  894. }
  895. return true;
  896. }
  897. return false;
  898. }
  899. // Queries the supported image formats for the device and prints
  900. // them to the screen
  901. void printSupportedImageFormats()
  902. {
  903. cl_uint numFormats;
  904. cl_int status;
  905. status = clGetSupportedImageFormats(context, 0, CL_MEM_OBJECT_IMAGE2D,
  906. 0, NULL, &numFormats);
  907. cl_errChk(status, "getting supported image formats", true);
  908. cl_image_format* imageFormats = NULL;
  909. imageFormats = (cl_image_format*)alloc(sizeof(cl_image_format)*numFormats);
  910. status = clGetSupportedImageFormats(context, 0, CL_MEM_OBJECT_IMAGE2D,
  911. numFormats, imageFormats, NULL);
  912. printf("There are %d supported image formats\n", numFormats);
  913. cl_uint orders[]={CL_R, CL_A, CL_INTENSITY, CL_LUMINANCE, CL_RG,
  914. CL_RA, CL_RGB, CL_RGBA, CL_ARGB, CL_BGRA};
  915. char *orderstr[]={(char *)"CL_R", (char *)"CL_A",(char *)"CL_INTENSITY", (char *)"CL_LUMINANCE", (char *)"CL_RG",
  916. (char *)"CL_RA", (char *)"CL_RGB", (char *)"CL_RGBA", (char *)"CL_ARGB", (char *)"CL_BGRA"};
  917. cl_uint types[]={
  918. CL_SNORM_INT8 , CL_SNORM_INT16, CL_UNORM_INT8, CL_UNORM_INT16,
  919. CL_UNORM_SHORT_565, CL_UNORM_SHORT_555, CL_UNORM_INT_101010,CL_SIGNED_INT8,
  920. CL_SIGNED_INT16, CL_SIGNED_INT32, CL_UNSIGNED_INT8, CL_UNSIGNED_INT16,
  921. CL_UNSIGNED_INT32, CL_HALF_FLOAT, CL_FLOAT};
  922. char * typesstr[]={
  923. (char *)"CL_SNORM_INT8" ,(char *)"CL_SNORM_INT16",(char *)"CL_UNORM_INT8",(char *)"CL_UNORM_INT16",
  924. (char *)"CL_UNORM_SHORT_565",(char *)"CL_UNORM_SHORT_555",(char *)"CL_UNORM_INT_101010",
  925. (char *)"CL_SIGNED_INT8",(char *)"CL_SIGNED_INT16",(char *)"CL_SIGNED_INT32",(char *)"CL_UNSIGNED_INT8",
  926. (char *)"CL_UNSIGNED_INT16",(char *)"CL_UNSIGNED_INT32",(char *)"CL_HALF_FLOAT",(char *)"CL_FLOAT"};
  927. printf("Supported Formats:\n");
  928. for(int i = 0; i < (int)numFormats; i++) {
  929. printf("\tFormat %d: ", i);
  930. for(int j = 0; j < (int)(sizeof(orders)/sizeof(cl_int)); j++) {
  931. if(imageFormats[i].image_channel_order == orders[j]) {
  932. printf("%s, ", orderstr[j]);
  933. }
  934. }
  935. for(int j = 0; j < (int)(sizeof(types)/sizeof(cl_int)); j++) {
  936. if(imageFormats[i].image_channel_data_type == types[j]) {
  937. printf("%s, ", typesstr[j]);
  938. }
  939. }
  940. printf("\n");
  941. }
  942. free(imageFormats);
  943. }
  944. //-------------------------------------------------------
  945. // Platform and device information
  946. //-------------------------------------------------------
  947. //! Returns true if AMD is the device vendor
  948. bool cl_deviceIsAMD(cl_device_id dev) {
  949. bool retval = false;
  950. char* vendor = cl_getDeviceVendor(dev);
  951. if(strncmp(vendor, "Advanced", 8) == 0) {
  952. retval = true;
  953. }
  954. free(vendor);
  955. return retval;
  956. }
  957. //! Returns true if NVIDIA is the device vendor
  958. bool cl_deviceIsNVIDIA(cl_device_id dev) {
  959. bool retval = false;
  960. char* vendor = cl_getDeviceVendor(dev);
  961. if(strncmp(vendor, "NVIDIA", 6) == 0) {
  962. retval = true;
  963. }
  964. free(vendor);
  965. return retval;
  966. }
  967. //! Returns true if NVIDIA is the device vendor
  968. bool cl_platformIsNVIDIA(cl_platform_id plat) {
  969. bool retval = false;
  970. char* vendor = cl_getPlatformVendor(plat);
  971. if(strncmp(vendor, "NVIDIA", 6) == 0) {
  972. retval = true;
  973. }
  974. free(vendor);
  975. return retval;
  976. }
  977. //! Get the name of the vendor for a device
  978. char* cl_getDeviceDriverVersion(cl_device_id dev)
  979. {
  980. cl_int status;
  981. size_t devInfoSize;
  982. char* devInfoStr = NULL;
  983. // If dev is NULL, set it to the default device
  984. if(dev == NULL) {
  985. dev = device;
  986. }
  987. // Print the vendor
  988. status = clGetDeviceInfo(dev, CL_DRIVER_VERSION, 0,
  989. NULL, &devInfoSize);
  990. cl_errChk(status, "Getting vendor name", true);
  991. devInfoStr = (char*)alloc(devInfoSize);
  992. status = clGetDeviceInfo(dev, CL_DRIVER_VERSION, devInfoSize,
  993. devInfoStr, NULL);
  994. cl_errChk(status, "Getting vendor name", true);
  995. return devInfoStr;
  996. }
  997. //! The the name of the device as supplied by the OpenCL implementation
  998. char* cl_getDeviceName(cl_device_id dev)
  999. {
  1000. cl_int status;
  1001. size_t devInfoSize;
  1002. char* devInfoStr = NULL;
  1003. // If dev is NULL, set it to the default device
  1004. if(dev == NULL) {
  1005. dev = device;
  1006. }
  1007. // Print the name
  1008. status = clGetDeviceInfo(dev, CL_DEVICE_NAME, 0,
  1009. NULL, &devInfoSize);
  1010. cl_errChk(status, "Getting device name", true);
  1011. devInfoStr = (char*)alloc(devInfoSize);
  1012. status = clGetDeviceInfo(dev, CL_DEVICE_NAME, devInfoSize,
  1013. devInfoStr, NULL);
  1014. cl_errChk(status, "Getting device name", true);
  1015. return(devInfoStr);
  1016. }
  1017. //! Get the name of the vendor for a device
  1018. char* cl_getDeviceVendor(cl_device_id dev)
  1019. {
  1020. cl_int status;
  1021. size_t devInfoSize;
  1022. char* devInfoStr = NULL;
  1023. // If dev is NULL, set it to the default device
  1024. if(dev == NULL) {
  1025. dev = device;
  1026. }
  1027. // Print the vendor
  1028. status = clGetDeviceInfo(dev, CL_DEVICE_VENDOR, 0,
  1029. NULL, &devInfoSize);
  1030. cl_errChk(status, "Getting vendor name", true);
  1031. devInfoStr = (char*)alloc(devInfoSize);
  1032. status = clGetDeviceInfo(dev, CL_DEVICE_VENDOR, devInfoSize,
  1033. devInfoStr, NULL);
  1034. cl_errChk(status, "Getting vendor name", true);
  1035. return devInfoStr;
  1036. }
  1037. //! Get the name of the vendor for a device
  1038. char* cl_getDeviceVersion(cl_device_id dev)
  1039. {
  1040. cl_int status;
  1041. size_t devInfoSize;
  1042. char* devInfoStr = NULL;
  1043. // If dev is NULL, set it to the default device
  1044. if(dev == NULL) {
  1045. dev = device;
  1046. }
  1047. // Print the vendor
  1048. status = clGetDeviceInfo(dev, CL_DEVICE_VERSION, 0,
  1049. NULL, &devInfoSize);
  1050. cl_errChk(status, "Getting vendor name", true);
  1051. devInfoStr = (char*)alloc(devInfoSize);
  1052. status = clGetDeviceInfo(dev, CL_DEVICE_VERSION, devInfoSize,
  1053. devInfoStr, NULL);
  1054. cl_errChk(status, "Getting vendor name", true);
  1055. return devInfoStr;
  1056. }
  1057. //! The the name of the device as supplied by the OpenCL implementation
  1058. char* cl_getPlatformName(cl_platform_id platform)
  1059. {
  1060. cl_int status;
  1061. size_t platformInfoSize;
  1062. char* platformInfoStr = NULL;
  1063. // Print the name
  1064. status = clGetPlatformInfo(platform, CL_PLATFORM_NAME, 0,
  1065. NULL, &platformInfoSize);
  1066. cl_errChk(status, "Getting platform name", true);
  1067. platformInfoStr = (char*)alloc(platformInfoSize);
  1068. status = clGetPlatformInfo(platform, CL_PLATFORM_NAME, platformInfoSize,
  1069. platformInfoStr, NULL);
  1070. cl_errChk(status, "Getting platform name", true);
  1071. return(platformInfoStr);
  1072. }
  1073. //! The the name of the device as supplied by the OpenCL implementation
  1074. char* cl_getPlatformVendor(cl_platform_id platform)
  1075. {
  1076. cl_int status;
  1077. size_t platformInfoSize;
  1078. char* platformInfoStr = NULL;
  1079. // Print the name
  1080. status = clGetPlatformInfo(platform, CL_PLATFORM_VENDOR, 0,
  1081. NULL, &platformInfoSize);
  1082. cl_errChk(status, "Getting platform name", true);
  1083. platformInfoStr = (char*)alloc(platformInfoSize);
  1084. status = clGetPlatformInfo(platform, CL_PLATFORM_VENDOR, platformInfoSize,
  1085. platformInfoStr, NULL);
  1086. cl_errChk(status, "Getting platform name", true);
  1087. return(platformInfoStr);
  1088. }