17#include <config_version.h>
18#include <config_feature_opencl.h>
19#include <config_folders.h>
21#include <rtl/bootstrap.hxx>
24#include <officecfg/Office/Calc.hxx>
25#include <officecfg/Office/Common.hxx>
31#include <com/sun/star/table/XCell2.hpp>
32#include <com/sun/star/sheet/XCalculatable.hpp>
33#include <com/sun/star/sheet/XSpreadsheet.hpp>
34#include <com/sun/star/sheet/XSpreadsheets.hpp>
35#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
37#if HAVE_FEATURE_OPENCL
42#include <osl/file.hxx>
43#include <osl/process.h>
51#if HAVE_FEATURE_OPENCL
53static bool testOpenCLDriver()
57 SAL_INFO(
"opencl",
"Starting CL driver test");
59 OUString testerURL(
"$BRAND_BASE_DIR/" LIBO_BIN_FOLDER
"/opencltest");
60 rtl::Bootstrap::expandMacros(testerURL);
62 OUString deviceName, platformName;
64 rtl_uString*
args[] = { deviceName.pData, platformName.pData };
65 sal_Int32 numArgs = 2;
68 oslSecurity security = osl_getCurrentSecurity();
69 oslProcessError error = osl_executeProcess(testerURL.pData, args, numArgs,
70 osl_Process_SEARCHPATH | osl_Process_HIDDEN, security,
71 nullptr,
nullptr, 0, &process );
72 osl_freeSecurityHandle( security );
73 if( error != osl_Process_E_None )
75 SAL_WARN(
"opencl",
"failed to start CL driver test: " << error );
79 TimeValue timeout( 10, 0 );
80 error = osl_joinProcessWithTimeout( process, &timeout );
81 if( error == osl_Process_E_None )
84 info.Size =
sizeof( info );
85 error = osl_getProcessInfo( process, osl_Process_EXITCODE, &info );
86 if( error == osl_Process_E_None )
90 SAL_INFO(
"opencl",
"CL driver test passed" );
91 osl_freeProcessHandle( process );
96 SAL_WARN(
"opencl",
"CL driver test failed - disabling: " << info.Code );
97 osl_freeProcessHandle( process );
102 SAL_WARN(
"opencl",
"CL driver test did not finish - disabling: " << error );
103 osl_terminateProcess( process );
104 osl_freeProcessHandle( process );
110 bool bSuccess =
false;
111 css::uno::Reference< css::lang::XComponent > xComponent;
115 SAL_INFO(
"opencl",
"Starting CL test spreadsheet");
120 lockFile.RemoveFileDirectly();
122 catch (
const css::uno::Exception&)
127 css::uno::Reference< css::frame::XComponentLoader > xLoader(xDesktop, css::uno::UNO_QUERY_THROW);
132 xComponent.set(xLoader->loadComponentFromURL(rURL,
"_blank", 0, aArgs));
135 css::uno::Reference< css::sheet::XCalculatable > xCalculatable( xComponent, css::uno::UNO_QUERY_THROW);
136 css::uno::Reference< css::sheet::XSpreadsheetDocument > xSpreadDoc( xComponent, css::uno::UNO_QUERY_THROW );
137 css::uno::Reference< css::sheet::XSpreadsheets > xSheets( xSpreadDoc->getSheets(), css::uno::UNO_SET_THROW );
138 css::uno::Reference< css::container::XIndexAccess > xIndex( xSheets, css::uno::UNO_QUERY_THROW );
139 css::uno::Reference< css::sheet::XSpreadsheet > xSheet( xIndex->getByIndex(0), css::uno::UNO_QUERY_THROW);
142 css::uno::Reference< css::table::XCell2 > xThresh( xSheet->getCellByPosition(1,1), css::uno::UNO_QUERY_THROW );
143 double fThreshold = xThresh->getValue();
147 xCalculatable->calculateAll();
150 css::uno::Reference< css::table::XCell2 > xCell( xSheet->getCellByPosition(1,0), css::uno::UNO_QUERY_THROW );
151 xCell->setFormula(
"=MAX(results)");
152 double fResult = xCell->getValue();
155 if (fResult > fThreshold)
157 SAL_WARN(
"opencl",
"OpenCL results unstable - disabling; result: "
158 << fResult <<
" vs. " << fThreshold);
162 SAL_INFO(
"opencl",
"calculating smoothly; result: " << fResult);
166 catch (
const css::uno::Exception &)
174 SAL_WARN(
"opencl",
"OpenCL kernels failed to compile, "
175 "or took SEH exceptions "
183 xComponent->dispose();
194 SAL_INFO(
"opencl",
"Initiating test of OpenCL device");
198 OUString aDevice = officecfg::Office::Calc::Formula::Calculation::OpenCLDevice::get();
199 OUString aSelectedCLDeviceVersionID;
202 officecfg::Office::Calc::Formula::Calculation::OpenCLAutoSelect::get(),
204 aSelectedCLDeviceVersionID))
206 SAL_WARN(
"opencl",
"Failed to initialize OpenCL for test");
212 aSelectedCLDeviceVersionID +=
"--" LIBO_VERSION_DOTTED;
215 OUString
aURL(
"$BRAND_BASE_DIR/" LIBO_ETC_FOLDER
"/opencl/cl-test.ods");
216 rtl::Bootstrap::expandMacros(
aURL);
219 (void)DirectoryItem::get(
aURL, aItem );
220 FileStatus aFileStatus( osl_FileStatus_Mask_ModifyTime );
221 (void)aItem.getFileStatus( aFileStatus );
222 TimeValue aTimeVal = aFileStatus.getModifyTime();
223 aSelectedCLDeviceVersionID +=
"--" +
224 OUString::number(aTimeVal.Seconds);
226 if (aSelectedCLDeviceVersionID == officecfg::Office::Common::Misc::SelectedOpenCLDeviceIdentifier::get())
231 sal_Int32 nOrigMinimumSize = officecfg::Office::Calc::Formula::Calculation::OpenCLMinimumDataSize::get();
234 officecfg::Office::Calc::Formula::Calculation::OpenCLMinimumDataSize::set(3 , xBatch);
241 bool bSucceeded = testOpenCLDriver() && testOpenCLCompute(xDesktop,
aURL);
245 officecfg::Office::Calc::Formula::Calculation::OpenCLMinimumDataSize::set(nOrigMinimumSize, xBatch);
246 officecfg::Office::Common::Misc::SelectedOpenCLDeviceIdentifier::set(aSelectedCLDeviceVersionID, xBatch);
static bool IsSafeModeEnabled()
static void hardDisable()
static std::shared_ptr< ConfigurationChanges > create()
static void CheckOpenCLCompute(const css::uno::Reference< css::frame::XDesktop2 > &)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
bool switchOpenCLDevice(std::u16string_view aDevice, bool bAutoSelect, bool bForceEvaluation, OUString &rOutSelectedDeviceVersionIDString)
void getOpenCLDeviceName(OUString &rDeviceName, OUString &rPlatformName)
sal_uInt64 kernelFailures