summaryrefslogtreecommitdiff
path: root/opencl
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2014-11-26 22:30:33 +0200
committerTor Lillqvist <tml@collabora.com>2014-11-28 10:22:45 +0200
commit7920af486b7124b85b2eb30c90aa26ddc471bd15 (patch)
tree41e9fcb149e5756da0a950c93008e15214738f79 /opencl
parent8d239f25a22523a35d862db18341606440ae5473 (diff)
Work in progress: Move Calc-independend OpenCL configuration out of sc
Intermediate commit. More changes will follow: The device selection logic needs to be moved, too. (And cleaned up.) Instead of the separate formulacalculationoptions dialog we should simply have a normal options page for those OpenCL-related settings that will remain purely Calc-specific, like the formula opcode subsetting. Change-Id: Id60d95e80d377cbbf5780beb473b221bce06b5e5
Diffstat (limited to 'opencl')
-rw-r--r--opencl/Library_opencl.mk42
-rw-r--r--opencl/Makefile14
-rw-r--r--opencl/Module_opencl.mk16
-rw-r--r--opencl/source/openclconfig.cxx256
-rw-r--r--opencl/source/platforminfo.cxx46
5 files changed, 374 insertions, 0 deletions
diff --git a/opencl/Library_opencl.mk b/opencl/Library_opencl.mk
new file mode 100644
index 000000000000..51ca62c71302
--- /dev/null
+++ b/opencl/Library_opencl.mk
@@ -0,0 +1,42 @@
+# -*- 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_Library_Library,opencl))
+
+$(eval $(call gb_Library_add_defs,opencl,\
+ -DOPENCL_DLLIMPLEMENTATION \
+))
+
+$(eval $(call gb_Library_use_externals,opencl,\
+ boost_headers \
+ clew \
+ icu_headers \
+ icui18n \
+ icuuc \
+))
+
+$(eval $(call gb_Library_use_custom_headers,opencl,\
+ officecfg/registry \
+))
+
+$(eval $(call gb_Library_use_sdk_api,opencl))
+
+$(eval $(call gb_Library_use_libraries,opencl,\
+ configmgr \
+ comphelper \
+ cppu \
+ sal \
+))
+
+$(eval $(call gb_Library_add_exception_objects,opencl,\
+ opencl/source/openclconfig \
+ opencl/source/platforminfo \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/opencl/Makefile b/opencl/Makefile
new file mode 100644
index 000000000000..0997e628485b
--- /dev/null
+++ b/opencl/Makefile
@@ -0,0 +1,14 @@
+# -*- 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/.
+#
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/opencl/Module_opencl.mk b/opencl/Module_opencl.mk
new file mode 100644
index 000000000000..92a80160a1bb
--- /dev/null
+++ b/opencl/Module_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_Module_Module,opencl))
+
+$(eval $(call gb_Module_add_targets,opencl,\
+ Library_opencl \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/opencl/source/openclconfig.cxx b/opencl/source/openclconfig.cxx
new file mode 100644
index 000000000000..aa7a07ae3e97
--- /dev/null
+++ b/opencl/source/openclconfig.cxx
@@ -0,0 +1,256 @@
+/* -*- 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/.
+ */
+
+#include <boost/shared_ptr.hpp>
+#include <unicode/regex.h>
+
+#include <comphelper/configuration.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <opencl/openclconfig.hxx>
+#include <opencl/platforminfo.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+OpenCLConfig::OpenCLConfig() :
+ mbUseOpenCL(true)
+{
+ // This entry we have had for some time (when blacklisting was
+ // done elsewhere in the code), so presumably there is a known
+ // good reason for it.
+ maBlackList.insert(ImplMatcher("Windows", "", "Intel\\(R\\) Corporation", "", "9\\.17\\.10\\.2884"));
+
+ // This is what I have tested on Linux and it works for our unit tests.
+ maWhiteList.insert(ImplMatcher("Linux", "", "Advanced Micro Devices, Inc\\.", "", "1445\\.5 \\(sse2,avx\\)"));
+
+ // For now, assume that AMD, Intel and NVIDIA drivers are good
+ maWhiteList.insert(ImplMatcher("", "", "Advanced Micro Devices, Inc\\.", "", ""));
+ maWhiteList.insert(ImplMatcher("", "", "Intel\\(R\\) Corporation", "", ""));
+ maWhiteList.insert(ImplMatcher("", "", "NVIDIA Corporation", "", ""));
+}
+
+bool OpenCLConfig::operator== (const OpenCLConfig& r) const
+{
+ return (mbUseOpenCL == r.mbUseOpenCL &&
+ maBlackList == r.maBlackList &&
+ maWhiteList == r.maWhiteList &&
+ true);
+}
+
+bool OpenCLConfig::operator!= (const OpenCLConfig& r) const
+{
+ return !operator== (r);
+}
+
+namespace {
+
+css::uno::Sequence<OUString> SetOfImplMatcherToStringSequence(const OpenCLConfig::ImplMatcherSet& rSet)
+{
+ css::uno::Sequence<OUString> result(rSet.size());
+
+ size_t n(0);
+ for (auto i = rSet.cbegin(); i != rSet.cend(); ++i)
+ {
+ result[n++] =
+ (*i).maOS.replaceAll("%", "%25").replaceAll("/", "%2F").replaceAll(";", "%3B") + "/" +
+ (*i).maOSVersion.replaceAll("%", "%25").replaceAll("/", "%2F").replaceAll(";", "%3B") + "/" +
+ (*i).maPlatformVendor.replaceAll("%", "%25").replaceAll("/", "%2F").replaceAll(";", "%3B") + "/" +
+ (*i).maDevice.replaceAll("%", "%25").replaceAll("/", "%2F").replaceAll(";", "%3B") + "/" +
+ (*i).maDriverVersion.replaceAll("%", "%25").replaceAll("/", "%2F").replaceAll(";", "%3B");
+ }
+
+ return result;
+}
+
+OUString getToken(const OUString& string, sal_Int32& index)
+{
+ OUString token(string.getToken(0, '/', index));
+ OUString result;
+ sal_Int32 i(0);
+ sal_Int32 p;
+ while ((p = token.indexOf('%', i)) >= 0)
+ {
+ if (p > i)
+ result += token.copy(i, p - i);
+ if (p < token.getLength() - 2)
+ {
+ result += OUString(static_cast<sal_Unicode>(token.copy(p+1, 2).toInt32(16)));
+ i = p + 3;
+ }
+ else
+ {
+ i = token.getLength();
+ }
+ }
+ result += token.copy(i);
+
+ return result;
+}
+
+OpenCLConfig::ImplMatcherSet StringSequenceToSetOfImplMatcher(const css::uno::Sequence<OUString>& rSequence)
+{
+ OpenCLConfig::ImplMatcherSet result;
+
+ for (auto i = rSequence.begin(); i != rSequence.end(); ++i)
+ {
+ OpenCLConfig::ImplMatcher m;
+ sal_Int32 index(0);
+ m.maOS = getToken(*i, index);
+ m.maOSVersion = getToken(*i, index);
+ m.maPlatformVendor = getToken(*i, index);
+ m.maDevice = getToken(*i, index);
+ m.maDriverVersion = getToken(*i, index);
+
+ result.insert(m);
+ }
+
+ return result;
+}
+
+bool match(const OUString& rPattern, const OUString& rInput)
+{
+ if (rPattern == "")
+ return true;
+
+ UErrorCode nIcuError(U_ZERO_ERROR);
+ icu::UnicodeString sIcuPattern(reinterpret_cast<const UChar*>(rPattern.getStr()), rPattern.getLength());
+ icu::UnicodeString sIcuInput(reinterpret_cast<const UChar*>(rInput.getStr()), rInput.getLength());
+ RegexMatcher aMatcher(sIcuPattern, sIcuInput, 0, nIcuError);
+
+ if (U_SUCCESS(nIcuError) && aMatcher.matches(nIcuError) && U_SUCCESS(nIcuError))
+ return true;
+
+ return false;
+}
+
+bool match(const OpenCLConfig::ImplMatcher& rListEntry, const OpenCLPlatformInfo& rPlatform, const OpenCLDeviceInfo& rDevice)
+{
+#if defined WNT
+ if (rListEntry.maOS != "" && rListEntry.maOS != "Windows")
+ return false;
+#elif defined LINUX
+ if (rListEntry.maOS != "" && rListEntry.maOS != "Linux")
+ return false;
+#elif defined MACOSX
+ if (rListEntry.maOS != "" && rListEntry.maOS != "OS X")
+ return false;
+#endif
+
+ // OS version check not yet implemented
+
+ if (!match(rListEntry.maPlatformVendor, rPlatform.maVendor))
+ return false;
+
+ if (!match(rListEntry.maDevice, rDevice.maName))
+ return false;
+
+ if (!match(rListEntry.maDriverVersion, rDevice.maDriver))
+ return false;
+
+ return true;
+}
+
+bool match(const OpenCLConfig::ImplMatcherSet& rList, const OpenCLPlatformInfo& rPlatform, const OpenCLDeviceInfo& rDevice, const char* sKindOfList)
+{
+ for (auto i = rList.cbegin(); i != rList.end(); ++i)
+ {
+ SAL_INFO("sc.opencl", "Looking for match for platform=" << rPlatform << ", device=" << rDevice <<
+ " in " << sKindOfList << " entry=" << *i);
+
+ if (match(*i, rPlatform, rDevice))
+ {
+ SAL_INFO("sc.opencl", "Match!");
+ return true;
+ }
+ }
+ return false;
+}
+
+} // anonymous namespace
+
+OpenCLConfig OpenCLConfig::get()
+{
+ OpenCLConfig result;
+
+ result.mbUseOpenCL = officecfg::Office::Common::Misc::UseOpenCL::get();
+
+ result.maBlackList = StringSequenceToSetOfImplMatcher(officecfg::Office::Common::Misc::OpenCLBlackList::get());
+ result.maWhiteList = StringSequenceToSetOfImplMatcher(officecfg::Office::Common::Misc::OpenCLWhiteList::get());
+
+ return result;
+}
+
+void OpenCLConfig::set()
+{
+ boost::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+
+ officecfg::Office::Common::Misc::UseOpenCL::set(mbUseOpenCL, batch);
+ officecfg::Office::Common::Misc::OpenCLBlackList::set(SetOfImplMatcherToStringSequence(maBlackList), batch);
+ officecfg::Office::Common::Misc::OpenCLWhiteList::set(SetOfImplMatcherToStringSequence(maWhiteList), batch);
+
+ batch->commit();
+}
+
+bool OpenCLConfig::checkImplementation(const OpenCLPlatformInfo& rPlatform, const OpenCLDeviceInfo& rDevice) const
+{
+ // Check blacklist of known bad OpenCL implementations
+ if (match(maBlackList, rPlatform, rDevice, "blacklist"))
+ {
+ SAL_INFO("opencl", "Rejecting");
+ return true;
+ }
+
+ // Check for whitelist of known good OpenCL implementations
+ if (match(maWhiteList, rPlatform, rDevice, "whitelist"))
+ {
+ SAL_INFO("opencl", "Approving");
+ return false;
+ }
+
+ // Fallback: reject
+ SAL_INFO("opencl", "Fallback: rejecting platform=" << rPlatform << ", device=" << rDevice);
+ return true;
+}
+
+std::ostream& operator<<(std::ostream& rStream, const OpenCLConfig& rConfig)
+{
+ rStream << "{"
+ "UseOpenCL=" << (rConfig.mbUseOpenCL ? "YES" : "NO") << ","
+ "BlackList=" << rConfig.maBlackList << ","
+ "WhiteList=" << rConfig.maWhiteList <<
+ "}";
+ return rStream;
+}
+
+std::ostream& operator<<(std::ostream& rStream, const OpenCLConfig::ImplMatcher& rImpl)
+{
+ rStream << "{"
+ "OS=" << rImpl.maOS << ","
+ "OSVersion=" << rImpl.maOSVersion << ","
+ "PlatformVendor=" << rImpl.maPlatformVendor << ","
+ "Device=" << rImpl.maDevice << ","
+ "DriverVersion=" << rImpl.maDriverVersion <<
+ "}";
+
+ return rStream;
+}
+
+std::ostream& operator<<(std::ostream& rStream, const OpenCLConfig::ImplMatcherSet& rSet)
+{
+ rStream << "{";
+ for (auto i = rSet.cbegin(); i != rSet.cend(); ++i)
+ {
+ if (i != rSet.cbegin())
+ rStream << ",";
+ rStream << *i;
+ }
+ rStream << "}";
+ return rStream;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/opencl/source/platforminfo.cxx b/opencl/source/platforminfo.cxx
new file mode 100644
index 000000000000..4871702800a0
--- /dev/null
+++ b/opencl/source/platforminfo.cxx
@@ -0,0 +1,46 @@
+/* -*- 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/.
+ */
+
+#include <ostream>
+
+#include <opencl/platforminfo.hxx>
+
+OpenCLDeviceInfo::OpenCLDeviceInfo()
+ : device(0)
+ , mnMemory(0)
+ , mnComputeUnits(0)
+ , mnFrequency(0)
+{
+}
+
+OpenCLPlatformInfo::OpenCLPlatformInfo()
+ : platform(NULL)
+{
+}
+
+std::ostream& operator<<(std::ostream& rStream, const OpenCLPlatformInfo& rPlatform)
+{
+ rStream << "{"
+ "Vendor=" << rPlatform.maVendor << ","
+ "Name=" << rPlatform.maName <<
+ "}";
+ return rStream;
+}
+
+std::ostream& operator<<(std::ostream& rStream, const OpenCLDeviceInfo& rDevice)
+{
+ rStream << "{"
+ "Name=" << rDevice.maName << ","
+ "Vendor=" << rDevice.maVendor << ","
+ "Driver=" << rDevice.maDriver <<
+ "}";
+ return rStream;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */