sc/source/core/opencl/openclwrapper.cxx | 296 +++++++++++++++++++------------- sc/source/core/opencl/openclwrapper.hxx | 2 2 files changed, 182 insertions(+), 116 deletions(-)
New commits: commit 5ccbc4ddf6b15a7f013049b79ebd1b7d3286ca7a Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Tue Oct 1 05:56:34 2013 +0200 make sure that we really fall back to new compile if binary failed If anything during binary import fails fall back to compiling from source. That includes a failure during building the binary file. Change-Id: I0f021f17c9be061fc9eb9f28ab470257d61f03cb diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx index f304695..2222ff6 100644 --- a/sc/source/core/opencl/openclwrapper.cxx +++ b/sc/source/core/opencl/openclwrapper.cxx @@ -452,21 +452,104 @@ int OpenclDevice::cachedOfKernerPrg( const GPUEnv *gpuEnvCached, const char * cl return 0; } -int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption ) +namespace { + +bool buildProgram(const char* buildOption, GPUEnv* gpuInfo, int idx) { - cl_int clStatus = 0; - int binary_status, idx; - const char* filename = "kernel.cl"; - fprintf(stderr, "compileKernelFile ... \n"); - if ( cachedOfKernerPrg(gpuInfo, filename) == 1 ) + cl_int clStatus; + //char options[512]; + // create a cl program executable for all the devices specified + printf("BuildProgram.\n"); + if (!gpuInfo->mnIsUserCreated) { - return 1; + clStatus = clBuildProgram(gpuInfo->mpArryPrograms[idx], 1, gpuInfo->mpArryDevsID, + buildOption, NULL, NULL); + } + else + { + clStatus = clBuildProgram(gpuInfo->mpArryPrograms[idx], 1, &(gpuInfo->mpDevID), + buildOption, NULL, NULL); } - idx = gpuInfo->mnFileCount; + if ( clStatus != CL_SUCCESS ) + { + size_t length; + printf ("BuildProgram error!\n"); + if ( !gpuInfo->mnIsUserCreated ) + { + clStatus = clGetProgramBuildInfo( gpuInfo->mpArryPrograms[idx], gpuInfo->mpArryDevsID[0], + CL_PROGRAM_BUILD_LOG, 0, NULL, &length ); + } + else + { + clStatus = clGetProgramBuildInfo( gpuInfo->mpArryPrograms[idx], gpuInfo->mpDevID, + CL_PROGRAM_BUILD_LOG, 0, NULL, &length); + } + if ( clStatus != CL_SUCCESS ) + { + printf("opencl create build log fail\n"); + return 0; + } + + boost::scoped_array<char> buildLog(new char[length]); + if ( !gpuInfo->mnIsUserCreated ) + { + clStatus = clGetProgramBuildInfo( gpuInfo->mpArryPrograms[idx], gpuInfo->mpArryDevsID[0], + CL_PROGRAM_BUILD_LOG, length, buildLog.get(), &length ); + } + else + { + clStatus = clGetProgramBuildInfo( gpuInfo->mpArryPrograms[idx], gpuInfo->mpDevID, + CL_PROGRAM_BUILD_LOG, length, buildLog.get(), &length ); + } + if ( clStatus != CL_SUCCESS ) + { + printf("opencl program build info fail\n"); + return false; + } + + OString aBuildLogFileURL = OpenclDevice::maCacheFolder + "kernel-build.log"; + osl::File aBuildLogFile(rtl::OStringToOUString(aBuildLogFileURL, RTL_TEXTENCODING_UTF8)); + osl::FileBase::RC status = aBuildLogFile.open( + osl_File_OpenFlag_Write | osl_File_OpenFlag_Create ); + + if(status != osl::FileBase::E_None) + return false; + + sal_uInt64 nBytesWritten = 0; + aBuildLogFile.write( buildLog.get(), length, nBytesWritten ); + + return false; + } + + return true; +} + +} + +bool OpenclDevice::buildProgramFromSource(const char* buildOption, GPUEnv* gpuInfo, const char* filename, int idx) +{ + cl_int clStatus = 0; + // create a CL program using the kernel source + fprintf(stderr, "Create kernel from source\n"); + size_t source_size[1]; + + source_size[0] = strlen( kernel_src ); + gpuInfo->mpArryPrograms[idx] = clCreateProgramWithSource( gpuInfo->mpContext, 1, &kernel_src, + source_size, &clStatus); + + if(clStatus != CL_SUCCESS) + return false; + bool bSuccess = buildProgram(buildOption, gpuInfo, idx); + generatBinFromKernelSource( gpuInfo->mpArryPrograms[idx], filename ); + return bSuccess; +} + +bool OpenclDevice::buildProgramFromBinary(const char* buildOption, GPUEnv* gpuInfo, const char* filename, int idx) +{ size_t numDevices; - clStatus = clGetContextInfo( gpuInfo->mpContext, CL_CONTEXT_DEVICES, + cl_int clStatus = clGetContextInfo( gpuInfo->mpContext, CL_CONTEXT_DEVICES, 0, NULL, &numDevices ); numDevices /= sizeof(numDevices); CHECK_OPENCL( clStatus, "clGetContextInfo" ); @@ -474,10 +557,8 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption ) std::vector<boost::shared_ptr<osl::File> > aGeneratedFiles = binaryGenerated( filename, gpuInfo->mpContext ); - bool bBinaryExisted = false; if (aGeneratedFiles.size() == numDevices) { - bBinaryExisted = true; boost::scoped_array<size_t> length(new size_t[numDevices]); boost::scoped_array<unsigned char*> pBinary(new unsigned char*[numDevices]); for(size_t i = 0; i < numDevices; ++i) @@ -506,8 +587,10 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption ) { delete[] pBinary[i]; } + return false; } - CHECK_OPENCL( clStatus, "clGetContextInfo" ); + + cl_int binary_status; fprintf(stderr, "Create kernel from binary\n"); gpuInfo->mpArryPrograms[idx] = clCreateProgramWithBinary( gpuInfo->mpContext,numDevices, @@ -516,7 +599,7 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption ) if(clStatus != CL_SUCCESS) { // something went wrong, fall back to compiling from source - bBinaryExisted = false; + return false; } for(size_t i = 0; i < numDevices; ++i) { @@ -524,96 +607,34 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption ) } } - if(!bBinaryExisted) - { - // create a CL program using the kernel source - fprintf(stderr, "Create kernel from source\n"); - size_t source_size[1]; - - source_size[0] = strlen( kernel_src ); - gpuEnv.mpArryPrograms[idx] = clCreateProgramWithSource( gpuEnv.mpContext, 1, &kernel_src, - source_size, &clStatus); - CHECK_OPENCL( clStatus, "clCreateProgramWithSource" ); - } - - if ( gpuInfo->mpArryPrograms[idx] == (cl_program) NULL ) + if ( !gpuInfo->mpArryPrograms[idx] ) { - return 0; + return false; } + return buildProgram(buildOption, gpuInfo, idx); +} - //char options[512]; - // create a cl program executable for all the devices specified - printf("BuildProgram.\n"); - if (!gpuInfo->mnIsUserCreated) - { - clStatus = clBuildProgram(gpuInfo->mpArryPrograms[idx], 1, gpuInfo->mpArryDevsID, - buildOption, NULL, NULL); - } - else +int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption ) +{ + int idx; + const char* filename = "kernel.cl"; + fprintf(stderr, "compileKernelFile ... \n"); + if ( cachedOfKernerPrg(gpuInfo, filename) == 1 ) { - clStatus = clBuildProgram(gpuInfo->mpArryPrograms[idx], 1, &(gpuInfo->mpDevID), - buildOption, NULL, NULL); + return 1; } - if ( clStatus != CL_SUCCESS ) - { - size_t length; - printf ("BuildProgram error!\n"); - if ( !gpuInfo->mnIsUserCreated ) - { - clStatus = clGetProgramBuildInfo( gpuInfo->mpArryPrograms[idx], gpuInfo->mpArryDevsID[0], - CL_PROGRAM_BUILD_LOG, 0, NULL, &length ); - } - else - { - clStatus = clGetProgramBuildInfo( gpuInfo->mpArryPrograms[idx], gpuInfo->mpDevID, - CL_PROGRAM_BUILD_LOG, 0, NULL, &length); - } - if ( clStatus != CL_SUCCESS ) - { - printf("opencl create build log fail\n"); - return 0; - } - - boost::scoped_array<char> buildLog(new char[length]); - if ( !gpuInfo->mnIsUserCreated ) - { - clStatus = clGetProgramBuildInfo( gpuInfo->mpArryPrograms[idx], gpuInfo->mpArryDevsID[0], - CL_PROGRAM_BUILD_LOG, length, buildLog.get(), &length ); - } - else - { - clStatus = clGetProgramBuildInfo( gpuInfo->mpArryPrograms[idx], gpuInfo->mpDevID, - CL_PROGRAM_BUILD_LOG, length, buildLog.get(), &length ); - } - if ( clStatus != CL_SUCCESS ) - { - printf("opencl program build info fail\n"); - return 0; - } - - OString aBuildLogFileURL = maCacheFolder + "kernel-build.log"; - osl::File aBuildLogFile(rtl::OStringToOUString(aBuildLogFileURL, RTL_TEXTENCODING_UTF8)); - osl::FileBase::RC status = aBuildLogFile.open( - osl_File_OpenFlag_Write | osl_File_OpenFlag_Create ); - - if(status != osl::FileBase::E_None) - return 0; - - sal_uInt64 nBytesWritten = 0; - aBuildLogFile.write( buildLog.get(), length, nBytesWritten ); - - return 0; - } + idx = gpuInfo->mnFileCount; - strcpy( gpuEnv.mArryKnelSrcFile[idx], filename ); + bool bSuccess = buildProgramFromBinary(buildOption, gpuInfo, filename, idx); + if(!bSuccess) + bSuccess = buildProgramFromSource(buildOption, gpuInfo, filename, idx); - if ( !bBinaryExisted ) - generatBinFromKernelSource( gpuEnv.mpArryPrograms[idx], filename ); + strcpy( gpuInfo->mArryKnelSrcFile[idx], filename ); gpuInfo->mnFileCount += 1; - return 1; + return bSuccess; } int OpenclDevice::initOpenclRunEnv( int argc ) diff --git a/sc/source/core/opencl/openclwrapper.hxx b/sc/source/core/opencl/openclwrapper.hxx index c81c313..dd95954 100644 --- a/sc/source/core/opencl/openclwrapper.hxx +++ b/sc/source/core/opencl/openclwrapper.hxx @@ -179,6 +179,8 @@ public: static int writeBinaryToFile( const OString& rName, const char* birary, size_t numBytes ); static std::vector<boost::shared_ptr<osl::File> > binaryGenerated( const char * clFileName, cl_context context); static int compileKernelFile( const char *filename, GPUEnv *gpuInfo, const char *buildOption ); + static bool buildProgramFromSource(const char* buildOption, GPUEnv* gpuEnv, const char* filename, int idx); + static bool buildProgramFromBinary(const char* buildOption, GPUEnv* gpuEnv, const char* filename, int idx); static int initOpenclAttr( OpenCLEnv * env ); static int setKernelEnv( KernelEnv *envInfo ); commit ac1956152c3e74010f4c8c1a1a69e6ab4fdbd6ec Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Tue Oct 1 01:36:04 2013 +0200 make source code opencl 1.0 compliant Change-Id: Id6055194eb225b85a5c66c5cf9fb44ad342df1a7 diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx index ff2cf1b..f304695 100644 --- a/sc/source/core/opencl/openclwrapper.cxx +++ b/sc/source/core/opencl/openclwrapper.cxx @@ -258,11 +258,12 @@ OString createFileName(cl_device_id deviceId, const char* clFileName) std::vector<boost::shared_ptr<osl::File> > OpenclDevice::binaryGenerated( const char * clFileName, cl_context context ) { - cl_uint numDevices=0; + size_t numDevices=0; std::vector<boost::shared_ptr<osl::File> > aGeneratedFiles; - cl_int clStatus = clGetContextInfo( context, CL_CONTEXT_NUM_DEVICES, - sizeof(numDevices), &numDevices, NULL ); + cl_int clStatus = clGetContextInfo( context, CL_CONTEXT_DEVICES, + 0, NULL, &numDevices ); + numDevices /= sizeof(numDevices); if(clStatus != CL_SUCCESS) return aGeneratedFiles; @@ -464,9 +465,10 @@ int OpenclDevice::compileKernelFile( GPUEnv *gpuInfo, const char *buildOption ) idx = gpuInfo->mnFileCount; - cl_uint numDevices; - clStatus = clGetContextInfo( gpuInfo->mpContext, CL_CONTEXT_NUM_DEVICES, - sizeof(numDevices), &numDevices, NULL ); + size_t numDevices; + clStatus = clGetContextInfo( gpuInfo->mpContext, CL_CONTEXT_DEVICES, + 0, NULL, &numDevices ); + numDevices /= sizeof(numDevices); CHECK_OPENCL( clStatus, "clGetContextInfo" ); std::vector<boost::shared_ptr<osl::File> > aGeneratedFiles = binaryGenerated( commit b35a8347cbf475cc9f54bc84d30d0af0faea29a3 Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Tue Oct 1 00:55:27 2013 +0200 hash platform version, device name, driver version into binary name Change-Id: Id34e7c6dad0587e2a8ea583c6df9bdc145f193bc diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx index aec9ee2..ff2cf1b 100644 --- a/sc/source/core/opencl/openclwrapper.cxx +++ b/sc/source/core/opencl/openclwrapper.cxx @@ -35,6 +35,8 @@ #endif #define DEVICE_NAME_LENGTH 1024 +#define DRIVER_VERSION_LENGTH 1024 +#define PLATFORM_VERSION_LENGTH 1024 using namespace std; @@ -47,16 +49,12 @@ int OpenclDevice::isInited =0; namespace { -OString generateHashForSource() +OString generateMD5(const void* pData, size_t length) { sal_uInt8 pBuffer[RTL_DIGEST_LENGTH_MD5]; - -#ifndef NDEBUG - size_t nLength = strlen(kernel_src); - rtlDigestError aError = rtl_digest_MD5(kernel_src, nLength, + rtlDigestError aError = rtl_digest_MD5(pData, length, pBuffer, RTL_DIGEST_LENGTH_MD5); - assert(aError == rtl_Digest_E_None); -#endif + SAL_WARN_IF(aError != rtl_Digest_E_None, "sc", "md5 generation failed"); OStringBuffer aBuffer; const char* pString = "0123456789ABCDEF"; @@ -69,6 +67,12 @@ OString generateHashForSource() return aBuffer.makeStringAndClear(); } +OString generateHashForSource() +{ + size_t nLength = strlen(kernel_src); + return generateMD5(kernel_src, nLength); +} + OString getCacheFolder() { OUString url("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/cache/"); @@ -229,8 +233,25 @@ OString createFileName(cl_device_id deviceId, const char* clFileName) char deviceName[DEVICE_NAME_LENGTH] = {0}; clGetDeviceInfo(deviceId, CL_DEVICE_NAME, sizeof(deviceName), deviceName, NULL); + + char driverVersion[DRIVER_VERSION_LENGTH] = {0}; + clGetDeviceInfo(deviceId, CL_DRIVER_VERSION, + sizeof(driverVersion), driverVersion, NULL); + + cl_platform_id platformId; + clGetDeviceInfo(deviceId, CL_DEVICE_PLATFORM, + sizeof(platformId), &platformId, NULL); + + char platformVersion[PLATFORM_VERSION_LENGTH] = {0}; + clGetPlatformInfo(platformId, CL_PLATFORM_VERSION, sizeof(platformVersion), + platformVersion, NULL); + + // create hash for deviceName + driver version + platform version + OString aString = OString(deviceName) + driverVersion + platformVersion; + OString aHash = generateMD5(aString.getStr(), aString.getLength()); + return OpenclDevice::maCacheFolder + fileName + "-" + - deviceName + "-" + OpenclDevice::maSourceHash + ".bin"; + aHash + "-" + OpenclDevice::maSourceHash + ".bin"; } } commit fce3beef3caf0fb8360aa097e547979ed2610e1b Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Mon Sep 30 22:46:38 2013 +0200 remove unused macros Change-Id: I8f195cf6f8f6962d73171fec65b46fbd96f74613 diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx index 4596b8b..aec9ee2 100644 --- a/sc/source/core/opencl/openclwrapper.cxx +++ b/sc/source/core/opencl/openclwrapper.cxx @@ -29,17 +29,6 @@ #ifdef WIN32 #include <Windows.h> -#define TRUE 1 -#define FALSE 0 - -#define OCL_INFO(str) \ - printf("[OCL_INFO] %s\n",str); -#define OCL_ERROR(str) \ - fprintf(stderr,"[OCL_ERROR] %s\n",str); -#define OCL_CHECK(value1,value2,str) \ - if(value1!=value2) \ - fprintf(stderr,"[OCL_ERROR] %s\n",str); - #define OPENCL_DLL_NAME "OpenCL.dll" #else #define OPENCL_DLL_NAME "libOpenCL.so" commit 700e921455789ec7387e26f1a8ec81f527a5cf59 Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Mon Sep 30 22:43:44 2013 +0200 clear cache of old files when opencl source changes Change-Id: I67bc06f80c284c85d2bb409380ba3a43611ec31c diff --git a/sc/source/core/opencl/openclwrapper.cxx b/sc/source/core/opencl/openclwrapper.cxx index d273463..4596b8b 100644 --- a/sc/source/core/opencl/openclwrapper.cxx +++ b/sc/source/core/opencl/openclwrapper.cxx @@ -90,6 +90,36 @@ OString getCacheFolder() return rtl::OUStringToOString(url, RTL_TEXTENCODING_UTF8); } +void clearCache() +{ + OUString aCacheDirURL(rtl::OStringToOUString(OpenclDevice::maCacheFolder, RTL_TEXTENCODING_UTF8)); + osl::Directory aCacheDir(aCacheDirURL); + osl::FileBase::RC status = aCacheDir.open(); + if(status != osl::FileBase::E_None) + return; + + osl::DirectoryItem aItem; + OUString aSourceString = rtl::OStringToOUString(OpenclDevice::maSourceHash + ".bin", RTL_TEXTENCODING_UTF8); + while(osl::FileBase::E_None == aCacheDir.getNextItem(aItem)) + { + osl::FileStatus aFileStatus(osl_FileStatus_Mask_FileName|osl_FileStatus_Mask_FileURL); + status = aItem.getFileStatus(aFileStatus); + if(status != osl::FileBase::E_None) + continue; + + OUString aFileName = aFileStatus.getFileName(); + if(aFileName.endsWith(".bin")) + { + if(!aFileName.endsWith(aSourceString)) + { + // delete the file + OUString aFileUrl = aFileStatus.getFileURL(); + osl::File::remove(aFileUrl); + } + } + } +} + } OString OpenclDevice::maSourceHash = generateHashForSource(); @@ -257,6 +287,7 @@ std::vector<boost::shared_ptr<osl::File> > OpenclDevice::binaryGenerated( const int OpenclDevice::writeBinaryToFile( const OString& rFileName, const char* binary, size_t numBytes ) { + clearCache(); osl::File file(rtl::OStringToOUString(rFileName, RTL_TEXTENCODING_UTF8)); osl::FileBase::RC status = file.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create ); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits