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:
Luboš Luňák
2022-09-20 08:44:30 +02:00
parent 2adc8a32ff
commit f0466cabc2
3 changed files with 106 additions and 155 deletions
+13 -154
View File
@@ -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";
+85
View File
@@ -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 )
{
+8 -1
View File
@@ -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