1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
10 #include <config_feature_opencl.h>
12 #include <formulagroup.hxx>
13 #include <formulagroupcl.hxx>
14 #include <document.hxx>
15 #include <formulacell.hxx>
16 #include <interpre.hxx>
17 #include <globalnames.hxx>
19 #include <officecfg/Office/Common.hxx>
20 #if HAVE_FEATURE_OPENCL
21 #include <opencl/platforminfo.hxx>
23 #include <sal/log.hxx>
27 #include <unordered_map>
30 #if HAVE_FEATURE_OPENCL
31 # include <opencl/openclwrapper.hxx>
36 FormulaGroupEntry::FormulaGroupEntry( ScFormulaCell
** pCells
, size_t nRow
, size_t nLength
) :
37 mpCells(pCells
), mnRow(nRow
), mnLength(nLength
), mbShared(true) {}
39 FormulaGroupEntry::FormulaGroupEntry( ScFormulaCell
* pCell
, size_t nRow
) :
40 mpCell(pCell
), mnRow(nRow
), mnLength(0), mbShared(false) {}
42 size_t FormulaGroupContext::ColKey::Hash::operator ()( const FormulaGroupContext::ColKey
& rKey
) const
44 return rKey
.mnTab
* MAXCOLCOUNT_JUMBO
+ rKey
.mnCol
;
47 FormulaGroupContext::ColKey::ColKey( SCTAB nTab
, SCCOL nCol
) : mnTab(nTab
), mnCol(nCol
) {}
49 bool FormulaGroupContext::ColKey::operator== ( const ColKey
& r
) const
51 return mnTab
== r
.mnTab
&& mnCol
== r
.mnCol
;
54 FormulaGroupContext::ColArray::ColArray( NumArrayType
* pNumArray
, StrArrayType
* pStrArray
) :
55 mpNumArray(pNumArray
), mpStrArray(pStrArray
), mnSize(0)
58 mnSize
= mpNumArray
->size();
60 mnSize
= mpStrArray
->size();
63 FormulaGroupContext::ColArray
* FormulaGroupContext::getCachedColArray( SCTAB nTab
, SCCOL nCol
, size_t nSize
)
65 ColArraysType::iterator itColArray
= maColArrays
.find(ColKey(nTab
, nCol
));
66 if (itColArray
== maColArrays
.end())
67 // Not cached for this column.
70 ColArray
& rCached
= itColArray
->second
;
71 if (nSize
> rCached
.mnSize
)
72 // Cached data array is not long enough for the requested range.
78 FormulaGroupContext::ColArray
* FormulaGroupContext::setCachedColArray(
79 SCTAB nTab
, SCCOL nCol
, NumArrayType
* pNumArray
, StrArrayType
* pStrArray
)
81 ColArraysType::iterator it
= maColArrays
.find(ColKey(nTab
, nCol
));
82 if (it
== maColArrays
.end())
84 std::pair
<ColArraysType::iterator
,bool> r
=
85 maColArrays
.emplace(ColKey(nTab
, nCol
), ColArray(pNumArray
, pStrArray
));
88 // Somehow the insertion failed.
91 return &r
.first
->second
;
94 // Prior array exists for this column. Overwrite it.
95 ColArray
& rArray
= it
->second
;
96 rArray
= ColArray(pNumArray
, pStrArray
);
100 void FormulaGroupContext::discardCachedColArray( SCTAB nTab
, SCCOL nCol
)
102 ColArraysType::iterator itColArray
= maColArrays
.find(ColKey(nTab
, nCol
));
103 if (itColArray
!= maColArrays
.end())
104 maColArrays
.erase(itColArray
);
107 void FormulaGroupContext::ensureStrArray( ColArray
& rColArray
, size_t nArrayLen
)
109 if (rColArray
.mpStrArray
)
112 m_StrArrays
.push_back(
113 std::make_unique
<sc::FormulaGroupContext::StrArrayType
>(nArrayLen
, nullptr));
114 rColArray
.mpStrArray
= m_StrArrays
.back().get();
117 void FormulaGroupContext::ensureNumArray( ColArray
& rColArray
, size_t nArrayLen
)
119 if (rColArray
.mpNumArray
)
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();
128 FormulaGroupContext::FormulaGroupContext()
132 FormulaGroupContext::~FormulaGroupContext()
136 CompiledFormula::CompiledFormula() {}
138 CompiledFormula::~CompiledFormula() {}
140 FormulaGroupInterpreter
*FormulaGroupInterpreter::msInstance
= nullptr;
142 void FormulaGroupInterpreter::MergeCalcConfig(const ScDocument
& rDoc
)
144 maCalcConfig
= ScInterpreter::GetGlobalConfig();
145 maCalcConfig
.MergeDocumentSpecific(rDoc
.GetCalcConfig());
148 /// load and/or configure the correct formula group interpreter
149 FormulaGroupInterpreter
*FormulaGroupInterpreter::getStatic()
153 #if HAVE_FEATURE_OPENCL
154 if (ScCalcConfig::isOpenCLEnabled())
156 const ScCalcConfig
& rConfig
= ScInterpreter::GetGlobalConfig();
157 if( !switchOpenCLDevice(rConfig
.maOpenCLDevice
, rConfig
.mbOpenCLAutoSelect
))
159 if( ScCalcConfig::getForceCalculationType() == ForceCalculationOpenCL
)
161 SAL_WARN( "opencl", "OpenCL forced but failed to initialize" );
172 #if HAVE_FEATURE_OPENCL
173 void FormulaGroupInterpreter::fillOpenCLInfo(std::vector
<OpenCLPlatformInfo
>& rPlatforms
)
175 const std::vector
<OpenCLPlatformInfo
>& rPlatformsFromWrapper
=
176 openclwrapper::fillOpenCLInfo();
178 rPlatforms
.assign(rPlatformsFromWrapper
.begin(), rPlatformsFromWrapper
.end());
181 bool FormulaGroupInterpreter::switchOpenCLDevice(std::u16string_view rDeviceId
, bool bAutoSelect
, bool bForceEvaluation
)
183 bool bOpenCLEnabled
= ScCalcConfig::isOpenCLEnabled();
184 if (!bOpenCLEnabled
|| (rDeviceId
== u
"" OPENCL_SOFTWARE_DEVICE_CONFIG_NAME
))
187 msInstance
= nullptr;
191 OUString aSelectedCLDeviceVersionID
;
192 bool bSuccess
= openclwrapper::switchOpenCLDevice(rDeviceId
, bAutoSelect
, bForceEvaluation
, aSelectedCLDeviceVersionID
);
198 msInstance
= new sc::opencl::FormulaGroupInterpreterOpenCL();
203 void FormulaGroupInterpreter::getOpenCLDeviceInfo(sal_Int32
& rDeviceId
, sal_Int32
& rPlatformId
)
207 bool bOpenCLEnabled
= ScCalcConfig::isOpenCLEnabled();
211 size_t aDeviceId
= static_cast<size_t>(-1);
212 size_t aPlatformId
= static_cast<size_t>(-1);
214 openclwrapper::getOpenCLDeviceInfo(aDeviceId
, aPlatformId
);
215 rDeviceId
= aDeviceId
;
216 rPlatformId
= aPlatformId
;
219 void FormulaGroupInterpreter::enableOpenCL_UnitTestsOnly()
221 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create());
222 officecfg::Office::Common::Misc::UseOpenCL::set(true, batch
);
225 ScCalcConfig aConfig
= ScInterpreter::GetGlobalConfig();
227 aConfig
.mbOpenCLSubsetOnly
= false;
228 aConfig
.mnOpenCLMinimumFormulaGroupSize
= 2;
230 ScInterpreter::SetGlobalConfig(aConfig
);
233 void FormulaGroupInterpreter::disableOpenCL_UnitTestsOnly()
235 std::shared_ptr
<comphelper::ConfigurationChanges
> batch(comphelper::ConfigurationChanges::create());
236 officecfg::Office::Common::Misc::UseOpenCL::set(false, batch
);
244 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */