summaryrefslogtreecommitdiff
path: root/opencl/source/openclwrapper.cxx
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2016-07-08 22:16:27 +0900
committerAndras Timar <andras.timar@collabora.com>2016-07-13 21:07:56 +0200
commite79f63ee76b2c4dd2e47c250e07931433305855c (patch)
tree8d59c099576d7b1af684794d29a983020ea01ead /opencl/source/openclwrapper.cxx
parentc44abe5735f17dcb678748766bf40ccf035642fd (diff)
opencl: OpenCLZone, detect CL device change and disable CL on crash
Guard OpenCL calls with OpenCLZone, so if a OpenCL call crashes we detect this and disable OpenCL so next time the user doesn't encounter the crash at the same calculation because he has a broken OpenCL drivers. Similar has been implemented for OpenGL with good results. Additionaly we persistently remember a known good OpenCL device ID and driver version so we can match this and perform calculation tests when they change. This is to ensure that the selected OpenCL device performs as we expect. In this commit the calculation tests aren't included yet. Remove complex static initializer in opencl wrapper library. Reviewed-on: https://gerrit.libreoffice.org/27064 Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> Tested-by: Tomaž Vajngerl <quikee@gmail.com> (cherry picked from commit f41eb66302208f384a475fb20c98b6d1b0676cb6) Change-Id: I1a8b81ee31298731efcf63dc6a476955afc035e9 Reviewed-on: https://gerrit.libreoffice.org/27103 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Michael Meeks <michael.meeks@collabora.com> (cherry picked from commit e1ef22371613f384cc2f6fc75d022cb01bf92af7)
Diffstat (limited to 'opencl/source/openclwrapper.cxx')
-rw-r--r--opencl/source/openclwrapper.cxx106
1 files changed, 62 insertions, 44 deletions
diff --git a/opencl/source/openclwrapper.cxx b/opencl/source/openclwrapper.cxx
index 384e9eb03310..1af142c1476c 100644
--- a/opencl/source/openclwrapper.cxx
+++ b/opencl/source/openclwrapper.cxx
@@ -21,6 +21,7 @@
#include <rtl/ustring.hxx>
#include <sal/config.h>
#include <sal/log.hxx>
+#include <opencl/OpenCLZone.hxx>
#include <memory>
#include <unicode/regex.h>
@@ -82,15 +83,19 @@ OString generateMD5(const void* pData, size_t length)
OString getCacheFolder()
{
- OUString url("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/cache/");
- rtl::Bootstrap::expandMacros(url);
+ static OString aCacheFolder;
- osl::Directory::create(url);
+ if (aCacheFolder.isEmpty())
+ {
+ OUString url("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap") ":UserInstallation}/cache/");
+ rtl::Bootstrap::expandMacros(url);
- return rtl::OUStringToOString(url, RTL_TEXTENCODING_UTF8);
-}
+ osl::Directory::create(url);
-OString maCacheFolder = getCacheFolder();
+ aCacheFolder = rtl::OUStringToOString(url, RTL_TEXTENCODING_UTF8);
+ }
+ return aCacheFolder;
+}
}
@@ -132,8 +137,7 @@ OString createFileName(cl_device_id deviceId, const char* clFileName)
OString aString = OString(deviceName) + driverVersion + platformVersion;
OString aHash = generateMD5(aString.getStr(), aString.getLength());
- return maCacheFolder + fileName + "-" +
- aHash + ".bin";
+ return getCacheFolder() + fileName + "-" + aHash + ".bin";
}
std::vector<std::shared_ptr<osl::File> > binaryGenerated( const char * clFileName, cl_context context )
@@ -267,6 +271,8 @@ bool initOpenCLAttr( OpenCLEnv * env )
void releaseOpenCLEnv( GPUEnv *gpuInfo )
{
+ OpenCLZone zone;
+
if ( !bIsInited )
{
return;
@@ -319,7 +325,7 @@ bool buildProgram(const char* buildOption, GPUEnv* gpuInfo, int idx)
return false;
}
- OString aBuildLogFileURL = maCacheFolder + "kernel-build.log";
+ OString aBuildLogFileURL = getCacheFolder() + "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 );
@@ -410,6 +416,8 @@ namespace {
void checkDeviceForDoubleSupport(cl_device_id deviceId, bool& bKhrFp64, bool& bAmdFp64)
{
+ OpenCLZone zone;
+
bKhrFp64 = false;
bAmdFp64 = false;
@@ -442,6 +450,8 @@ void checkDeviceForDoubleSupport(cl_device_id deviceId, bool& bKhrFp64, bool& bA
bool initOpenCLRunEnv( GPUEnv *gpuInfo )
{
+ OpenCLZone zone;
+
bool bKhrFp64 = false;
bool bAmdFp64 = false;
@@ -684,7 +694,7 @@ void findDeviceInfoFromDeviceId(cl_device_id aDeviceId, size_t& rDeviceId, size_
}
-bool switchOpenCLDevice(const OUString* pDevice, bool bAutoSelect, bool bForceEvaluation)
+bool switchOpenCLDevice(const OUString* pDevice, bool bAutoSelect, bool bForceEvaluation, OUString& rOutSelectedDeviceVersionIDString)
{
if(fillOpenCLInfo().empty())
return false;
@@ -716,54 +726,62 @@ bool switchOpenCLDevice(const OUString* pDevice, bool bAutoSelect, bool bForceEv
return pDeviceId != nullptr;
}
+ cl_context context;
cl_platform_id platformId;
- cl_int nState = clGetDeviceInfo(pDeviceId, CL_DEVICE_PLATFORM,
- sizeof(platformId), &platformId, nullptr);
-
- cl_context_properties cps[3];
- cps[0] = CL_CONTEXT_PLATFORM;
- cps[1] = reinterpret_cast<cl_context_properties>(platformId);
- cps[2] = 0;
- cl_context context = clCreateContext( cps, 1, &pDeviceId, nullptr, nullptr, &nState );
- if (nState != CL_SUCCESS)
- SAL_WARN("opencl", "clCreateContext failed: " << errorString(nState));
+ cl_command_queue command_queue[OPENCL_CMDQUEUE_SIZE];
- if(nState != CL_SUCCESS || context == nullptr)
{
- if(context != nullptr)
- clReleaseContext(context);
+ OpenCLZone zone;
+ cl_int nState = clGetDeviceInfo(pDeviceId, CL_DEVICE_PLATFORM,
+ sizeof(platformId), &platformId, nullptr);
+
+ cl_context_properties cps[3];
+ cps[0] = CL_CONTEXT_PLATFORM;
+ cps[1] = reinterpret_cast<cl_context_properties>(platformId);
+ cps[2] = 0;
+ context = clCreateContext( cps, 1, &pDeviceId, nullptr, nullptr, &nState );
+ if (nState != CL_SUCCESS)
+ SAL_WARN("opencl", "clCreateContext failed: " << errorString(nState));
- SAL_WARN("opencl", "failed to set/switch opencl device");
- return false;
- }
- SAL_INFO("opencl", "Created context " << context << " for platform " << platformId << ", device " << pDeviceId);
+ if(nState != CL_SUCCESS || context == nullptr)
+ {
+ if(context != nullptr)
+ clReleaseContext(context);
- cl_command_queue command_queue[OPENCL_CMDQUEUE_SIZE];
- for (int i = 0; i < OPENCL_CMDQUEUE_SIZE; ++i)
- {
- command_queue[i] = clCreateCommandQueue(
- context, pDeviceId, 0, &nState);
- if (nState != CL_SUCCESS)
- SAL_WARN("opencl", "clCreateCommandQueue failed: " << errorString(nState));
+ SAL_WARN("opencl", "failed to set/switch opencl device");
+ return false;
+ }
+ SAL_INFO("opencl", "Created context " << context << " for platform " << platformId << ", device " << pDeviceId);
- if (command_queue[i] == nullptr || nState != CL_SUCCESS)
+ for (int i = 0; i < OPENCL_CMDQUEUE_SIZE; ++i)
{
- // Release all command queues created so far.
- for (int j = 0; j <= i; ++j)
+ command_queue[i] = clCreateCommandQueue(
+ context, pDeviceId, 0, &nState);
+ if (nState != CL_SUCCESS)
+ SAL_WARN("opencl", "clCreateCommandQueue failed: " << errorString(nState));
+
+ if (command_queue[i] == nullptr || nState != CL_SUCCESS)
{
- if (command_queue[j])
+ // Release all command queues created so far.
+ for (int j = 0; j <= i; ++j)
{
- clReleaseCommandQueue(command_queue[j]);
- command_queue[j] = nullptr;
+ if (command_queue[j])
+ {
+ clReleaseCommandQueue(command_queue[j]);
+ command_queue[j] = nullptr;
+ }
}
+
+ clReleaseContext(context);
+ SAL_WARN("opencl", "failed to set/switch opencl device");
+ return false;
}
- clReleaseContext(context);
- SAL_WARN("opencl", "failed to set/switch opencl device");
- return false;
+ SAL_INFO("opencl", "Created command queue " << command_queue[i] << " for context " << context);
}
- SAL_INFO("opencl", "Created command queue " << command_queue[i] << " for context " << context);
+ OString sDeviceID = getDeviceInfoString(pDeviceId, CL_DEVICE_VENDOR) + " " + getDeviceInfoString(pDeviceId, CL_DRIVER_VERSION);
+ rOutSelectedDeviceVersionIDString = OStringToOUString(sDeviceID, RTL_TEXTENCODING_UTF8);
}
setOpenCLCmdQueuePosition(0); // Call this just to avoid the method being deleted from unused function deleter.