[Libreoffice-commits] core.git: Branch 'private/tml/opencl-background-compilation' - 2 commits - sc/CppunitTest_sc_opencl_test.mk sc/inc sc/Library_sc.mk sc/source

Tor Lillqvist tml at collabora.com
Thu Nov 14 09:32:33 PST 2013


 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 <tml at collabora.com>
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 <tml at collabora.com>
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 \


More information about the Libreoffice-commits mailing list