MiniCL.cpp

Go to the documentation of this file.
00001 /*
00002    Copyright (C) 2010 Sony Computer Entertainment Inc.
00003    All rights reserved.
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 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.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 
00015 */
00016 
00017 
00018 #include "MiniCL/cl.h"
00019 #define __PHYSICS_COMMON_H__ 1
00020 #ifdef _WIN32
00021 #include "BulletMultiThreaded/Win32ThreadSupport.h"
00022 #endif
00023 
00024 #include "BulletMultiThreaded/PlatformDefinitions.h"
00025 #ifdef USE_PTHREADS
00026 #include "BulletMultiThreaded/PosixThreadSupport.h"
00027 #endif
00028 
00029 
00030 #include "BulletMultiThreaded/SequentialThreadSupport.h"
00031 #include "MiniCLTaskScheduler.h"
00032 #include "MiniCLTask/MiniCLTask.h"
00033 #include "LinearMath/btMinMax.h"
00034 #include <stdio.h>
00035 #include <stddef.h>
00036 
00037 //#define DEBUG_MINICL_KERNELS 1
00038 
00039 static const char* spPlatformID = "MiniCL, SCEA";
00040 static const char* spDriverVersion= "1.0";
00041 
00042 CL_API_ENTRY cl_int CL_API_CALL clGetPlatformIDs(
00043         cl_uint           num_entries,
00044     cl_platform_id *  platforms,
00045     cl_uint *         num_platforms ) CL_API_SUFFIX__VERSION_1_0
00046 {
00047         if(platforms != NULL)
00048         {
00049                 if(num_entries <= 0)
00050                 {
00051                         return CL_INVALID_VALUE; 
00052                 }
00053                 *((const char**)platforms) = spPlatformID;
00054         }
00055         if(num_platforms != NULL)
00056         {
00057                 *num_platforms = 1;
00058         }
00059         return CL_SUCCESS;
00060 }
00061 
00062 
00063 CL_API_ENTRY cl_int CL_API_CALL clGetPlatformInfo(
00064         cl_platform_id   platform, 
00065         cl_platform_info param_name,
00066         size_t           param_value_size, 
00067         void *           param_value,
00068         size_t *         param_value_size_ret) CL_API_SUFFIX__VERSION_1_0
00069 {
00070         char* pId = (char*)platform;
00071         if(strcmp(pId, spPlatformID))
00072         {
00073                         return CL_INVALID_PLATFORM; 
00074         }
00075         switch(param_name)
00076         {
00077         case CL_PLATFORM_VERSION:
00078                 {
00079                         if(param_value_size < (strlen(spDriverVersion) + 1))
00080                         {
00081                                 return CL_INVALID_VALUE; 
00082                         }
00083                         strcpy((char*)param_value, spDriverVersion);
00084                         if(param_value_size_ret != NULL)
00085                         {
00086                                 *param_value_size_ret = strlen(spDriverVersion) + 1;
00087                         }
00088                         break;
00089                 }
00090                 case CL_PLATFORM_NAME:
00091                 case CL_PLATFORM_VENDOR :
00092                         if(param_value_size < (strlen(spPlatformID) + 1))
00093                         {
00094                                 return CL_INVALID_VALUE; 
00095                         }
00096                         strcpy((char*)param_value, spPlatformID);
00097                         if(param_value_size_ret != NULL)
00098                         {
00099                                 *param_value_size_ret = strlen(spPlatformID) + 1;
00100                         }
00101                         break;
00102                 default : 
00103                         return CL_INVALID_VALUE; 
00104         }
00105         return CL_SUCCESS;
00106 }
00107 
00108 
00109 
00110 
00111 CL_API_ENTRY cl_int CL_API_CALL clGetDeviceInfo(
00112         cl_device_id            device ,
00113         cl_device_info          param_name ,
00114         size_t                  param_value_size ,
00115         void *                  param_value ,
00116         size_t *                param_value_size_ret) CL_API_SUFFIX__VERSION_1_0
00117 {
00118 
00119         switch (param_name)
00120         {
00121         case CL_DEVICE_NAME:
00122                 {
00123                         char deviceName[] = "MiniCL CPU";
00124                         unsigned int nameLen = (unsigned int)strlen(deviceName)+1;
00125                         btAssert(param_value_size>strlen(deviceName));
00126                         if (nameLen < param_value_size)
00127                         {
00128                                 const char* cpuName = "MiniCL CPU";
00129                                 sprintf((char*)param_value,"%s",cpuName);
00130                         } else
00131                         {
00132                                 printf("error: param_value_size should be at least %d, but it is %zu\n",nameLen,param_value_size);
00133                                 return CL_INVALID_VALUE; 
00134                         }
00135                         break;
00136                 }
00137         case CL_DEVICE_TYPE:
00138                 {
00139                         if (param_value_size>=sizeof(cl_device_type))
00140                         {
00141                                 cl_device_type* deviceType = (cl_device_type*)param_value;
00142                                 *deviceType = CL_DEVICE_TYPE_CPU;
00143                         } else
00144                         {
00145                                 printf("error: param_value_size should be at least %zu\n",sizeof(cl_device_type));
00146                                 return CL_INVALID_VALUE; 
00147                         }
00148                         break;
00149                 }
00150         case CL_DEVICE_MAX_COMPUTE_UNITS:
00151                 {
00152                         if (param_value_size>=sizeof(cl_uint))
00153                         {
00154                                 cl_uint* numUnits = (cl_uint*)param_value;
00155                                 *numUnits= 4;
00156                         } else
00157                         {
00158                                 printf("error: param_value_size should be at least %zu\n",sizeof(cl_uint));
00159                                 return CL_INVALID_VALUE; 
00160                         }
00161 
00162                         break;
00163                 }
00164         case CL_DEVICE_MAX_WORK_ITEM_SIZES:
00165                 {
00166                         size_t workitem_size[3];
00167 
00168                         if (param_value_size>=sizeof(workitem_size))
00169                         {
00170                                 size_t* workItemSize = (size_t*)param_value;
00171                                 workItemSize[0] = 64;
00172                                 workItemSize[1] = 24;
00173                                 workItemSize[2] = 16;
00174                         } else
00175                         {
00176                                 printf("error: param_value_size should be at least %zu\n",sizeof(cl_uint));
00177                                 return CL_INVALID_VALUE; 
00178                         }
00179                         break;
00180                 }
00181         case CL_DEVICE_MAX_CLOCK_FREQUENCY:
00182                 {
00183                          cl_uint* clock_frequency = (cl_uint*)param_value;
00184                          *clock_frequency = 3*1024;
00185                         break;
00186                 }
00187 
00188         case CL_DEVICE_VENDOR   :
00189                 {
00190                         if(param_value_size < (strlen(spPlatformID) + 1))
00191                         {
00192                                 return CL_INVALID_VALUE; 
00193                         }
00194                         strcpy((char*)param_value, spPlatformID);
00195                         if(param_value_size_ret != NULL)
00196                         {
00197                                 *param_value_size_ret = strlen(spPlatformID) + 1;
00198                         }
00199                         break;
00200                 }
00201         case CL_DRIVER_VERSION:
00202                 {
00203                         if(param_value_size < (strlen(spDriverVersion) + 1))
00204                         {
00205                                 return CL_INVALID_VALUE; 
00206                         }
00207                         strcpy((char*)param_value, spDriverVersion);
00208                         if(param_value_size_ret != NULL)
00209                         {
00210                                 *param_value_size_ret = strlen(spDriverVersion) + 1;
00211                         }
00212 
00213                         break;
00214                 }
00215         case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:
00216                 {
00217                          cl_uint* maxDimensions = (cl_uint*)param_value;
00218                          *maxDimensions = 1;
00219                          break;
00220                 }
00221                 case CL_DEVICE_MAX_WORK_GROUP_SIZE:
00222                 {
00223                          cl_uint* maxWorkGroupSize = (cl_uint*)param_value;
00224                          *maxWorkGroupSize = 128;//1;
00225                          break;
00226                 }
00227                 case CL_DEVICE_ADDRESS_BITS:
00228                 {
00229                          cl_uint* addressBits = (cl_uint*)param_value;
00230                          *addressBits= 32; //@todo: should this be 64 for 64bit builds?
00231                          break;
00232                 }
00233                 case CL_DEVICE_MAX_MEM_ALLOC_SIZE:
00234                         {
00235                                 cl_ulong* maxMemAlloc = (cl_ulong*)param_value;
00236                                 *maxMemAlloc= 512*1024*1024; //this "should be enough for everyone" ?
00237                          break;
00238                         }
00239                 case CL_DEVICE_GLOBAL_MEM_SIZE:
00240                         {
00241                                 cl_ulong* maxMemAlloc = (cl_ulong*)param_value;
00242                                 *maxMemAlloc= 1024*1024*1024; //this "should be enough for everyone" ?
00243                          break;
00244                         }
00245 
00246                 case CL_DEVICE_ERROR_CORRECTION_SUPPORT:
00247                         {
00248                         cl_bool* error_correction_support = (cl_bool*)param_value;
00249                         *error_correction_support = CL_FALSE;
00250                         break;
00251                         }
00252 
00253                 case CL_DEVICE_LOCAL_MEM_TYPE:
00254                         {
00255                         cl_device_local_mem_type* local_mem_type = (cl_device_local_mem_type*)param_value;
00256                         *local_mem_type = CL_GLOBAL;
00257                         break;
00258                         }
00259                 case CL_DEVICE_LOCAL_MEM_SIZE:
00260                         {
00261                                 cl_ulong* localmem = (cl_ulong*) param_value;
00262                                 *localmem = 32*1024;
00263                                 break;
00264                         }
00265 
00266                 case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:
00267                         {
00268                                 cl_ulong* localmem = (cl_ulong*) param_value;
00269                                 *localmem = 64*1024;
00270                                 break;
00271                         }
00272                 case CL_DEVICE_QUEUE_PROPERTIES:
00273                         {
00274                                 cl_command_queue_properties* queueProp = (cl_command_queue_properties*) param_value;
00275                                 memset(queueProp,0,param_value_size);
00276 
00277                                 break;
00278                         }
00279                 case CL_DEVICE_IMAGE_SUPPORT:
00280                         {
00281                                 cl_bool* imageSupport = (cl_bool*) param_value;
00282                                 *imageSupport = CL_FALSE;
00283                                 break;
00284                         }
00285 
00286                 case CL_DEVICE_MAX_WRITE_IMAGE_ARGS:
00287                 case CL_DEVICE_MAX_READ_IMAGE_ARGS:
00288                         {
00289                                 cl_uint* imageArgs = (cl_uint*) param_value;
00290                                 *imageArgs = 0;
00291                                 break;
00292                         }
00293                 case CL_DEVICE_IMAGE3D_MAX_DEPTH:
00294                 case CL_DEVICE_IMAGE3D_MAX_HEIGHT:
00295                 case CL_DEVICE_IMAGE2D_MAX_HEIGHT:
00296                 case CL_DEVICE_IMAGE3D_MAX_WIDTH:
00297                 case CL_DEVICE_IMAGE2D_MAX_WIDTH:
00298                         {
00299                                 size_t* maxSize = (size_t*) param_value;
00300                                 *maxSize = 0;
00301                                 break;
00302                         }
00303 
00304                 case CL_DEVICE_EXTENSIONS:
00305                         {
00306                                 char* extensions = (char*) param_value;
00307                                 *extensions = 0;
00308                                 break;
00309                         }
00310 
00311                 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE:
00312                 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT:
00313                 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG:
00314                 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT:
00315                 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT:
00316                 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR:
00317                         {
00318                                 cl_uint* width  = (cl_uint*) param_value;
00319                                 *width = 1;
00320                                 break;
00321                         }
00322                         
00323         default:
00324                 {
00325                         printf("error: unsupported param_name:%d\n",param_name);
00326                 }
00327         }
00328 
00329 
00330         return 0;
00331 }
00332 
00333 CL_API_ENTRY cl_int CL_API_CALL clReleaseMemObject(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0
00334 {
00335         return 0;
00336 }
00337 
00338 
00339 
00340 CL_API_ENTRY cl_int CL_API_CALL clReleaseCommandQueue(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0
00341 {
00342         return 0;
00343 }
00344 
00345 CL_API_ENTRY cl_int CL_API_CALL clReleaseProgram(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0
00346 {
00347         return 0;
00348 }
00349 
00350 CL_API_ENTRY cl_int CL_API_CALL clReleaseKernel(cl_kernel   /* kernel */) CL_API_SUFFIX__VERSION_1_0
00351 {
00352         return 0;
00353 }
00354 
00355 
00356 // Enqueued Commands APIs
00357 CL_API_ENTRY cl_int CL_API_CALL clEnqueueReadBuffer(cl_command_queue     command_queue ,
00358                     cl_mem               buffer ,
00359                     cl_bool             /* blocking_read */,
00360                     size_t               offset ,
00361                     size_t               cb , 
00362                     void *               ptr ,
00363                     cl_uint             /* num_events_in_wait_list */,
00364                     const cl_event *    /* event_wait_list */,
00365                     cl_event *          /* event */) CL_API_SUFFIX__VERSION_1_0
00366 {
00367         MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue;
00368 
00370         scheduler->flush();
00371 
00372         memcpy(ptr,(char*)buffer + offset,cb);
00373         return 0;
00374 }
00375 
00376 
00377 CL_API_ENTRY cl_int clGetProgramBuildInfo(cl_program            /* program */,
00378                       cl_device_id          /* device */,
00379                       cl_program_build_info /* param_name */,
00380                       size_t                /* param_value_size */,
00381                       void *                /* param_value */,
00382                       size_t *              /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0
00383 {
00384 
00385         return 0;
00386 }
00387 
00388 
00389 // Program Object APIs
00390 CL_API_ENTRY cl_program
00391 clCreateProgramWithSource(cl_context         context ,
00392                           cl_uint           /* count */,
00393                           const char **     /* strings */,
00394                           const size_t *    /* lengths */,
00395                           cl_int *          errcode_ret ) CL_API_SUFFIX__VERSION_1_0
00396 {
00397         *errcode_ret = CL_SUCCESS;
00398         return (cl_program)context;
00399 }
00400 
00401 CL_API_ENTRY cl_int CL_API_CALL clEnqueueWriteBuffer(cl_command_queue     command_queue ,
00402                     cl_mem               buffer ,
00403                     cl_bool             /* blocking_read */,
00404                     size_t              offset,
00405                     size_t               cb , 
00406                     const void *         ptr ,
00407                     cl_uint             /* num_events_in_wait_list */,
00408                     const cl_event *    /* event_wait_list */,
00409                     cl_event *          /* event */) CL_API_SUFFIX__VERSION_1_0
00410 {
00411         MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue;
00412 
00414         scheduler->flush();
00415 
00416         memcpy((char*)buffer + offset, ptr,cb);
00417         return 0;
00418 }
00419 
00420 CL_API_ENTRY cl_int CL_API_CALL clFlush(cl_command_queue  command_queue)
00421 {
00422         MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue;
00424         scheduler->flush();
00425         return 0;
00426 }
00427 
00428 
00429 CL_API_ENTRY cl_int CL_API_CALL clEnqueueNDRangeKernel(cl_command_queue /* command_queue */,
00430                        cl_kernel         clKernel ,
00431                        cl_uint           work_dim ,
00432                        const size_t *   /* global_work_offset */,
00433                        const size_t *    global_work_size ,
00434                        const size_t *   /* local_work_size */,
00435                        cl_uint          /* num_events_in_wait_list */,
00436                        const cl_event * /* event_wait_list */,
00437                        cl_event *       /* event */) CL_API_SUFFIX__VERSION_1_0
00438 {
00439 
00440         
00441         MiniCLKernel* kernel = (MiniCLKernel*) clKernel;
00442         for (unsigned int ii=0;ii<work_dim;ii++)
00443         {
00444                 int maxTask = kernel->m_scheduler->getMaxNumOutstandingTasks();
00445                 int numWorkItems = global_work_size[ii];
00446 
00447 //              //at minimum 64 work items per task
00448 //              int numWorkItemsPerTask = btMax(64,numWorkItems / maxTask);
00449                 int numWorkItemsPerTask = numWorkItems / maxTask;
00450                 if (!numWorkItemsPerTask) numWorkItemsPerTask = 1;
00451 
00452                 for (int t=0;t<numWorkItems;)
00453                 {
00454                         //Performance Hint: tweak this number during benchmarking
00455                         int endIndex = (t+numWorkItemsPerTask) < numWorkItems ? t+numWorkItemsPerTask : numWorkItems;
00456                         kernel->m_scheduler->issueTask(t, endIndex, kernel);
00457                         t = endIndex;
00458                 }
00459         }
00460 /*
00461 
00462         void* bla = 0;
00463 
00464         scheduler->issueTask(bla,2,3);
00465         scheduler->flush();
00466 
00467         */
00468 
00469         return 0;
00470 }
00471 
00472 #define LOCAL_BUF_SIZE 32768
00473 static int sLocalMemBuf[LOCAL_BUF_SIZE * 4 + 16];
00474 static int* spLocalBufCurr = NULL;
00475 static int sLocalBufUsed = LOCAL_BUF_SIZE; // so it will be reset at the first call
00476 static void* localBufMalloc(int size)
00477 {
00478         int size16 = (size + 15) >> 4; // in 16-byte units
00479         if((sLocalBufUsed + size16) > LOCAL_BUF_SIZE)
00480         { // reset
00481                 spLocalBufCurr = sLocalMemBuf;
00482                 while((size_t)spLocalBufCurr & 0x0F) spLocalBufCurr++; // align to 16 bytes
00483                 sLocalBufUsed = 0;
00484         }
00485         void* ret = spLocalBufCurr;
00486         spLocalBufCurr += size16 * 4;
00487         sLocalBufUsed += size;
00488         return ret;
00489 }
00490 
00491 
00492 
00493 CL_API_ENTRY cl_int CL_API_CALL clSetKernelArg(cl_kernel    clKernel ,
00494                cl_uint      arg_index ,
00495                size_t       arg_size ,
00496                const void *  arg_value ) CL_API_SUFFIX__VERSION_1_0
00497 {
00498         MiniCLKernel* kernel = (MiniCLKernel* ) clKernel;
00499         btAssert(arg_size <= MINICL_MAX_ARGLENGTH);
00500         if (arg_index>MINI_CL_MAX_ARG)
00501         {
00502                 printf("error: clSetKernelArg arg_index (%u) exceeds %u\n",arg_index,MINI_CL_MAX_ARG);
00503         } else
00504         {
00505                 if (arg_size>MINICL_MAX_ARGLENGTH)
00506                 //if (arg_size != MINICL_MAX_ARGLENGTH)
00507                 {
00508                         printf("error: clSetKernelArg argdata too large: %zu (maximum is %zu)\n",arg_size,MINICL_MAX_ARGLENGTH);
00509                 } 
00510                 else
00511                 {
00512                         if(arg_value == NULL)
00513                         {       // this is only for __local memory qualifier
00514                                 void* ptr = localBufMalloc(arg_size);
00515                                 kernel->m_argData[arg_index] = ptr;
00516                         }
00517                         else
00518                         {
00519                                 memcpy(&(kernel->m_argData[arg_index]), arg_value, arg_size);
00520                         }
00521                         kernel->m_argSizes[arg_index] = arg_size;
00522                         if(arg_index >= kernel->m_numArgs)
00523                         {
00524                                 kernel->m_numArgs = arg_index + 1;
00525                                 kernel->updateLauncher();
00526                         }
00527                 }
00528         }
00529         return 0;
00530 }
00531 
00532 // Kernel Object APIs
00533 CL_API_ENTRY cl_kernel CL_API_CALL clCreateKernel(cl_program       program ,
00534                const char *     kernel_name ,
00535                cl_int *         errcode_ret ) CL_API_SUFFIX__VERSION_1_0
00536 {
00537         MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) program;
00538         int nameLen = strlen(kernel_name);
00539         if(nameLen >= MINI_CL_MAX_KERNEL_NAME)
00540         {
00541                 *errcode_ret = CL_INVALID_KERNEL_NAME;
00542                 return NULL;
00543         }
00544 
00545         MiniCLKernel* kernel = new MiniCLKernel();
00546 
00547         strcpy(kernel->m_name, kernel_name);
00548         kernel->m_numArgs = 0;
00549 
00550         //kernel->m_kernelProgramCommandId = scheduler->findProgramCommandIdByName(kernel_name);
00551         //if (kernel->m_kernelProgramCommandId>=0)
00552         //{
00553         //      *errcode_ret = CL_SUCCESS;
00554         //} else
00555         //{
00556         //      *errcode_ret = CL_INVALID_KERNEL_NAME;
00557         //}
00558         kernel->m_scheduler = scheduler;
00559         if(kernel->registerSelf() == NULL)
00560         {
00561                 *errcode_ret = CL_INVALID_KERNEL_NAME;
00562                 delete kernel;
00563                 return NULL;
00564         }
00565         else
00566         {
00567                 *errcode_ret = CL_SUCCESS;
00568         }
00569 
00570         return (cl_kernel)kernel;
00571 
00572 }
00573 
00574 
00575 CL_API_ENTRY cl_int CL_API_CALL clBuildProgram(cl_program           /* program */,
00576                cl_uint              /* num_devices */,
00577                const cl_device_id * /* device_list */,
00578                const char *         /* options */, 
00579                void (*pfn_notify)(cl_program /* program */, void * /* user_data */),
00580                void *               /* user_data */) CL_API_SUFFIX__VERSION_1_0
00581 {
00582         return CL_SUCCESS;
00583 }
00584 
00585 CL_API_ENTRY cl_program CL_API_CALL clCreateProgramWithBinary(cl_context                     context ,
00586                           cl_uint                        /* num_devices */,
00587                           const cl_device_id *           /* device_list */,
00588                           const size_t *                 /* lengths */,
00589                           const unsigned char **         /* binaries */,
00590                           cl_int *                       /* binary_status */,
00591                           cl_int *                       /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0
00592 {
00593         return (cl_program)context;
00594 }
00595 
00596 
00597 // Memory Object APIs
00598 CL_API_ENTRY cl_mem CL_API_CALL clCreateBuffer(cl_context   /* context */,
00599                cl_mem_flags flags ,
00600                size_t       size,
00601                void *       host_ptr ,
00602                cl_int *     errcode_ret ) CL_API_SUFFIX__VERSION_1_0
00603 {
00604         cl_mem buf = (cl_mem)malloc(size);
00605         if ((flags&CL_MEM_COPY_HOST_PTR) && host_ptr)
00606         {
00607                 memcpy(buf,host_ptr,size);
00608         }
00609         *errcode_ret = 0;
00610         return buf;
00611 }
00612 
00613 // Command Queue APIs
00614 CL_API_ENTRY cl_command_queue CL_API_CALL clCreateCommandQueue(cl_context                      context , 
00615                      cl_device_id                   /* device */, 
00616                      cl_command_queue_properties    /* properties */,
00617                      cl_int *                        errcode_ret ) CL_API_SUFFIX__VERSION_1_0
00618 {
00619         *errcode_ret = 0;
00620         return (cl_command_queue) context;
00621 }
00622 
00623 extern CL_API_ENTRY cl_int CL_API_CALL clGetContextInfo(cl_context         /* context */, 
00624                  cl_context_info    param_name , 
00625                  size_t             param_value_size , 
00626                  void *             param_value, 
00627                  size_t *           param_value_size_ret ) CL_API_SUFFIX__VERSION_1_0
00628 {
00629 
00630         switch (param_name)
00631         {
00632         case CL_CONTEXT_DEVICES:
00633                 {
00634                         if (!param_value_size)
00635                         {
00636                                 *param_value_size_ret = 13;
00637                         } else
00638                         {
00639                                 const char* testName = "MiniCL_Test.";
00640                                 sprintf((char*)param_value,"%s",testName);
00641                         }
00642                         break;
00643                 };
00644         default:
00645                 {
00646                         printf("unsupported\n");
00647                 }
00648         }
00649         
00650         return 0;
00651 }
00652 
00653 
00654 
00655 CL_API_ENTRY cl_context CL_API_CALL clCreateContextFromType(const cl_context_properties * /* properties */,
00656                         cl_device_type           device_type ,
00657                         void (*pfn_notify)(const char *, const void *, size_t, void *) /* pfn_notify */,
00658                         void *                  /* user_data */,
00659                         cl_int *                 errcode_ret ) CL_API_SUFFIX__VERSION_1_0
00660 {
00661         int maxNumOutstandingTasks = 4;
00662 //      int maxNumOutstandingTasks = 2;
00663 //      int maxNumOutstandingTasks = 1;
00664         gMiniCLNumOutstandingTasks = maxNumOutstandingTasks;
00665         const int maxNumOfThreadSupports = 8;
00666         static int sUniqueThreadSupportIndex = 0;
00667         static const char* sUniqueThreadSupportName[maxNumOfThreadSupports] = 
00668         {
00669                 "MiniCL_0", "MiniCL_1", "MiniCL_2", "MiniCL_3", "MiniCL_4", "MiniCL_5", "MiniCL_6", "MiniCL_7" 
00670         };
00671 
00672         btThreadSupportInterface* threadSupport = 0;
00673 
00674         if (device_type==CL_DEVICE_TYPE_DEBUG)
00675         {
00676                 SequentialThreadSupport::SequentialThreadConstructionInfo stc("MiniCL",processMiniCLTask,createMiniCLLocalStoreMemory);
00677                 threadSupport = new SequentialThreadSupport(stc);
00678         } else
00679         {
00680 
00681 #if _WIN32
00682         btAssert(sUniqueThreadSupportIndex < maxNumOfThreadSupports);
00683         const char* bla = "MiniCL";
00684         threadSupport = new Win32ThreadSupport(Win32ThreadSupport::Win32ThreadConstructionInfo(
00685 //                                                              bla,
00686                                                                 sUniqueThreadSupportName[sUniqueThreadSupportIndex++],
00687                                                                 processMiniCLTask, //processCollisionTask,
00688                                                                 createMiniCLLocalStoreMemory,//createCollisionLocalStoreMemory,
00689                                                                 maxNumOutstandingTasks));
00690 #else
00691 
00692 #ifdef USE_PTHREADS
00693                 PosixThreadSupport::ThreadConstructionInfo constructionInfo("PosixThreads",
00694                                                                                                                                         processMiniCLTask,
00695                                                                                                                                         createMiniCLLocalStoreMemory,
00696                                                                                                                                         maxNumOutstandingTasks);
00697                 threadSupport = new PosixThreadSupport(constructionInfo);
00698 
00699 #else
00700 
00701         SequentialThreadSupport::SequentialThreadConstructionInfo stc("MiniCL",processMiniCLTask,createMiniCLLocalStoreMemory);
00702         threadSupport = new SequentialThreadSupport(stc);
00703 #endif //USE_PTHREADS
00704 #endif
00705 
00706         }
00707         
00708         
00709         MiniCLTaskScheduler* scheduler = new MiniCLTaskScheduler(threadSupport,maxNumOutstandingTasks);
00710 
00711         *errcode_ret = 0;
00712         return (cl_context)scheduler;
00713 }
00714 
00715 CL_API_ENTRY cl_int CL_API_CALL
00716 clGetDeviceIDs(cl_platform_id   /* platform */,
00717                cl_device_type   /* device_type */, 
00718                cl_uint          /* num_entries */, 
00719                cl_device_id *   /* devices */, 
00720                cl_uint *        /* num_devices */) CL_API_SUFFIX__VERSION_1_0
00721 {
00722         return 0;
00723 }
00724 
00725 CL_API_ENTRY cl_context CL_API_CALL
00726 clCreateContext(const cl_context_properties *  properties ,
00727                 cl_uint                        num_devices ,
00728                 const cl_device_id *           devices ,
00729                  void (*pfn_notify)(const char *, const void *, size_t, void *),
00730                 void *                         user_data ,
00731                 cl_int *                       errcode_ret ) CL_API_SUFFIX__VERSION_1_0
00732 {
00733         
00734         return  clCreateContextFromType(properties,CL_DEVICE_TYPE_ALL,pfn_notify,user_data,errcode_ret);
00735 }
00736 
00737 CL_API_ENTRY cl_int CL_API_CALL clReleaseContext(cl_context  context ) CL_API_SUFFIX__VERSION_1_0
00738 {
00739 
00740         MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) context;
00741         
00742         btThreadSupportInterface* threadSupport = scheduler->getThreadSupportInterface();
00743         delete scheduler;
00744         delete threadSupport;
00745         
00746         return 0;
00747 }
00748 extern CL_API_ENTRY cl_int CL_API_CALL
00749 clFinish(cl_command_queue command_queue ) CL_API_SUFFIX__VERSION_1_0
00750 {
00751         MiniCLTaskScheduler* scheduler = (MiniCLTaskScheduler*) command_queue;
00753         scheduler->flush();
00754         return CL_SUCCESS;
00755 }
00756 
00757 extern CL_API_ENTRY cl_int CL_API_CALL 
00758 clGetProgramInfo(cl_program         /* program */,
00759                  cl_program_info    /* param_name */,
00760                  size_t             /* param_value_size */,
00761                  void *             /* param_value */,
00762                  size_t *           /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0
00763 {
00764    return 0;
00765 }
00766 
00767 extern CL_API_ENTRY cl_int CL_API_CALL
00768 clGetKernelWorkGroupInfo(cl_kernel                   kernel ,
00769                          cl_device_id               /* device */,
00770                          cl_kernel_work_group_info  wgi/* param_name */,
00771                          size_t   sz                  /* param_value_size */,
00772                          void *     ptr                /* param_value */,
00773                          size_t *                   /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0
00774 {
00775         if((wgi == CL_KERNEL_WORK_GROUP_SIZE)
00776          &&(sz == sizeof(size_t))
00777          &&(ptr != NULL))
00778         {
00779                 MiniCLKernel* miniCLKernel = (MiniCLKernel*)kernel;
00780                 MiniCLTaskScheduler* scheduler = miniCLKernel->m_scheduler;
00781                 *((size_t*)ptr) = scheduler->getMaxNumOutstandingTasks();
00782                 return CL_SUCCESS;
00783         }
00784         else
00785         {
00786                 return CL_INVALID_VALUE;
00787         }
00788 }