[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