reduce opencl copy&paste also when handling svDoubleVectorRef
This is for when a simple loop is enough to handle the ranges. Change-Id: Ia2fa3b6944573f30fafea614a9ec51a21c7e8226 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140187 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
This commit is contained in:
@@ -19,6 +19,7 @@ namespace sc::opencl {
|
||||
void OpVar::GenSlidingWindowFunction(outputstream &ss,
|
||||
const std::string &sSymName, SubArguments &vSubArguments)
|
||||
{
|
||||
CHECK_PARAMETER_COUNT( 1, 30 );
|
||||
GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
|
||||
ss << "{\n";
|
||||
ss << " int gid0 = get_global_id(0);\n";
|
||||
@@ -26,160 +27,18 @@ void OpVar::GenSlidingWindowFunction(outputstream &ss,
|
||||
ss << " double fMean = 0.0;\n";
|
||||
ss << " double vSum = 0.0;\n";
|
||||
ss << " double fCount = 0.0;\n";
|
||||
ss << " double arg = 0.0;\n";
|
||||
unsigned i = vSubArguments.size();
|
||||
while (i--)
|
||||
{
|
||||
FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
|
||||
assert(pCur);
|
||||
if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
|
||||
{
|
||||
if (pCur->GetType() == formula::svDoubleVectorRef)
|
||||
{
|
||||
const formula::DoubleVectorRefToken* pDVR =
|
||||
static_cast<const formula::DoubleVectorRefToken *>(pCur);
|
||||
size_t nCurWindowSize = pDVR->GetRefRowSize();
|
||||
ss << " for (int i = ";
|
||||
if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
|
||||
{
|
||||
ss << "gid0; i < " << pDVR->GetArrayLength();
|
||||
ss << " && i < " << nCurWindowSize << "; i++)\n";
|
||||
ss << " {\n";
|
||||
}
|
||||
else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
|
||||
{
|
||||
ss << "0; i < " << pDVR->GetArrayLength();
|
||||
ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
|
||||
ss << " {\n";
|
||||
}
|
||||
else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
|
||||
{
|
||||
ss << "0; i + gid0 < " << pDVR->GetArrayLength();
|
||||
ss << " && i < " << nCurWindowSize << "; i++)\n";
|
||||
ss << " {\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
|
||||
ss << " {\n";
|
||||
}
|
||||
ss << " arg = ";
|
||||
ss << vSubArguments[i]->GenSlidingWindowDeclRef();
|
||||
ss << ";\n";
|
||||
ss << " if (isnan(arg))\n";
|
||||
ss << " continue;\n";
|
||||
ss << " fSum += arg;\n";
|
||||
ss << " fCount += 1.0;\n";
|
||||
ss << " }\n";
|
||||
}
|
||||
else if (pCur->GetType() == formula::svSingleVectorRef)
|
||||
{
|
||||
const formula::SingleVectorRefToken* pSVR =
|
||||
static_cast< const formula::SingleVectorRefToken*>(pCur);
|
||||
ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
|
||||
ss << " {\n";
|
||||
ss << " arg = ";
|
||||
ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
|
||||
ss << " if (!isnan(arg))\n";
|
||||
ss << " {\n";
|
||||
ss << " fSum += arg;\n";
|
||||
ss << " fCount += 1.0;\n";
|
||||
ss << " }\n";
|
||||
ss << " }\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << " arg = " << pCur->GetDouble() << ";\n";
|
||||
ss << " fSum += arg;\n";
|
||||
ss << " fCount += 1.0;\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << " arg = ";
|
||||
ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
|
||||
ss << " fSum += arg;\n";
|
||||
ss << " fCount += 1.0;\n";
|
||||
}
|
||||
if (i == 0)
|
||||
{
|
||||
ss << " fMean = fSum / fCount;\n";
|
||||
}
|
||||
}
|
||||
i = vSubArguments.size();
|
||||
while (i--)
|
||||
{
|
||||
FormulaToken *pCur = vSubArguments[i]->GetFormulaToken();
|
||||
assert(pCur);
|
||||
if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
|
||||
{
|
||||
if (pCur->GetType() == formula::svDoubleVectorRef)
|
||||
{
|
||||
const formula::DoubleVectorRefToken* pDVR =
|
||||
static_cast<const formula::DoubleVectorRefToken *>(pCur);
|
||||
size_t nCurWindowSize = pDVR->GetRefRowSize();
|
||||
ss << " for (int i = ";
|
||||
if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
|
||||
{
|
||||
ss << "gid0; i < " << pDVR->GetArrayLength();
|
||||
ss << " && i < " << nCurWindowSize << "; i++)\n";
|
||||
ss << " {\n";
|
||||
}
|
||||
else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
|
||||
{
|
||||
ss << "0; i < " << pDVR->GetArrayLength();
|
||||
ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
|
||||
ss << " {\n";
|
||||
}
|
||||
else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
|
||||
{
|
||||
ss << "0; i + gid0 < " << pDVR->GetArrayLength();
|
||||
ss << " && i < " << nCurWindowSize << "; i++)\n";
|
||||
ss << " {\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
|
||||
ss << " {\n";
|
||||
}
|
||||
|
||||
ss << " arg = ";
|
||||
ss << vSubArguments[i]->GenSlidingWindowDeclRef();
|
||||
ss << ";\n";
|
||||
ss << " if (isnan(arg))\n";
|
||||
ss << " continue;\n";
|
||||
ss << " vSum += (arg - fMean) * (arg - fMean);\n";
|
||||
ss << " }\n";
|
||||
}
|
||||
else if (pCur->GetType() == formula::svSingleVectorRef)
|
||||
{
|
||||
const formula::SingleVectorRefToken* pSVR =
|
||||
static_cast< const formula::SingleVectorRefToken*>(pCur);
|
||||
ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
|
||||
ss << " {\n";
|
||||
ss << " if (!isnan(";
|
||||
ss << vSubArguments[i]->GenSlidingWindowDeclRef();
|
||||
ss << "))\n";
|
||||
ss << " {\n";
|
||||
ss << " arg = ";
|
||||
ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
|
||||
ss << " vSum += (arg - fMean) * (arg - fMean);\n";
|
||||
ss << " }\n";
|
||||
ss << " }\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << " arg=" << pCur->GetDouble() << ";\n";
|
||||
ss << " vSum += (arg - fMean) * (arg - fMean);\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << " arg = ";
|
||||
ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
|
||||
ss << " vSum += (arg - fMean) * (arg - fMean);\n";
|
||||
}
|
||||
}
|
||||
GenerateRangeArgs( vSubArguments, ss,
|
||||
" if (!isnan(arg))\n"
|
||||
" {\n"
|
||||
" fSum += arg;\n"
|
||||
" fCount += 1.0;\n"
|
||||
" }\n"
|
||||
);
|
||||
ss << " fMean = fSum / fCount;\n";
|
||||
GenerateRangeArgs( vSubArguments, ss,
|
||||
" if (!isnan(arg))\n"
|
||||
" vSum += (arg - fMean) * (arg - fMean);\n"
|
||||
);
|
||||
ss << " if (fCount <= 1.0)\n";
|
||||
ss << " return CreateDoubleError(DivisionByZero);\n";
|
||||
ss << " else\n";
|
||||
|
||||
@@ -222,6 +222,91 @@ void SlidingFunctionBase::GenerateArgWithDefault( const char* name, int num, dou
|
||||
ss << " double " << name << " = " << def << ";\n";
|
||||
}
|
||||
|
||||
void SlidingFunctionBase::GenerateRangeArgs( int firstArg, int lastArg, SubArguments& vSubArguments,
|
||||
outputstream& ss, const char* code )
|
||||
{
|
||||
assert( firstArg >= 0 );
|
||||
assert( lastArg < int( vSubArguments.size()));
|
||||
for( int i = firstArg;
|
||||
i <= lastArg;
|
||||
++i )
|
||||
{
|
||||
FormulaToken *token = vSubArguments[i]->GetFormulaToken();
|
||||
if( token == nullptr )
|
||||
throw Unhandled( __FILE__, __LINE__ );
|
||||
if(token->GetOpCode() == ocPush)
|
||||
{
|
||||
if (token->GetType() == formula::svDoubleVectorRef)
|
||||
{
|
||||
const formula::DoubleVectorRefToken* pDVR =
|
||||
static_cast<const formula::DoubleVectorRefToken *>(token);
|
||||
size_t nCurWindowSize = pDVR->GetRefRowSize();
|
||||
ss << " for (int i = ";
|
||||
if (!pDVR->IsStartFixed() && pDVR->IsEndFixed())
|
||||
{
|
||||
ss << "gid0; i < " << pDVR->GetArrayLength();
|
||||
ss << " && i < " << nCurWindowSize << "; i++)\n";
|
||||
ss << " {\n";
|
||||
}
|
||||
else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
|
||||
{
|
||||
ss << "0; i < " << pDVR->GetArrayLength();
|
||||
ss << " && i < gid0+" << nCurWindowSize << "; i++)\n";
|
||||
ss << " {\n";
|
||||
}
|
||||
else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
|
||||
{
|
||||
ss << "0; i + gid0 < " << pDVR->GetArrayLength();
|
||||
ss << " && i < " << nCurWindowSize << "; i++)\n";
|
||||
ss << " {\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n";
|
||||
ss << " {\n";
|
||||
}
|
||||
ss << " double arg = ";
|
||||
ss << vSubArguments[i]->GenSlidingWindowDeclRef();
|
||||
ss << ";\n";
|
||||
ss << code;
|
||||
ss << " }\n";
|
||||
}
|
||||
else if (token->GetType() == formula::svSingleVectorRef)
|
||||
{
|
||||
const formula::SingleVectorRefToken* pSVR =
|
||||
static_cast< const formula::SingleVectorRefToken*>(token);
|
||||
ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n";
|
||||
ss << " {\n";
|
||||
ss << " double arg = ";
|
||||
ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
|
||||
ss << code;
|
||||
ss << " }\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << " {\n";
|
||||
ss << " double arg = " << token->GetDouble() << ";\n";
|
||||
ss << code;
|
||||
ss << " }\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << " {\n";
|
||||
ss << " double arg = ";
|
||||
ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n";
|
||||
ss << code;
|
||||
ss << " }\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SlidingFunctionBase::GenerateRangeArgs( SubArguments& vSubArguments,
|
||||
outputstream& ss, const char* code )
|
||||
{
|
||||
GenerateRangeArgs( 0, vSubArguments.size() - 1, vSubArguments, ss, code );
|
||||
}
|
||||
|
||||
void SlidingFunctionBase::GenerateFunctionDeclaration( const std::string& sSymName,
|
||||
SubArguments& vSubArguments, outputstream& ss )
|
||||
{
|
||||
|
||||
@@ -254,7 +254,7 @@ public:
|
||||
virtual void GenSlidingWindowFunction( outputstream&,
|
||||
const std::string&, SubArguments& ) = 0;
|
||||
protected:
|
||||
// generate code for "double <name> = <value>;" from vSubArguments
|
||||
// generate code for "double <name> = <value>;" from vSubArguments, svDoubleVectorRef is not supported
|
||||
static void GenerateArg( const char* name, int num, SubArguments& vSubArguments, outputstream& ss );
|
||||
// overload, variable will be named "arg<num>"
|
||||
static void GenerateArg( int num, SubArguments& vSubArguments, outputstream& ss );
|
||||
@@ -264,6 +264,13 @@ protected:
|
||||
outputstream& ss );
|
||||
void GenerateFunctionDeclaration( const std::string& sSymName,
|
||||
SubArguments& vSubArguments, outputstream& ss );
|
||||
// Generate code that will handle all arguments firstArg-lastArg (zero-based, inclusive),
|
||||
// including range arguments (svDoubleVectorRef) and each value will be processed by 'code',
|
||||
// value will be named "arg". There is no isnan(arg) checking.
|
||||
static void GenerateRangeArgs( int firstArg, int lastArg, SubArguments& vSubArguments,
|
||||
outputstream& ss, const char* code );
|
||||
// overload, handle all arguments
|
||||
static void GenerateRangeArgs( SubArguments& vSubArguments, outputstream& ss, const char* code );
|
||||
};
|
||||
|
||||
class Normal : public SlidingFunctionBase
|
||||
|
||||
Reference in New Issue
Block a user