summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorWei Wei <weiwei@multicorewareinc.com>2013-12-13 11:48:38 -0600
committerI-Jui (Ray) Sung <ray@multicorewareinc.com>2013-12-18 20:34:50 -0600
commitdf54e4f174659e2a4ceba517c30e7af2a633b0fb (patch)
treee7c77985db537f9c71d45a101fa16a4d8a095a12 /sc
parenta70dfc34a67e9fb240cc70853da0c49fa01c2e4f (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.mk1
-rw-r--r--sc/qa/unit/data/xls/opencl/spreadsheet/VLookup.xlsbin0 -> 26624 bytes
-rw-r--r--sc/qa/unit/opencl-test.cxx31
-rw-r--r--sc/source/core/opencl/formulagroupcl.cxx5
-rw-r--r--sc/source/core/opencl/op_spreadsheet.cxx238
-rw-r--r--sc/source/core/opencl/op_spreadsheet.hxx29
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
new file mode 100644
index 000000000000..89fd6db03692
--- /dev/null
+++ b/sc/qa/unit/data/xls/opencl/spreadsheet/VLookup.xls
Binary files differ
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: */