sc/CppunitTest_sc_opencl_test.mk | 1 sc/Library_sc.mk | 1 sc/inc/formulagroupinterpreter.hxx | 10 - sc/source/core/data/formulacell.cxx | 245 ---------------------------- sc/source/core/data/grouptokenconverter.cxx | 236 ++++++++++++++++++++++++++ sc/source/core/inc/grouptokenconverter.hxx | 38 ++++ sc/source/core/opencl/formulagroupcl.cxx | 44 +++-- sc/source/core/tool/clkernelthread.cxx | 3 sc/source/core/tool/formulagroup.cxx | 7 9 files changed, 326 insertions(+), 259 deletions(-)
New commits: commit 246b6f96b7d23e9c742b2e255d6295a4453d9888 Author: Tor Lillqvist <[email protected]> Date: Thu Nov 14 19:30:36 2013 +0200 WIP: Background ahead-of-time OpenCL compilation Work in progress, does not work. That's what WIP means. Change-Id: I31459624a45370384e00392937ac9a5b9cd893c2 diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index 90280ce..0fb25ea 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -146,6 +146,7 @@ $(eval $(call gb_Library_add_exception_objects,sc,\ sc/source/core/data/global \ sc/source/core/data/global2 \ sc/source/core/data/globalx \ + sc/source/core/data/grouptokenconverter \ sc/source/core/data/listenercontext \ sc/source/core/data/markarr \ sc/source/core/data/markdata \ diff --git a/sc/inc/formulagroupinterpreter.hxx b/sc/inc/formulagroupinterpreter.hxx index 452ee61..f408727 100644 --- a/sc/inc/formulagroupinterpreter.hxx +++ b/sc/inc/formulagroupinterpreter.hxx @@ -49,8 +49,9 @@ class SC_DLLPUBLIC FormulaGroupInterpreter virtual ScMatrixRef inverseMatrix(const ScMatrix& rMat) = 0; virtual CompiledFormula* createCompiledFormula(ScDocument& rDoc, const ScAddress& rTopPos, + ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode) = 0; - virtual bool interpret(ScDocument& rDoc, const ScAddress& rTopPos, const ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode) = 0; + virtual bool interpret(ScDocument& rDoc, const ScAddress& rTopPos, ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode) = 0; }; /// Inherit from this for alternate formula group calculation approaches. @@ -60,11 +61,12 @@ public: FormulaGroupInterpreterSoftware(); virtual ~FormulaGroupInterpreterSoftware() {} - virtual ScMatrixRef inverseMatrix(const ScMatrix& rMat); + virtual ScMatrixRef inverseMatrix(const ScMatrix& rMat) SAL_OVERRIDE; virtual CompiledFormula* createCompiledFormula(ScDocument& rDoc, const ScAddress& rTopPos, - ScTokenArray& rCode); - virtual bool interpret(ScDocument& rDoc, const ScAddress& rTopPos, const ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode); + ScFormulaCellGroupRef& xGroup, + ScTokenArray& rCode) SAL_OVERRIDE; + virtual bool interpret(ScDocument& rDoc, const ScAddress& rTopPos, ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode) SAL_OVERRIDE; }; } diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx index 724922b..9f6fa00 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -3451,233 +3451,6 @@ ScFormulaCell::CompareState ScFormulaCell::CompareByTokenArray( ScFormulaCell& r return bInvariant ? EqualInvariant : EqualRelativeRef; } -namespace { - -class GroupTokenConverter -{ - ScTokenArray& mrGroupTokens; - ScDocument& mrDoc; - ScFormulaCell& mrCell; - const ScAddress& mrPos; - - bool isSelfReferenceRelative(const ScAddress& rRefPos, SCROW nRelRow) - { - if (rRefPos.Col() != mrPos.Col()) - return false; - - SCROW nLen = mrCell.GetCellGroup()->mnLength; - SCROW nEndRow = mrPos.Row() + nLen - 1; - - if (nRelRow < 0) - { - SCROW nTest = nEndRow; - nTest += nRelRow; - if (nTest >= mrPos.Row()) - return true; - } - else if (nRelRow > 0) - { - SCROW nTest = mrPos.Row(); // top row. - nTest += nRelRow; - if (nTest <= nEndRow) - return true; - } - - return false; - } - - bool isSelfReferenceAbsolute(const ScAddress& rRefPos) - { - if (rRefPos.Col() != mrPos.Col()) - return false; - - SCROW nLen = mrCell.GetCellGroup()->mnLength; - SCROW nEndRow = mrPos.Row() + nLen - 1; - - if (rRefPos.Row() < mrPos.Row()) - return false; - - if (rRefPos.Row() > nEndRow) - return false; - - return true; - } - - SCROW trimLength(SCTAB nTab, SCCOL nCol1, SCCOL nCol2, SCROW nRow, SCROW nRowLen) - { - SCROW nLastRow = nRow + nRowLen - 1; // current last row. - nLastRow = mrDoc.GetLastDataRow(nTab, nCol1, nCol2, nLastRow); - if (nLastRow < (nRow + nRowLen - 1)) - nRowLen = nLastRow - nRow + 1; - else if (nLastRow == 0) - // Column is empty. - nRowLen = 1; - - return nRowLen; - } -public: - GroupTokenConverter(ScTokenArray& rGroupTokens, ScDocument& rDoc, ScFormulaCell& rCell, const ScAddress& rPos) : - mrGroupTokens(rGroupTokens), mrDoc(rDoc), mrCell(rCell), mrPos(rPos) {} - - bool convert(ScTokenArray& rCode) - { -#if 0 - { // debug to start with: - ScCompiler aComp( &mrDoc, mrPos, rCode); - aComp.SetGrammar(formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1); - OUStringBuffer aAsString; - aComp.CreateStringFromTokenArray(aAsString); - } -#endif - - rCode.Reset(); - for (const formula::FormulaToken* p = rCode.First(); p; p = rCode.Next()) - { - // A reference can be either absolute or relative. If it's absolute, - // convert it to a static value token. If relative, convert it to a - // vector reference token. Note: we only care about relative vs - // absolute reference state for row directions. - - const ScToken* pToken = static_cast<const ScToken*>(p); - SCROW nLen = mrCell.GetCellGroup()->mnLength; - switch (pToken->GetType()) - { - case svSingleRef: - { - ScSingleRefData aRef = pToken->GetSingleRef(); - ScAddress aRefPos = aRef.toAbs(mrPos); - if (aRef.IsRowRel()) - { - if (isSelfReferenceRelative(aRefPos, aRef.Row())) - return false; - - // Trim data array length to actual data range. - nLen = trimLength(aRefPos.Tab(), aRefPos.Col(), aRefPos.Col(), aRefPos.Row(), nLen); - - // Fetch double array guarantees that the length of the - // returned array equals or greater than the requested - // length. - - formula::VectorRefArray aArray = mrDoc.FetchVectorRefArray(aRefPos, nLen); - if (!aArray.isValid()) - return false; - - formula::SingleVectorRefToken aTok(aArray, nLen); - mrGroupTokens.AddToken(aTok); - } - else - { - // Absolute row reference. - if (isSelfReferenceAbsolute(aRefPos)) - return false; - - formula::FormulaTokenRef pNewToken = mrDoc.ResolveStaticReference(aRefPos); - if (!pNewToken) - return false; - - mrGroupTokens.AddToken(*pNewToken); - } - } - break; - case svDoubleRef: - { - ScComplexRefData aRef = pToken->GetDoubleRef(); - ScRange aAbs = aRef.toAbs(mrPos); - - // Check for self reference. - if (aRef.Ref1.IsRowRel()) - { - if (isSelfReferenceRelative(aAbs.aStart, aRef.Ref1.Row())) - return false; - } - else if (isSelfReferenceAbsolute(aAbs.aStart)) - return false; - - if (aRef.Ref2.IsRowRel()) - { - if (isSelfReferenceRelative(aAbs.aEnd, aRef.Ref2.Row())) - return false; - } - else if (isSelfReferenceAbsolute(aAbs.aEnd)) - return false; - - // Row reference is relative. - bool bAbsFirst = !aRef.Ref1.IsRowRel(); - bool bAbsLast = !aRef.Ref2.IsRowRel(); - ScAddress aRefPos = aAbs.aStart; - size_t nCols = aAbs.aEnd.Col() - aAbs.aStart.Col() + 1; - std::vector<formula::VectorRefArray> aArrays; - aArrays.reserve(nCols); - SCROW nRefRowSize = aAbs.aEnd.Row() - aAbs.aStart.Row() + 1; - SCROW nArrayLength = nRefRowSize; - if (!bAbsLast) - { - // range end position is relative. Extend the array length. - SCROW nLastRefRowOffset = aAbs.aEnd.Row() - mrPos.Row(); - SCROW nLastRefRow = mrPos.Row() + nLen - 1 + nLastRefRowOffset; - SCROW nNewLength = nLastRefRow - aAbs.aStart.Row() + 1; - if (nNewLength > nArrayLength) - nArrayLength = nNewLength; - } - - // Trim trailing empty rows. - nArrayLength = trimLength(aRefPos.Tab(), aAbs.aStart.Col(), aAbs.aEnd.Col(), aRefPos.Row(), nArrayLength); - - for (SCCOL i = aAbs.aStart.Col(); i <= aAbs.aEnd.Col(); ++i) - { - aRefPos.SetCol(i); - formula::VectorRefArray aArray = mrDoc.FetchVectorRefArray(aRefPos, nArrayLength); - if (!aArray.isValid()) - return false; - - aArrays.push_back(aArray); - } - - formula::DoubleVectorRefToken aTok(aArrays, nArrayLength, nRefRowSize, bAbsFirst, bAbsLast); - mrGroupTokens.AddToken(aTok); - } - break; - case svIndex: - { - // Named range. - ScRangeName* pNames = mrDoc.GetRangeName(); - if (!pNames) - // This should never fail. - return false; - - ScRangeData* pRange = pNames->findByIndex(p->GetIndex()); - if (!pRange) - // No named range exists by that index. - return false; - - ScTokenArray* pNamedTokens = pRange->GetCode(); - if (!pNamedTokens) - // This named range is empty. - return false; - - mrGroupTokens.AddOpCode(ocOpen); - - if (!convert(*pNamedTokens)) - return false; - - mrGroupTokens.AddOpCode(ocClose); - } - break; - default: - mrGroupTokens.AddToken(*pToken); - } - } - - ScCompiler aComp(&mrDoc, mrPos, mrGroupTokens); - aComp.SetGrammar(mrDoc.GetGrammar()); - aComp.CompileTokenArray(); // Regenerate RPN tokens. - - return true; - } -}; - -} - bool ScFormulaCell::InterpretFormulaGroup() { if (!ScInterpreter::GetGlobalConfig().mbOpenCLEnabled) @@ -3707,23 +3480,17 @@ bool ScFormulaCell::InterpretFormulaGroup() if (mxGroup->mbInvariant && false) return InterpretInvariantFormulaGroup(); - ScTokenArray aCode; - ScAddress aTopPos = mxGroup->mpTopCell->aPos; - GroupTokenConverter aConverter(aCode, *pDocument, *this, aTopPos); - if (!aConverter.convert(*pCode)) + ScTokenArray aDummy; + if (mxGroup->meCalcState == sc::GroupCalcEnabled) + mxGroup->meCalcState = sc::GroupCalcRunning; + if (!sc::FormulaGroupInterpreter::getStatic()->interpret(*pDocument, mxGroup->mpTopCell->aPos, mxGroup, aDummy)) { mxGroup->meCalcState = sc::GroupCalcDisabled; return false; } - mxGroup->meCalcState = sc::GroupCalcRunning; - if (!sc::FormulaGroupInterpreter::getStatic()->interpret(*pDocument, aTopPos, mxGroup, aCode)) - { - mxGroup->meCalcState = sc::GroupCalcDisabled; - return false; - } - - mxGroup->meCalcState = sc::GroupCalcEnabled; + if (mxGroup->meCalcState == sc::GroupCalcRunning) + mxGroup->meCalcState = sc::GroupCalcEnabled; return true; } diff --git a/sc/source/core/data/grouptokenconverter.cxx b/sc/source/core/data/grouptokenconverter.cxx new file mode 100644 index 0000000..55b2709 --- /dev/null +++ b/sc/source/core/data/grouptokenconverter.cxx @@ -0,0 +1,236 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <formula/token.hxx> +#include <formula/vectortoken.hxx> + +#include "compiler.hxx" +#include "grouptokenconverter.hxx" + +using namespace formula; + +bool ScGroupTokenConverter::isSelfReferenceRelative(const ScAddress& rRefPos, SCROW nRelRow) +{ + if (rRefPos.Col() != mrPos.Col()) + return false; + + SCROW nLen = mrCell.GetCellGroup()->mnLength; + SCROW nEndRow = mrPos.Row() + nLen - 1; + + if (nRelRow < 0) + { + SCROW nTest = nEndRow; + nTest += nRelRow; + if (nTest >= mrPos.Row()) + return true; + } + else if (nRelRow > 0) + { + SCROW nTest = mrPos.Row(); // top row. + nTest += nRelRow; + if (nTest <= nEndRow) + return true; + } + + return false; +} + +bool ScGroupTokenConverter::isSelfReferenceAbsolute(const ScAddress& rRefPos) +{ + if (rRefPos.Col() != mrPos.Col()) + return false; + + SCROW nLen = mrCell.GetCellGroup()->mnLength; + SCROW nEndRow = mrPos.Row() + nLen - 1; + + if (rRefPos.Row() < mrPos.Row()) + return false; + + if (rRefPos.Row() > nEndRow) + return false; + + return true; +} + +SCROW ScGroupTokenConverter::trimLength(SCTAB nTab, SCCOL nCol1, SCCOL nCol2, SCROW nRow, SCROW nRowLen) +{ + SCROW nLastRow = nRow + nRowLen - 1; // current last row. + nLastRow = mrDoc.GetLastDataRow(nTab, nCol1, nCol2, nLastRow); + if (nLastRow < (nRow + nRowLen - 1)) + nRowLen = nLastRow - nRow + 1; + else if (nLastRow == 0) + // Column is empty. + nRowLen = 1; + + return nRowLen; +} + +ScGroupTokenConverter::ScGroupTokenConverter(ScTokenArray& rGroupTokens, ScDocument& rDoc, ScFormulaCell& rCell, const ScAddress& rPos) : + mrGroupTokens(rGroupTokens), mrDoc(rDoc), mrCell(rCell), mrPos(rPos) + +{ +} + +bool ScGroupTokenConverter::convert(ScTokenArray& rCode) +{ +#if 0 + { // debug to start with: + ScCompiler aComp( &mrDoc, mrPos, rCode); + aComp.SetGrammar(formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1); + OUStringBuffer aAsString; + aComp.CreateStringFromTokenArray(aAsString); + } +#endif + + rCode.Reset(); + for (const formula::FormulaToken* p = rCode.First(); p; p = rCode.Next()) + { + // A reference can be either absolute or relative. If it's absolute, + // convert it to a static value token. If relative, convert it to a + // vector reference token. Note: we only care about relative vs + // absolute reference state for row directions. + + const ScToken* pToken = static_cast<const ScToken*>(p); + SCROW nLen = mrCell.GetCellGroup()->mnLength; + switch (pToken->GetType()) + { + case svSingleRef: + { + ScSingleRefData aRef = pToken->GetSingleRef(); + ScAddress aRefPos = aRef.toAbs(mrPos); + if (aRef.IsRowRel()) + { + if (isSelfReferenceRelative(aRefPos, aRef.Row())) + return false; + + // Trim data array length to actual data range. + nLen = trimLength(aRefPos.Tab(), aRefPos.Col(), aRefPos.Col(), aRefPos.Row(), nLen); + + // Fetch double array guarantees that the length of the + // returned array equals or greater than the requested + // length. + + formula::VectorRefArray aArray = mrDoc.FetchVectorRefArray(aRefPos, nLen); + if (!aArray.isValid()) + return false; + + formula::SingleVectorRefToken aTok(aArray, nLen); + mrGroupTokens.AddToken(aTok); + } + else + { + // Absolute row reference. + if (isSelfReferenceAbsolute(aRefPos)) + return false; + + formula::FormulaTokenRef pNewToken = mrDoc.ResolveStaticReference(aRefPos); + if (!pNewToken) + return false; + + mrGroupTokens.AddToken(*pNewToken); + } + } + break; + case svDoubleRef: + { + ScComplexRefData aRef = pToken->GetDoubleRef(); + ScRange aAbs = aRef.toAbs(mrPos); + + // Check for self reference. + if (aRef.Ref1.IsRowRel()) + { + if (isSelfReferenceRelative(aAbs.aStart, aRef.Ref1.Row())) + return false; + } + else if (isSelfReferenceAbsolute(aAbs.aStart)) + return false; + + if (aRef.Ref2.IsRowRel()) + { + if (isSelfReferenceRelative(aAbs.aEnd, aRef.Ref2.Row())) + return false; + } + else if (isSelfReferenceAbsolute(aAbs.aEnd)) + return false; + + // Row reference is relative. + bool bAbsFirst = !aRef.Ref1.IsRowRel(); + bool bAbsLast = !aRef.Ref2.IsRowRel(); + ScAddress aRefPos = aAbs.aStart; + size_t nCols = aAbs.aEnd.Col() - aAbs.aStart.Col() + 1; + std::vector<formula::VectorRefArray> aArrays; + aArrays.reserve(nCols); + SCROW nRefRowSize = aAbs.aEnd.Row() - aAbs.aStart.Row() + 1; + SCROW nArrayLength = nRefRowSize; + if (!bAbsLast) + { + // range end position is relative. Extend the array length. + SCROW nLastRefRowOffset = aAbs.aEnd.Row() - mrPos.Row(); + SCROW nLastRefRow = mrPos.Row() + nLen - 1 + nLastRefRowOffset; + SCROW nNewLength = nLastRefRow - aAbs.aStart.Row() + 1; + if (nNewLength > nArrayLength) + nArrayLength = nNewLength; + } + + // Trim trailing empty rows. + nArrayLength = trimLength(aRefPos.Tab(), aAbs.aStart.Col(), aAbs.aEnd.Col(), aRefPos.Row(), nArrayLength); + + for (SCCOL i = aAbs.aStart.Col(); i <= aAbs.aEnd.Col(); ++i) + { + aRefPos.SetCol(i); + formula::VectorRefArray aArray = mrDoc.FetchVectorRefArray(aRefPos, nArrayLength); + if (!aArray.isValid()) + return false; + + aArrays.push_back(aArray); + } + + formula::DoubleVectorRefToken aTok(aArrays, nArrayLength, nRefRowSize, bAbsFirst, bAbsLast); + mrGroupTokens.AddToken(aTok); + } + break; + case svIndex: + { + // Named range. + ScRangeName* pNames = mrDoc.GetRangeName(); + if (!pNames) + // This should never fail. + return false; + + ScRangeData* pRange = pNames->findByIndex(p->GetIndex()); + if (!pRange) + // No named range exists by that index. + return false; + + ScTokenArray* pNamedTokens = pRange->GetCode(); + if (!pNamedTokens) + // This named range is empty. + return false; + + mrGroupTokens.AddOpCode(ocOpen); + + if (!convert(*pNamedTokens)) + return false; + + mrGroupTokens.AddOpCode(ocClose); + } + break; + default: + mrGroupTokens.AddToken(*pToken); + } + } + + ScCompiler aComp(&mrDoc, mrPos, mrGroupTokens); + aComp.SetGrammar(mrDoc.GetGrammar()); + aComp.CompileTokenArray(); // Regenerate RPN tokens. + + return true; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/inc/grouptokenconverter.hxx b/sc/source/core/inc/grouptokenconverter.hxx new file mode 100644 index 0000000..9685681 --- /dev/null +++ b/sc/source/core/inc/grouptokenconverter.hxx @@ -0,0 +1,38 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_SC_SOURCE_CORE_INC_GROUPTOKENCONVERTER_HXX +#define INCLUDED_SC_SOURCE_CORE_INC_GROUPTOKENCONVERTER_HXX + +#include "document.hxx" +#include "formulacell.hxx" +#include "scdllapi.h" +#include "tokenarray.hxx" +#include "types.hxx" + +class SC_DLLPUBLIC ScGroupTokenConverter +{ + ScTokenArray& mrGroupTokens; + ScDocument& mrDoc; + ScFormulaCell& mrCell; + const ScAddress& mrPos; + + bool isSelfReferenceRelative(const ScAddress& rRefPos, SCROW nRelRow); + bool isSelfReferenceAbsolute(const ScAddress& rRefPos); + SCROW trimLength(SCTAB nTab, SCCOL nCol1, SCCOL nCol2, SCROW nRow, SCROW nRowLen); + +public: + ScGroupTokenConverter(ScTokenArray& rGroupTokens, ScDocument& rDoc, ScFormulaCell& rCell, const ScAddress& rPos); + + bool convert(ScTokenArray& rCode); +}; + +#endif // INCLUDED_SC_SOURCE_CORE_INC_GROUPTOKENCONVERTER_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx index a1b902e..3465dd9 100644 --- a/sc/source/core/opencl/formulagroupcl.cxx +++ b/sc/source/core/opencl/formulagroupcl.cxx @@ -8,6 +8,7 @@ */ #include "formulagroupinterpreter.hxx" +#include "grouptokenconverter.hxx" #include "document.hxx" #include "formulacell.hxx" #include "tokenarray.hxx" @@ -1449,12 +1450,13 @@ public: { } - virtual ScMatrixRef inverseMatrix( const ScMatrix& rMat ); + virtual ScMatrixRef inverseMatrix( const ScMatrix& rMat ) SAL_OVERRIDE; virtual CompiledFormula* createCompiledFormula(ScDocument& rDoc, const ScAddress& rTopPos, - ScTokenArray& rCode); + ScFormulaCellGroupRef& xGroup, + ScTokenArray& rCode) SAL_OVERRIDE; virtual bool interpret( ScDocument& rDoc, const ScAddress& rTopPos, - const ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode ); + ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode ) SAL_OVERRIDE; }; ScMatrixRef FormulaGroupInterpreterOpenCL::inverseMatrix( const ScMatrix& ) @@ -1512,9 +1514,10 @@ DynamicKernel* DynamicKernel::create(ScDocument& /* rDoc */, if (!pDynamicKernel) return NULL; - // OpenCL source code generation + // OpenCL source code generation and kernel compilation try { pDynamicKernel->CodeGen(); + pDynamicKernel->CreateKernel(); } catch (const UnhandledToken &ut) { std::cerr << "\nDynamic formual compiler: unhandled token: "; @@ -1531,29 +1534,46 @@ DynamicKernel* DynamicKernel::create(ScDocument& /* rDoc */, CompiledFormula* FormulaGroupInterpreterOpenCL::createCompiledFormula(ScDocument& rDoc, const ScAddress& rTopPos, + ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode) { - return DynamicKernel::create(rDoc, rTopPos, rCode); + ScTokenArray aCode; + ScGroupTokenConverter aConverter(aCode, rDoc, *xGroup->mpTopCell, rTopPos); + if (!aConverter.convert(rCode)) + { + return NULL; + } + + return DynamicKernel::create(rDoc, rTopPos, aCode); } bool FormulaGroupInterpreterOpenCL::interpret( ScDocument& rDoc, - const ScAddress& rTopPos, const ScFormulaCellGroupRef& xGroup, + const ScAddress& rTopPos, ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode ) { DynamicKernel *pKernel; osl::ResettableMutexGuard aGuard(xGroup->maMutex); - if (xGroup->meCalcState == sc::GroupCalcOpenCLKernelCompilationScheduled) + if (xGroup->meCalcState == sc::GroupCalcOpenCLKernelCompilationScheduled || + xGroup->meCalcState == sc::GroupCalcOpenCLKernelBinaryCreated) { - aGuard.clear(); - xGroup->maCompilationDone.wait(); - xGroup->maCompilationDone.reset(); + if (xGroup->meCalcState == sc::GroupCalcOpenCLKernelCompilationScheduled) + { + aGuard.clear(); + xGroup->maCompilationDone.wait(); + xGroup->maCompilationDone.reset(); + } + else + { + aGuard.clear(); + } + pKernel = static_cast<DynamicKernel*>(xGroup->mpCompiledFormula); } else { aGuard.clear(); - pKernel = DynamicKernel::create(rDoc, rTopPos, rCode); + pKernel = static_cast<DynamicKernel*>(createCompiledFormula(rDoc, rTopPos, xGroup, rCode)); } if (!pKernel) @@ -1563,8 +1583,6 @@ bool FormulaGroupInterpreterOpenCL::interpret( ScDocument& rDoc, // Obtain cl context KernelEnv kEnv; OpenclDevice::setKernelEnv(&kEnv); - // Compile kernel here!!! - pKernel->CreateKernel(); // Run the kernel. pKernel->Launch(xGroup->mnLength); // Map results back diff --git a/sc/source/core/tool/clkernelthread.cxx b/sc/source/core/tool/clkernelthread.cxx index 7404a80..f4debc6 100644 --- a/sc/source/core/tool/clkernelthread.cxx +++ b/sc/source/core/tool/clkernelthread.cxx @@ -10,6 +10,7 @@ #include <sal/log.hxx> #include "formulagroupinterpreter.hxx" +#include "grouptokenconverter.hxx" #include "clkernelthread.hxx" @@ -52,8 +53,10 @@ void CLBuildKernelThread::execute() aWorkItem.mxGroup->mpCompiledFormula = sc::FormulaGroupInterpreter::getStatic()->createCompiledFormula(*aWorkItem.mxGroup->mpTopCell->GetDocument(), aWorkItem.mxGroup->mpTopCell->aPos, + aWorkItem.mxGroup, *aWorkItem.mxGroup->mpCode); aWorkItem.mxGroup->meCalcState = sc::GroupCalcOpenCLKernelBinaryCreated; + SAL_INFO("sc.opencl.thread", "group " << aWorkItem.mxGroup << " compilation done"); aWorkItem.mxGroup->maCompilationDone.set(); break; case CLBuildKernelWorkItem::FINISH: diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx index 4ddea3b..7bb10ad 100644 --- a/sc/source/core/tool/formulagroup.cxx +++ b/sc/source/core/tool/formulagroup.cxx @@ -288,13 +288,14 @@ ScMatrixRef FormulaGroupInterpreterSoftware::inverseMatrix(const ScMatrix& /*rMa CompiledFormula* FormulaGroupInterpreterSoftware::createCompiledFormula(ScDocument& /* rDoc */, const ScAddress& /* rTopPos */, + ScFormulaCellGroupRef& /* xGroup */, ScTokenArray& /* rCode */) { return NULL; } bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddress& rTopPos, - const ScFormulaCellGroupRef& xGroup, + ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode) { typedef boost::unordered_map<const formula::FormulaToken*, formula::FormulaTokenRef> CachedTokensType; @@ -493,8 +494,8 @@ public: FormulaGroupInterpreterOpenCLMissing() : FormulaGroupInterpreter() {} virtual ~FormulaGroupInterpreterOpenCLMissing() {} virtual ScMatrixRef inverseMatrix(const ScMatrix&) { return ScMatrixRef(); } - virtual CompiledFormula* createCompiledFormula(ScDocument&, const ScAddress&, ScTokenArray&) { return NULL; } - virtual bool interpret(ScDocument&, const ScAddress&, const ScFormulaCellGroupRef&, ScTokenArray&) { return false; } + virtual CompiledFormula* createCompiledFormula(ScDocument&, const ScAddress&, ScFormulaCellGroupRef&, ScTokenArray&) { return NULL; } + virtual bool interpret(ScDocument&, const ScAddress&, ScFormulaCellGroupRef&, ScTokenArray&) { return false; } }; static void SAL_CALL thisModule() {} commit d1c0c80b3134aa44c5d26841b800fc918bddb857 Author: Tor Lillqvist <[email protected]> Date: Thu Nov 14 18:31:40 2013 +0200 This test opens the scopencl library dynamically, sigh Change-Id: I34c512573fcee108ab9b27a631671587665aad22 diff --git a/sc/CppunitTest_sc_opencl_test.mk b/sc/CppunitTest_sc_opencl_test.mk index ecb6d29..d808e44 100644 --- a/sc/CppunitTest_sc_opencl_test.mk +++ b/sc/CppunitTest_sc_opencl_test.mk @@ -37,6 +37,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sc_opencl_test, \ salhelper \ sax \ sc \ + scopencl \ scqahelper \ sfx \ sot \ _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
