diff options
author | Michael Meeks <michael.meeks@suse.com> | 2013-06-27 16:49:41 +0100 |
---|---|---|
committer | Michael Meeks <michael.meeks@suse.com> | 2013-06-27 19:34:39 +0100 |
commit | 66e72c38f77bedc28b990b2a724829b50c70bf8d (patch) | |
tree | d04bcc7fa3062071f1fdcc5454ad574a025aab28 | |
parent | d7f2e338cf00052f7edbecf664b3d0088198a374 (diff) |
abstract out the FormulaGroupInterpreter more cleanly.
-rw-r--r-- | sc/Library_sc.mk | 1 | ||||
-rw-r--r-- | sc/inc/document.hxx | 1 | ||||
-rw-r--r-- | sc/inc/formulagroup.hxx | 30 | ||||
-rw-r--r-- | sc/source/core/data/documen2.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/formulacell.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/opencl/formulagroupcl.cxx | 287 | ||||
-rw-r--r-- | sc/source/core/opencl/openclwrapper.hxx (renamed from sc/source/core/inc/openclwrapper.hxx) | 0 | ||||
-rw-r--r-- | sc/source/core/tool/formulagroup.cxx | 228 | ||||
-rw-r--r-- | sc/source/ui/app/scmod.cxx | 17 |
9 files changed, 362 insertions, 208 deletions
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk index 94c9a5274996..e96bb1470170 100644 --- a/sc/Library_sc.mk +++ b/sc/Library_sc.mk @@ -58,6 +58,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 ff0b869cc532..377c80eacba4 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -415,6 +415,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 55f6e0997ff8..e5839e4c7116 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 b1b316064d41..6244eac58bb5 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 68d242dc485c..f57da6fdef5e 100644 --- a/sc/source/core/data/formulacell.cxx +++ b/sc/source/core/data/formulacell.cxx @@ -3094,9 +3094,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 000000000000..54fd8e8c898a --- /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 index 62006d116a3b..62006d116a3b 100644 --- a/sc/source/core/inc/openclwrapper.hxx +++ b/sc/source/core/opencl/openclwrapper.hxx diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx index 9d9b504a09c9..f9d251bbada3 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 4edfcf04c50c..d9b5d021f97e 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) |