Bump version to 6.0-14
[LibreOffice.git] / opencl / source / openclconfig.cxx
blob0ec2347fb3323bda1cb24d1545631d63dd253d78
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <unicode/regex.h>
12 #include <comphelper/configuration.hxx>
13 #include <officecfg/Office/Common.hxx>
14 #include <opencl/openclconfig.hxx>
15 #include <opencl/platforminfo.hxx>
16 #include <rtl/ustring.hxx>
17 #include <sal/log.hxx>
18 #include <sal/types.h>
20 OpenCLConfig::OpenCLConfig() :
21 mbUseOpenCL(true)
23 // This entry we have had for some time (when blacklisting was
24 // done elsewhere in the code), so presumably there is a known
25 // good reason for it.
26 maBlackList.insert(ImplMatcher("Windows", "", "Intel\\(R\\) Corporation", "", "9\\.17\\.10\\.2884"));
28 // This is what I have tested on Linux and it works for our unit tests.
29 maWhiteList.insert(ImplMatcher("Linux", "", "Advanced Micro Devices, Inc\\.", "", "1445\\.5 \\(sse2,avx\\)"));
31 // For now, assume that AMD, Intel and NVIDIA drivers are good
32 maWhiteList.insert(ImplMatcher("", "", "Advanced Micro Devices, Inc\\.", "", ""));
33 maWhiteList.insert(ImplMatcher("", "", "Intel\\(R\\) Corporation", "", ""));
34 maWhiteList.insert(ImplMatcher("", "", "NVIDIA Corporation", "", ""));
37 bool OpenCLConfig::operator== (const OpenCLConfig& r) const
39 return (mbUseOpenCL == r.mbUseOpenCL &&
40 maBlackList == r.maBlackList &&
41 maWhiteList == r.maWhiteList);
44 bool OpenCLConfig::operator!= (const OpenCLConfig& r) const
46 return !operator== (r);
49 namespace {
51 css::uno::Sequence<OUString> SetOfImplMatcherToStringSequence(const OpenCLConfig::ImplMatcherSet& rSet)
53 css::uno::Sequence<OUString> result(rSet.size());
55 size_t n(0);
56 for (auto i = rSet.cbegin(); i != rSet.cend(); ++i)
58 result[n++] =
59 (*i).maOS.replaceAll("%", "%25").replaceAll("/", "%2F").replaceAll(";", "%3B") + "/" +
60 (*i).maOSVersion.replaceAll("%", "%25").replaceAll("/", "%2F").replaceAll(";", "%3B") + "/" +
61 (*i).maPlatformVendor.replaceAll("%", "%25").replaceAll("/", "%2F").replaceAll(";", "%3B") + "/" +
62 (*i).maDevice.replaceAll("%", "%25").replaceAll("/", "%2F").replaceAll(";", "%3B") + "/" +
63 (*i).maDriverVersion.replaceAll("%", "%25").replaceAll("/", "%2F").replaceAll(";", "%3B");
66 return result;
69 OUString getToken(const OUString& string, sal_Int32& index)
71 OUString token(string.getToken(0, '/', index));
72 OUString result;
73 sal_Int32 i(0);
74 sal_Int32 p;
75 while ((p = token.indexOf('%', i)) >= 0)
77 if (p > i)
78 result += token.copy(i, p - i);
79 if (p < token.getLength() - 2)
81 result += OUStringLiteral1(token.copy(p+1, 2).toInt32(16));
82 i = p + 3;
84 else
86 i = token.getLength();
89 result += token.copy(i);
91 return result;
94 OpenCLConfig::ImplMatcherSet StringSequenceToSetOfImplMatcher(const css::uno::Sequence<OUString>& rSequence)
96 OpenCLConfig::ImplMatcherSet result;
98 for (auto i = rSequence.begin(); i != rSequence.end(); ++i)
100 OpenCLConfig::ImplMatcher m;
101 sal_Int32 index(0);
102 m.maOS = getToken(*i, index);
103 m.maOSVersion = getToken(*i, index);
104 m.maPlatformVendor = getToken(*i, index);
105 m.maDevice = getToken(*i, index);
106 m.maDriverVersion = getToken(*i, index);
108 result.insert(m);
111 return result;
114 bool match(const OUString& rPattern, const OUString& rInput)
116 if (rPattern.isEmpty())
117 return true;
119 UErrorCode nIcuError(U_ZERO_ERROR);
120 icu::UnicodeString sIcuPattern(reinterpret_cast<const UChar*>(rPattern.getStr()), rPattern.getLength());
121 icu::UnicodeString sIcuInput(reinterpret_cast<const UChar*>(rInput.getStr()), rInput.getLength());
122 icu::RegexMatcher aMatcher(sIcuPattern, sIcuInput, 0, nIcuError);
124 return U_SUCCESS(nIcuError) && aMatcher.matches(nIcuError) && U_SUCCESS(nIcuError);
127 bool match(const OpenCLConfig::ImplMatcher& rListEntry, const OpenCLPlatformInfo& rPlatform, const OpenCLDeviceInfo& rDevice)
129 #if defined(_WIN32)
130 if (!rListEntry.maOS.isEmpty() && rListEntry.maOS != "Windows")
131 return false;
132 #elif defined LINUX
133 if (!rListEntry.maOS.isEmpty() && rListEntry.maOS != "Linux")
134 return false;
135 #elif defined MACOSX
136 if (!rListEntry.maOS.isEmpty() && rListEntry.maOS != "OS X")
137 return false;
138 #endif
140 // OS version check not yet implemented
142 if (!match(rListEntry.maPlatformVendor, rPlatform.maVendor))
143 return false;
145 if (!match(rListEntry.maDevice, rDevice.maName))
146 return false;
148 if (!match(rListEntry.maDriverVersion, rDevice.maDriver))
149 return false;
151 return true;
154 bool match(const OpenCLConfig::ImplMatcherSet& rList, const OpenCLPlatformInfo& rPlatform, const OpenCLDeviceInfo& rDevice, const char* sKindOfList)
156 for (auto i = rList.cbegin(); i != rList.end(); ++i)
158 SAL_INFO("opencl", "Looking for match for platform=" << rPlatform << ", device=" << rDevice <<
159 " in " << sKindOfList << " entry=" << *i);
161 if (match(*i, rPlatform, rDevice))
163 SAL_INFO("opencl", "Match!");
164 return true;
167 return false;
170 } // anonymous namespace
172 OpenCLConfig OpenCLConfig::get()
174 OpenCLConfig result;
176 result.mbUseOpenCL = officecfg::Office::Common::Misc::UseOpenCL::get();
178 result.maBlackList = StringSequenceToSetOfImplMatcher(officecfg::Office::Common::Misc::OpenCLBlackList::get());
179 result.maWhiteList = StringSequenceToSetOfImplMatcher(officecfg::Office::Common::Misc::OpenCLWhiteList::get());
181 return result;
184 void OpenCLConfig::set()
186 std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
188 officecfg::Office::Common::Misc::UseOpenCL::set(mbUseOpenCL, batch);
189 officecfg::Office::Common::Misc::OpenCLBlackList::set(SetOfImplMatcherToStringSequence(maBlackList), batch);
190 officecfg::Office::Common::Misc::OpenCLWhiteList::set(SetOfImplMatcherToStringSequence(maWhiteList), batch);
192 batch->commit();
195 bool OpenCLConfig::checkImplementation(const OpenCLPlatformInfo& rPlatform, const OpenCLDeviceInfo& rDevice) const
197 // Check blacklist of known bad OpenCL implementations
198 if (match(maBlackList, rPlatform, rDevice, "blacklist"))
200 SAL_INFO("opencl", "Rejecting");
201 return true;
204 // Check for whitelist of known good OpenCL implementations
205 if (match(maWhiteList, rPlatform, rDevice, "whitelist"))
207 SAL_INFO("opencl", "Approving");
208 return false;
211 // Fallback: reject
212 SAL_INFO("opencl", "Fallback: rejecting platform=" << rPlatform << ", device=" << rDevice);
213 return true;
216 std::ostream& operator<<(std::ostream& rStream, const OpenCLConfig& rConfig)
218 rStream << "{"
219 "UseOpenCL=" << (rConfig.mbUseOpenCL ? "YES" : "NO") << ","
220 "BlackList=" << rConfig.maBlackList << ","
221 "WhiteList=" << rConfig.maWhiteList <<
222 "}";
223 return rStream;
226 std::ostream& operator<<(std::ostream& rStream, const OpenCLConfig::ImplMatcher& rImpl)
228 rStream << "{"
229 "OS=" << rImpl.maOS << ","
230 "OSVersion=" << rImpl.maOSVersion << ","
231 "PlatformVendor=" << rImpl.maPlatformVendor << ","
232 "Device=" << rImpl.maDevice << ","
233 "DriverVersion=" << rImpl.maDriverVersion <<
234 "}";
236 return rStream;
239 std::ostream& operator<<(std::ostream& rStream, const OpenCLConfig::ImplMatcherSet& rSet)
241 rStream << "{";
242 for (auto i = rSet.cbegin(); i != rSet.cend(); ++i)
244 if (i != rSet.cbegin())
245 rStream << ",";
246 rStream << *i;
248 rStream << "}";
249 return rStream;
252 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */