Kaydet (Commit) 4d61abf9 authored tarafından Tor Lillqvist's avatar Tor Lillqvist Kaydeden (comit) Andras Timar

Fix the OpenCL VLOOKUP to work properly and add it to the trusted subset

Treat an array of null string pointers as no strings for OpenCL. For
some reason, at least in the case of the "Test OpenCL" thing, we got
an mpStringArray that is non-null but where all the elements
(rtl_uString pointers) in it are null. Treat that case as if the
mpStringArray was null.

This makes the tests "Test OpenCL" actually use OpenCL. Maybe it has other
useful effects, too. (But for normal spreadsheet use, the mpStringArray that
gets handled here *is* null when all the cells used by a formula group are
numbers. At least it seemed so in a simple test.)

Add a few more useful (?) SAL_INFO calls.

Some cosmetic changes to make the code look saner.

Return correct value from the OpenCL VLOOKUP implementation. Also,
when the lookup fails, produce the expected N/A error code instead of
a bare NaN.

Don't claim we support strings arguments in the OpenCL VLOOKUP.  The
string support certainly isn't complete or correct anyway. Partially
revert c3383aaf.

Add VLOOKUP to the set of opcodes that we trust the OpenCL
implementation for.

(cherry picked from commit 7e91726f)
(cherry picked from commit d4310b6c)
(cherry picked from commit 32b35d9d)
(cherry picked from commit 41a60940)
(cherry picked from commit 16226445)
(cherry picked from commit 7bb7539c)

Change-Id: I5402732c9ddcac1efcc25960a5c46175d7a90b4d
Reviewed-on: https://gerrit.libreoffice.org/18022Reviewed-by: 's avatarMichael Meeks <michael.meeks@collabora.com>
Reviewed-by: 's avatarEike Rathke <erack@redhat.com>
Tested-by: 's avatarJan Holesovsky <kendy@collabora.com>
üst 1ce4906e
...@@ -1373,7 +1373,7 @@ ...@@ -1373,7 +1373,7 @@
true, and a formula contains only these operators and true, and a formula contains only these operators and
functions, it might be calculated using OpenCL.</desc> functions, it might be calculated using OpenCL.</desc>
</info> </info>
<value>+;-;*;/;RAND;SIN;COS;TAN;ATAN;EXP;LN;SQRT;NORMSDIST;NORMSINV;ROUND;POWER;SUMPRODUCT;MIN;MAX;SUM;PRODUCT;AVERAGE;COUNT;VAR;NORMDIST;CORREL;COVAR;PEARSON;SLOPE;SUMIFS</value> <value>+;-;*;/;RAND;SIN;COS;TAN;ATAN;EXP;LN;SQRT;NORMSDIST;NORMSINV;ROUND;POWER;SUMPRODUCT;MIN;MAX;SUM;PRODUCT;AVERAGE;COUNT;VAR;NORMDIST;VLOOKUP;CORREL;COVAR;PEARSON;SLOPE;SUMIFS</value>
</prop> </prop>
<prop oor:name="OpenCLAutoSelect" oor:type="xs:boolean" oor:nillable="false"> <prop oor:name="OpenCLAutoSelect" oor:type="xs:boolean" oor:nillable="false">
<!-- UIHints: Tools - Options Spreadsheet Formula --> <!-- UIHints: Tools - Options Spreadsheet Formula -->
......
...@@ -40,6 +40,7 @@ static const char* publicFunc = ...@@ -40,6 +40,7 @@ static const char* publicFunc =
"#define errIllegalFPOperation 503 // #NUM!\n" "#define errIllegalFPOperation 503 // #NUM!\n"
"#define errNoValue 519 // #VALUE!\n" "#define errNoValue 519 // #VALUE!\n"
"#define errDivisionByZero 532 // #DIV/0!\n" "#define errDivisionByZero 532 // #DIV/0!\n"
"#define NOTAVAILABLE 0x7fff // #N/A\n"
"\n" "\n"
"double CreateDoubleError(ulong nErr)\n" "double CreateDoubleError(ulong nErr)\n"
"{\n" "{\n"
...@@ -152,6 +153,19 @@ std::string linenumberify(const std::string& s) ...@@ -152,6 +153,19 @@ std::string linenumberify(const std::string& s)
} }
#endif #endif
bool AllStringsAreNull(const rtl_uString* const* pStringArray, size_t nLength)
{
if (pStringArray == nullptr)
return true;
for (size_t i = 0; i < nLength; i++)
if (pStringArray[i] != nullptr)
return false;
return true;
}
} // anonymous namespace } // anonymous namespace
/// Map the buffer used by an argument and do necessary argument setting /// Map the buffer used by an argument and do necessary argument setting
...@@ -2615,8 +2629,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config, ...@@ -2615,8 +2629,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config,
for (size_t j = 0; j < pDVR->GetArrays().size(); ++j) for (size_t j = 0; j < pDVR->GetArrays().size(); ++j)
{ {
SAL_INFO("sc.opencl", "j=" << j << " mpNumericArray=" << pDVR->GetArrays()[j].mpNumericArray << SAL_INFO("sc.opencl", "i=" << i << " j=" << j <<
" mpNumericArray=" << pDVR->GetArrays()[j].mpNumericArray <<
" mpStringArray=" << pDVR->GetArrays()[j].mpStringArray << " mpStringArray=" << pDVR->GetArrays()[j].mpStringArray <<
" allStringsAreNull=" << (AllStringsAreNull(pDVR->GetArrays()[j].mpStringArray, pDVR->GetArrayLength())?"YES":"NO") <<
" takeNumeric=" << (pCodeGen->takeNumeric()?"YES":"NO") << " takeNumeric=" << (pCodeGen->takeNumeric()?"YES":"NO") <<
" takeString=" << (pCodeGen->takeString()?"YES":"NO")); " takeString=" << (pCodeGen->takeString()?"YES":"NO"));
...@@ -2629,6 +2645,8 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config, ...@@ -2629,6 +2645,8 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config,
pDVR->GetArrays()[j].mpStringArray && pDVR->GetArrays()[j].mpStringArray &&
pCodeGen->takeString()) pCodeGen->takeString())
{ {
// Function takes numbers or strings, there are both
SAL_INFO("sc.opencl", "Numbers and strings and that is OK");
mvSubArguments.push_back( mvSubArguments.push_back(
DynamicKernelArgumentRef( DynamicKernelArgumentRef(
new DynamicKernelMixedSlidingArgument(mCalcConfig, new DynamicKernelMixedSlidingArgument(mCalcConfig,
...@@ -2636,16 +2654,22 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config, ...@@ -2636,16 +2654,22 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config,
} }
else else
{ {
// Not sure I can figure out what case this exactly is;)
SAL_INFO("sc.opencl", "The other case");
mvSubArguments.push_back( mvSubArguments.push_back(
DynamicKernelArgumentRef(VectorRefFactory<VectorRef>(mCalcConfig, DynamicKernelArgumentRef(VectorRefFactory<VectorRef>(mCalcConfig,
ts, ft->Children[i], mpCodeGen, j))); ts, ft->Children[i], mpCodeGen, j)));
} }
} }
else else
{
// Ditto here. This is such crack.
SAL_INFO("sc.opencl", "The outer other case (can't figure out what it exactly means)");
mvSubArguments.push_back( mvSubArguments.push_back(
DynamicKernelArgumentRef(VectorRefFactory DynamicKernelArgumentRef(VectorRefFactory
<DynamicKernelStringArgument>(mCalcConfig, <DynamicKernelStringArgument>(mCalcConfig,
ts, ft->Children[i], mpCodeGen, j))); ts, ft->Children[i], mpCodeGen, j)));
}
} }
} }
else if (pChild->GetType() == formula::svSingleVectorRef) else if (pChild->GetType() == formula::svSingleVectorRef)
...@@ -2653,8 +2677,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config, ...@@ -2653,8 +2677,10 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config,
const formula::SingleVectorRefToken* pSVR = const formula::SingleVectorRefToken* pSVR =
static_cast<const formula::SingleVectorRefToken*>(pChild); static_cast<const formula::SingleVectorRefToken*>(pChild);
SAL_INFO("sc.opencl", "mpNumericArray=" << pSVR->GetArray().mpNumericArray << SAL_INFO("sc.opencl", "i=" << i <<
" mpNumericArray=" << pSVR->GetArray().mpNumericArray <<
" mpStringArray=" << pSVR->GetArray().mpStringArray << " mpStringArray=" << pSVR->GetArray().mpStringArray <<
" allStringsAreNull=" << (AllStringsAreNull(pSVR->GetArray().mpStringArray, pSVR->GetArrayLength())?"YES":"NO") <<
" takeNumeric=" << (pCodeGen->takeNumeric()?"YES":"NO") << " takeNumeric=" << (pCodeGen->takeNumeric()?"YES":"NO") <<
" takeString=" << (pCodeGen->takeString()?"YES":"NO")); " takeString=" << (pCodeGen->takeString()?"YES":"NO"));
...@@ -2664,17 +2690,19 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config, ...@@ -2664,17 +2690,19 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config,
pCodeGen->takeString()) pCodeGen->takeString())
{ {
// Function takes numbers or strings, there are both // Function takes numbers or strings, there are both
SAL_INFO("sc.opencl", "Numbers and strings and that is OK");
mvSubArguments.push_back( mvSubArguments.push_back(
DynamicKernelArgumentRef(new DynamicKernelMixedArgument(mCalcConfig, DynamicKernelArgumentRef(new DynamicKernelMixedArgument(mCalcConfig,
ts, ft->Children[i]))); ts, ft->Children[i])));
} }
else if (pSVR->GetArray().mpNumericArray && else if (pSVR->GetArray().mpNumericArray &&
pCodeGen->takeNumeric() && pCodeGen->takeNumeric() &&
(pSVR->GetArray().mpStringArray == NULL || mCalcConfig.meStringConversion == ScCalcConfig::StringConversion::ZERO)) (AllStringsAreNull(pSVR->GetArray().mpStringArray, pSVR->GetArrayLength()) || mCalcConfig.meStringConversion == ScCalcConfig::StringConversion::ZERO))
{ {
// Function takes numbers, and either there // Function takes numbers, and either there
// are no strings, or there are strings but // are no strings, or there are strings but
// they are to be treated as zero // they are to be treated as zero
SAL_INFO("sc.opencl", "Maybe strings even if want numbers but should be treated as zero");
mvSubArguments.push_back( mvSubArguments.push_back(
DynamicKernelArgumentRef(new VectorRef(mCalcConfig, ts, DynamicKernelArgumentRef(new VectorRef(mCalcConfig, ts,
ft->Children[i]))); ft->Children[i])));
...@@ -2686,6 +2714,7 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config, ...@@ -2686,6 +2714,7 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config,
{ {
// Function takes numbers, and there are only // Function takes numbers, and there are only
// strings, but they are to be treated as zero // strings, but they are to be treated as zero
SAL_INFO("sc.opencl", "Only strings even if want numbers but should be treated as zero");
mvSubArguments.push_back( mvSubArguments.push_back(
DynamicKernelArgumentRef(new VectorRef(mCalcConfig, ts, DynamicKernelArgumentRef(new VectorRef(mCalcConfig, ts,
ft->Children[i]))); ft->Children[i])));
...@@ -2693,28 +2722,32 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config, ...@@ -2693,28 +2722,32 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config,
else if (pSVR->GetArray().mpStringArray && else if (pSVR->GetArray().mpStringArray &&
pCodeGen->takeString()) pCodeGen->takeString())
{ {
// There are strings, and the function takes // There are strings, and the function takes strings.
// strings. SAL_INFO("sc.opencl", "Strings only");
mvSubArguments.push_back( mvSubArguments.push_back(
DynamicKernelArgumentRef(new DynamicKernelStringArgument(mCalcConfig, DynamicKernelArgumentRef(new DynamicKernelStringArgument(mCalcConfig,
ts, ft->Children[i]))); ts, ft->Children[i])));
} }
else if (pSVR->GetArray().mpStringArray == NULL && else if (AllStringsAreNull(pSVR->GetArray().mpStringArray, pSVR->GetArrayLength()) &&
pSVR->GetArray().mpNumericArray == NULL) pSVR->GetArray().mpNumericArray == NULL)
{ {
// There are only empty cells. Push as an // There are only empty cells. Push as an
// array of NANs // array of NANs
SAL_INFO("sc.opencl", "Only empty cells");
mvSubArguments.push_back( mvSubArguments.push_back(
DynamicKernelArgumentRef(new VectorRef(mCalcConfig, ts, DynamicKernelArgumentRef(new VectorRef(mCalcConfig, ts,
ft->Children[i]))); ft->Children[i])));
} }
else else
{
SAL_INFO("sc.opencl", "Fallback case, rejecting for OpenCL");
throw UnhandledToken(pChild, throw UnhandledToken(pChild,
"Got unhandled case here", __FILE__, __LINE__); "Got unhandled case here", __FILE__, __LINE__);
}
} }
else if (pChild->GetType() == formula::svDouble) else if (pChild->GetType() == formula::svDouble)
{ {
SAL_INFO("sc.opencl", "Constant number (?) case");
mvSubArguments.push_back( mvSubArguments.push_back(
DynamicKernelArgumentRef(new DynamicKernelConstantArgument(mCalcConfig, ts, DynamicKernelArgumentRef(new DynamicKernelConstantArgument(mCalcConfig, ts,
ft->Children[i]))); ft->Children[i])));
...@@ -2722,12 +2755,14 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config, ...@@ -2722,12 +2755,14 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config,
else if (pChild->GetType() == formula::svString else if (pChild->GetType() == formula::svString
&& pCodeGen->takeString()) && pCodeGen->takeString())
{ {
SAL_INFO("sc.opencl", "Constant string (?) case");
mvSubArguments.push_back( mvSubArguments.push_back(
DynamicKernelArgumentRef(new ConstStringArgument(mCalcConfig, ts, DynamicKernelArgumentRef(new ConstStringArgument(mCalcConfig, ts,
ft->Children[i]))); ft->Children[i])));
} }
else else
{ {
SAL_INFO("sc.opencl", "Fallback case, rejecting for OpenCL");
throw UnhandledToken(pChild, ("unhandled operand " + StackVarEnumToString(pChild->GetType()) + " for ocPush").c_str()); throw UnhandledToken(pChild, ("unhandled operand " + StackVarEnumToString(pChild->GetType()) + " for ocPush").c_str());
} }
break; break;
......
...@@ -35,25 +35,27 @@ void OpVLookup::GenSlidingWindowFunction(std::stringstream &ss, ...@@ -35,25 +35,27 @@ void OpVLookup::GenSlidingWindowFunction(std::stringstream &ss,
} }
ss << ")\n {\n"; ss << ")\n {\n";
ss << " int gid0=get_global_id(0);\n"; ss << " int gid0=get_global_id(0);\n";
ss << " double tmp = NAN;\n"; ss << " double tmp = CreateDoubleError(NOTAVAILABLE);\n";
ss << " double intermediate = DBL_MAX;\n"; ss << " double intermediate = DBL_MAX;\n";
ss << " int singleIndex = gid0;\n"; ss << " int singleIndex = gid0;\n";
ss << " int rowNum = -1;\n"; ss << " int rowNum = -1;\n";
GenTmpVariables(ss,vSubArguments); GenTmpVariables(ss,vSubArguments);
int arg=0; int arg=0;
CheckSubArgumentIsNan(ss,vSubArguments,arg++); CheckSubArgumentIsNan(ss,vSubArguments,arg++);
int secondParaWidth = 1; int secondParaWidth = 1;
if(vSubArguments[1]->GetFormulaToken()->GetType() ==
formula::svDoubleVectorRef) if (vSubArguments[1]->GetFormulaToken()->GetType() == formula::svDoubleVectorRef)
{ {
FormulaToken *tmpCur = vSubArguments[1]->GetFormulaToken(); FormulaToken *tmpCur = vSubArguments[1]->GetFormulaToken();
const formula::DoubleVectorRefToken*pCurDVR= static_cast<const const formula::DoubleVectorRefToken*pCurDVR = static_cast<const formula::DoubleVectorRefToken *>(tmpCur);
formula::DoubleVectorRefToken *>(tmpCur);
secondParaWidth = pCurDVR->GetArrays().size(); secondParaWidth = pCurDVR->GetArrays().size();
} }
arg+=secondParaWidth;
arg += secondParaWidth;
CheckSubArgumentIsNan(ss,vSubArguments,arg++); CheckSubArgumentIsNan(ss,vSubArguments,arg++);
if(vSubArguments.size() == (unsigned int)(3+(secondParaWidth-1)))
if (vSubArguments.size() == (unsigned int)(3+(secondParaWidth-1)))
{ {
ss << " double tmp"; ss << " double tmp";
ss << 3+(secondParaWidth-1); ss << 3+(secondParaWidth-1);
...@@ -64,53 +66,57 @@ void OpVLookup::GenSlidingWindowFunction(std::stringstream &ss, ...@@ -64,53 +66,57 @@ void OpVLookup::GenSlidingWindowFunction(std::stringstream &ss,
CheckSubArgumentIsNan(ss,vSubArguments,arg++); CheckSubArgumentIsNan(ss,vSubArguments,arg++);
} }
if(vSubArguments[1]->GetFormulaToken()->GetType() == if (vSubArguments[1]->GetFormulaToken()->GetType() == formula::svDoubleVectorRef)
formula::svDoubleVectorRef)
{ {
FormulaToken *tmpCur = vSubArguments[1]->GetFormulaToken(); FormulaToken *tmpCur = vSubArguments[1]->GetFormulaToken();
const formula::DoubleVectorRefToken*pCurDVR= static_cast<const const formula::DoubleVectorRefToken*pCurDVR = static_cast<const formula::DoubleVectorRefToken *>(tmpCur);
formula::DoubleVectorRefToken *>(tmpCur); size_t nCurWindowSize = pCurDVR->GetArrayLength() < pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength() : pCurDVR->GetRefRowSize() ;
size_t nCurWindowSize = pCurDVR->GetArrayLength() <
pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength():
pCurDVR->GetRefRowSize() ;
int unrollSize = 8; int unrollSize = 8;
ss << " int loop;\n"; ss << " int loop;\n";
if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) { if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed())
{
ss << " loop = ("<<nCurWindowSize<<" - gid0)/"; ss << " loop = ("<<nCurWindowSize<<" - gid0)/";
ss << unrollSize<<";\n"; ss << unrollSize<<";\n";
} else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) { }
else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
{
ss << " loop = ("<<nCurWindowSize<<" + gid0)/"; ss << " loop = ("<<nCurWindowSize<<" + gid0)/";
ss << unrollSize<<";\n"; ss << unrollSize<<";\n";
} else { }
else
{
ss << " loop = "<<nCurWindowSize<<"/"<< unrollSize<<";\n"; ss << " loop = "<<nCurWindowSize<<"/"<< unrollSize<<";\n";
} }
for(int i=0;i<secondParaWidth;i++) for (int i = 0; i < secondParaWidth; i++)
{ {
ss << " for ( int j = 0;j< loop; j++)\n"; ss << " for ( int j = 0;j< loop; j++)\n";
ss << " {\n"; ss << " {\n";
ss << " int i = "; ss << " int i = ";
if (!pCurDVR->IsStartFixed()&& pCurDVR->IsEndFixed()) { if (!pCurDVR->IsStartFixed()&& pCurDVR->IsEndFixed())
ss << "gid0 + j * "<< unrollSize <<";\n"; {
}else { ss << "gid0 + j * "<< unrollSize <<";\n";
ss << "j * "<< unrollSize <<";\n";
} }
if(!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) else
{ {
ss << " int doubleIndex = i+gid0;\n"; ss << "j * "<< unrollSize <<";\n";
}else }
if (!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
{ {
ss << " int doubleIndex = i;\n"; ss << " int doubleIndex = i+gid0;\n";
}
else
{
ss << " int doubleIndex = i;\n";
} }
ss << " if(tmp"; ss << " if(tmp";
ss << 3+(secondParaWidth-1); ss << 3+(secondParaWidth-1);
ss << " == 1)\n"; ss << " == 1)\n";
ss << " {\n"; ss << " {\n";
for(int j =0;j < unrollSize;j++) for (int j = 0;j < unrollSize; j++)
{ {
CheckSubArgumentIsNan(ss,vSubArguments,1+i); CheckSubArgumentIsNan(ss,vSubArguments,1+i);
...@@ -131,7 +137,7 @@ void OpVLookup::GenSlidingWindowFunction(std::stringstream &ss, ...@@ -131,7 +137,7 @@ void OpVLookup::GenSlidingWindowFunction(std::stringstream &ss,
ss << " }else\n"; ss << " }else\n";
ss << " {\n"; ss << " {\n";
for(int j =0;j < unrollSize;j++) for (int j = 0; j < unrollSize; j++)
{ {
CheckSubArgumentIsNan(ss,vSubArguments,1+i); CheckSubArgumentIsNan(ss,vSubArguments,1+i);
...@@ -149,55 +155,41 @@ void OpVLookup::GenSlidingWindowFunction(std::stringstream &ss, ...@@ -149,55 +155,41 @@ void OpVLookup::GenSlidingWindowFunction(std::stringstream &ss,
ss << " }\n"; ss << " }\n";
ss << " if(rowNum!=-1)\n"; ss << " if(rowNum!=-1)\n";
ss << " {\n"; ss << " {\n";
for(int j=0;j< secondParaWidth; j++) for (int j = 0; j < secondParaWidth; j++)
{ {
ss << " if(tmp"; ss << " if(tmp";
ss << 2+(secondParaWidth-1); ss << 2+(secondParaWidth-1);
ss << " == "; ss << " == ";
ss << j+1; ss << j+1;
ss << ")\n"; ss << ")\n";
if( !(vSubArguments[1+j]->IsMixedArgument())) ss << " tmp = ";
{ vSubArguments[1+j]->GenDeclRef(ss);
ss << " {\n"; ss << "[rowNum];\n";
ss << " tmp = ";
vSubArguments[1+j]->GenDeclRef(ss);
ss << "[rowNum];\n";
ss << " }\n";
}
else
{
ss << " {\n";
ss << " tmp = isNan(";
vSubArguments[1+j]->GenNumDeclRef(ss);
ss << "[rowNum])?";
vSubArguments[1+j]->GenNumDeclRef(ss);
ss << "[rowNum]:";
vSubArguments[1+j]->GenStringDeclRef(ss);
ss << "[rowNum];\n";
ss << " }\n";
}
} }
ss << " return tmp;\n"; ss << " return tmp;\n";
ss << " }\n"; ss << " }\n";
ss << " for (int i = "; ss << " for (int i = ";
if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) { if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed())
ss << "gid0 + loop *"<<unrollSize<<"; i < "; {
ss << nCurWindowSize <<"; i++)\n"; ss << "gid0 + loop *"<<unrollSize<<"; i < ";
} else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) { ss << nCurWindowSize <<"; i++)\n";
ss << "0 + loop *"<<unrollSize<<"; i < gid0+"; }
ss << nCurWindowSize <<"; i++)\n"; else if (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
} else { {
ss << "0 + loop *"<<unrollSize<<"; i < "; ss << "0 + loop *"<<unrollSize<<"; i < gid0+";
ss << nCurWindowSize <<"; i++)\n"; ss << nCurWindowSize <<"; i++)\n";
}
else
{
ss << "0 + loop *"<<unrollSize<<"; i < ";
ss << nCurWindowSize <<"; i++)\n";
} }
ss << " {\n"; ss << " {\n";
if(!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) if (!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
{ {
ss << " int doubleIndex = i+gid0;\n"; ss << " int doubleIndex = i+gid0;\n";
}else }
else
{ {
ss << " int doubleIndex = i;\n"; ss << " int doubleIndex = i;\n";
} }
...@@ -232,38 +224,21 @@ void OpVLookup::GenSlidingWindowFunction(std::stringstream &ss, ...@@ -232,38 +224,21 @@ void OpVLookup::GenSlidingWindowFunction(std::stringstream &ss,
ss << " if(rowNum!=-1)\n"; ss << " if(rowNum!=-1)\n";
ss << " {\n"; ss << " {\n";
for(int j=0;j< secondParaWidth; j++) for (int j = 0; j < secondParaWidth; j++)
{ {
ss << " if(tmp"; ss << " if(tmp";
ss << 2+(secondParaWidth-1); ss << 2+(secondParaWidth-1);
ss << " == "; ss << " == ";
ss << j+1; ss << j+1;
ss << ")\n"; ss << ")\n";
///Add MixedArguments for string support in Vlookup. ss << " tmp = ";
if( !(vSubArguments[1+j]->IsMixedArgument())) vSubArguments[1+j]->GenDeclRef(ss);
{ ss << "[rowNum];\n";
ss << " tmp = ";
vSubArguments[1+j]->GenDeclRef(ss);
ss << "[rowNum];\n";
}
else
{
ss << " tmp = isNan(";
vSubArguments[1+j]->GenNumDeclRef(ss);
ss << "[rowNum])?";
vSubArguments[1+j]->GenNumDeclRef(ss);
ss << "[rowNum]:";
vSubArguments[1+j]->GenStringDeclRef(ss);
ss << "[rowNum];\n";
}
} }
ss << " return tmp;\n"; ss << " return tmp;\n";
ss << " }\n"; ss << " }\n";
} }
} }
else else
{ {
......
...@@ -20,7 +20,6 @@ public: ...@@ -20,7 +20,6 @@ public:
virtual void GenSlidingWindowFunction(std::stringstream &ss, virtual void GenSlidingWindowFunction(std::stringstream &ss,
const std::string &sSymName, SubArguments &vSubArguments) SAL_OVERRIDE; const std::string &sSymName, SubArguments &vSubArguments) SAL_OVERRIDE;
virtual std::string BinFuncName() const SAL_OVERRIDE { return "VLookup"; } virtual std::string BinFuncName() const SAL_OVERRIDE { return "VLookup"; }
virtual bool takeString() const SAL_OVERRIDE { return true; }
}; };
}} }}
......
...@@ -67,6 +67,7 @@ void ScCalcConfig::setOpenCLConfigToDefault() ...@@ -67,6 +67,7 @@ void ScCalcConfig::setOpenCLConfigToDefault()
maOpenCLSubsetOpCodes.insert(ocCount); maOpenCLSubsetOpCodes.insert(ocCount);
maOpenCLSubsetOpCodes.insert(ocVar); maOpenCLSubsetOpCodes.insert(ocVar);
maOpenCLSubsetOpCodes.insert(ocNormDist); maOpenCLSubsetOpCodes.insert(ocNormDist);
maOpenCLSubsetOpCodes.insert(ocVLookup);
maOpenCLSubsetOpCodes.insert(ocCorrel); maOpenCLSubsetOpCodes.insert(ocCorrel);
maOpenCLSubsetOpCodes.insert(ocCovar); maOpenCLSubsetOpCodes.insert(ocCovar);
maOpenCLSubsetOpCodes.insert(ocPearson); maOpenCLSubsetOpCodes.insert(ocPearson);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment