[Libreoffice-commits] core.git: Branch 'feature/calc-group-interpreter-3' - 5 commits - sc/source
Markus Mohrhard
markus.mohrhard at googlemail.com
Mon Sep 30 21:09:52 PDT 2013
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.mohrhard at 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.mohrhard at 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.mohrhard at 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.mohrhard at 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.mohrhard at 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 );
More information about the Libreoffice-commits
mailing list