10#include <config_folders.h>
18#include <osl/file.hxx>
19#include <rtl/bootstrap.hxx>
20#include <rtl/digest.h>
21#include <rtl/strbuf.hxx>
22#include <rtl/ustring.hxx>
32#include <officecfg/Office/Common.hxx>
37#define OPENCL_DLL_NAME "OpenCL.dll"
39#define OPENCL_DLL_NAME nullptr
41#define OPENCL_DLL_NAME "libOpenCL.so.1"
44#ifdef _WIN32_WINNT_WINBLUE
45#include <VersionHelpers.h>
48#define DEVICE_NAME_LENGTH 1024
49#define DRIVER_VERSION_LENGTH 1024
50#define PLATFORM_VERSION_LENGTH 1024
52#define CHECK_OPENCL(status,name) \
53if( status != CL_SUCCESS ) \
55 SAL_WARN( "opencl", "OpenCL error code " << status << " at " SAL_DETAIL_WHERE "from " name ); \
61bool bIsInited =
false;
73OString generateMD5(
const void*
pData,
size_t length)
76 rtlDigestError aError = rtl_digest_MD5(
pData,
length,
77 pBuffer, RTL_DIGEST_LENGTH_MD5);
78 SAL_WARN_IF(aError != rtl_Digest_E_None,
"opencl",
"md5 generation failed");
81 const char*
const pString =
"0123456789ABCDEF";
84 aBuffer.append(OStringChar(pString[val/16]) + OStringChar(pString[val%16]));
86 return aBuffer.makeStringAndClear();
89OString
const & getCacheFolder()
91 static OString
const aCacheFolder = []()
93 OUString url(
"${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER
"/" SAL_CONFIGFILE(
"bootstrap")
":UserInstallation}/cache/");
94 rtl::Bootstrap::expandMacros(url);
96 osl::Directory::create(url);
118 if (command_queue[
i] ==
nullptr ||
nState != CL_SUCCESS)
121 for (
int j = 0; j <=
i; ++j)
123 if (command_queue[j])
125 clReleaseCommandQueue(command_queue[j]);
126 command_queue[j] =
nullptr;
131 SAL_WARN(
"opencl",
"failed to set/switch opencl device");
135 SAL_INFO(
"opencl",
"Created command queue " << command_queue[
i] <<
" for context " << aGpuEnv.
mpContext);
162OString createFileName(cl_device_id deviceId,
const char* clFileName)
164 OString fileName(clFileName);
165 sal_Int32
nIndex = fileName.lastIndexOf(
".cl");
167 fileName = fileName.copy(0, nIndex);
170 clGetDeviceInfo(deviceId, CL_DEVICE_NAME,
171 sizeof(deviceName), deviceName,
nullptr);
174 clGetDeviceInfo(deviceId, CL_DRIVER_VERSION,
175 sizeof(driverVersion), driverVersion,
nullptr);
177 cl_platform_id platformId;
178 clGetDeviceInfo(deviceId, CL_DEVICE_PLATFORM,
179 sizeof(platformId), &platformId,
nullptr);
182 clGetPlatformInfo(platformId, CL_PLATFORM_VERSION,
sizeof(platformVersion),
183 platformVersion,
nullptr);
186 OString aString = OString::Concat(deviceName) + driverVersion + platformVersion;
187 OString aHash = generateMD5(aString.getStr(), aString.getLength());
189 return getCacheFolder() + fileName +
"-" + aHash +
".bin";
192std::vector<std::shared_ptr<osl::File> > binaryGenerated(
const char * clFileName, cl_context context )
196 std::vector<std::shared_ptr<osl::File> > aGeneratedFiles;
197 cl_int clStatus = clGetContextInfo( context, CL_CONTEXT_DEVICES,
198 0,
nullptr, &numDevices );
199 numDevices /=
sizeof(numDevices);
201 if(clStatus != CL_SUCCESS)
202 return aGeneratedFiles;
204 assert(numDevices == 1);
208 clStatus = clGetContextInfo( context, CL_CONTEXT_DEVICES,
209 sizeof( cl_device_id ), &pDevID,
nullptr );
211 if(clStatus != CL_SUCCESS)
212 return aGeneratedFiles;
216 OString fileName = createFileName(
gpuEnv.
mpDevID, clFileName);
217 auto pNewFile = std::make_shared<osl::File>(OStringToOUString(fileName, RTL_TEXTENCODING_UTF8));
218 if(pNewFile->open(osl_File_OpenFlag_Read) == osl::FileBase::E_None)
220 aGeneratedFiles.push_back(pNewFile);
221 SAL_INFO(
"opencl.file",
"Opening binary file '" << fileName <<
"' for reading: success");
225 SAL_INFO(
"opencl.file",
"Opening binary file '" << fileName <<
"' for reading: FAIL");
228 return aGeneratedFiles;
231bool writeBinaryToFile( std::string_view rFileName,
const char* binary,
size_t numBytes )
233 osl::File file(OStringToOUString(rFileName, RTL_TEXTENCODING_UTF8));
234 osl::FileBase::RC status = file.open(
235 osl_File_OpenFlag_Write | osl_File_OpenFlag_Create );
237 if(status != osl::FileBase::E_None)
240 sal_uInt64 nBytesWritten = 0;
241 file.write( binary, numBytes, nBytesWritten );
243 assert(numBytes == nBytesWritten);
254 cl_int clStatus = clGetProgramInfo( program, CL_PROGRAM_NUM_DEVICES,
255 sizeof(numDevices), &numDevices,
nullptr );
258 assert(numDevices == 1);
262 clStatus = clGetProgramInfo( program, CL_PROGRAM_DEVICES,
263 sizeof(cl_device_id), &pDevID,
nullptr );
269 clStatus = clGetProgramInfo( program, CL_PROGRAM_BINARY_SIZES,
270 sizeof(
size_t), &binarySize,
nullptr );
274 if ( binarySize != 0 )
276 std::unique_ptr<char[]> binary(
new char[binarySize]);
277 clStatus = clGetProgramInfo( program, CL_PROGRAM_BINARIES,
278 sizeof(
char *), &binary,
nullptr );
281 OString fileName = createFileName(pDevID, clFileName);
282 if ( !writeBinaryToFile( fileName,
283 binary.get(), binarySize ) )
284 SAL_INFO(
"opencl.file",
"Writing binary file '" << fileName <<
"': FAIL");
286 SAL_INFO(
"opencl.file",
"Writing binary file '" << fileName <<
"': success");
300bool initOpenCLAttr( OpenCLEnv * env )
318bool buildProgram(
const char* buildOption, GPUEnv* gpuInfo,
int idx)
323 clStatus = clBuildProgram(gpuInfo->mpArryPrograms[idx], 1, &gpuInfo->mpDevID,
324 buildOption,
nullptr,
nullptr);
326 if ( clStatus != CL_SUCCESS )
329 clStatus = clGetProgramBuildInfo( gpuInfo->mpArryPrograms[idx], gpuInfo->mpDevID,
330 CL_PROGRAM_BUILD_LOG, 0,
nullptr, &length);
331 if ( clStatus != CL_SUCCESS )
336 std::unique_ptr<char[]> buildLog(
new char[length]);
337 clStatus = clGetProgramBuildInfo( gpuInfo->mpArryPrograms[idx], gpuInfo->mpDevID,
338 CL_PROGRAM_BUILD_LOG, length, buildLog.get(), &length );
339 if ( clStatus != CL_SUCCESS )
344 OString aBuildLogFileURL = getCacheFolder() +
"kernel-build.log";
345 osl::File aBuildLogFile(OStringToOUString(aBuildLogFileURL, RTL_TEXTENCODING_UTF8));
346 osl::FileBase::RC status = aBuildLogFile.open(
347 osl_File_OpenFlag_Write | osl_File_OpenFlag_Create );
349 if(status != osl::FileBase::E_None)
352 sal_uInt64 nBytesWritten = 0;
353 aBuildLogFile.write( buildLog.get(), length, nBytesWritten );
366 cl_int clStatus = clGetContextInfo( gpuInfo->
mpContext, CL_CONTEXT_DEVICES,
367 0,
nullptr, &numDevices );
368 numDevices /=
sizeof(numDevices);
371 std::vector<std::shared_ptr<osl::File> > aGeneratedFiles = binaryGenerated(
374 if (aGeneratedFiles.size() == numDevices)
376 std::unique_ptr<size_t[]>
length(
new size_t[numDevices]);
377 std::unique_ptr<unsigned char*[]> pBinary(
new unsigned char*[numDevices]);
378 for(
size_t i = 0;
i < numDevices; ++
i)
381 aGeneratedFiles[
i]->getSize(nSize);
382 unsigned char* binary =
new unsigned char[nSize];
383 sal_uInt64 nBytesRead;
384 aGeneratedFiles[
i]->read(binary, nSize, nBytesRead);
385 if(nSize != nBytesRead)
394 std::unique_ptr<cl_device_id[]> pArryDevsID(
new cl_device_id[numDevices]);
395 clStatus = clGetContextInfo( gpuInfo->
mpContext, CL_CONTEXT_DEVICES,
396 sizeof( cl_device_id ) * numDevices, pArryDevsID.get(),
nullptr );
398 if(clStatus != CL_SUCCESS)
400 for(
size_t i = 0;
i < numDevices; ++
i)
407 cl_int binary_status;
410 pArryDevsID.get(),
length.get(),
const_cast<const unsigned char**
>(pBinary.get()),
411 &binary_status, &clStatus );
412 if(clStatus != CL_SUCCESS)
418 for(
size_t i = 0;
i < numDevices; ++
i)
428 return buildProgram(buildOption, gpuInfo,
idx);
433void checkDeviceForDoubleSupport(cl_device_id deviceId,
bool& bKhrFp64,
bool& bAmdFp64)
441 size_t aDevExtInfoSize = 0;
443 cl_uint clStatus = clGetDeviceInfo( deviceId, CL_DEVICE_EXTENSIONS, 0,
nullptr, &aDevExtInfoSize );
444 if( clStatus != CL_SUCCESS )
447 std::unique_ptr<char[]> pExtInfo(
new char[aDevExtInfoSize]);
449 clStatus = clGetDeviceInfo( deviceId, CL_DEVICE_EXTENSIONS,
450 sizeof(
char) * aDevExtInfoSize, pExtInfo.get(),
nullptr);
452 if( clStatus != CL_SUCCESS )
455 if ( strstr( pExtInfo.get(),
"cl_khr_fp64" ) )
462 if ( strstr( pExtInfo.get(),
"cl_amd_fp64" ) )
467bool initOpenCLRunEnv( GPUEnv *gpuInfo )
470 cl_uint nPreferredVectorWidthFloat;
473 bool bKhrFp64 =
false;
474 bool bAmdFp64 =
false;
476 checkDeviceForDoubleSupport(gpuInfo->mpDevID, bKhrFp64, bAmdFp64);
478 gpuInfo->mnKhrFp64Flag = bKhrFp64;
479 gpuInfo->mnAmdFp64Flag = bAmdFp64;
481 gpuInfo->mbNeedsTDRAvoidance =
false;
483 clGetDeviceInfo(gpuInfo->mpDevID, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT,
sizeof(cl_uint),
484 &nPreferredVectorWidthFloat,
nullptr);
485 SAL_INFO(
"opencl",
"CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT=" << nPreferredVectorWidthFloat);
487 clGetPlatformInfo(gpuInfo->mpPlatformID, CL_PLATFORM_NAME, 64,
492# ifdef _WIN32_WINNT_WINBLUE
493 const bool bIsNotWinOrIsWin8OrGreater = IsWindows8OrGreater();
495 bool bIsNotWinOrIsWin8OrGreater =
true;
496 OSVERSIONINFOW aVersionInfo = {};
497 aVersionInfo.dwOSVersionInfoSize =
sizeof( aVersionInfo );
498 if (GetVersionExW( &aVersionInfo ))
501 if (aVersionInfo.dwMajorVersion < 6 ||
502 (aVersionInfo.dwMajorVersion == 6 && aVersionInfo.dwMinorVersion < 2))
503 bIsNotWinOrIsWin8OrGreater =
false;
507 const bool bIsNotWinOrIsWin8OrGreater =
true;
514 gpuInfo->mbNeedsTDRAvoidance = ( nPreferredVectorWidthFloat == 4 ) ||
515 ( !bIsNotWinOrIsWin8OrGreater &&
516 OUString::createFromAscii(pName).indexOf(
"NVIDIA") > -1 );
518 size_t nMaxParameterSize;
519 clGetDeviceInfo(gpuInfo->mpDevID, CL_DEVICE_MAX_PARAMETER_SIZE,
sizeof(
size_t),
520 &nMaxParameterSize,
nullptr);
521 SAL_INFO(
"opencl",
"CL_DEVICE_MAX_PARAMETER_SIZE=" << nMaxParameterSize);
526bool initOpenCLRunEnv(
int argc )
537 bool status = initOpenCLRunEnv( &
gpuEnv );
543 if( getenv(
"SC_FLOAT" ) )
550 SAL_INFO(
"opencl",
"Use Khr double");
554 SAL_INFO(
"opencl",
"Use AMD double type");
558 SAL_INFO(
"opencl",
"USE float type");
569 aDeviceInfo.
device = aDeviceId;
573 if(nState != CL_SUCCESS)
576 aDeviceInfo.
maName = OUString::createFromAscii(pName);
580 if(nState != CL_SUCCESS)
583 aDeviceInfo.
maVendor = OUString::createFromAscii(pVendor);
586 nState = clGetDeviceInfo(aDeviceId, CL_DEVICE_GLOBAL_MEM_SIZE,
sizeof(nMemSize), &nMemSize,
nullptr);
587 if(nState != CL_SUCCESS)
592 cl_uint nClockFrequency;
593 nState = clGetDeviceInfo(aDeviceId, CL_DEVICE_MAX_CLOCK_FREQUENCY,
sizeof(nClockFrequency), &nClockFrequency,
nullptr);
594 if(nState != CL_SUCCESS)
599 cl_uint nComputeUnits;
600 nState = clGetDeviceInfo(aDeviceId, CL_DEVICE_MAX_COMPUTE_UNITS,
sizeof(nComputeUnits), &nComputeUnits,
nullptr);
601 if(nState != CL_SUCCESS)
607 if(nState != CL_SUCCESS)
610 aDeviceInfo.
maDriver = OUString::createFromAscii(pDriver);
612 bool bKhrFp64 =
false;
613 bool bAmdFp64 =
false;
614 checkDeviceForDoubleSupport(aDeviceId, bKhrFp64, bAmdFp64);
617 if(!bKhrFp64 && !bAmdFp64)
623 rPlatformInfo.
maDevices.push_back(aDeviceInfo);
628 rPlatformInfo.
platform = nPlatformId;
630 cl_int
nState = clGetPlatformInfo(nPlatformId, CL_PLATFORM_NAME, 64,
632 if(nState != CL_SUCCESS)
634 rPlatformInfo.
maName = OUString::createFromAscii(pName);
637 nState = clGetPlatformInfo(nPlatformId, CL_PLATFORM_VENDOR, 64,
639 if(nState != CL_SUCCESS)
642 rPlatformInfo.
maVendor = OUString::createFromAscii(pVendor);
645 nState = clGetDeviceIDs(nPlatformId, CL_DEVICE_TYPE_ALL, 0,
nullptr, &nDevices);
646 if(nState != CL_SUCCESS)
651 cl_device_id* pDevices =
new cl_device_id[nDevices];
652 nState = clGetDeviceIDs(nPlatformId, CL_DEVICE_TYPE_ALL, nDevices, pDevices,
nullptr);
653 if(nState != CL_SUCCESS)
656 for(
size_t i = 0;
i < nDevices; ++
i)
658 createDeviceInfo(pDevices[i], rPlatformInfo);
668 static std::vector<OpenCLPlatformInfo> aPlatforms;
679 cl_int
nState = clGetPlatformIDs(0,
nullptr, &nPlatforms);
686 cl_platform_id* pPlatforms =
new cl_platform_id[nPlatforms];
687 nState = clGetPlatformIDs(nPlatforms, pPlatforms,
nullptr);
692 for(
size_t i = 0;
i < nPlatforms; ++
i)
695 if(createPlatformInfo(pPlatforms[
i], aPlatformInfo))
696 aPlatforms.push_back(aPlatformInfo);
704cl_device_id findDeviceIdByDeviceString(std::u16string_view rString,
const std::vector<OpenCLPlatformInfo>& rPlatforms)
710 OUString aDeviceId = rDeviceInfo.
maVendor +
" " + rDeviceInfo.
maName;
711 if (rString == aDeviceId)
713 return rDeviceInfo.
device;
721void findDeviceInfoFromDeviceId(cl_device_id aDeviceId,
size_t& rDeviceId,
size_t& rPlatformId)
723 cl_platform_id platformId;
724 cl_int
nState = clGetDeviceInfo(aDeviceId, CL_DEVICE_PLATFORM,
725 sizeof(platformId), &platformId,
nullptr);
727 if(nState != CL_SUCCESS)
730 const std::vector<OpenCLPlatformInfo>& rPlatforms =
fillOpenCLInfo();
731 for(
size_t i = 0;
i < rPlatforms.size(); ++
i)
733 cl_platform_id platId = rPlatforms[
i].platform;
734 if(platId != platformId)
737 for(
size_t j = 0; j < rPlatforms[
i].maDevices.size(); ++j)
739 cl_device_id
id = rPlatforms[
i].maDevices[j].device;
754 if(
const char*
env = getenv(
"SC_FORCE_CALCULATION" ))
756 if( strcmp(
env,
"opencl" ) == 0 )
759 return !getenv(
"SAL_DISABLE_OPENCL") && officecfg::Office::Common::Misc::UseOpenCL::get();
762bool switchOpenCLDevice(std::u16string_view aDevice,
bool bAutoSelect,
bool bForceEvaluation, OUString& rOutSelectedDeviceVersionIDString)
767 cl_device_id pDeviceId = findDeviceIdByDeviceString(aDevice,
fillOpenCLInfo());
769 if(!pDeviceId || bAutoSelect)
775 OUString url(OStringToOUString(getCacheFolder(), RTL_TEXTENCODING_UTF8));
777 osl::FileBase::getSystemPathFromFileURL(url,path);
788 return pDeviceId !=
nullptr;
792 cl_platform_id platformId;
796 cl_int
nState = clGetDeviceInfo(pDeviceId, CL_DEVICE_PLATFORM,
797 sizeof(platformId), &platformId,
nullptr);
799 cl_context_properties cps[3];
800 cps[0] = CL_CONTEXT_PLATFORM;
801 cps[1] =
reinterpret_cast<cl_context_properties
>(platformId);
803 context = clCreateContext( cps, 1, &pDeviceId,
nullptr,
nullptr, &
nState );
807 if(
nState != CL_SUCCESS || context ==
nullptr)
809 if(context !=
nullptr)
810 clReleaseContext(context);
812 SAL_WARN(
"opencl",
"failed to set/switch opencl device");
815 SAL_INFO(
"opencl",
"Created context " << context <<
" for platform " << platformId <<
", device " << pDeviceId);
818 rOutSelectedDeviceVersionIDString = OStringToOUString(sDeviceID, RTL_TEXTENCODING_UTF8);
826 env.mpOclPlatformID = platformId;
827 env.mpOclContext = context;
828 env.mpOclDevsID = pDeviceId;
830 initOpenCLAttr(&
env);
832 return !initOpenCLRunEnv(0);
845 findDeviceInfoFromDeviceId(
id, rDeviceId, rPlatformId);
858 cl_platform_id platformId;
859 if( clGetDeviceInfo(deviceId, CL_DEVICE_PLATFORM,
sizeof(platformId), &platformId,
nullptr) != CL_SUCCESS )
863 if( clGetDeviceInfo(deviceId, CL_DEVICE_NAME,
sizeof(deviceName), deviceName,
nullptr) != CL_SUCCESS )
865 char platformName[64];
866 if( clGetPlatformInfo(platformId, CL_PLATFORM_NAME, 64, platformName,
nullptr) != CL_SUCCESS )
868 rDeviceName = OUString::createFromAscii(deviceName);
869 rPlatformName = OUString::createFromAscii(platformName);
883#define CASE(val) case CL_##val: return #val
887 CASE(DEVICE_NOT_FOUND);
888 CASE(DEVICE_NOT_AVAILABLE);
889 CASE(COMPILER_NOT_AVAILABLE);
890 CASE(MEM_OBJECT_ALLOCATION_FAILURE);
891 CASE(OUT_OF_RESOURCES);
892 CASE(OUT_OF_HOST_MEMORY);
893 CASE(PROFILING_INFO_NOT_AVAILABLE);
894 CASE(MEM_COPY_OVERLAP);
895 CASE(IMAGE_FORMAT_MISMATCH);
896 CASE(IMAGE_FORMAT_NOT_SUPPORTED);
897 CASE(BUILD_PROGRAM_FAILURE);
900 CASE(INVALID_DEVICE_TYPE);
901 CASE(INVALID_PLATFORM);
902 CASE(INVALID_DEVICE);
903 CASE(INVALID_CONTEXT);
904 CASE(INVALID_QUEUE_PROPERTIES);
905 CASE(INVALID_COMMAND_QUEUE);
906 CASE(INVALID_HOST_PTR);
907 CASE(INVALID_MEM_OBJECT);
908 CASE(INVALID_IMAGE_FORMAT_DESCRIPTOR);
909 CASE(INVALID_IMAGE_SIZE);
910 CASE(INVALID_SAMPLER);
911 CASE(INVALID_BINARY);
912 CASE(INVALID_BUILD_OPTIONS);
913 CASE(INVALID_PROGRAM);
914 CASE(INVALID_PROGRAM_EXECUTABLE);
915 CASE(INVALID_KERNEL_NAME);
916 CASE(INVALID_KERNEL_DEFINITION);
917 CASE(INVALID_KERNEL);
918 CASE(INVALID_ARG_INDEX);
919 CASE(INVALID_ARG_VALUE);
920 CASE(INVALID_ARG_SIZE);
921 CASE(INVALID_KERNEL_ARGS);
922 CASE(INVALID_WORK_DIMENSION);
923 CASE(INVALID_WORK_GROUP_SIZE);
924 CASE(INVALID_WORK_ITEM_SIZE);
925 CASE(INVALID_GLOBAL_OFFSET);
926 CASE(INVALID_EVENT_WAIT_LIST);
928 CASE(INVALID_OPERATION);
929 CASE(INVALID_GL_OBJECT);
930 CASE(INVALID_BUFFER_SIZE);
931 CASE(INVALID_MIP_LEVEL);
932 CASE(INVALID_GLOBAL_WORK_SIZE);
934 return "Unknown OpenCL error code";
959 clReleaseCommandQueue(
i);
#define SAL_CONFIGFILE(name)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
const css::uno::Reference< css::xml::crypto::XSecurityEnvironment > & env
std::unique_ptr< sal_Int32[]> pData
bool switchOpenCLDevice(std::u16string_view aDevice, bool bAutoSelect, bool bForceEvaluation, OUString &rOutSelectedDeviceVersionIDString)
Used to set or switch between OpenCL devices.
const char * errorString(cl_int nError)
Return a textual representation of an OpenCL error code.
static bool initializeCommandQueue(GPUEnv &aGpuEnv)
const std::vector< OpenCLPlatformInfo > & fillOpenCLInfo()
void setOpenCLCmdQueuePosition(int nPos)
Set the current command queue position in case of multiple command queues for a given device.
void getOpenCLDeviceName(OUString &rDeviceName, OUString &rPlatformName)
bool buildProgramFromBinary(const char *buildOption, GPUEnv *gpuInfo, const char *filename, int idx)
void setKernelEnv(KernelEnv *envInfo)
sal_uInt64 kernelFailures
bool generatBinFromKernelSource(cl_program program, const char *clFileName)
void getOpenCLDeviceInfo(size_t &rDeviceId, size_t &rPlatformId)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
ds_device const & getDeviceSelection(std::u16string_view sProfilePath, bool bForceSelection)
OString getDeviceInfoString(cl_device_id aDeviceId, cl_device_info aDeviceInfo)
#define PLATFORM_VERSION_LENGTH
#define DEVICE_NAME_LENGTH
#define DRIVER_VERSION_LENGTH
void releaseOpenCLEnv(openclwrapper::GPUEnv *gpuInfo)
cl_platform_id mpOclPlatformID
#define CHECK_OPENCL(status, name)
#define OPENCL_CMDQUEUE_SIZE
ParserContextSharedPtr mpContext
static OpenCLConfig get()
cl_program mpArryPrograms[MAX_CLFILE_NUM]
cl_platform_id mpPlatformID
static bool isOpenCLEnabled()
bool mbCommandQueueInitialized
cl_command_queue mpCmdQueue[OPENCL_CMDQUEUE_SIZE]
cl_command_queue mpkCmdQueue
std::unique_ptr< char[]> aBuffer