LibreOffice Module sc (master)  1
formulagroup.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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  */
9 
10 #include <config_feature_opencl.h>
11 
12 #include <formulagroup.hxx>
13 #include <formulagroupcl.hxx>
14 #include <document.hxx>
15 #include <formulacell.hxx>
16 #include <tokenarray.hxx>
17 #include <compiler.hxx>
18 #include <interpre.hxx>
19 #include <scmatrix.hxx>
20 #include <globalnames.hxx>
22 #include <tools/cpuid.hxx>
23 
24 #include <formula/vectortoken.hxx>
25 #include <officecfg/Office/Common.hxx>
26 #include <officecfg/Office/Calc.hxx>
27 #if HAVE_FEATURE_OPENCL
28 #include <opencl/platforminfo.hxx>
29 #endif
30 #include <rtl/bootstrap.hxx>
31 #include <sal/log.hxx>
32 
33 #include <cstdio>
34 #include <unordered_map>
35 #include <vector>
36 
37 #if HAVE_FEATURE_OPENCL
38 # include <opencl/openclwrapper.hxx>
39 #endif
40 
41 namespace sc {
42 
43 FormulaGroupEntry::FormulaGroupEntry( ScFormulaCell** pCells, size_t nRow, size_t nLength ) :
44  mpCells(pCells), mnRow(nRow), mnLength(nLength), mbShared(true) {}
45 
47  mpCell(pCell), mnRow(nRow), mnLength(0), mbShared(false) {}
48 
50 {
51  return rKey.mnTab * MAXCOLCOUNT + rKey.mnCol;
52 }
53 
55 
57 {
58  return mnTab == r.mnTab && mnCol == r.mnCol;
59 }
60 
62  mpNumArray(pNumArray), mpStrArray(pStrArray), mnSize(0)
63 {
64  if (mpNumArray)
65  mnSize = mpNumArray->size();
66  else if (mpStrArray)
67  mnSize = mpStrArray->size();
68 }
69 
71 {
72  ColArraysType::iterator itColArray = maColArrays.find(ColKey(nTab, nCol));
73  if (itColArray == maColArrays.end())
74  // Not cached for this column.
75  return nullptr;
76 
77  ColArray& rCached = itColArray->second;
78  if (nSize > rCached.mnSize)
79  // Cached data array is not long enough for the requested range.
80  return nullptr;
81 
82  return &rCached;
83 }
84 
86  SCTAB nTab, SCCOL nCol, NumArrayType* pNumArray, StrArrayType* pStrArray )
87 {
88  ColArraysType::iterator it = maColArrays.find(ColKey(nTab, nCol));
89  if (it == maColArrays.end())
90  {
91  std::pair<ColArraysType::iterator,bool> r =
92  maColArrays.emplace(ColKey(nTab, nCol), ColArray(pNumArray, pStrArray));
93 
94  if (!r.second)
95  // Somehow the insertion failed.
96  return nullptr;
97 
98  return &r.first->second;
99  }
100 
101  // Prior array exists for this column. Overwrite it.
102  ColArray& rArray = it->second;
103  rArray = ColArray(pNumArray, pStrArray);
104  return &rArray;
105 }
106 
108 {
109  ColArraysType::iterator itColArray = maColArrays.find(ColKey(nTab, nCol));
110  if (itColArray != maColArrays.end())
111  maColArrays.erase(itColArray);
112 }
113 
114 void FormulaGroupContext::ensureStrArray( ColArray& rColArray, size_t nArrayLen )
115 {
116  if (rColArray.mpStrArray)
117  return;
118 
119  m_StrArrays.push_back(
120  std::make_unique<sc::FormulaGroupContext::StrArrayType>(nArrayLen, nullptr));
121  rColArray.mpStrArray = m_StrArrays.back().get();
122 }
123 
124 void FormulaGroupContext::ensureNumArray( ColArray& rColArray, size_t nArrayLen )
125 {
126  if (rColArray.mpNumArray)
127  return;
128 
129  double fNan;
130  rtl::math::setNan(&fNan);
131 
132  m_NumArrays.push_back(
133  std::make_unique<sc::FormulaGroupContext::NumArrayType>(nArrayLen, fNan));
134  rColArray.mpNumArray = m_NumArrays.back().get();
135 }
136 
138 {
139 }
140 
142 {
143 }
144 
146 
148 
150 
152 {
153  maCalcConfig = ScInterpreter::GetGlobalConfig();
154  maCalcConfig.MergeDocumentSpecific(rDoc.GetCalcConfig());
155 }
156 
159 {
160  if ( !msInstance )
161  {
162 #if HAVE_FEATURE_OPENCL
164  {
165  const ScCalcConfig& rConfig = ScInterpreter::GetGlobalConfig();
167  {
169  {
170  SAL_WARN( "opencl", "OpenCL forced but failed to initialize" );
171  abort();
172  }
173  }
174  }
175 #endif
176  }
177 
178  return msInstance;
179 }
180 
181 #if HAVE_FEATURE_OPENCL
182 void FormulaGroupInterpreter::fillOpenCLInfo(std::vector<OpenCLPlatformInfo>& rPlatforms)
183 {
184  const std::vector<OpenCLPlatformInfo>& rPlatformsFromWrapper =
186 
187  rPlatforms.assign(rPlatformsFromWrapper.begin(), rPlatformsFromWrapper.end());
188 }
189 
190 bool FormulaGroupInterpreter::switchOpenCLDevice(const OUString& rDeviceId, bool bAutoSelect, bool bForceEvaluation)
191 {
192  bool bOpenCLEnabled = ScCalcConfig::isOpenCLEnabled();
193  if (!bOpenCLEnabled || (rDeviceId == OPENCL_SOFTWARE_DEVICE_CONFIG_NAME))
194  {
195  delete msInstance;
196  msInstance = nullptr;
197  return false;
198  }
199 
200  OUString aSelectedCLDeviceVersionID;
201  bool bSuccess = openclwrapper::switchOpenCLDevice(&rDeviceId, bAutoSelect, bForceEvaluation, aSelectedCLDeviceVersionID);
202 
203  if (!bSuccess)
204  return false;
205 
206  delete msInstance;
208 
209  return true;
210 }
211 
212 void FormulaGroupInterpreter::getOpenCLDeviceInfo(sal_Int32& rDeviceId, sal_Int32& rPlatformId)
213 {
214  rDeviceId = -1;
215  rPlatformId = -1;
216  bool bOpenCLEnabled = ScCalcConfig::isOpenCLEnabled();
217  if(!bOpenCLEnabled)
218  return;
219 
220  size_t aDeviceId = static_cast<size_t>(-1);
221  size_t aPlatformId = static_cast<size_t>(-1);
222 
223  openclwrapper::getOpenCLDeviceInfo(aDeviceId, aPlatformId);
224  rDeviceId = aDeviceId;
225  rPlatformId = aPlatformId;
226 }
227 
228 void FormulaGroupInterpreter::enableOpenCL_UnitTestsOnly()
229 {
230  std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
231  officecfg::Office::Common::Misc::UseOpenCL::set(true, batch);
232  batch->commit();
233 
235 
236  aConfig.mbOpenCLSubsetOnly = false;
238 
240 }
241 
242 void FormulaGroupInterpreter::disableOpenCL_UnitTestsOnly()
243 {
244  std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
245  officecfg::Office::Common::Misc::UseOpenCL::set(false, batch);
246  batch->commit();
247 }
248 
249 #endif
250 
251 } // namespace sc
252 
253 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ColArray * setCachedColArray(SCTAB nTab, SCCOL nCol, NumArrayType *pNumArray, StrArrayType *pStrArray)
void getOpenCLDeviceInfo(size_t &rDeviceId, size_t &rPlatformId)
OUString maOpenCLDevice
Definition: calcconfig.hxx:64
Abstract base class for vectorised formula group interpreters, plus a global instance factory...
bool switchOpenCLDevice(const OUString *pDeviceId, bool bAutoSelect, bool bForceEvaluation, OUString &rOutSelectedDeviceVersionIDString)
ColArray * getCachedColArray(SCTAB nTab, SCCOL nCol, size_t nSize)
keep track of longest array for each column.
sal_Int32 mnCol
size_t operator()(const ColKey &rKey) const
void MergeCalcConfig(const ScDocument &rDoc)
Merge global and document specific settings.
static FormulaGroupInterpreter * getStatic()
load and/or configure the correct formula group interpreter
static ForceCalculationType getForceCalculationType()
Definition: calcconfig.cxx:68
const SCCOL MAXCOLCOUNT
Definition: address.hxx:64
void ensureStrArray(ColArray &rColArray, size_t nArrayLen)
ColArray(NumArrayType *pNumArray, StrArrayType *pStrArray)
ScFormulaCell * mpCell
static std::shared_ptr< ConfigurationChanges > create(css::uno::Reference< css::uno::XComponentContext > const &context=comphelper::getProcessComponentContext())
std::vector< double, DoubleAllocType > NumArrayType
bool mbOpenCLSubsetOnly
Definition: calcconfig.hxx:62
bool operator==(const ColKey &r) const
StrArrayStoreType m_StrArrays
manage life cycle of numeric arrays.
void discardCachedColArray(SCTAB nTab, SCCOL nCol)
static void SetGlobalConfig(const ScCalcConfig &rConfig)
Definition: interpr4.cxx:3871
sal_Int16 SCCOL
Definition: types.hxx:22
virtual ~CompiledFormula()
ColKey(SCTAB nTab, SCCOL nCol)
static FormulaGroupInterpreter * msInstance
FormulaGroupEntry(ScFormulaCell **pCells, size_t nRow, size_t nLength)
std::vector< rtl_uString * > StrArrayType
static const ScCalcConfig & GetGlobalConfig()
Definition: interpr4.cxx:3876
bool mbOpenCLAutoSelect
Definition: calcconfig.hxx:63
static bool isOpenCLEnabled()
Definition: calcconfig.cxx:74
Configuration options for formula interpreter.
Definition: calcconfig.hxx:43
sal_Int32 mnOpenCLMinimumFormulaGroupSize
Definition: calcconfig.hxx:65
NumArrayStoreType m_NumArrays
const ScCalcConfig & GetCalcConfig() const
Definition: document.hxx:2528
void ensureNumArray(ColArray &rColArray, size_t nArrayLen)
#define OPENCL_SOFTWARE_DEVICE_CONFIG_NAME
Definition: globalnames.hxx:24
#define SAL_WARN(area, stream)
sal_Int32 mnRow
sal_Int16 SCTAB
Definition: types.hxx:23
const std::vector< OpenCLPlatformInfo > & fillOpenCLInfo()
ColArraysType maColArrays
manage life cycle of string arrays.
sal_uInt32 mnSize