[Libreoffice-commits] core.git: Branch 'feature/calc-group-interpreter' - sc/inc sc/Library_sc.mk sc/source

Michael Meeks michael.meeks at suse.com
Thu Jun 27 08:49:18 PDT 2013


 sc/Library_sc.mk                         |    1 
 sc/inc/document.hxx                      |    1 
 sc/inc/formulagroup.hxx                  |   30 ++-
 sc/source/core/data/documen2.cxx         |    2 
 sc/source/core/data/formulacell.cxx      |    4 
 sc/source/core/inc/openclwrapper.hxx     |  184 -------------------
 sc/source/core/opencl/formulagroupcl.cxx |  287 +++++++++++++++++++++++++++++++
 sc/source/core/opencl/openclwrapper.hxx  |  184 +++++++++++++++++++
 sc/source/core/tool/formulagroup.cxx     |  228 ++++--------------------
 sc/source/ui/app/scmod.cxx               |   17 -
 10 files changed, 546 insertions(+), 392 deletions(-)

New commits:
commit 943d4491300708b05e478690010a1209398aeabb
Author: Michael Meeks <michael.meeks at suse.com>
Date:   Thu Jun 27 16:49:41 2013 +0100

    abstract out the FormulaGroupInterpreter more cleanly.

diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 070aa37..7afd018 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -53,6 +53,7 @@ ifeq ($(ENABLE_OPENCL),TRUE)
 $(eval $(call gb_Library_use_externals,sc,opencl))
 
 $(eval $(call gb_Library_add_exception_objects,sc,\
+	sc/source/core/opencl/formulagroupcl \
 	sc/source/core/opencl/openclwrapper \
 ))
 endif
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index f123008..12cd7ff 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -417,6 +417,7 @@ private:
     ::std::set<ScFormulaCell*> maSubTotalCells;
 
     bool                mbUseEmbedFonts;
+
 public:
     bool              IsUsingEmbededFonts() { return mbUseEmbedFonts; }
     void              SetIsUsingEmbededFonts( bool bUse ) { mbUseEmbedFonts = bUse; }
diff --git a/sc/inc/formulagroup.hxx b/sc/inc/formulagroup.hxx
index 55f6e09..e5839e4 100644
--- a/sc/inc/formulagroup.hxx
+++ b/sc/inc/formulagroup.hxx
@@ -30,19 +30,31 @@ struct FormulaGroupContext : boost::noncopyable
 };
 
 /**
- * All the vectorized formula calculation code should be collectd here.
+ * All the vectorized formula calculation code should be collected here.
+ *
+ * Abstract base class for formula group interpreters, and a factory.
  */
-class FormulaGroupInterpreter
+class SC_DLLPUBLIC FormulaGroupInterpreter
+{
+    static FormulaGroupInterpreter *msInstance;
+ protected:
+    FormulaGroupInterpreter() {}
+    virtual ~FormulaGroupInterpreter() {}
+ public:
+    static FormulaGroupInterpreter *getStatic();
+
+    virtual bool interpret(ScDocument& rDoc, const ScAddress& rTopPos, const ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode) = 0;
+};
+
+/// Inherit from this for alternate formula group calculation approaches.
+class SC_DLLPUBLIC FormulaGroupInterpreterSoftware : public FormulaGroupInterpreter
 {
-    ScDocument& mrDoc;
-    ScAddress maTopPos;
-    ScFormulaCellGroupRef mxGroup;
-    ScTokenArray& mrCode;
 public:
-    FormulaGroupInterpreter(
-        ScDocument& rDoc, const ScAddress& rTopPos, const ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode);
+    FormulaGroupInterpreterSoftware() :
+        FormulaGroupInterpreter() {}
+    virtual ~FormulaGroupInterpreterSoftware() {}
 
-    bool interpret();
+    virtual bool interpret(ScDocument& rDoc, const ScAddress& rTopPos, const ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode);
 };
 
 }
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 3869f6e..6c520a0 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -86,6 +86,8 @@
 #include "macromgr.hxx"
 #include "formulacell.hxx"
 #include "clipcontext.hxx"
+#include "interpre.hxx"
+#include "formulagroup.hxx"
 
 using namespace com::sun::star;
 
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 48af974..c175010 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -3120,9 +3120,7 @@ bool ScFormulaCell::InterpretFormulaGroup()
     GroupTokenConverter aConverter(aCode, *pDocument, *this);
     if (!aConverter.convert(*pCode))
         return false;
-
-    sc::FormulaGroupInterpreter aInterpreter(*pDocument, aPos, xGroup, aCode);
-    return aInterpreter.interpret();
+    return sc::FormulaGroupInterpreter::getStatic()->interpret(*pDocument, aPos, xGroup, aCode);
 }
 
 bool ScFormulaCell::InterpretInvariantFormulaGroup()
diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
new file mode 100644
index 0000000..54fd8e8
--- /dev/null
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -0,0 +1,287 @@
+/* -*- 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 <config_features.h>
+#include "formulagroup.hxx"
+#include "document.hxx"
+#include "formulacell.hxx"
+#include "tokenarray.hxx"
+#include "compiler.hxx"
+#include "interpre.hxx"
+#include "formula/vectortoken.hxx"
+
+#include "openclwrapper.hxx"
+
+namespace sc {
+
+// A single public entry point for a factory function:
+namespace opencl {
+    extern sc::FormulaGroupInterpreter *createFormulaGroupInterpreter();
+}
+
+/////time test dbg
+double getTimeDiff(const TimeValue& t1, const TimeValue& t2)
+{
+    double tv1 = t1.Seconds;
+    double tv2 = t2.Seconds;
+    tv1 += t1.Nanosec / 1000000000.0;
+    tv2 += t2.Nanosec / 1000000000.0;
+
+    return tv1 - tv2;
+}//dbg-t
+TimeValue aTimeBefore, aTimeAfter;
+///////////////////////////////////////
+
+class FormulaGroupInterpreterOpenCL : public FormulaGroupInterpreterSoftware
+{
+public:
+    FormulaGroupInterpreterOpenCL() :
+        FormulaGroupInterpreterSoftware()
+    {
+        OclCalc::InitEnv();
+    }
+    virtual ~FormulaGroupInterpreterOpenCL()
+    {
+        OclCalc::ReleaseOpenclRunEnv();
+    }
+    virtual bool interpret(ScDocument& rDoc, const ScAddress& rTopPos,
+                           const ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode);
+};
+
+bool FormulaGroupInterpreterOpenCL::interpret(ScDocument& rDoc, const ScAddress& rTopPos,
+                                              const ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode)
+{
+    size_t rowSize = xGroup->mnLength; //, srcSize = 0;
+    fprintf(stderr,"rowSize at begin is ...%ld.\n",(long)rowSize);
+    int *rangeStart =NULL; // The first position for calculation,for example,the A1 in (=MAX(A1:A100))
+    int *rangeEnd = NULL; // The last position for calculation,for example, the A100 in (=MAX(A1:A100))
+    // The row quantity can be gotten from p2->GetArrayLength()
+    int count1 =0,count2 =0,count3=0;
+    int oclOp=0;
+    double *srcData = NULL; // Point to the input data from CPU
+    double *rResult=NULL; // Point to the output data from GPU
+    double *leftData=NULL; // Left input for binary operator(+,-,*,/),for example,(=leftData+rightData)
+    double *rightData=NULL; // Right input for binary operator(+,-,*,/),for example,(=leftData/rightData)
+                            // The rightData can't be zero for "/"
+
+    leftData  = (double *)malloc(sizeof(double) * rowSize);
+    rightData = (double *)malloc(sizeof(double) * rowSize);
+    rResult   = (double *)malloc(sizeof(double) * rowSize*2);// For 2 columns(B,C)
+    srcData = (double *)calloc(rowSize,sizeof(double));
+
+    rangeStart =(int *)malloc(sizeof(int) * rowSize);
+    rangeEnd   =(int *)malloc(sizeof(int) * rowSize);
+
+    memset(rResult,0,rowSize);
+    if(NULL==leftData||NULL==rightData||
+           NULL==rResult||NULL==rangeStart||NULL==rangeEnd)
+    {
+        printf("malloc err\n");
+        return false;
+    }
+    // printf("rowSize is %d.\n",rowsize);
+
+    // Until we implement group calculation for real, decompose the group into
+    // individual formula token arrays for individual calculation.
+    ScAddress aTmpPos = rTopPos;
+    for (sal_Int32 i = 0; i < xGroup->mnLength; ++i)
+    {
+        aTmpPos.SetRow(xGroup->mnStart + i);
+        ScTokenArray aCode2;
+        for (const formula::FormulaToken* p = rCode.First(); p; p = rCode.Next())
+        {
+            switch (p->GetType())
+            {
+                case formula::svSingleVectorRef:
+                {
+                    const formula::SingleVectorRefToken* p2 = static_cast<const formula::SingleVectorRefToken*>(p);
+                    const double* pArray = p2->GetArray();
+                    aCode2.AddDouble(static_cast<size_t>(i) < p2->GetArrayLength() ? pArray[i] : 0.0);
+                }
+                break;
+                case formula::svDoubleVectorRef:
+                {
+                    const formula::DoubleVectorRefToken* p2 = static_cast<const formula::DoubleVectorRefToken*>(p);
+                    const std::vector<const double*>& rArrays = p2->GetArrays();
+                    size_t nColSize = rArrays.size();
+                    size_t nRowStart = p2->IsStartFixed() ? 0 : i;
+                    size_t nRowEnd = p2->GetRefRowSize() - 1;
+                    if (!p2->IsEndFixed())
+                        nRowEnd += i;
+                    size_t nRowSize = nRowEnd - nRowStart + 1;
+                    ScMatrixRef pMat(new ScMatrix(nColSize, nRowSize, 0.0));
+
+                    //srcSize = rowSize+nRowSize-rowSize%nRowSize;//align as nRowSize
+                    //srcData = (double *)calloc(srcSize,sizeof(double));
+                    rangeStart[i] = nRowStart;//record the start position
+                    rangeEnd[i] = nRowEnd;//record the end position
+
+                    for (size_t nCol = 0; nCol < nColSize; ++nCol)
+                    {
+                        const double* pArray = rArrays[nCol];
+
+                        //printf("pArray is %p.\n",pArray);
+                        if( NULL==pArray )
+                        {
+                            fprintf(stderr,"Error: pArray is NULL!\n");
+                            return false;
+                        }
+                        //fprintf(stderr,"(rowSize+nRowSize-1) is %d.\n",rowSize+nRowSize-1);
+                        for( size_t u=0; u<rowSize; u++ )
+                        {
+                            srcData[u] = pArray[u];// note:rowSize<=srcSize
+                            //fprintf(stderr,"srcData[%d] is %f.\n",u,srcData[u]);
+                        }
+
+                        for (size_t nRow = 0; nRow < nRowSize; ++nRow)
+                        {
+                            if (nRowStart + nRow < p2->GetArrayLength())
+                            {
+                                double fVal = pArray[nRowStart+nRow];
+                                pMat->PutDouble(fVal, nCol, nRow);
+                            }
+                        }
+                    }
+
+                    ScMatrixToken aTok(pMat);
+                    aCode2.AddToken(aTok);
+                }
+                break;
+                default:
+                    aCode2.AddToken(*p);
+            }
+        }
+
+        ScFormulaCell* pDest = rDoc.GetFormulaCell(aTmpPos);
+        if (!pDest)
+            return false;
+
+        const formula::FormulaToken *pCur = aCode2.First();
+        aCode2.Reset();
+        while( ( pCur = aCode2.Next() ) != NULL )
+        {
+            OpCode eOp = pCur->GetOpCode();
+            if(eOp==0)
+            {
+                  if(count3%2==0)
+                    leftData[count1++] = pCur->GetDouble();
+                   else
+                    rightData[count2++] = pCur->GetDouble();
+                count3++;
+               }
+               else if( eOp!=ocOpen && eOp!=ocClose )
+                oclOp = eOp;
+
+//            if(count1>0){//dbg
+//                fprintf(stderr,"leftData is %f.\n",leftData[count1-1]);
+//                count1--;
+//            }
+//            if(count2>0){//dbg
+//                fprintf(stderr,"rightData is %f.\n",rightData[count2-1]);
+//                count2--;
+//            }
+        }
+
+        if(!getenv("SC_GPU"))
+        {
+            fprintf(stderr,"ccCPU flow...\n\n");
+            ScCompiler aComp(&rDoc, aTmpPos, aCode2);
+            aComp.SetGrammar(rDoc.GetGrammar());
+            aComp.CompileTokenArray(); // Create RPN token array.
+            ScInterpreter aInterpreter(pDest, &rDoc, aTmpPos, aCode2);
+            aInterpreter.Interpret();
+            pDest->SetResultToken(aInterpreter.GetResultToken().get());
+            pDest->ResetDirty();
+            pDest->SetChanged(true);
+        }
+    } // for loop end (xGroup->mnLength)
+
+    // For GPU calculation
+    if(getenv("SC_GPU"))
+    {
+            fprintf(stderr,"ggGPU flow...\n\n");
+            printf(" oclOp is... %d\n",oclOp);
+            osl_getSystemTime(&aTimeBefore); //timer
+            static OclCalc ocl_calc;
+            switch(oclOp)
+            {
+                case ocAdd:
+                       ocl_calc.OclHostSignedAdd(leftData,rightData,rResult,count1);
+                    break;
+                case ocSub:
+                    ocl_calc.OclHostSignedSub(leftData,rightData,rResult,count1);
+                    break;
+                case ocMul:
+                    ocl_calc.OclHostSignedMul(leftData,rightData,rResult,count1);
+                    break;
+                case ocDiv:
+                    ocl_calc.OclHostSignedDiv(leftData,rightData,rResult,count1);
+                    break;
+                case ocMax:
+                    ocl_calc.OclHostFormulaMax(srcData,rangeStart,rangeEnd,rResult,rowSize);
+                    break;
+                case ocMin:
+                    ocl_calc.OclHostFormulaMin(srcData,rangeStart,rangeEnd,rResult,rowSize);
+                    break;
+                case ocAverage:
+                    ocl_calc.OclHostFormulaAverage(srcData,rangeStart,rangeEnd,rResult,rowSize);
+                    break;
+                default:
+                    fprintf(stderr,"No OpenCL function for this calculation.\n");
+                    break;
+            }
+            /////////////////////////////////////////////////////
+            osl_getSystemTime(&aTimeAfter);
+            double diff = getTimeDiff(aTimeAfter, aTimeBefore);
+            //if (diff >= 1.0)
+            {
+                fprintf(stderr,"OpenCL,diff...%f.\n",diff);
+            }
+/////////////////////////////////////////////////////
+
+//rResult[i];
+//            for(sal_Int32 i = 0; i < rowSize; ++i){//dbg output results
+//                fprintf(stderr,"After GPU,rRsults[%d] is ...%f\n",i,rResult[i]);
+//            }
+
+            // Insert the double data, in rResult[i] back into the document
+            rDoc.SetFormulaResults(rTopPos, rResult, xGroup->mnLength);
+        }
+
+        if(leftData)
+            free(leftData);
+        if(rightData)
+            free(rightData);
+        if(rangeStart)
+            free(rangeStart);
+        if(rangeEnd)
+            free(rangeEnd);
+        if(rResult)
+            free(rResult);
+        if(srcData)
+            free(srcData);
+
+        if(getenv("SC_GPUSAMPLE")){
+            //fprintf(stderr,"FormulaGroupInterpreter::interpret(),iniflag...%d\n",ocl_calc.GetOpenclState());
+            //ocl_calc.OclTest();//opencl test sample for debug
+        }
+
+    return true;
+}
+
+namespace opencl {
+    sc::FormulaGroupInterpreter *createFormulaGroupInterpreter()
+    {
+        return new sc::FormulaGroupInterpreterOpenCL();
+    }
+} // namespace opencl
+
+} // namespace sc
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/inc/openclwrapper.hxx b/sc/source/core/opencl/openclwrapper.hxx
similarity index 100%
rename from sc/source/core/inc/openclwrapper.hxx
rename to sc/source/core/opencl/openclwrapper.hxx
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index 9d9b504..f9d251b 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -16,70 +16,20 @@
 #include "interpre.hxx"
 #include "formula/vectortoken.hxx"
 
-#if HAVE_FEATURE_OPENCL
-#  include "openclwrapper.hxx"
-#endif
-
 namespace sc {
 
-FormulaGroupInterpreter::FormulaGroupInterpreter(
-    ScDocument& rDoc, const ScAddress& rTopPos, const ScFormulaCellGroupRef& xGroup, ScTokenArray& rCode) :
-    mrDoc(rDoc), maTopPos(rTopPos), mxGroup(xGroup), mrCode(rCode) {}
-
-/////time test dbg
-double getTimeDiff(const TimeValue& t1, const TimeValue& t2)
-{
-    double tv1 = t1.Seconds;
-    double tv2 = t2.Seconds;
-    tv1 += t1.Nanosec / 1000000000.0;
-    tv2 += t2.Nanosec / 1000000000.0;
-
-    return tv1 - tv2;
-}//dbg-t
-TimeValue aTimeBefore, aTimeAfter;
-///////////////////////////////////////
-
-bool FormulaGroupInterpreter::interpret()
+bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddress& rTopPos,
+                                                const ScFormulaCellGroupRef& xGroup,
+                                                ScTokenArray& rCode)
 {
-#if HAVE_FEATURE_OPENCL
-    size_t rowSize = mxGroup->mnLength; //, srcSize = 0;
-    fprintf(stderr,"rowSize at begin is ...%ld.\n",(long)rowSize);
-    int *rangeStart =NULL; // The first position for calculation,for example,the A1 in (=MAX(A1:A100))
-    int *rangeEnd = NULL; // The last position for calculation,for example, the A100 in (=MAX(A1:A100))
-    // The row quantity can be gotten from p2->GetArrayLength()
-    int count1 =0,count2 =0,count3=0;
-    int oclOp=0;
-    double *srcData = NULL; // Point to the input data from CPU
-    double *rResult=NULL; // Point to the output data from GPU
-    double *leftData=NULL; // Left input for binary operator(+,-,*,/),for example,(=leftData+rightData)
-    double *rightData=NULL; // Right input for binary operator(+,-,*,/),for example,(=leftData/rightData)
-                            // The rightData can't be zero for "/"
-
-    leftData  = (double *)malloc(sizeof(double) * rowSize);
-    rightData = (double *)malloc(sizeof(double) * rowSize);
-    rResult   = (double *)malloc(sizeof(double) * rowSize*2);// For 2 columns(B,C)
-    srcData = (double *)calloc(rowSize,sizeof(double));
-
-    rangeStart =(int *)malloc(sizeof(int) * rowSize);
-    rangeEnd   =(int *)malloc(sizeof(int) * rowSize);
-
-    memset(rResult,0,rowSize);
-    if(NULL==leftData||NULL==rightData||
-           NULL==rResult||NULL==rangeStart||NULL==rangeEnd)
-    {
-        printf("malloc err\n");
-        return false;
-    }
-    // printf("rowSize is %d.\n",rowsize);
-#endif
     // Until we implement group calculation for real, decompose the group into
     // individual formula token arrays for individual calculation.
-    ScAddress aTmpPos = maTopPos;
-    for (sal_Int32 i = 0; i < mxGroup->mnLength; ++i)
+    ScAddress aTmpPos = rTopPos;
+    for (sal_Int32 i = 0; i < xGroup->mnLength; ++i)
     {
-        aTmpPos.SetRow(mxGroup->mnStart + i);
+        aTmpPos.SetRow(xGroup->mnStart + i);
         ScTokenArray aCode2;
-        for (const formula::FormulaToken* p = mrCode.First(); p; p = mrCode.Next())
+        for (const formula::FormulaToken* p = rCode.First(); p; p = rCode.Next())
         {
             switch (p->GetType())
             {
@@ -101,29 +51,9 @@ bool FormulaGroupInterpreter::interpret()
                         nRowEnd += i;
                     size_t nRowSize = nRowEnd - nRowStart + 1;
                     ScMatrixRef pMat(new ScMatrix(nColSize, nRowSize, 0.0));
-#if HAVE_FEATURE_OPENCL
-                    //srcSize = rowSize+nRowSize-rowSize%nRowSize;//align as nRowSize
-                    //srcData = (double *)calloc(srcSize,sizeof(double));
-                    rangeStart[i] = nRowStart;//record the start position
-                    rangeEnd[i] = nRowEnd;//record the end position
-#endif
                     for (size_t nCol = 0; nCol < nColSize; ++nCol)
                     {
                         const double* pArray = rArrays[nCol];
-#if HAVE_FEATURE_OPENCL
-                        //printf("pArray is %p.\n",pArray);
-                        if( NULL==pArray )
-                        {
-                            fprintf(stderr,"Error: pArray is NULL!\n");
-                            return false;
-                        }
-                        //fprintf(stderr,"(rowSize+nRowSize-1) is %d.\n",rowSize+nRowSize-1);
-                        for( size_t u=0; u<rowSize; u++ )
-                        {
-                            srcData[u] = pArray[u];// note:rowSize<=srcSize
-                            //fprintf(stderr,"srcData[%d] is %f.\n",u,srcData[u]);
-                        }
-#endif
                         for (size_t nRow = 0; nRow < nRowSize; ++nRow)
                         {
                             if (nRowStart + nRow < p2->GetArrayLength())
@@ -143,123 +73,53 @@ bool FormulaGroupInterpreter::interpret()
             }
         }
 
-        ScFormulaCell* pDest = mrDoc.GetFormulaCell(aTmpPos);
+        ScFormulaCell* pDest = rDoc.GetFormulaCell(aTmpPos);
         if (!pDest)
             return false;
 
-#if HAVE_FEATURE_OPENCL
-        const formula::FormulaToken *pCur = aCode2.First();
-        aCode2.Reset();
-        while( ( pCur = aCode2.Next() ) != NULL )
-        {
-            OpCode eOp = pCur->GetOpCode();
-            if(eOp==0)
-            {
-                  if(count3%2==0)
-                    leftData[count1++] = pCur->GetDouble();
-                   else
-                    rightData[count2++] = pCur->GetDouble();
-                count3++;
-               }
-               else if( eOp!=ocOpen && eOp!=ocClose )
-                oclOp = eOp;
+        ScCompiler aComp(&rDoc, aTmpPos, aCode2);
+        aComp.SetGrammar(rDoc.GetGrammar());
+        aComp.CompileTokenArray(); // Create RPN token array.
+        ScInterpreter aInterpreter(pDest, &rDoc, aTmpPos, aCode2);
+        aInterpreter.Interpret();
+        pDest->SetResultToken(aInterpreter.GetResultToken().get());
+        pDest->ResetDirty();
+        pDest->SetChanged(true);
+    } // for loop end (xGroup->mnLength)
 
-//            if(count1>0){//dbg
-//                fprintf(stderr,"leftData is %f.\n",leftData[count1-1]);
-//                count1--;
-//            }
-//            if(count2>0){//dbg
-//                fprintf(stderr,"rightData is %f.\n",rightData[count2-1]);
-//                count2--;
-//            }
-        }
-#endif
-        if(!getenv("SC_GPU"))
-        {
-            fprintf(stderr,"ccCPU flow...\n\n");
-            ScCompiler aComp(&mrDoc, aTmpPos, aCode2);
-            aComp.SetGrammar(mrDoc.GetGrammar());
-            aComp.CompileTokenArray(); // Create RPN token array.
-            ScInterpreter aInterpreter(pDest, &mrDoc, aTmpPos, aCode2);
-            aInterpreter.Interpret();
-            pDest->SetResultToken(aInterpreter.GetResultToken().get());
-            pDest->ResetDirty();
-            pDest->SetChanged(true);
-        }
-    } // for loop end (mxGroup->mnLength)
-    // For GPU calculation
-#if HAVE_FEATURE_OPENCL //dbg: Using "export SC_GPU=1" to open if{} in terminal
-    if(getenv("SC_GPU"))
-    {
-            fprintf(stderr,"ggGPU flow...\n\n");
-            printf(" oclOp is... %d\n",oclOp);
-            osl_getSystemTime(&aTimeBefore); //timer
-            static OclCalc ocl_calc;
-            switch(oclOp)
-            {
-                case ocAdd:
-                       ocl_calc.OclHostSignedAdd(leftData,rightData,rResult,count1);
-                    break;
-                case ocSub:
-                    ocl_calc.OclHostSignedSub(leftData,rightData,rResult,count1);
-                    break;
-                case ocMul:
-                    ocl_calc.OclHostSignedMul(leftData,rightData,rResult,count1);
-                    break;
-                case ocDiv:
-                    ocl_calc.OclHostSignedDiv(leftData,rightData,rResult,count1);
-                    break;
-                case ocMax:
-                    ocl_calc.OclHostFormulaMax(srcData,rangeStart,rangeEnd,rResult,rowSize);
-                    break;
-                case ocMin:
-                    ocl_calc.OclHostFormulaMin(srcData,rangeStart,rangeEnd,rResult,rowSize);
-                    break;
-                case ocAverage:
-                    ocl_calc.OclHostFormulaAverage(srcData,rangeStart,rangeEnd,rResult,rowSize);
-                    break;
-                default:
-                    fprintf(stderr,"No OpenCL function for this calculation.\n");
-                    break;
-            }
-            /////////////////////////////////////////////////////
-            osl_getSystemTime(&aTimeAfter);
-            double diff = getTimeDiff(aTimeAfter, aTimeBefore);
-            //if (diff >= 1.0)
-            {
-                fprintf(stderr,"OpenCL,diff...%f.\n",diff);
-            }
-/////////////////////////////////////////////////////
+    return true;
+}
 
-//rResult[i];
-//            for(sal_Int32 i = 0; i < rowSize; ++i){//dbg output results
-//                fprintf(stderr,"After GPU,rRsults[%d] is ...%f\n",i,rResult[i]);
-//            }
+// TODO: load module, hook symbol out, check it works, UI on failure etc.
+namespace opencl {
+    extern sc::FormulaGroupInterpreter *createFormulaGroupInterpreter();
+}
 
-            // Insert the double data, in rResult[i] back into the document
-            mrDoc.SetFormulaResults(maTopPos, rResult, mxGroup->mnLength);
-        }
+FormulaGroupInterpreter *FormulaGroupInterpreter::msInstance = NULL;
 
-        if(leftData)
-            free(leftData);
-        if(rightData)
-            free(rightData);
-        if(rangeStart)
-            free(rangeStart);
-        if(rangeEnd)
-            free(rangeEnd);
-        if(rResult)
-            free(rResult);
-        if(srcData)
-            free(srcData);
+/// load and/or configure the correct formula group interpreter
+FormulaGroupInterpreter *FormulaGroupInterpreter::getStatic()
+{
+    static bool bOpenCLEnabled = false;
 
-        if(getenv("SC_GPUSAMPLE")){
-            //fprintf(stderr,"FormulaGroupInterpreter::interpret(),iniflag...%d\n",ocl_calc.GetOpenclState());
-            //ocl_calc.OclTest();//opencl test sample for debug
-        }
+    if ( msInstance &&
+         bOpenCLEnabled != ScInterpreter::GetGlobalConfig().mbOpenCLEnabled )
+    {
+        delete msInstance;
+        msInstance = NULL;
+    }
+
+    if ( !msInstance )
+    {
+#if HAVE_FEATURE_OPENCL
+        if ( ScInterpreter::GetGlobalConfig().mbOpenCLEnabled )
+            msInstance = sc::opencl::createFormulaGroupInterpreter();
 #endif
+        if ( !msInstance ) // software fallback
+            msInstance = new sc::FormulaGroupInterpreterSoftware();
+    }
 
-    return true;
+    return msInstance;
 }
 
 }
diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx
index 586e89d..3330a75 100644
--- a/sc/source/ui/app/scmod.cxx
+++ b/sc/source/ui/app/scmod.cxx
@@ -102,10 +102,7 @@
 
 #include "scabstdlg.hxx"
 #include "formula/errorcodes.hxx"
-
-#if HAVE_FEATURE_OPENCL
-#  include "openclwrapper.hxx"
-#endif
+#include "formulagroup.hxx"
 
 #define SC_IDLE_MIN     150
 #define SC_IDLE_MAX     3000
@@ -154,12 +151,8 @@ ScModule::ScModule( SfxObjectFactory* pFact ) :
     mbIsInSharedDocLoading( false ),
     mbIsInSharedDocSaving( false )
 {
-#if HAVE_FEATURE_OPENCL
-    OclCalc::InitEnv();
-#endif
     //  im ctor ist der ResManager (DLL-Daten) noch nicht initialisiert!
-
-    SetName(OUString("StarCalc"));       // fuer Basic
+    SetName(OUString("StarCalc"));       // for Basic
 
     ResetDragObject();
     SetClipObject( NULL, NULL );
@@ -186,13 +179,13 @@ ScModule::ScModule( SfxObjectFactory* pFact ) :
     ScGlobal::InitTextHeight( pMessagePool );
 
     StartListening( *SFX_APP() );       // for SFX_HINT_DEINITIALIZING
+
+    // initialize formula grouping
+    sc::FormulaGroupInterpreter::getStatic();
 }
 
 ScModule::~ScModule()
 {
-#if HAVE_FEATURE_OPENCL
-    OclCalc::ReleaseOpenclRunEnv();
-#endif
     OSL_ENSURE( !pSelTransfer, "Selection Transfer object not deleted" );
 
     //  InputHandler braucht nicht mehr geloescht zu werden (gibt keinen an der App mehr)


More information about the Libreoffice-commits mailing list