/* -*- 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/.
*/
void OpInt::GenerateCode( outputstream& ss ) const
{
ss << " return floor( value_approx( arg0 ));\n";
}
void OpNegSub::GenerateCode( outputstream& ss ) const
{
ss << " return -arg0;\n";
}
void OpRadians::GenerateCode( outputstream& ss ) const
{
ss << " return arg0 * M_PI / 180.0;\n";
}
void OpIsEven::GenerateCode( outputstream& ss ) const
{
ss << " return (fmod(floor(fabs(arg0)), 2.0)<0.5);\n";
}
void OpIsOdd::GenerateCode( outputstream& ss ) const
{
ss << " return !(fmod(floor(fabs(arg0)), 2.0)<0.5);\n";
}
void OpSqrtPi::GenerateCode( outputstream& ss ) const
{
ss << " return (double)sqrt(arg0 * M_PI);\n";
}
void OpDeg::GenerateCode( outputstream& ss ) const
{
ss << " return arg0 / M_PI * 180;\n";
}
void OpFact::GenerateCode( outputstream& ss ) const
{
ss << " arg0 = floor(arg0);\n";
ss << " if (arg0 < 0.0)\n";
ss << " return CreateDoubleError(IllegalArgument);\n";
ss << " else if (arg0 == 0.0)\n";
ss << " return 1.0;\n";
ss << " else if (arg0 <= 170.0)\n";
ss << " {\n";
ss << " double fTemp = arg0;\n";
ss << " while (fTemp > 2.0)\n";
ss << " {\n";
ss << " fTemp = fTemp - 1;\n";
ss << " arg0 = arg0 * fTemp;\n";
ss << " }\n";
ss << " }\n";
ss << " else\n";
ss << " return CreateDoubleError(NoValue);\n";
ss << " return arg0;\n";
}
void OpOdd::GenerateCode( outputstream& ss ) const
{
ss << " double tmp;\n";
ss << " if (arg0 > 0.0 ){\n";
ss << " tmp=Intg(arg0);\n";
ss << " if(tmp-trunc(tmp/2)*2 == 0)\n";
ss << " tmp=tmp+1;\n";
ss << " }else if (arg0 < 0.0 ){\n";
ss << " tmp=Intg(arg0);\n";
ss << " if(tmp-trunc(tmp/2)*2 == 0)\n";
ss << " tmp=tmp-1.0;\n";
ss << " }else\n";
ss << " tmp=1.0;\n";
ss << " return tmp;\n";
}
void OpCombinA::GenerateCode( outputstream& ss ) const
{
ss << " arg0 = trunc(arg0);\n";
ss << " arg1 = trunc(arg1);\n";
ss << " if (arg0 < 0.0 || arg1 < 0.0 || arg1 > arg0)\n";
ss << " return CreateDoubleError(IllegalArgument);\n";
ss << " double tem;\n";
ss << " if(arg0 >= arg1 && arg0 > 0 && arg1 > 0)\n";
ss << " tem = bik(arg0+arg1-1,arg1);\n";
ss << " else if(arg0 == 0 && arg1 == 0)\n";
ss << " tem = 0;\n";
ss << " else if(arg0 > 0 && arg1 == 0)\n";
ss << " tem = 1;\n";
ss << " else\n";
ss << " tem = -1;\n";
ss << " double i = tem - trunc(tem);\n";
ss << " if(i < 0.5)\n";
ss << " tem = trunc(tem);\n";
ss << " else\n";
ss << " tem = trunc(tem) + 1;\n";
ss << " return tem;\n";
}
void OpCombin::GenerateCode( outputstream& ss ) const
{
ss << " double result = -1.0;\n";
ss << " double num = floor( arg0 );\n";
ss << " double num_chosen = floor( arg1 );\n";
ss << " if(num < 0 || num_chosen < 0 || num < num_chosen )\n";
ss << " return CreateDoubleError(IllegalArgument);\n";
ss << " result = select(result, 0.0, (ulong)(num < num_chosen));\n";
ss << " result = select(result, 1.0, (ulong)(num_chosen == 0.0));\n";
ss << " if(result == 0 || result ==1)\n";
ss << " return result;\n";
ss << " double4 db4num;\n";
ss << " double4 db4num_chosen;\n";
ss << " double4 db4result;\n";
ss << " double2 db2result;\n";
ss << " result = 1.0;\n";
ss << " int loop = num_chosen/4;\n";
ss << " for(int i=0; i;
ss << " {\n";
ss << " db4num = (double4){num,\n";
ss << " num-1.0,\n";
ss << " num-2.0,\n";
ss << " num-3.0};\n";
ss << " db4num_chosen = (double4){num_chosen,\n";
ss << " num_chosen-1.0,\n";
ss << " num_chosen-2.0,\n";
ss << " num_chosen-3.0};\n";
ss << " db4result = db4num / db4num_chosen;\n";
ss << " db2result = db4result.xy * db4result.zw;\n";
ss << " result *= db2result.x * db2result.y;\n";
ss << " num = num - 4.0;\n";
ss << " num_chosen = num_chosen - 4.0;\n";
ss << " }\n";
ss << " while ( num_chosen > 0){\n";
ss << " result *= num / num_chosen;\n";
ss << " num = num - 1.0;\n";
ss << " num_chosen = num_chosen - 1.0;\n";
ss << " }\n";
ss << " return result;\n";
}
mNeedReductionKernel = vSubArguments[0]->NeedParallelReduction(); if (mNeedReductionKernel)
{ // generate reduction functions
ss << "__kernel void ";
ss << vSubArguments[0]->GetName();
ss << "_SumIfs_reduction( "; for (size_t i = 0; i < vSubArguments.size(); i++)
{ if (i)
ss << ",";
vSubArguments[i]->GenSlidingWindowDecl(ss);
}
ss << ", __global double *result,int arrayLength,int windowSize";
ss << ")\n{\n";
ss << " double tmp =0;\n";
ss << " int i ;\n";
GenTmpVariables(ss,vSubArguments);
ss << " double current_result = 0.0;\n";
ss << " int writePos = get_group_id(1);\n"; if (pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed())
ss << " int offset = 0;\n"; elseif (!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
ss << " int offset = get_group_id(1);\n"; else throw Unhandled(__FILE__, __LINE__); // actually unreachable
ss << " int lidx = get_local_id(0);\n";
ss << " __local double shm_buf[256];\n";
ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
ss << " int loop = arrayLength/512 + 1;\n";
ss << " for (int l=0; l;
ss << " tmp = 0.0;\n";
ss << " int loopOffset = l*512;\n";
ss << " int p1 = loopOffset + lidx + offset, p2 = p1 + 256;\n";
ss << " if (p2 < min(offset + windowSize, arrayLength)) {\n";
ss << " tmp0 = 0.0;\n"; int mm=0;
std::string p1 = "p1";
std::string p2 = "p2"; for(size_t j=1;j<vSubArguments.size();j+=2,mm++)
{
CheckSubArgumentIsNan2(ss,vSubArguments,j,p1);
CheckSubArgumentIsNan2(ss,vSubArguments,j+1,p1);
ss << "";
ss <<" if(isequal(";
ss <<"tmp";
ss <<j;
ss <<" , ";
ss << "tmp";
ss << j+1;
ss << "))";
ss << "{\n";
}
CheckSubArgumentIsNan2(ss,vSubArguments,0,p1);
ss << " tmp += tmp0;\n"; for(size_t j=1;j<vSubArguments.size();j+=2,mm--)
{ for(int n = 0;n<mm+1;n++)
{
ss << " ";
}
ss<< "}\n\n";
}
mm=0; for(size_t j=1;j<vSubArguments.size();j+=2,mm++)
{
CheckSubArgumentIsNan2(ss,vSubArguments,j,p2);
CheckSubArgumentIsNan2(ss,vSubArguments,j+1,p2);
ss <<" if(isequal(";
ss <<"tmp";
ss <<j;
ss <<" , ";
ss << "tmp";
ss << j+1;
ss << ")){\n";
}
CheckSubArgumentIsNan2(ss,vSubArguments,0,p2);
ss << " tmp += tmp0;\n"; for(size_t j=1;j< vSubArguments.size();j+=2,mm--)
{ for(int n = 0;n<mm+1;n++)
{
ss << " ";
}
ss<< "}\n";
}
ss << " }\n";
ss << " else if (p1 < min(arrayLength, offset + windowSize)) {\n";
mm=0; for(size_t j=1;j<vSubArguments.size();j+=2,mm++)
{
CheckSubArgumentIsNan2(ss,vSubArguments,j,p1);
CheckSubArgumentIsNan2(ss,vSubArguments,j+1,p1);
ss <<" if(isequal(";
ss <<"tmp";
ss <<j;
ss <<" , ";
ss << "tmp";
ss << j+1;
ss << ")){\n";
}
CheckSubArgumentIsNan2(ss,vSubArguments,0,p1);
ss << " tmp += tmp0;\n"; for(size_t j=1;j<vSubArguments.size();j+=2,mm--)
{ for(int n = 0;n<mm+1;n++)
{
ss << " ";
}
ss<< "}\n\n";
}
ss << " }\n";
ss << " shm_buf[lidx] = tmp;\n";
ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
ss << " for (int i = 128; i >0; i/=2) {\n";
ss << " if (lidx < i)\n";
ss << " shm_buf[lidx] += shm_buf[lidx + i];\n";
ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
ss << " }\n";
ss << " if (lidx == 0)\n";
ss << " current_result += shm_buf[0];\n";
ss << " barrier(CLK_LOCAL_MEM_FENCE);\n";
ss << " }\n";
ss << " if (lidx == 0)\n";
ss << " result[writePos] = current_result;\n";
ss << "}\n";
}// finish generate reduction code // generate functions as usual
GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
ss << "{\n";
ss <<" int gid0=get_global_id(0);\n";
ss << " double tmp =0;\n"; if (!mNeedReductionKernel)
{
ss << " int i ;\n";
GenTmpVariables(ss,vSubArguments);
ss << " for (i = "; if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) {
ss << "gid0; i < "<< nCurWindowSize <<"; i++)\n";
} elseif (pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed()) {
ss << "0; i < gid0+"<< nCurWindowSize <<"; i++)\n";
} else {
ss << "0; i < "<< nCurWindowSize <<"; i++)\n";
}
ss << " {\n"; if(!pCurDVR->IsStartFixed() && !pCurDVR->IsEndFixed())
{
ss<< " int doubleIndex =i+gid0;\n";
}else
{
ss<< " int doubleIndex =i;\n";
}
ss<< " int singleIndex =gid0;\n"; int m=0; for(size_t j=1;j<vSubArguments.size();j+=2,m++)
{
CheckSubArgumentIsNan(ss,vSubArguments,j);
CheckSubArgumentIsNan(ss,vSubArguments,j+1);
ss <<" if(isequal(";
ss <<"tmp";
ss <<j;
ss <<" , ";
ss << "tmp";
ss << j+1;
ss << ")){\n";
}
CheckSubArgumentIsNan(ss,vSubArguments,0);
ss << " tmp += tmp0;\n"; for(size_t j=1;j<=vSubArguments.size();j+=2,m--)
{ for(int n = 0;n<m+1;n++)
{
ss << " ";
}
ss<< "}\n";
}
} if (mNeedReductionKernel)
{
ss << "tmp =";
vSubArguments[0]->GenDeclRef(ss);
ss << "[gid0];\n";
}
ss << "return tmp;\n";
ss << "}";
}
void OpAverageIfs::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
{
FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); const formula::DoubleVectorRefToken*pCurDVR= static_cast<const
formula::DoubleVectorRefToken *>(tmpCur);
size_t nCurWindowSize = pCurDVR->GetArrayLength() <
pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength():
pCurDVR->GetRefRowSize() ;
GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
ss << "{\n";
ss <<" int gid0=get_global_id(0);\n";
ss << " double tmp =0;\n";
ss << " int count=0;\n";
ss << " int loop;";
GenTmpVariables(ss,vSubArguments);
ss<< " int singleIndex =gid0;\n"; int m=0;
outputstream tmpss; for(size_t j=1;j<vSubArguments.size();j+=2,m++)
{
CheckSubArgumentIsNan(tmpss,vSubArguments,j);
CheckSubArgumentIsNan(ss,vSubArguments,j+1);
tmpss <<" if(isequal(";
tmpss <<"tmp";
tmpss <<j;
tmpss <<" , ";
tmpss << "tmp";
tmpss << j+1;
tmpss << ")){\n";
}
CheckSubArgumentIsNan(tmpss,vSubArguments,0);
tmpss << " tmp += tmp0;\n";
tmpss << " count++;\n"; for(size_t j=1;j<vSubArguments.size();j+=2,m--)
{ for(int n = 0;n<m+1;n++)
{
tmpss << " ";
}
tmpss<< "}\n";
}
void OpRound::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
{
CHECK_PARAMETER_COUNT( 1, 2 );
GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
ss << "{\n";
ss << " int gid0=get_global_id(0);\n";
GenerateArg( "value", 0, vSubArguments, ss ); if(vSubArguments.size() ==1)
ss << " return round(value);\n"; else
{
GenerateArg( "fDec", 1, vSubArguments, ss );
ss << " int dec = floor( fDec );\n";
ss << " if( dec < -20 || dec > 20 )\n";
ss << " return CreateDoubleError( IllegalArgument );\n";
ss << " if( dec == 0 )\n";
ss << " return round(value);\n";
ss << " double orig_value = value;\n";
ss << " value = fabs(value);\n";
ss << " double multiply = pown(10.0, dec);\n";
ss << " double tmp = value*multiply;\n";
ss << " tmp = Round( tmp );\n";
ss << " return copysign(tmp/multiply, orig_value);\n";
}
ss << "}";
}
void OpRoundUp::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
{
CHECK_PARAMETER_COUNT( 1, 2 );
GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
ss << "{\n";
ss << " int gid0=get_global_id(0);\n";
GenerateArg( "value", 0, vSubArguments, ss );
GenerateArgWithDefault( "fDec", 1, 0, vSubArguments, ss );
ss << " int dec = floor( fDec );\n";
ss << " if( dec < -20 || dec > 20 )\n";
ss << " return CreateDoubleError( IllegalArgument );\n";
ss << " double orig_value = value;\n";
ss << " value = fabs(value);\n";
ss << " double multiply = pown(10.0, dec);\n";
ss << " double tmp = value*multiply;\n";
ss << " double integral;\n"; // The pown() above increases rounding error, so compensate for it here. // If the fractional part is close above zero, adjusted for rounding error, // the number just needs to be rounded (=truncated).
ss << " if( modf( tmp, &integral ) / multiply < 1e-12 )\n";
ss << " tmp = integral;\n";
ss << " else\n";
ss << " tmp = integral + 1;\n";
ss << " return copysign(tmp/multiply, orig_value);\n";
ss << "}";
}
void OpRoundDown::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
{
CHECK_PARAMETER_COUNT( 1, 2 );
GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
ss << "{\n";
ss << " int gid0=get_global_id(0);\n";
GenerateArg( "value", 0, vSubArguments, ss );
GenerateArgWithDefault( "fDec", 1, 0, vSubArguments, ss );
ss << " int dec = floor( fDec );\n";
ss << " if( dec < -20 || dec > 20 )\n";
ss << " return CreateDoubleError( IllegalArgument );\n";
ss << " double orig_value = value;\n";
ss << " value = fabs(value);\n";
ss << " double multiply = pown(10.0, dec);\n";
ss << " double tmp = value*multiply;\n";
ss << " double integral;\n"; // The pown() above increases rounding error, so compensate for it here. // If the fractional part is close below one, adjusted for rounding error, // the number just needs to be rounded (=truncated + 1).
ss << " if(( 1 - modf( tmp, &integral )) / multiply < 1e-12 )\n";
ss << " tmp = integral + 1;\n";
ss << " else\n";
ss << " tmp = integral;\n";
ss << " return copysign(tmp/multiply, orig_value);\n";
ss << "}";
}
void OpCountIf::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
{
GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
ss << "{\n";
ss << " int gid0=get_global_id(0);\n";
ss << " double vara, varb;\n";
ss << " int varc = 0;\n";
FormulaToken *tmpCur = vSubArguments[1]->GetFormulaToken();
assert(tmpCur); if(ocPush == vSubArguments[1]->GetFormulaToken()->GetOpCode())
{ if(tmpCur->GetType() == formula::svSingleVectorRef)
{ const formula::SingleVectorRefToken* tmpCurDVR= static_cast< const formula::SingleVectorRefToken *>(tmpCur);
ss << " varb = ";
ss << vSubArguments[1]->GenSlidingWindowDeclRef();
ss << ";\n";
ss << " if(isnan(varb)||(gid0>=";
ss << tmpCurDVR->GetArrayLength();
ss << "))\n";
ss << " varb = 0;\n";
} elseif(tmpCur->GetType() == formula::svDouble)
{
ss << " varb = ";
ss << tmpCur->GetDouble() << ";\n";
}
} else
{
ss << " varb = ";
ss << vSubArguments[1]->GenSlidingWindowDeclRef();
ss << ";\n";
}
tmpCur = vSubArguments[0]->GetFormulaToken();
assert(tmpCur); if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
{ //TODO DoubleVector if (tmpCur->GetType() == formula::svDoubleVectorRef)
{ const formula::DoubleVectorRefToken* pDVR = static_cast<const formula::DoubleVectorRefToken *>(tmpCur);
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";
} elseif (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
{
ss << "0; i < " << pDVR->GetArrayLength();
ss << " && i < gid0+"<< nCurWindowSize << "; ++i)\n";
ss << " {\n";
} elseif (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
{
ss << "0; i + gid0 < " << pDVR->GetArrayLength();
ss << " && i < "<< nCurWindowSize << "; ++i)\n";
ss << " {\n";
} else
{
ss << "0; i < "<< nCurWindowSize << "; ++i)\n";
ss << " {\n";
}
ss << " vara = ";
ss << vSubArguments[0]->GenSlidingWindowDeclRef();
ss << ";\n";
ss << " if (isnan(vara))\n";
ss << " continue;\n";
ss << " (vara == varb) && varc++;\n";
ss << " }\n";
} elseif(tmpCur->GetType() == formula::svSingleVectorRef)
{ const formula::SingleVectorRefToken* tmpCurDVR= static_cast< const formula::SingleVectorRefToken *>(tmpCur);
ss << " vara = ";
ss << vSubArguments[0]->GenSlidingWindowDeclRef();
ss << ";\n";
ss << " if(isnan(vara)||(gid0>=";
ss << tmpCurDVR->GetArrayLength();
ss << "))\n";
ss << " return 0;\n";
ss << " (vara == varb) && varc++;\n";
}
}
ss << " return varc;\n";
ss << "}";
}
void OpSumIf::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
{
GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
ss << "{\n";
ss << " int gid0=get_global_id(0);\n";
ss << " double vara, varb, varc, sum = 0.0f;\n"; int flag = 3 == vSubArguments.size() ? 2 : 0;
FormulaToken *tmpCur = vSubArguments[1]->GetFormulaToken();
assert(tmpCur); if(ocPush == vSubArguments[1]->GetFormulaToken()->GetOpCode())
{ if(tmpCur->GetType() == formula::svSingleVectorRef)
{ const formula::SingleVectorRefToken* tmpCurDVR= static_cast< const formula::SingleVectorRefToken *>(tmpCur);
ss << " varb = ";
ss << vSubArguments[1]->GenSlidingWindowDeclRef();
ss << ";\n";
ss << " if(isnan(varb)||(gid0>=";
ss << tmpCurDVR->GetArrayLength();
ss << "))\n";
ss << " varb = 0;\n";
} elseif(tmpCur->GetType() == formula::svDouble)
{
ss << " varb = ";
ss << tmpCur->GetDouble() << ";\n";
}
} else
{
ss << " varb = ";
ss << vSubArguments[1]->GenSlidingWindowDeclRef();
ss << ";\n";
}
tmpCur = vSubArguments[0]->GetFormulaToken();
assert(tmpCur); if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode())
{ //TODO DoubleVector if (tmpCur->GetType() == formula::svDoubleVectorRef)
{ const formula::DoubleVectorRefToken* pDVR = static_cast<const formula::DoubleVectorRefToken *>(tmpCur);
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";
} elseif (pDVR->IsStartFixed() && !pDVR->IsEndFixed())
{
ss << "0; i < " << pDVR->GetArrayLength();
ss << " && i < gid0+"<< nCurWindowSize << "; ++i)\n";
ss << " {\n";
} elseif (!pDVR->IsStartFixed() && !pDVR->IsEndFixed())
{
ss << "0; i + gid0 < " << pDVR->GetArrayLength();
ss << " && i < "<< nCurWindowSize << "; ++i)\n";
ss << " {\n";
} else
{
ss << "0; i < "<< nCurWindowSize << "; ++i)\n";
ss << " {\n";
}
ss << " vara = ";
ss << vSubArguments[0]->GenSlidingWindowDeclRef();
ss << ";\n";
ss << " if (isnan(vara))\n";
ss << " continue;\n";
ss << " varc = ";
ss << vSubArguments[flag]->GenSlidingWindowDeclRef();
ss << ";\n";
ss << " if (isnan(varc))\n";
ss << " varc = 0.0f;\n";
ss << " (vara == varb)&&(sum = sum + varc);\n";
ss << " }\n";
} elseif(tmpCur->GetType() == formula::svSingleVectorRef)
{ const formula::SingleVectorRefToken* tmpCurDVR= static_cast< const formula::SingleVectorRefToken *>(tmpCur);
ss << " vara = ";
ss << vSubArguments[0]->GenSlidingWindowDeclRef();
ss << ";\n";
ss << " if(isnan(vara)||(gid0>=";
ss << tmpCurDVR->GetArrayLength();
ss << "))\n";
ss << " return 0;\n";
ss << " int i = 0;\n";
ss << " varc = ";
ss << vSubArguments[flag]->GenSlidingWindowDeclRef();
ss << ";\n";
ss << " if(isnan(varc)||(gid0>=";
ss << tmpCurDVR->GetArrayLength();
ss << "))\n";
ss << " varc = 0.0f;\n";
ss << " (vara == varb)&&(sum = sum + varc);\n";
}
}
ss << " return sum;\n";
ss << "}";
}
void OpFloor::GenSlidingWindowFunction(
outputstream &ss, const std::string &sSymName,
SubArguments &vSubArguments)
{
CHECK_PARAMETER_COUNT( 2, 3 );
GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
ss << "{\n";
ss << " int gid0=get_global_id(0);\n";
GenerateArg( "arg0", 0, vSubArguments, ss );
GenerateArg( "arg1", 1, vSubArguments, ss );
GenerateArgWithDefault( "arg2", 2, 0, vSubArguments, ss );
ss << " if(isnan(arg0) || isnan(arg1))\n";
ss << " return 0;\n";
ss << " if(isnan(arg2))\n";
ss << " arg2 = 0.0;\n";
ss << " if(arg0*arg1<0)\n";
ss << " return CreateDoubleError(IllegalArgument);\n";
ss << " if(arg1 == 0.0)\n";
ss << " return 0.0;\n";
ss << " else if(arg2==0.0&&arg0<0.0)\n";
ss << " return (trunc(arg0/arg1)+1)*arg1;\n";
ss << " else\n";
ss << " return trunc(arg0/arg1)*arg1;\n";
ss << "}\n";
}
void OpSumSQ::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";
ss << " double sum = 0.0f, arg;\n";
GenerateRangeArgs( vSubArguments, ss, SkipEmpty, " sum += pown(arg, 2);\n"
);
ss << " return sum;\n";
ss << "}";
}
void OpCeil::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
{
CHECK_PARAMETER_COUNT( 2, 3 );
GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
ss << "{\n";
ss << " int gid0 = get_global_id(0);\n";
GenerateArg( "num", 0, vSubArguments, ss );
GenerateArg( "significance", 1, vSubArguments, ss );
GenerateArgWithDefault( "bAbs", 2, 0, vSubArguments, ss );
ss << " if(num*significance < 0.0)\n";
ss << " return CreateDoubleError(IllegalArgument);\n";
ss << " if(significance == 0.0)\n";
ss << " return 0.0;\n";
ss << " return ";
ss << "( !(int)bAbs && num < 0.0 ? floor( num / significance ) : ";
ss << "ceil( num / significance ) )";
ss << "*significance;\n";
ss << "}";
}
void OpProduct::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";
ss << " double product=1.0;\n";
ss << " int count = 0;\n\n";
GenerateRangeArgs( vSubArguments, ss, SkipEmpty, " product = product*arg;\n" " ++count;\n"
);
ss << " if(count == 0)\n";
ss << " return 0;\n";
ss << " return product;\n";
ss << "}";
}
void OpAverageIf::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments)
{
GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
ss << "{\n";
ss << " int gid0=get_global_id(0);\n";
ss << " double tmp =0;\n";
ss << " double count=0;\n";
ss << " int singleIndex =gid0;\n";
ss << " int doubleIndex;\n";
ss << " int i ;\n";
ss << " int j ;\n";
GenTmpVariables(ss,vSubArguments);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.