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 <interpre.hxx>
17 #include <globalnames.hxx>
18 
19 #include <officecfg/Office/Common.hxx>
20 #if HAVE_FEATURE_OPENCL
21 #include <opencl/platforminfo.hxx>
22 #endif
23 #include <sal/log.hxx>
24 
25 #include <cstdio>
26 #include <limits>
27 #include <unordered_map>
28 #include <vector>
29 
30 #if HAVE_FEATURE_OPENCL
31 # include <opencl/openclwrapper.hxx>
32 #endif
33 
34 namespace sc {
35 
36 FormulaGroupEntry::FormulaGroupEntry( ScFormulaCell** pCells, size_t nRow, size_t nLength ) :
37  mpCells(pCells), mnRow(nRow), mnLength(nLength), mbShared(true) {}
38 
40  mpCell(pCell), mnRow(nRow), mnLength(0), mbShared(false) {}
41 
43 {
44  return rKey.mnTab * MAXCOLCOUNT + rKey.mnCol;
45 }
46 
48 
50 {
51  return mnTab == r.mnTab && mnCol == r.mnCol;
52 }
53 
55  mpNumArray(pNumArray), mpStrArray(pStrArray), mnSize(0)
56 {
57  if (mpNumArray)
58  mnSize = mpNumArray->size();
59  else if (mpStrArray)
60  mnSize = mpStrArray->size();
61 }
62 
64 {
65  ColArraysType::iterator itColArray = maColArrays.find(ColKey(nTab, nCol));
66  if (itColArray == maColArrays.end())
67  // Not cached for this column.
68  return nullptr;
69 
70  ColArray& rCached = itColArray->second;
71  if (nSize > rCached.mnSize)
72  // Cached data array is not long enough for the requested range.
73  return nullptr;
74 
75  return &rCached;
76 }
77 
79  SCTAB nTab, SCCOL nCol, NumArrayType* pNumArray, StrArrayType* pStrArray )
80 {
81  ColArraysType::iterator it = maColArrays.find(ColKey(nTab, nCol));
82  if (it == maColArrays.end())
83  {
84  std::pair<ColArraysType::iterator,bool> r =
85  maColArrays.emplace(ColKey(nTab, nCol), ColArray(pNumArray, pStrArray));
86 
87  if (!r.second)
88  // Somehow the insertion failed.
89  return nullptr;
90 
91  return &r.first->second;
92  }
93 
94  // Prior array exists for this column. Overwrite it.
95  ColArray& rArray = it->second;
96  rArray = ColArray(pNumArray, pStrArray);
97  return &rArray;
98 }
99 
101 {
102  ColArraysType::iterator itColArray = maColArrays.find(ColKey(nTab, nCol));
103  if (itColArray != maColArrays.end())
104  maColArrays.erase(itColArray);
105 }
106 
107 void FormulaGroupContext::ensureStrArray( ColArray& rColArray, size_t nArrayLen )
108 {
109  if (rColArray.mpStrArray)
110  return;
111 
112  m_StrArrays.push_back(
113  std::make_unique<sc::FormulaGroupContext::StrArrayType>(nArrayLen, nullptr));
114  rColArray.mpStrArray = m_StrArrays.back().get();
115 }
116 
117 void FormulaGroupContext::ensureNumArray( ColArray& rColArray, size_t nArrayLen )
118 {
119  if (rColArray.mpNumArray)
120  return;
121 
122  m_NumArrays.push_back(
123  std::make_unique<sc::FormulaGroupContext::NumArrayType>(nArrayLen,
124  std::numeric_limits<double>::quiet_NaN()));
125  rColArray.mpNumArray = m_NumArrays.back().get();
126 }
127 
129 {
130 }
131 
133 {
134 }
135 
137 
139 
141 
143 {
144  maCalcConfig = ScInterpreter::GetGlobalConfig();
145  maCalcConfig.MergeDocumentSpecific(rDoc.GetCalcConfig());
146 }
147 
150 {
151  if ( !msInstance )
152  {
153 #if HAVE_FEATURE_OPENCL
155  {
156  const ScCalcConfig& rConfig = ScInterpreter::GetGlobalConfig();
158  {
160  {
161  SAL_WARN( "opencl", "OpenCL forced but failed to initialize" );
162  abort();
163  }
164  }
165  }
166 #endif
167  }
168 
169  return msInstance;
170 }
171 
172 #if HAVE_FEATURE_OPENCL
173 void FormulaGroupInterpreter::fillOpenCLInfo(std::vector<OpenCLPlatformInfo>& rPlatforms)
174 {
175  const std::vector<OpenCLPlatformInfo>& rPlatformsFromWrapper =
177 
178  rPlatforms.assign(rPlatformsFromWrapper.begin(), rPlatformsFromWrapper.end());
179 }
180 
181 bool FormulaGroupInterpreter::switchOpenCLDevice(const OUString& rDeviceId, bool bAutoSelect, bool bForceEvaluation)
182 {
183  bool bOpenCLEnabled = ScCalcConfig::isOpenCLEnabled();
184  if (!bOpenCLEnabled || (rDeviceId == OPENCL_SOFTWARE_DEVICE_CONFIG_NAME))
185  {
186  delete msInstance;
187  msInstance = nullptr;
188  return false;
189  }
190 
191  OUString aSelectedCLDeviceVersionID;
192  bool bSuccess = openclwrapper::switchOpenCLDevice(&rDeviceId, bAutoSelect, bForceEvaluation, aSelectedCLDeviceVersionID);
193 
194  if (!bSuccess)
195  return false;
196 
197  delete msInstance;
199 
200  return true;
201 }
202 
203 void FormulaGroupInterpreter::getOpenCLDeviceInfo(sal_Int32& rDeviceId, sal_Int32& rPlatformId)
204 {
205  rDeviceId = -1;
206  rPlatformId = -1;
207  bool bOpenCLEnabled = ScCalcConfig::isOpenCLEnabled();
208  if(!bOpenCLEnabled)
209  return;
210 
211  size_t aDeviceId = static_cast<size_t>(-1);
212  size_t aPlatformId = static_cast<size_t>(-1);
213 
214  openclwrapper::getOpenCLDeviceInfo(aDeviceId, aPlatformId);
215  rDeviceId = aDeviceId;
216  rPlatformId = aPlatformId;
217 }
218 
219 void FormulaGroupInterpreter::enableOpenCL_UnitTestsOnly()
220 {
221  std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
222  officecfg::Office::Common::Misc::UseOpenCL::set(true, batch);
223  batch->commit();
224 
226 
227  aConfig.mbOpenCLSubsetOnly = false;
229 
231 }
232 
233 void FormulaGroupInterpreter::disableOpenCL_UnitTestsOnly()
234 {
235  std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
236  officecfg::Office::Common::Misc::UseOpenCL::set(false, batch);
237  batch->commit();
238 }
239 
240 #endif
241 
242 } // namespace sc
243 
244 /* 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:63
const SCCOL MAXCOLCOUNT
Definition: address.hxx:63
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:3863
sal_Int16 SCCOL
Definition: types.hxx:21
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:3868
bool mbOpenCLAutoSelect
Definition: calcconfig.hxx:63
static bool isOpenCLEnabled()
Definition: calcconfig.cxx:69
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:2532
void ensureNumArray(ColArray &rColArray, size_t nArrayLen)
#define OPENCL_SOFTWARE_DEVICE_CONFIG_NAME
Definition: globalnames.hxx:23
#define SAL_WARN(area, stream)
sal_Int32 mnRow
sal_Int16 SCTAB
Definition: types.hxx:22
const std::vector< OpenCLPlatformInfo > & fillOpenCLInfo()
ColArraysType maColArrays
manage life cycle of string arrays.
sal_uInt32 mnSize