MiniCL.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. /*
  2. Copyright (C) 2010 Sony Computer Entertainment Inc.
  3. All rights reserved.
  4. This software is provided 'as-is', without any express or implied warranty.
  5. In no event will the authors be held liable for any damages arising from the use of this software.
  6. Permission is granted to anyone to use this software for any purpose,
  7. including commercial applications, and to alter it and redistribute it freely,
  8. subject to the following restrictions:
  9. 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
  10. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
  11. 3. This notice may not be removed or altered from any source distribution.
  12. */
  13. #include "bullet/MiniCL/cl.h"
  14. #define __PHYSICS_COMMON_H__ 1
  15. #ifdef _WIN32
  16. #include "bullet/BulletMultiThreaded/Win32ThreadSupport.h"
  17. #endif
  18. #include "bullet/BulletMultiThreaded/PlatformDefinitions.h"
  19. #ifdef USE_PTHREADS
  20. #include "bullet/BulletMultiThreaded/PosixThreadSupport.h"
  21. #endif
  22. #include "bullet/BulletMultiThreaded/SequentialThreadSupport.h"
  23. #include "MiniCLTaskScheduler.h"
  24. #include "MiniCLTask/MiniCLTask.h"
  25. #include "bullet/LinearMath/btMinMax.h"
  26. #include <stdio.h>
  27. #include <stddef.h>
  28. //#define DEBUG_MINICL_KERNELS 1
  29. static const char* spPlatformID = "MiniCL, SCEA";
  30. static const char* spDriverVersion= "1.0";
  31. CL_API_ENTRY cl_int CL_API_CALL clGetPlatformIDs(
  32. cl_uint num_entries,
  33. cl_platform_id * platforms,
  34. cl_uint * num_platforms ) CL_API_SUFFIX__VERSION_1_0
  35. {
  36. if(platforms != NULL)
  37. {
  38. if(num_entries <= 0)
  39. {
  40. return CL_INVALID_VALUE;
  41. }
  42. *((const char**)platforms) = spPlatformID;
  43. }
  44. if(num_platforms != NULL)
  45. {
  46. *num_platforms = 1;
  47. }
  48. return CL_SUCCESS;
  49. }
  50. CL_API_ENTRY cl_int CL_API_CALL clGetPlatformInfo(
  51. cl_platform_id platform,
  52. cl_platform_info param_name,
  53. size_t param_value_size,
  54. void * param_value,
  55. size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0
  56. {
  57. char* pId = (char*)platform;
  58. if(strcmp(pId, spPlatformID))
  59. {
  60. return CL_INVALID_PLATFORM;
  61. }
  62. switch(param_name)
  63. {
  64. case CL_PLATFORM_VERSION:
  65. {
  66. if(param_value_size < (strlen(spDriverVersion) + 1))
  67. {
  68. return CL_INVALID_VALUE;
  69. }
  70. strcpy((char*)param_value, spDriverVersion);
  71. if(param_value_size_ret != NULL)
  72. {
  73. *param_value_size_ret = strlen(spDriverVersion) + 1;
  74. }
  75. break;
  76. }
  77. case CL_PLATFORM_NAME:
  78. case CL_PLATFORM_VENDOR :
  79. if(param_value_size < (strlen(spPlatformID) + 1))
  80. {
  81. return CL_INVALID_VALUE;
  82. }
  83. strcpy((char*)param_value, spPlatformID);
  84. if(param_value_size_ret != NULL)
  85. {
  86. *param_value_size_ret = strlen(spPlatformID) + 1;
  87. }
  88. break;
  89. default :
  90. return CL_INVALID_VALUE;
  91. }
  92. return CL_SUCCESS;
  93. }
  94. CL_API_ENTRY cl_int CL_API_CALL clGetDeviceInfo(
  95. cl_device_id device ,
  96. cl_device_info param_name ,
  97. size_t param_value_size ,
  98. void * param_value ,
  99. size_t * param_value_size_ret) CL_API_SUFFIX__VERSION_1_0
  100. {
  101. switch (param_name)
  102. {
  103. case CL_DEVICE_NAME:
  104. {
  105. char deviceName[] = "MiniCL CPU";
  106. unsigned int nameLen = (unsigned int)strlen(deviceName)+1;
  107. btAssert(param_value_size>strlen(deviceName));
  108. if (nameLen < param_value_size)
  109. {
  110. const char* cpuName = "MiniCL CPU";
  111. sprintf((char*)param_value,"%s",cpuName);
  112. } else
  113. {
  114. printf("error: param_value_size should be at least %d, but it is %zu\n",nameLen,param_value_size);
  115. return CL_INVALID_VALUE;
  116. }
  117. break;
  118. }
  119. case CL_DEVICE_TYPE:
  120. {
  121. if (param_value_size>=sizeof(cl_device_type))
  122. {
  123. cl_device_type* deviceType = (cl_device_type*)param_value;
  124. *deviceType = CL_DEVICE_TYPE_CPU;
  125. } else
  126. {
  127. printf("error: param_value_size should be at least %zu\n",sizeof(cl_device_type));
  128. return CL_INVALID_VALUE;
  129. }
  130. break;
  131. }
  132. case CL_DEVICE_MAX_COMPUTE_UNITS:
  133. {
  134. if (param_value_size>=sizeof(cl_uint))
  135. {
  136. cl_uint* numUnits = (cl_uint*)param_value;
  137. *numUnits= 4;
  138. } else
  139. {
  140. printf("error: param_value_size should be at least %zu\n",sizeof(cl_uint));
  141. return CL_INVALID_VALUE;
  142. }
  143. break;
  144. }
  145. case CL_DEVICE_MAX_WORK_ITEM_SIZES:
  146. {
  147. size_t workitem_size[3];
  148. if (param_value_size>=sizeof(workitem_size))
  149. {
  150. size_t* workItemSize = (size_t*)param_value;
  151. workItemSize[0] = 64;
  152. workItemSize[1] = 24;
  153. workItemSize[2] = 16;
  154. } else
  155. {
  156. printf("error: param_value_size should be at least %zu\n",sizeof(cl_uint));
  157. return CL_INVALID_VALUE;
  158. }
  159. break;
  160. }
  161. case CL_DEVICE_MAX_CLOCK_FREQUENCY:
  162. {
  163. cl_uint* clock_frequency = (cl_uint*)param_value;
  164. *clock_frequency = 3*1024;
  165. break;
  166. }
  167. case CL_DEVICE_VENDOR :
  168. {
  169. if(param_value_size < (strlen(spPlatformID) + 1))
  170. {
  171. return CL_INVALID_VALUE;
  172. }
  173. strcpy((char*)param_value, spPlatformID);
  174. if(param_value_size_ret != NULL)
  175. {
  176. *param_value_size_ret = strlen(spPlatformID) + 1;
  177. }
  178. break;
  179. }
  180. case CL_DRIVER_VERSION:
  181. {
  182. if(param_value_size < (strlen(spDriverVersion) + 1))
  183. {
  184. return CL_INVALID_VALUE;
  185. }
  186. strcpy((char*)param_value, spDriverVersion);
  187. if(param_value_size_ret != NULL)
  188. {
  189. *param_value_size_ret = strlen(spDriverVersion) + 1;
  190. }
  191. break;
  192. }
  193. case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:
  194. {
  195. cl_uint* maxDimensions = (cl_uint*)param_value;
  196. *maxDimensions = 1;
  197. break;
  198. }
  199. case CL_DEVICE_MAX_WORK_GROUP_SIZE:
  200. {
  201. cl_uint* maxWorkGroupSize = (cl_uint*)param_value;
  202. *maxWorkGroupSize = 128;//1;
  203. break;
  204. }
  205. case CL_DEVICE_ADDRESS_BITS:
  206. {
  207. cl_uint* addressBits = (cl_uint*)param_value;
  208. *addressBits= 32; //@todo: should this be 64 for 64bit builds?
  209. break;
  210. }
  211. case CL_DEVICE_MAX_MEM_ALLOC_SIZE:
  212. {
  213. cl_ulong* maxMemAlloc = (cl_ulong*)param_value;
  214. *maxMemAlloc= 512*1024*1024; //this "should be enough for everyone" ?
  215. break;
  216. }
  217. case CL_DEVICE_GLOBAL_MEM_SIZE:
  218. {
  219. cl_ulong* maxMemAlloc = (cl_ulong*)param_value;
  220. *maxMemAlloc= 1024*1024*1024; //this "should be enough for everyone" ?
  221. break;
  222. }
  223. case CL_DEVICE_ERROR_CORRECTION_SUPPORT:
  224. {
  225. cl_bool* error_correction_support = (cl_bool*)param_value;
  226. *error_correction_support = CL_FALSE;
  227. break;
  228. }
  229. case CL_DEVICE_LOCAL_MEM_TYPE:
  230. {
  231. cl_device_local_mem_type* local_mem_type = (cl_device_local_mem_type*)param_value;
  232. *local_mem_type = CL_GLOBAL;
  233. break;
  234. }
  235. case CL_DEVICE_LOCAL_MEM_SIZE:
  236. {
  237. cl_ulong* localmem = (cl_ulong*) param_value;
  238. *localmem = 32*1024;
  239. break;
  240. }
  241. case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:
  242. {
  243. cl_ulong* localmem = (cl_ulong*) param_value;
  244. *localmem = 64*1024;
  245. break;
  246. }
  247. case CL_DEVICE_QUEUE_PROPERTIES:
  248. {
  249. cl_command_queue_properties* queueProp = (cl_command_queue_properties*) param_value;
  250. memset(queueProp,0,param_value_size);
  251. break;
  252. }
  253. case CL_DEVICE_IMAGE_SUPPORT:
  254. {
  255. cl_bool* imageSupport = (cl_bool*) param_value;
  256. *imageSupport = CL_FALSE;
  257. break;
  258. }
  259. case CL_DEVICE_MAX_WRITE_IMAGE_ARGS:
  260. case CL_DEVICE_MAX_READ_IMAGE_ARGS:
  261. {
  262. cl_uint* imageArgs = (cl_uint*) param_value;
  263. *imageArgs = 0;
  264. break;
  265. }
  266. case CL_DEVICE_IMAGE3D_MAX_DEPTH:
  267. case CL_DEVICE_IMAGE3D_MAX_HEIGHT:
  268. case CL_DEVICE_IMAGE2D_MAX_HEIGHT:
  269. case CL_DEVICE_IMAGE3D_MAX_WIDTH:
  270. case CL_DEVICE_IMAGE2D_MAX_WIDTH:
  271. {
  272. size_t* maxSize = (size_t*) param_value;
  273. *maxSize = 0;
  274. break;
  275. }
  276. case CL_DEVICE_EXTENSIONS:
  277. {
  278. char* extensions = (char*) param_value;
  279. *extensions = 0;
  280. break;
  281. }
  282. case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE:
  283. case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT:
  284. case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG:
  285. case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT:
  286. case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT:
  287. case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR:
  288. {
  289. cl_uint* width = (cl_uint*) param_value;
  290. *width = 1;
  291. break;
  292. }
  293. default:
  294. {
  295. printf("error: unsupported param_name:%d\n",param_name);
  296. }
  297. }
  298. return 0;
  299. }
  300. CL_API_ENTRY cl_int CL_API_CALL clReleaseMemObject(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0
  301. {
  302. return 0;
  303. }
  304. CL_API_ENTRY cl_int CL_API_CALL clReleaseCommandQueue(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0
  305. {
  306. return 0;
  307. }
  308. CL_API_ENTRY cl_int CL_API_CALL clReleaseProgram(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0
  309. {
  310. return 0;
  311. }
  312. CL_API_ENTRY cl_int CL_API_CALL clReleaseKernel(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0
  313. {
  314. return 0;
  315. }
  316. // Enqueued Commands APIs
  317. CL_API_ENTRY cl_int CL_API_CALL clEnqueueReadBuffer(cl_command_queue command_queue ,
  318. cl_mem buffer ,
  319. cl_bool /* blocking_read */,
  320. size_t offset ,
  321. size_t cb ,
  322. void * ptr ,
  323. cl_uint /* num_events_in_wait_list */,
  324. const cl_event * /* event_wait_list */,
  325. cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0
  326. {
  327. MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue;
  328. ///wait for all work items to be completed
  329. scheduler->flush();
  330. memcpy(ptr,(char*)buffer + offset,cb);
  331. return 0;
  332. }
  333. CL_API_ENTRY cl_int clGetProgramBuildInfo(cl_program /* program */,
  334. cl_device_id /* device */,
  335. cl_program_build_info /* param_name */,
  336. size_t /* param_value_size */,
  337. void * /* param_value */,
  338. size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0
  339. {
  340. return 0;
  341. }
  342. // Program Object APIs
  343. CL_API_ENTRY cl_program
  344. clCreateProgramWithSource(cl_context context ,
  345. cl_uint /* count */,
  346. const char ** /* strings */,
  347. const size_t * /* lengths */,
  348. cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0
  349. {
  350. *errcode_ret = CL_SUCCESS;
  351. return (cl_program)context;
  352. }
  353. CL_API_ENTRY cl_int CL_API_CALL clEnqueueWriteBuffer(cl_command_queue command_queue ,
  354. cl_mem buffer ,
  355. cl_bool /* blocking_read */,
  356. size_t offset,
  357. size_t cb ,
  358. const void * ptr ,
  359. cl_uint /* num_events_in_wait_list */,
  360. const cl_event * /* event_wait_list */,
  361. cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0
  362. {
  363. MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue;
  364. ///wait for all work items to be completed
  365. scheduler->flush();
  366. memcpy((char*)buffer + offset, ptr,cb);
  367. return 0;
  368. }
  369. CL_API_ENTRY cl_int CL_API_CALL clFlush(cl_command_queue command_queue)
  370. {
  371. MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue;
  372. ///wait for all work items to be completed
  373. scheduler->flush();
  374. return 0;
  375. }
  376. CL_API_ENTRY cl_int CL_API_CALL clEnqueueNDRangeKernel(cl_command_queue /* command_queue */,
  377. cl_kernel clKernel ,
  378. cl_uint work_dim ,
  379. const size_t * /* global_work_offset */,
  380. const size_t * global_work_size ,
  381. const size_t * /* local_work_size */,
  382. cl_uint /* num_events_in_wait_list */,
  383. const cl_event * /* event_wait_list */,
  384. cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0
  385. {
  386. MiniCLKernel* kernel = (MiniCLKernel*) clKernel;
  387. for (unsigned int ii=0;ii<work_dim;ii++)
  388. {
  389. int maxTask = kernel->m_scheduler->getMaxNumOutstandingTasks();
  390. int numWorkItems = global_work_size[ii];
  391. // //at minimum 64 work items per task
  392. // int numWorkItemsPerTask = btMax(64,numWorkItems / maxTask);
  393. int numWorkItemsPerTask = numWorkItems / maxTask;
  394. if (!numWorkItemsPerTask) numWorkItemsPerTask = 1;
  395. for (int t=0;t<numWorkItems;)
  396. {
  397. //Performance Hint: tweak this number during benchmarking
  398. int endIndex = (t+numWorkItemsPerTask) < numWorkItems ? t+numWorkItemsPerTask : numWorkItems;
  399. kernel->m_scheduler->issueTask(t, endIndex, kernel);
  400. t = endIndex;
  401. }
  402. }
  403. /*
  404. void* bla = 0;
  405. scheduler->issueTask(bla,2,3);
  406. scheduler->flush();
  407. */
  408. return 0;
  409. }
  410. #define LOCAL_BUF_SIZE 32768
  411. static int sLocalMemBuf[LOCAL_BUF_SIZE * 4 + 16];
  412. static int* spLocalBufCurr = NULL;
  413. static int sLocalBufUsed = LOCAL_BUF_SIZE; // so it will be reset at the first call
  414. static void* localBufMalloc(int size)
  415. {
  416. int size16 = (size + 15) >> 4; // in 16-byte units
  417. if((sLocalBufUsed + size16) > LOCAL_BUF_SIZE)
  418. { // reset
  419. spLocalBufCurr = sLocalMemBuf;
  420. while((size_t)spLocalBufCurr & 0x0F) spLocalBufCurr++; // align to 16 bytes
  421. sLocalBufUsed = 0;
  422. }
  423. void* ret = spLocalBufCurr;
  424. spLocalBufCurr += size16 * 4;
  425. sLocalBufUsed += size;
  426. return ret;
  427. }
  428. CL_API_ENTRY cl_int CL_API_CALL clSetKernelArg(cl_kernel clKernel ,
  429. cl_uint arg_index ,
  430. size_t arg_size ,
  431. const void * arg_value ) CL_API_SUFFIX__VERSION_1_0
  432. {
  433. MiniCLKernel* kernel = (MiniCLKernel* ) clKernel;
  434. btAssert(arg_size <= MINICL_MAX_ARGLENGTH);
  435. if (arg_index>MINI_CL_MAX_ARG)
  436. {
  437. printf("error: clSetKernelArg arg_index (%u) exceeds %u\n",arg_index,MINI_CL_MAX_ARG);
  438. } else
  439. {
  440. if (arg_size>MINICL_MAX_ARGLENGTH)
  441. //if (arg_size != MINICL_MAX_ARGLENGTH)
  442. {
  443. printf("error: clSetKernelArg argdata too large: %zu (maximum is %zu)\n",arg_size,MINICL_MAX_ARGLENGTH);
  444. }
  445. else
  446. {
  447. if(arg_value == NULL)
  448. { // this is only for __local memory qualifier
  449. void* ptr = localBufMalloc(arg_size);
  450. kernel->m_argData[arg_index] = ptr;
  451. }
  452. else
  453. {
  454. memcpy(&(kernel->m_argData[arg_index]), arg_value, arg_size);
  455. }
  456. kernel->m_argSizes[arg_index] = arg_size;
  457. if(arg_index >= kernel->m_numArgs)
  458. {
  459. kernel->m_numArgs = arg_index + 1;
  460. kernel->updateLauncher();
  461. }
  462. }
  463. }
  464. return 0;
  465. }
  466. // Kernel Object APIs
  467. CL_API_ENTRY cl_kernel CL_API_CALL clCreateKernel(cl_program program ,
  468. const char * kernel_name ,
  469. cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0
  470. {
  471. MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) program;
  472. int nameLen = strlen(kernel_name);
  473. if(nameLen >= MINI_CL_MAX_KERNEL_NAME)
  474. {
  475. *errcode_ret = CL_INVALID_KERNEL_NAME;
  476. return NULL;
  477. }
  478. MiniCLKernel* kernel = new MiniCLKernel();
  479. strcpy(kernel->m_name, kernel_name);
  480. kernel->m_numArgs = 0;
  481. //kernel->m_kernelProgramCommandId = scheduler->findProgramCommandIdByName(kernel_name);
  482. //if (kernel->m_kernelProgramCommandId>=0)
  483. //{
  484. // *errcode_ret = CL_SUCCESS;
  485. //} else
  486. //{
  487. // *errcode_ret = CL_INVALID_KERNEL_NAME;
  488. //}
  489. kernel->m_scheduler = scheduler;
  490. if(kernel->registerSelf() == NULL)
  491. {
  492. *errcode_ret = CL_INVALID_KERNEL_NAME;
  493. delete kernel;
  494. return NULL;
  495. }
  496. else
  497. {
  498. *errcode_ret = CL_SUCCESS;
  499. }
  500. return (cl_kernel)kernel;
  501. }
  502. CL_API_ENTRY cl_int CL_API_CALL clBuildProgram(cl_program /* program */,
  503. cl_uint /* num_devices */,
  504. const cl_device_id * /* device_list */,
  505. const char * /* options */,
  506. void (*pfn_notify)(cl_program /* program */, void * /* user_data */),
  507. void * /* user_data */) CL_API_SUFFIX__VERSION_1_0
  508. {
  509. return CL_SUCCESS;
  510. }
  511. CL_API_ENTRY cl_program CL_API_CALL clCreateProgramWithBinary(cl_context context ,
  512. cl_uint /* num_devices */,
  513. const cl_device_id * /* device_list */,
  514. const size_t * /* lengths */,
  515. const unsigned char ** /* binaries */,
  516. cl_int * /* binary_status */,
  517. cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0
  518. {
  519. return (cl_program)context;
  520. }
  521. // Memory Object APIs
  522. CL_API_ENTRY cl_mem CL_API_CALL clCreateBuffer(cl_context /* context */,
  523. cl_mem_flags flags ,
  524. size_t size,
  525. void * host_ptr ,
  526. cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0
  527. {
  528. cl_mem buf = (cl_mem)malloc(size);
  529. if ((flags&CL_MEM_COPY_HOST_PTR) && host_ptr)
  530. {
  531. memcpy(buf,host_ptr,size);
  532. }
  533. *errcode_ret = 0;
  534. return buf;
  535. }
  536. // Command Queue APIs
  537. CL_API_ENTRY cl_command_queue CL_API_CALL clCreateCommandQueue(cl_context context ,
  538. cl_device_id /* device */,
  539. cl_command_queue_properties /* properties */,
  540. cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0
  541. {
  542. *errcode_ret = 0;
  543. return (cl_command_queue) context;
  544. }
  545. extern CL_API_ENTRY cl_int CL_API_CALL clGetContextInfo(cl_context /* context */,
  546. cl_context_info param_name ,
  547. size_t param_value_size ,
  548. void * param_value,
  549. size_t * param_value_size_ret ) CL_API_SUFFIX__VERSION_1_0
  550. {
  551. switch (param_name)
  552. {
  553. case CL_CONTEXT_DEVICES:
  554. {
  555. if (!param_value_size)
  556. {
  557. *param_value_size_ret = 13;
  558. } else
  559. {
  560. const char* testName = "MiniCL_Test.";
  561. sprintf((char*)param_value,"%s",testName);
  562. }
  563. break;
  564. };
  565. default:
  566. {
  567. printf("unsupported\n");
  568. }
  569. }
  570. return 0;
  571. }
  572. CL_API_ENTRY cl_context CL_API_CALL clCreateContextFromType(const cl_context_properties * /* properties */,
  573. cl_device_type device_type ,
  574. void (*pfn_notify)(const char *, const void *, size_t, void *) /* pfn_notify */,
  575. void * /* user_data */,
  576. cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0
  577. {
  578. int maxNumOutstandingTasks = 4;
  579. // int maxNumOutstandingTasks = 2;
  580. // int maxNumOutstandingTasks = 1;
  581. gMiniCLNumOutstandingTasks = maxNumOutstandingTasks;
  582. const int maxNumOfThreadSupports = 8;
  583. static int sUniqueThreadSupportIndex = 0;
  584. static const char* sUniqueThreadSupportName[maxNumOfThreadSupports] =
  585. {
  586. "MiniCL_0", "MiniCL_1", "MiniCL_2", "MiniCL_3", "MiniCL_4", "MiniCL_5", "MiniCL_6", "MiniCL_7"
  587. };
  588. btThreadSupportInterface* threadSupport = 0;
  589. if (device_type==CL_DEVICE_TYPE_DEBUG)
  590. {
  591. SequentialThreadSupport::SequentialThreadConstructionInfo stc("MiniCL",processMiniCLTask,createMiniCLLocalStoreMemory);
  592. threadSupport = new SequentialThreadSupport(stc);
  593. } else
  594. {
  595. #if _WIN32
  596. btAssert(sUniqueThreadSupportIndex < maxNumOfThreadSupports);
  597. const char* bla = "MiniCL";
  598. threadSupport = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo(
  599. // bla,
  600. sUniqueThreadSupportName[sUniqueThreadSupportIndex++],
  601. processMiniCLTask, //processCollisionTask,
  602. createMiniCLLocalStoreMemory,//createCollisionLocalStoreMemory,
  603. maxNumOutstandingTasks));
  604. #else
  605. #ifdef USE_PTHREADS
  606. PosixThreadSupport::ThreadConstructionInfo constructionInfo("PosixThreads",
  607. processMiniCLTask,
  608. createMiniCLLocalStoreMemory,
  609. maxNumOutstandingTasks);
  610. threadSupport = new PosixThreadSupport(constructionInfo);
  611. #else
  612. ///todo: add posix thread support for other platforms
  613. SequentialThreadSupport::SequentialThreadConstructionInfo stc("MiniCL",processMiniCLTask,createMiniCLLocalStoreMemory);
  614. threadSupport = new SequentialThreadSupport(stc);
  615. #endif //USE_PTHREADS
  616. #endif
  617. }
  618. MiniCLTaskScheduler* scheduler = new MiniCLTaskScheduler(threadSupport,maxNumOutstandingTasks);
  619. *errcode_ret = 0;
  620. return (cl_context)scheduler;
  621. }
  622. CL_API_ENTRY cl_int CL_API_CALL
  623. clGetDeviceIDs(cl_platform_id /* platform */,
  624. cl_device_type /* device_type */,
  625. cl_uint /* num_entries */,
  626. cl_device_id * /* devices */,
  627. cl_uint * /* num_devices */) CL_API_SUFFIX__VERSION_1_0
  628. {
  629. return 0;
  630. }
  631. CL_API_ENTRY cl_context CL_API_CALL
  632. clCreateContext(const cl_context_properties * properties ,
  633. cl_uint num_devices ,
  634. const cl_device_id * devices ,
  635. void (*pfn_notify)(const char *, const void *, size_t, void *),
  636. void * user_data ,
  637. cl_int * errcode_ret ) CL_API_SUFFIX__VERSION_1_0
  638. {
  639. return clCreateContextFromType(properties,CL_DEVICE_TYPE_ALL,pfn_notify,user_data,errcode_ret);
  640. }
  641. CL_API_ENTRY cl_int CL_API_CALL clReleaseContext(cl_context context ) CL_API_SUFFIX__VERSION_1_0
  642. {
  643. MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) context;
  644. btThreadSupportInterface* threadSupport = scheduler->getThreadSupportInterface();
  645. delete scheduler;
  646. delete threadSupport;
  647. return 0;
  648. }
  649. extern CL_API_ENTRY cl_int CL_API_CALL
  650. clFinish(cl_command_queue command_queue ) CL_API_SUFFIX__VERSION_1_0
  651. {
  652. MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue;
  653. ///wait for all work items to be completed
  654. scheduler->flush();
  655. return CL_SUCCESS;
  656. }
  657. extern CL_API_ENTRY cl_int CL_API_CALL
  658. clGetProgramInfo(cl_program /* program */,
  659. cl_program_info /* param_name */,
  660. size_t /* param_value_size */,
  661. void * /* param_value */,
  662. size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0
  663. {
  664. return 0;
  665. }
  666. extern CL_API_ENTRY cl_int CL_API_CALL
  667. clGetKernelWorkGroupInfo(cl_kernel kernel ,
  668. cl_device_id /* device */,
  669. cl_kernel_work_group_info wgi/* param_name */,
  670. size_t sz /* param_value_size */,
  671. void * ptr /* param_value */,
  672. size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0
  673. {
  674. if((wgi == CL_KERNEL_WORK_GROUP_SIZE)
  675. &&(sz == sizeof(size_t))
  676. &&(ptr != NULL))
  677. {
  678. MiniCLKernel* miniCLKernel = (MiniCLKernel*)kernel;
  679. MiniCLTaskScheduler* scheduler = miniCLKernel->m_scheduler;
  680. *((size_t*)ptr) = scheduler->getMaxNumOutstandingTasks();
  681. return CL_SUCCESS;
  682. }
  683. else
  684. {
  685. return CL_INVALID_VALUE;
  686. }
  687. }