diff options
author | Tor Lillqvist <tml@collabora.com> | 2014-11-26 22:30:33 +0200 |
---|---|---|
committer | Tor Lillqvist <tml@collabora.com> | 2014-11-27 11:07:37 +0200 |
commit | c1d09b1ad02160850d40c0d242a0d0ec0a8dc1bc (patch) | |
tree | e39b6a73639f483a3000cdec31890cfdd051a5af /opencl | |
parent | ccfb8c78277d4a4f85af5ebbd96cf87f0d729016 (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.mk | 42 | ||||
-rw-r--r-- | opencl/Makefile | 14 | ||||
-rw-r--r-- | opencl/Module_opencl.mk | 16 | ||||
-rw-r--r-- | opencl/source/openclconfig.cxx | 256 | ||||
-rw-r--r-- | opencl/source/platforminfo.cxx | 46 |
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: */ |