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 <unordered_map>
27 #include <vector>
28 
29 #if HAVE_FEATURE_OPENCL
30 # include <opencl/openclwrapper.hxx>
31 #endif
32 
33 namespace sc {
34 
35 FormulaGroupEntry::FormulaGroupEntry( ScFormulaCell** pCells, size_t nRow, size_t nLength ) :
36  mpCells(pCells), mnRow(nRow), mnLength(nLength), mbShared(true) {}
37 
39  mpCell(pCell), mnRow(nRow), mnLength(0), mbShared(false) {}
40 
42 {
43  return rKey.mnTab * MAXCOLCOUNT + rKey.mnCol;
44 }
45 
47 
49 {
50  return mnTab == r.mnTab && mnCol == r.mnCol;
51 }
52 
54  mpNumArray(pNumArray), mpStrArray(pStrArray), mnSize(0)
55 {
56  if (mpNumArray)
57  mnSize = mpNumArray->size();
58  else if (mpStrArray)
59  mnSize = mpStrArray->size();
60 }
61 
63 {
64  ColArraysType::iterator itColArray = maColArrays.find(ColKey(nTab, nCol));
65  if (itColArray == maColArrays.end())
66  // Not cached for this column.
67  return nullptr;
68 
69  ColArray& rCached = itColArray->second;
70  if (nSize > rCached.mnSize)
71  // Cached data array is not long enough for the requested range.
72  return nullptr;
73 
74  return &rCached;
75 }
76 
78  SCTAB nTab, SCCOL nCol, NumArrayType* pNumArray, StrArrayType* pStrArray )
79 {
80  ColArraysType::iterator it = maColArrays.find(ColKey(nTab, nCol));
81  if (it == maColArrays.end())
82  {
83  std::pair<ColArraysType::iterator,bool> r =
84  maColArrays.emplace(ColKey(nTab, nCol), ColArray(pNumArray, pStrArray));
85 
86  if (!r.second)
87  // Somehow the insertion failed.
88  return nullptr;
89 
90  return &r.first->second;
91  }
92 
93  // Prior array exists for this column. Overwrite it.
94  ColArray& rArray = it->second;
95  rArray = ColArray(pNumArray, pStrArray);
96  return &rArray;
97 }
98 
100 {
101  ColArraysType::iterator itColArray = maColArrays.find(ColKey(nTab, nCol));
102  if (itColArray != maColArrays.end())
103  maColArrays.erase(itColArray);
104 }
105 
106 void FormulaGroupContext::ensureStrArray( ColArray& rColArray, size_t nArrayLen )
107 {
108  if (rColArray.mpStrArray)
109  return;
110 
111  m_StrArrays.push_back(
112  std::make_unique<sc::FormulaGroupContext::StrArrayType>(nArrayLen, nullptr));
113  rColArray.mpStrArray = m_StrArrays.back().get();
114 }
115 
116 void FormulaGroupContext::ensureNumArray( ColArray& rColArray, size_t nArrayLen )
117 {
118  if (rColArray.mpNumArray)
119  return;
120 
121  double fNan;
122  rtl::math::setNan(&fNan);
123 
124  m_NumArrays.push_back(
125  std::make_unique<sc::FormulaGroupContext::NumArrayType>(nArrayLen, fNan));
126  rColArray.mpNumArray = m_NumArrays.back().get();
127 }
128 
130 {
131 }
132 
134 {
135 }
136 
138 
140 
142 
144 {
145  maCalcConfig = ScInterpreter::GetGlobalConfig();
146  maCalcConfig.MergeDocumentSpecific(rDoc.GetCalcConfig());
147 }
148 
151 {
152  if ( !msInstance )
153  {
154 #if HAVE_FEATURE_OPENCL
156  {
157  const ScCalcConfig& rConfig = ScInterpreter::GetGlobalConfig();
159  {
161  {
162  SAL_WARN( "opencl", "OpenCL forced but failed to initialize" );
163  abort();
164  }
165  }
166  }
167 #endif
168  }
169 
170  return msInstance;
171 }
172 
173 #if HAVE_FEATURE_OPENCL
174 void FormulaGroupInterpreter::fillOpenCLInfo(std::vector<OpenCLPlatformInfo>& rPlatforms)
175 {
176  const std::vector<OpenCLPlatformInfo>& rPlatformsFromWrapper =
178 
179  rPlatforms.assign(rPlatformsFromWrapper.begin(), rPlatformsFromWrapper.end());
180 }
181 
182 bool FormulaGroupInterpreter::switchOpenCLDevice(const OUString& rDeviceId, bool bAutoSelect, bool bForceEvaluation)
183 {
184  bool bOpenCLEnabled = ScCalcConfig::isOpenCLEnabled();
185  if (!bOpenCLEnabled || (rDeviceId == OPENCL_SOFTWARE_DEVICE_CONFIG_NAME))
186  {
187  delete msInstance;
188  msInstance = nullptr;
189  return false;
190  }
191 
192  OUString aSelectedCLDeviceVersionID;
193  bool bSuccess = openclwrapper::switchOpenCLDevice(&rDeviceId, bAutoSelect, bForceEvaluation, aSelectedCLDeviceVersionID);
194 
195  if (!bSuccess)
196  return false;
197 
198  delete msInstance;
200 
201  return true;
202 }
203 
204 void FormulaGroupInterpreter::getOpenCLDeviceInfo(sal_Int32& rDeviceId, sal_Int32& rPlatformId)
205 {
206  rDeviceId = -1;
207  rPlatformId = -1;
208  bool bOpenCLEnabled = ScCalcConfig::isOpenCLEnabled();
209  if(!bOpenCLEnabled)
210  return;
211 
212  size_t aDeviceId = static_cast<size_t>(-1);
213  size_t aPlatformId = static_cast<size_t>(-1);
214 
215  openclwrapper::getOpenCLDeviceInfo(aDeviceId, aPlatformId);
216  rDeviceId = aDeviceId;
217  rPlatformId = aPlatformId;
218 }
219 
220 void FormulaGroupInterpreter::enableOpenCL_UnitTestsOnly()
221 {
222  std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
223  officecfg::Office::Common::Misc::UseOpenCL::set(true, batch);
224  batch->commit();
225 
227 
228  aConfig.mbOpenCLSubsetOnly = false;
230 
232 }
233 
234 void FormulaGroupInterpreter::disableOpenCL_UnitTestsOnly()
235 {
236  std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
237  officecfg::Office::Common::Misc::UseOpenCL::set(false, batch);
238  batch->commit();
239 }
240 
241 #endif
242 
243 } // namespace sc
244 
245 /* 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:3867
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:3872
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:2526
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