diff options
author | Wei Wei <weiwei@multicorewareinc.com> | 2013-12-13 11:48:38 -0600 |
---|---|---|
committer | I-Jui (Ray) Sung <ray@multicorewareinc.com> | 2013-12-18 20:34:50 -0600 |
commit | df54e4f174659e2a4ceba517c30e7af2a633b0fb (patch) | |
tree | e7c77985db537f9c71d45a101fa16a4d8a095a12 /sc | |
parent | a70dfc34a67e9fb240cc70853da0c49fa01c2e4f (diff) |
GPU Calc: VLOOKUP implementation
Change-Id: I0bec6d69f3302f01829bac903f68bc0f28db4c9d
Signed-off-by: I-Jui (Ray) Sung <ray@multicorewareinc.com>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/Library_scopencl.mk | 1 | ||||
-rw-r--r-- | sc/qa/unit/data/xls/opencl/spreadsheet/VLookup.xls | bin | 0 -> 26624 bytes | |||
-rw-r--r-- | sc/qa/unit/opencl-test.cxx | 31 | ||||
-rw-r--r-- | sc/source/core/opencl/formulagroupcl.cxx | 5 | ||||
-rw-r--r-- | sc/source/core/opencl/op_spreadsheet.cxx | 238 | ||||
-rw-r--r-- | sc/source/core/opencl/op_spreadsheet.hxx | 29 |
6 files changed, 304 insertions, 0 deletions
diff --git a/sc/Library_scopencl.mk b/sc/Library_scopencl.mk index ed33ff88bb18..a126dd669b58 100644 --- a/sc/Library_scopencl.mk +++ b/sc/Library_scopencl.mk @@ -45,6 +45,7 @@ $(eval $(call gb_Library_add_exception_objects,scopencl,\ sc/source/core/opencl/op_statistical \ sc/source/core/opencl/op_array \ sc/source/core/opencl/op_logical \ + sc/source/core/opencl/op_spreadsheet \ sc/source/core/opencl/clcc/clew \ )) diff --git a/sc/qa/unit/data/xls/opencl/spreadsheet/VLookup.xls b/sc/qa/unit/data/xls/opencl/spreadsheet/VLookup.xls Binary files differnew file mode 100644 index 000000000000..89fd6db03692 --- /dev/null +++ b/sc/qa/unit/data/xls/opencl/spreadsheet/VLookup.xls diff --git a/sc/qa/unit/opencl-test.cxx b/sc/qa/unit/opencl-test.cxx index 833d9c0824a6..e1f435e8f73b 100644 --- a/sc/qa/unit/opencl-test.cxx +++ b/sc/qa/unit/opencl-test.cxx @@ -244,6 +244,7 @@ public: void testMathFormulaSumProduct(); void testMathFormulaSumProduct2(); void testStatisticalParallelCountBug(); + void testSpreadSheetFormulaVLookup(); CPPUNIT_TEST_SUITE(ScOpenclTest); CPPUNIT_TEST(testSharedFormulaXLS); CPPUNIT_TEST(testFinacialFormula); @@ -419,6 +420,7 @@ public: CPPUNIT_TEST(testMathFormulaSumProduct); CPPUNIT_TEST(testMathFormulaSumProduct2); CPPUNIT_TEST(testStatisticalParallelCountBug); + CPPUNIT_TEST(testSpreadSheetFormulaVLookup); CPPUNIT_TEST_SUITE_END(); private: @@ -4130,6 +4132,35 @@ void ScOpenclTest::testMathFormulaLog() xDocSh->DoClose(); xDocShRes->DoClose(); } +//[AMLOEXT-171] +void ScOpenclTest::testSpreadSheetFormulaVLookup() +{ + if (!detectOpenCLDevice()) + return; + ScDocShellRef xDocSh = loadDoc("opencl/spreadsheet/VLookup.", XLS); + ScDocument* pDoc = xDocSh->GetDocument(); + CPPUNIT_ASSERT(pDoc); + enableOpenCL(); + pDoc->CalcAll(); + ScDocShellRef xDocShRes = loadDoc("opencl/spreadsheet/VLookup.", XLS); + ScDocument* pDocRes = xDocShRes->GetDocument(); + CPPUNIT_ASSERT(pDocRes); + // Check the results of formula cells in the shared formula range. + for (SCROW i = 1; i <= 32; ++i) + { + double fLibre = pDoc->GetValue(ScAddress(5,i,0)); + double fExcel = pDocRes->GetValue(ScAddress(5,i,0)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel)); + } + for (SCROW i = 40; i <= 50; ++i) + { + double fLibre = pDoc->GetValue(ScAddress(5,i,0)); + double fExcel = pDocRes->GetValue(ScAddress(5,i,0)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(fExcel, fLibre, fabs(0.0001*fExcel)); + } + xDocSh->DoClose(); + xDocShRes->DoClose(); +} //[AMLOEXT-173] void ScOpenclTest::testStatisticalFormulaChiInv() { diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx index b73b32a2db89..66d9452518d7 100644 --- a/sc/source/core/opencl/formulagroupcl.cxx +++ b/sc/source/core/opencl/formulagroupcl.cxx @@ -26,6 +26,7 @@ #include "op_logical.hxx" #include "op_statistical.hxx" #include "op_array.hxx" +#include "op_spreadsheet.hxx" /// CONFIGURATIONS // Comment out this to turn off FMIN and FMAX intrinsics #define USE_FMIN_FMAX 1 @@ -2294,6 +2295,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments( mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpAnd)); break; + case ocVLookup: + mvSubArguments.push_back(SoPHelper(ts, + ft->Children[i], new OpVLookup)); + break; case ocExternal: if ( !(pChild->GetExternal().compareTo(OUString( "com.sun.star.sheet.addin.Analysis.getEffect")))) diff --git a/sc/source/core/opencl/op_spreadsheet.cxx b/sc/source/core/opencl/op_spreadsheet.cxx new file mode 100644 index 000000000000..9d3db144bfe6 --- /dev/null +++ b/sc/source/core/opencl/op_spreadsheet.cxx @@ -0,0 +1,238 @@ +/* -*- 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 "op_spreadsheet.hxx" + +#include "formulagroup.hxx" +#include "document.hxx" +#include "formulacell.hxx" +#include "tokenarray.hxx" +#include "compiler.hxx" +#include "interpre.hxx" +#include "formula/vectortoken.hxx" +#include <sstream> + +using namespace formula; + +namespace sc { namespace opencl { + +void OpVLookup::GenSlidingWindowFunction(std::stringstream &ss, + const std::string sSymName, SubArguments &vSubArguments) +{ + ss << "\ndouble " << sSymName; + ss << "_"<< BinFuncName() <<"("; + for (unsigned i = 0; i < vSubArguments.size(); i++) + { + if (i) + ss << ","; + vSubArguments[i]->GenSlidingWindowDecl(ss); + } + ss << ")\n {\n"; + ss << " int gid0=get_global_id(0);\n"; + ss << " double tmp = NAN;\n"; + ss << " double intermediate = DBL_MAX;\n"; + ss << " int singleIndex = gid0;\n"; + ss << " int rowNum = -1;\n"; + GenTmpVariables(ss,vSubArguments); + int arg=0; + CheckSubArgumentIsNan(ss,vSubArguments,arg++); + int secondParaWidth = 1; + if(vSubArguments[1]->GetFormulaToken()->GetType() == + formula::svDoubleVectorRef) + { + FormulaToken *tmpCur = vSubArguments[1]->GetFormulaToken(); + const formula::DoubleVectorRefToken*pCurDVR= dynamic_cast<const + formula::DoubleVectorRefToken *>(tmpCur); + secondParaWidth = pCurDVR->GetArrays().size(); + } + arg+=secondParaWidth; + CheckSubArgumentIsNan(ss,vSubArguments,arg++); + if(vSubArguments.size() == (unsigned int)(3+(secondParaWidth-1))) + { + ss << " double tmp"; + ss << 3+(secondParaWidth-1); + ss << "= 1;\n"; + } + else + { + CheckSubArgumentIsNan(ss,vSubArguments,arg++); + } + + if(vSubArguments[1]->GetFormulaToken()->GetType() == + formula::svDoubleVectorRef) + { + FormulaToken *tmpCur = vSubArguments[1]->GetFormulaToken(); + const formula::DoubleVectorRefToken*pCurDVR= dynamic_cast<const + formula::DoubleVectorRefToken *>(tmpCur); + size_t nCurWindowSize = pCurDVR->GetArrayLength() < + pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength(): + pCurDVR->GetRefRowSize() ; + int unrollSize = 16; + ss << " int loop;\n"; + ss << " int remainder;\n"; + if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) { + ss << " loop = ("<<nCurWindowSize<<" - gid0)/"; + ss << unrollSize<<";\n"; + + } else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) { + ss << " loop = ("<<nCurWindowSize<<" + gid0)/"; + ss << unrollSize<<";\n"; + + } else { + ss << " loop = "<<nCurWindowSize<<"/"<< unrollSize<<";\n"; + } + + for(int i=0;i<secondParaWidth;i++) + { + + ss << " for ( int j = 0;j< loop; j++)\n"; + ss << " {\n"; + ss << " int i = "; + if (!pCurDVR->IsStartFixed()&& pCurDVR->IsEndFixed()) { + ss << "gid0 + j * "<< unrollSize <<";\n"; + }else { + ss << "j * "<< unrollSize <<";\n"; + } + if(!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) + { + ss << " int doubleIndex = i+gid0;\n"; + }else + { + ss << " int doubleIndex = i;\n"; + } + ss << " if(tmp"; + ss << 3+(secondParaWidth-1); + ss << " == 1)\n"; + ss << " {\n"; + + for(int j =0;j < unrollSize;j++) + { + CheckSubArgumentIsNan(ss,vSubArguments,1+i); + + ss << " if((tmp0 - tmp"; + ss << 1+i; + ss << ")>=0 && intermediate > ( tmp0 -tmp"; + ss << 1+i; + ss << "))\n"; + ss << " {\n"; + ss << " rowNum = doubleIndex;\n"; + ss << " intermediate = tmp0 - tmp"; + ss << 1+i; + ss << ";\n"; + ss << " }\n"; + + ss << " i++;\n"; + ss << " doubleIndex++;\n"; + } + + ss << " }else\n"; + ss << " {\n"; + for(int j =0;j < unrollSize;j++) + { + CheckSubArgumentIsNan(ss,vSubArguments,1+i); + + ss << " if(tmp0 == tmp"; + ss << 1+i; + ss << " && rowNum == -1)\n"; + ss << " {\n"; + ss << " rowNum = doubleIndex;\n"; + ss << " }\n"; + + ss << " i++;\n"; + ss << " doubleIndex++;\n"; + } + ss << " }\n\n"; + + ss << " }\n"; + ss << " for (int i = "; + if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) { + ss << "gid0 + loop *"<<unrollSize<<"; i < "; + ss << nCurWindowSize <<"; i++)\n"; + } else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) { + ss << "0 + loop *"<<unrollSize<<"; i < gid0+"; + ss << nCurWindowSize <<"; i++)\n"; + } else { + ss << "0 + loop *"<<unrollSize<<"; i < "; + ss << nCurWindowSize <<"; i++)\n"; + } + ss << " {\n"; + if(!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) + { + ss << " int doubleIndex = i+gid0;\n"; + }else + { + ss << " int doubleIndex = i;\n"; + } + CheckSubArgumentIsNan(ss,vSubArguments,1+i); + ss << " if(tmp"; + ss << 3+(secondParaWidth-1); + ss << " == 1)\n"; + ss << " {\n"; + ss << " if((tmp0 - tmp"; + ss << 1+i; + ss << ")>=0 && intermediate > ( tmp0 -tmp"; + ss << 1+i; + ss << "))\n"; + ss << " {\n"; + ss << " rowNum = doubleIndex;\n"; + ss << " intermediate = tmp0 - tmp"; + ss << 1+i; + ss << ";\n"; + ss << " }\n"; + ss << " }else\n"; + ss << " {\n"; + ss << " if(tmp0 == tmp"; + ss << 1+i; + ss << " && rowNum == -1)\n"; + ss << " {\n"; + ss << " rowNum = doubleIndex;\n"; + ss << " }\n"; + ss << " }\n"; + + ss << " }\n\n"; + + } + + ss << " if(rowNum!=-1)\n"; + ss << " {\n"; + + for(int j=0;j< secondParaWidth; j++) + { + + ss << " if(tmp"; + ss << 2+(secondParaWidth-1); + ss << " == "; + ss << j+1; + ss << ")\n"; + ss << " tmp = "; + vSubArguments[1+j]->GenDeclRef(ss); + ss << "[rowNum];\n"; + } + ss << " }\n"; + } + else + { + CheckSubArgumentIsNan(ss,vSubArguments,1); + ss << " if(tmp3 == 1)\n"; + ss << " {\n"; + ss << " tmp = tmp1;\n"; + ss << " }else\n"; + ss << " {\n"; + ss << " if(tmp0 == tmp1)\n"; + ss << " tmp = tmp1;\n"; + ss << " }\n"; + } + + ss << " return tmp;\n"; + ss << "}"; +} + +}} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/opencl/op_spreadsheet.hxx b/sc/source/core/opencl/op_spreadsheet.hxx new file mode 100644 index 000000000000..c9656c974bc4 --- /dev/null +++ b/sc/source/core/opencl/op_spreadsheet.hxx @@ -0,0 +1,29 @@ +/* -*- 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 SC_OPENCL_OP_SPREADSHEET_HXX +#define SC_OPENCL_OP_SPREADSHEET_HXX + +#include "opbase.hxx" + +namespace sc { namespace opencl { + +class OpVLookup: public CheckVariables +{ +public: + virtual void GenSlidingWindowFunction(std::stringstream &ss, + const std::string sSymName, SubArguments &vSubArguments); + virtual std::string BinFuncName(void) const { return "VLookup"; } +}; + +}} + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |