[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - desktop/inc desktop/Library_sofficeapp.mk desktop/source opencl/inc opencl/Library_opencl.mk opencl/source Repository.mk sc/Module_sc.mk sc/Package_opencl.mk sc/source solenv/gbuild

Michael Meeks michael.meeks at collabora.com
Tue Jul 12 15:33:36 UTC 2016


 Repository.mk                                  |    1 
 desktop/Library_sofficeapp.mk                  |    2 
 desktop/inc/app.hxx                            |    1 
 desktop/source/app/app.cxx                     |    5 
 desktop/source/app/opencl.cxx                  |  174 +++++++++++++++++++++++++
 opencl/Library_opencl.mk                       |    1 
 opencl/inc/opencl_device.hxx                   |    3 
 opencl/source/OpenCLZone.cxx                   |    4 
 opencl/source/openclwrapper.cxx                |    6 
 sc/Module_sc.mk                                |    1 
 sc/Package_opencl.mk                           |   16 ++
 sc/source/core/opencl/cl-test.ods              |binary
 sc/source/core/tool/formulagroup.cxx           |   21 ---
 solenv/gbuild/extensions/pre_MergedLibsList.mk |    1 
 14 files changed, 215 insertions(+), 21 deletions(-)

New commits:
commit 9befbe1f81a7930e167e0a711666b0779898c12e
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Mon Jul 11 15:12:38 2016 +0100

    desktop: validate OpenCL drivers before use.
    
    OpenCL validation needs to happen before drivers are used in
    anger. This should isolate any crashes, and/or mis-behavior to
    We use app version, CL driver version and file time-stamp to
    trigger re-testing the device. If anything fails: hard disable
    OpenCL.
    
    We use an opencl validation sheet (cl-test.ods) and install it.
    It is a minimal CL set - it requires a very short formula group
    length, and combines several CL functions into few formulae to
    test more.
    
    The sheet structure, in particular the manual squaring / SQRT is
    necessary to stick within the default CL subset, and ensure that
    formulae are CL enabled from the root of the dependency tree up.
    
    Reviewed-on: https://gerrit.libreoffice.org/27131
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>
    (cherry picked from commit c44726c48228d9c6a5960e302b1c0bd16b0099c4)
    
    + opencl: bail out early in missing OpenCL case.
    (cherry picked from commit 605a5dc088385ad21c33028d8107125c0316ddb1)
    
    + Remove bogus dependency from opencl to configmgr
    Since f41eb66302208f384a475fb20c98b6d1b0676cb6 "opencl: OpenCLZone, detect CL
    device change and disable CL on crash" vcl links against opencl (so indirectly
    linked against configmgr), which caused CppunitTest_configmgr_unit to include
    the configmgr object files both statically (through
    gb_CppunitTest_use_library_objects) and through the linked-in configmgr dynamic
    library, which in turn caused ASan builds to report an ODR violation for a
    doubly defined 'typeinfo name for configmgr::Access'.
    
    (cherry picked from commit 9c711f05fa10dc70e4257a1f48d43f539353541a)
    
    Change-Id: I18682dbdf9a8ba9c16d52bad4447e9acce97f0a3
    Reviewed-on: https://gerrit.libreoffice.org/27146
    Reviewed-by: Jan Holesovsky <kendy at collabora.com>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/Repository.mk b/Repository.mk
index 04519cb..adfc34b 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -820,6 +820,7 @@ $(eval $(call gb_Helper_register_packages_for_install,ooo,\
 		vcl_opengl_blacklist \
 	) \
 	$(if $(ENABLE_OPENGL_CANVAS),canvas_opengl_shader) \
+    $(if $(filter OPENCL,$(BUILD_TYPE)),sc_opencl_runtimetest) \
 ))
 
 $(eval $(call gb_Helper_register_packages_for_install,ogltrans,\
diff --git a/desktop/Library_sofficeapp.mk b/desktop/Library_sofficeapp.mk
index ef95ecf..785ab24 100644
--- a/desktop/Library_sofficeapp.mk
+++ b/desktop/Library_sofficeapp.mk
@@ -48,6 +48,7 @@ $(eval $(call gb_Library_use_libraries,sofficeapp,\
     deploymentmisc \
     editeng \
     i18nlangtag \
+    $(if $(filter OPENCL,$(BUILD_TYPE)),opencl) \
     sal \
     salhelper \
     sb \
@@ -93,6 +94,7 @@ $(eval $(call gb_Library_add_exception_objects,sofficeapp,\
     desktop/source/app/langselect \
     desktop/source/app/lockfile2 \
     desktop/source/app/officeipcthread \
+    desktop/source/app/opencl \
     desktop/source/app/sofficemain \
     desktop/source/app/userinstall \
     desktop/source/migration/migration \
diff --git a/desktop/inc/app.hxx b/desktop/inc/app.hxx
index d07d285..f9e7db6 100644
--- a/desktop/inc/app.hxx
+++ b/desktop/inc/app.hxx
@@ -84,6 +84,7 @@ class Desktop : public Application
 
         static void             OpenClients();
         static void             OpenDefault();
+        static void             CheckOpenCLCompute(const css::uno::Reference<css::frame::XDesktop2> &);
 
         DECL_STATIC_LINK_TYPED( Desktop, EnableAcceptors_Impl, void*, void);
 
diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx
index 958ca8a..1a47e8c 100644
--- a/desktop/source/app/app.cxx
+++ b/desktop/source/app/app.cxx
@@ -1573,6 +1573,11 @@ int Desktop::Main()
             FatalError( MakeStartupErrorMessage(e.Message) );
         }
 
+        // FIXME: move this somewhere sensible.
+#if HAVE_FEATURE_OPENCL
+        CheckOpenCLCompute(xDesktop);
+#endif
+
         // Release solar mutex just before we wait for our client to connect
         {
             SolarMutexReleaser aReleaser;
diff --git a/desktop/source/app/opencl.cxx b/desktop/source/app/opencl.cxx
new file mode 100644
index 0000000..09f2204
--- /dev/null
+++ b/desktop/source/app/opencl.cxx
@@ -0,0 +1,174 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+/*
+ * This module exists to validate the OpenCL implementation,
+ * where necessary during startup; and before we load or
+ * calculate using OpenCL.
+ */
+
+#include "app.hxx"
+
+#include <config_version.h>
+#include <config_folders.h>
+
+#include <rtl/bootstrap.hxx>
+
+#include <officecfg/Office/Calc.hxx>
+#include <officecfg/Office/Common.hxx>
+
+#include <com/sun/star/table/XCell2.hpp>
+#include <com/sun/star/sheet/XCalculatable.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheets.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+
+#include <opencl/openclwrapper.hxx>
+#include <opencl/OpenCLZone.hxx>
+
+#include <osl/file.hxx>
+
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::frame;
+
+namespace desktop {
+
+#if HAVE_FEATURE_OPENCL
+
+bool testOpenCLCompute(const Reference< XDesktop2 > &xDesktop, const OUString &rURL)
+{
+    bool bSuccess = false;
+    css::uno::Reference< css::lang::XComponent > xComponent;
+
+    SAL_INFO("opencl", "Starting CL test spreadsheet");
+
+    try {
+        css::uno::Reference< css::frame::XComponentLoader > xLoader(xDesktop, css::uno::UNO_QUERY_THROW);
+
+        css::uno::Sequence< css::beans::PropertyValue > aArgs(1);
+        aArgs[0].Name = "Hidden";
+        aArgs[0].Value = makeAny(true);
+
+        xComponent.set(xLoader->loadComponentFromURL(rURL, "_blank", 0, aArgs));
+
+        // What an unpleasant API to use.
+        css::uno::Reference< css::sheet::XCalculatable > xCalculatable( xComponent, css::uno::UNO_QUERY_THROW);
+        css::uno::Reference< css::sheet::XSpreadsheetDocument > xSpreadDoc( xComponent, css::uno::UNO_QUERY_THROW );
+        css::uno::Reference< css::sheet::XSpreadsheets > xSheets( xSpreadDoc->getSheets(), css::uno::UNO_QUERY_THROW );
+        css::uno::Reference< css::container::XIndexAccess > xIndex( xSheets, css::uno::UNO_QUERY_THROW );
+        css::uno::Reference< css::sheet::XSpreadsheet > xSheet( xIndex->getByIndex(0), css::uno::UNO_QUERY_THROW);
+
+        // So we insert our MAX call at the end on a named range.
+        css::uno::Reference< css::table::XCell2 > xThresh( xSheet->getCellByPosition(1,1), css::uno::UNO_QUERY_THROW ); // B2
+        double fThreshold = xThresh->getValue();
+
+        // We need pure OCL formulae all the way through the
+        // dependency chain, or we fall-back.
+        xCalculatable->calculateAll();
+
+        // So we insert our MAX call at the end on a named range.
+        css::uno::Reference< css::table::XCell2 > xCell( xSheet->getCellByPosition(1,0), css::uno::UNO_QUERY_THROW );
+        xCell->setFormula("=MAX(results)");
+        double fResult = xCell->getValue();
+
+        // Ensure the maximum variance is below our tolerance.
+        if (fResult > fThreshold)
+        {
+            SAL_WARN("opencl", "OpenCL results unstable - disabling; result: "
+                     << fResult << " vs. " << fThreshold);
+        }
+        else
+        {
+            SAL_INFO("opencl", "calculating smoothly; result: " << fResult);
+            bSuccess = true;
+        }
+    }
+    catch (const css::uno::Exception &e)
+    {
+        (void)e;
+        SAL_WARN("opencl", "OpenCL testing failed - disabling: " << e.Message);
+    }
+
+    if (!bSuccess)
+        OpenCLZone::hardDisable();
+    if (xComponent.is())
+        xComponent->dispose();
+
+    return bSuccess;
+}
+
+void Desktop::CheckOpenCLCompute(const Reference< XDesktop2 > &xDesktop)
+{
+    if (getenv("SAL_DISABLE_OPENCL") ||
+        !officecfg::Office::Common::Misc::UseOpenCL::get())
+        return;
+
+    SAL_INFO("opencl", "Initiating test of OpenCL device");
+    OpenCLZone aZone;
+
+    OUString aDevice = officecfg::Office::Calc::Formula::Calculation::OpenCLDevice::get();
+    OUString aSelectedCLDeviceVersionID;
+    if (!opencl::switchOpenCLDevice(
+            &aDevice,
+            officecfg::Office::Calc::Formula::Calculation::OpenCLAutoSelect::get(),
+            false /* bForceEvaluation */,
+            aSelectedCLDeviceVersionID))
+    {
+        SAL_WARN("opencl", "Failed to initialize OpenCL for test");
+        OpenCLZone::hardDisable();
+        return;
+    }
+
+    // Append our app version as well.
+    aSelectedCLDeviceVersionID += "--";
+    aSelectedCLDeviceVersionID += LIBO_VERSION_DOTTED;
+
+    // Append timestamp of the file.
+    OUString aURL("$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/opencl/cl-test.ods");
+    rtl::Bootstrap::expandMacros(aURL);
+
+    DirectoryItem aItem;
+    DirectoryItem::get( aURL, aItem );
+    FileStatus aFileStatus( osl_FileStatus_Mask_ModifyTime );
+    aItem.getFileStatus( aFileStatus );
+    TimeValue aTimeVal = aFileStatus.getModifyTime();
+    aSelectedCLDeviceVersionID += "--";
+    aSelectedCLDeviceVersionID += OUString::number(aTimeVal.Seconds);
+
+    if (aSelectedCLDeviceVersionID != officecfg::Office::Common::Misc::SelectedOpenCLDeviceIdentifier::get())
+    {
+        // OpenCL device changed - sanity check it and disable if bad.
+
+        boost::optional<sal_Int32> nOrigMinimumSize = officecfg::Office::Calc::Formula::Calculation::OpenCLMinimumDataSize::get();
+        { // set the group size to something small for quick testing.
+            std::shared_ptr<comphelper::ConfigurationChanges> xBatch(comphelper::ConfigurationChanges::create());
+            officecfg::Office::Calc::Formula::Calculation::OpenCLMinimumDataSize::set(3 /* small */, xBatch);
+            xBatch->commit();
+        }
+
+        bool bSucceeded = testOpenCLCompute(xDesktop, aURL);
+
+        // it passed -> save the device.
+        {
+            std::shared_ptr<comphelper::ConfigurationChanges> xBatch(comphelper::ConfigurationChanges::create());
+            officecfg::Office::Calc::Formula::Calculation::OpenCLMinimumDataSize::set(nOrigMinimumSize, xBatch);
+            // allow the user to subsequently manually enable it.
+            officecfg::Office::Common::Misc::SelectedOpenCLDeviceIdentifier::set(aSelectedCLDeviceVersionID, xBatch);
+            xBatch->commit();
+        }
+
+        if (!bSucceeded)
+            OpenCLZone::hardDisable();
+    }
+}
+#endif // HAVE_FEATURE_OPENCL
+
+} // end namespace desktop
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/opencl/Library_opencl.mk b/opencl/Library_opencl.mk
index 3d9b032..927de0f 100644
--- a/opencl/Library_opencl.mk
+++ b/opencl/Library_opencl.mk
@@ -34,7 +34,6 @@ $(eval $(call gb_Library_use_sdk_api,opencl))
 
 $(eval $(call gb_Library_use_libraries,opencl,\
     clew \
-    configmgr \
     comphelper \
     cppu \
     sal \
diff --git a/opencl/inc/opencl_device.hxx b/opencl/inc/opencl_device.hxx
index 0963304..216af72 100644
--- a/opencl/inc/opencl_device.hxx
+++ b/opencl/inc/opencl_device.hxx
@@ -16,6 +16,9 @@ namespace opencl {
 
 ds_device getDeviceSelection(OUString const & pFileName, bool bForceSelection = false);
 
+struct GPUEnv;
+void releaseOpenCLEnv( GPUEnv *gpuInfo );
+
 }
 
 #endif
diff --git a/opencl/source/OpenCLZone.cxx b/opencl/source/OpenCLZone.cxx
index dc3a952..03521a2 100644
--- a/opencl/source/OpenCLZone.cxx
+++ b/opencl/source/OpenCLZone.cxx
@@ -7,7 +7,9 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
+#include <opencl/openclwrapper.hxx>
 #include <opencl/OpenCLZone.hxx>
+#include "opencl_device.hxx"
 
 #include <memory>
 
@@ -40,6 +42,8 @@ void OpenCLZone::hardDisable()
         auto xConfProvider = css::configuration::theDefaultProvider::get(comphelper::getProcessComponentContext());
         css::uno::Reference<css::util::XFlushable> xFlushable(xConfProvider, css::uno::UNO_QUERY_THROW);
         xFlushable->flush();
+
+        releaseOpenCLEnv(&opencl::gpuEnv);
     }
 }
 
diff --git a/opencl/source/openclwrapper.cxx b/opencl/source/openclwrapper.cxx
index 1af142c..807a185 100644
--- a/opencl/source/openclwrapper.cxx
+++ b/opencl/source/openclwrapper.cxx
@@ -269,6 +269,8 @@ bool initOpenCLAttr( OpenCLEnv * env )
     return false;
 }
 
+}
+
 void releaseOpenCLEnv( GPUEnv *gpuInfo )
 {
     OpenCLZone zone;
@@ -299,6 +301,8 @@ void releaseOpenCLEnv( GPUEnv *gpuInfo )
     return;
 }
 
+namespace {
+
 bool buildProgram(const char* buildOption, GPUEnv* gpuInfo, int idx)
 {
     cl_int clStatus;
@@ -696,7 +700,7 @@ void findDeviceInfoFromDeviceId(cl_device_id aDeviceId, size_t& rDeviceId, size_
 
 bool switchOpenCLDevice(const OUString* pDevice, bool bAutoSelect, bool bForceEvaluation, OUString& rOutSelectedDeviceVersionIDString)
 {
-    if(fillOpenCLInfo().empty())
+    if(fillOpenCLInfo().empty() || getenv("SAL_DISABLE_OPENCL"))
         return false;
 
     cl_device_id pDeviceId = nullptr;
diff --git a/sc/Module_sc.mk b/sc/Module_sc.mk
index 3dcb39a..73019d6 100644
--- a/sc/Module_sc.mk
+++ b/sc/Module_sc.mk
@@ -15,6 +15,7 @@ $(eval $(call gb_Module_add_targets,sc,\
 	Library_scd \
 	Library_scfilt \
 	$(call gb_Helper_optional,DESKTOP,Library_scui) \
+	$(call gb_Helper_optional,OPENCL,Package_opencl) \
 ))
 
 $(eval $(call gb_Module_add_l10n_targets,sc,\
diff --git a/sc/Package_opencl.mk b/sc/Package_opencl.mk
new file mode 100644
index 0000000..ef1579f
--- /dev/null
+++ b/sc/Package_opencl.mk
@@ -0,0 +1,16 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Package_Package,sc_opencl_runtimetest,$(SRCDIR)/sc/source/core/opencl))
+
+$(eval $(call gb_Package_add_files,sc_opencl_runtimetest,$(LIBO_ETC_FOLDER)/opencl,\
+	cl-test.ods \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/sc/source/core/opencl/cl-test.ods b/sc/source/core/opencl/cl-test.ods
new file mode 100644
index 0000000..8380e0b
Binary files /dev/null and b/sc/source/core/opencl/cl-test.ods differ
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index abe92e8..8f166ce 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -338,26 +338,9 @@ bool FormulaGroupInterpreter::switchOpenCLDevice(const OUString& rDeviceId, bool
         return false;
 
     delete msInstance;
-    msInstance = nullptr;
+    msInstance = new sc::opencl::FormulaGroupInterpreterOpenCL();
 
-    if (bOpenCLEnabled)
-    {
-        msInstance = new sc::opencl::FormulaGroupInterpreterOpenCL();
-
-        if (aSelectedCLDeviceVersionID != officecfg::Office::Common::Misc::SelectedOpenCLDeviceIdentifier::get())
-        {
-            // perform OpenCL calculation tests
-
-            // save the device
-            std::shared_ptr<comphelper::ConfigurationChanges> xBatch(comphelper::ConfigurationChanges::create());
-            officecfg::Office::Common::Misc::SelectedOpenCLDeviceIdentifier::set(aSelectedCLDeviceVersionID, xBatch);
-            xBatch->commit();
-        }
-
-        return msInstance != nullptr;
-    }
-
-    return false;
+    return true;
 }
 
 void FormulaGroupInterpreter::getOpenCLDeviceInfo(sal_Int32& rDeviceId, sal_Int32& rPlatformId)
diff --git a/solenv/gbuild/extensions/pre_MergedLibsList.mk b/solenv/gbuild/extensions/pre_MergedLibsList.mk
index b338570..20cc510 100644
--- a/solenv/gbuild/extensions/pre_MergedLibsList.mk
+++ b/solenv/gbuild/extensions/pre_MergedLibsList.mk
@@ -12,6 +12,7 @@
 MERGE_LIBRARY_LIST := \
 	avmedia \
 	$(if $(filter $(OS),ANDROID),,basebmp) \
+	$(if $(filter OPENCL,$(BUILD_TYPE)),clew) \
 	basegfx \
 	canvastools \
 	configmgr \


More information about the Libreoffice-commits mailing list