From 85bf78b31b3719edd7a22ae768d8b2e23816cdbd Mon Sep 17 00:00:00 2001 From: Luboš Luňák Date: Tue, 6 Sep 2022 12:37:55 +0200 Subject: reduce opencl copy&paste in op_math.cxx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ibe2afa6ca3720a6cec8b74af5c582cb946cf5396 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139486 Tested-by: Jenkins Reviewed-by: Luboš Luňák --- sc/source/core/opencl/op_math.cxx | 2427 ++++++++-------------------- sc/source/core/opencl/op_math.hxx | 351 ++-- sc/source/core/opencl/opbase.cxx | 9 + sc/source/core/opencl/opbase.hxx | 4 + sc/source/core/opencl/opinlinefun_math.hxx | 21 +- 5 files changed, 854 insertions(+), 1958 deletions(-) (limited to 'sc') diff --git a/sc/source/core/opencl/op_math.cxx b/sc/source/core/opencl/op_math.cxx index b837d930910f..550446393a8f 100644 --- a/sc/source/core/opencl/op_math.cxx +++ b/sc/source/core/opencl/op_math.cxx @@ -17,200 +17,63 @@ using namespace formula; namespace sc::opencl { -void OpCos::GenSlidingWindowFunction(outputstream &ss, +void OpMathOneArgument::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 arg0 = 0.0f;\n"; - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - assert(tmpCur); - if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode()) - { - if(tmpCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken*tmpCurDVR= - static_cast - (tmpCur); - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ")||(gid0>="; - ss << tmpCurDVR->GetArrayLength(); - ss << "))\n"; - ss << " { arg0 = 0.0f; }\n"; - } - else if(tmpCur->GetType() == formula::svDouble) - { - ss << " arg0=" << tmpCur->GetDouble() << ";\n"; - } - } - else - { - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - } - ss << " return cos(arg0);\n"; - ss << "}"; - + CHECK_PARAMETER_COUNT( 1, 1 ); + GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); + ss << "{\n"; + ss << " int gid0 = get_global_id(0);\n"; + GenerateArg( 0, vSubArguments, ss ); + GenerateCode( ss ); + ss << "}"; } -void OpSec::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) + +void OpMathTwoArguments::GenSlidingWindowFunction(outputstream &ss, + const std::string &sSymName, SubArguments &vSubArguments) { - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVR= static_cast(tmpCur); + CHECK_PARAMETER_COUNT( 2, 2 ); GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); ss << "{\n"; - ss <<" int gid0=get_global_id(0);\n"; - ss <<" double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss <<";\n"; - ss<<" if(isnan(arg0)||(gid0>="; - ss<GetArrayLength(); - ss<<"))\n"; - ss<<" arg0 = 0;\n"; - ss << " return 1.0 / cos(arg0);\n"; + ss << " double tmp = 0;\n"; + ss << " int gid0 = get_global_id(0);\n"; + GenerateArg( 0, vSubArguments, ss ); + GenerateArg( 1, vSubArguments, ss ); + GenerateCode( ss ); ss << "}"; } -void OpCosh::BinInlineFun(std::set& decls, - std::set& funs) + +void OpCos::GenerateCode( outputstream& ss ) const { - decls.insert(local_coshDecl); - funs.insert(local_cosh); + ss << " return cos(arg0);\n"; } -void OpSecH::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) + +void OpSec::GenerateCode( outputstream& ss ) const { - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVR= static_cast(tmpCur); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss <<" int gid0=get_global_id(0);\n"; - ss <<" double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss <<";\n"; - ss<<" if(isnan(arg0)||(gid0>="; - ss<GetArrayLength(); - ss<<"))\n"; - ss<<" arg0 = 0;\n"; - ss << " return 1.0 / cosh(arg0);\n"; - ss << "}"; + ss << " return 1.0 / cos(arg0);\n"; } -void OpMROUND::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) + +void OpSecH::GenerateCode( outputstream& ss ) const { - CHECK_PARAMETER_COUNT(2, 2); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss<<" double tmp = 0;\n"; - ss<<" int gid0 = get_global_id(0);\n"; - ss<<" double arg0=0;\n"; - ss<<" double arg1=0;\n"; - ss <<"\n "; - //while (i-- > 1) - for (size_t i = 0; i < vSubArguments.size(); i++) - { - FormulaToken *pCur = vSubArguments[i]->GetFormulaToken(); - assert(pCur); - if (pCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* pSVR = - static_cast< const formula::SingleVectorRefToken* >(pCur); - ss << "if (gid0 < " << pSVR->GetArrayLength() << "){\n"; - } - else if (pCur->GetType() == formula::svDouble) - { - ss << "{\n"; - } + ss << " return 1.0 / cosh(arg0);\n"; +} - if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode()) - { - ss << " tmp="; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(tmp))\n"; - ss << " arg"<& decls, + std::set& funs) +{ + decls.insert(local_coshDecl); + funs.insert(local_cosh); } -void OpCosh::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) + +void OpCosh::GenerateCode( outputstream& ss ) const { - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVR= static_cast(tmpCur); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss <<" int gid0=get_global_id(0);\n"; - ss << " double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss<< " if(isnan(arg0)||(gid0>="; - ss<GetArrayLength(); - ss<<"))\n"; - ss<<" arg0 = 0;\n"; - ss << " double tmp=local_cosh(arg0);\n"; - ss << " return tmp;\n"; - ss << "}"; + ss << " return local_cosh(arg0);\n"; } -void OpCot::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) +void OpCot::GenerateCode( outputstream& ss ) const { - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0=get_global_id(0);\n"; - ss << " double arg0 = 0.0f;\n"; - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - assert(tmpCur); - if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode()) - { - if(tmpCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken*tmpCurDVR= - static_cast - (tmpCur); - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ")||(gid0>="; - ss << tmpCurDVR->GetArrayLength(); - ss << "))\n"; - ss << " { arg0 = 0.0f; }\n"; - } - else if(tmpCur->GetType() == formula::svDouble) - { - ss << " arg0="; - ss << tmpCur->GetDouble() << ";\n"; - } - } - else - { - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - } ss << " arg0 = arg0 * M_1_PI;\n"; ss << " return cospi(arg0) / sinpi(arg0);\n"; - ss << "}"; } void OpCoth::BinInlineFun(std::set& decls, @@ -220,98 +83,14 @@ void OpCoth::BinInlineFun(std::set& decls, funs.insert(local_coth); } -void OpCoth::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVR= static_cast(tmpCur); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss <<" int gid0=get_global_id(0);\n"; - ss << " double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss<< " if(isnan(arg0)||(gid0>="; - ss<GetArrayLength(); - ss<<"))\n"; - ss<<" arg0 = 0;\n"; - ss << " double tmp=local_coth(arg0);\n"; - ss << " return tmp;\n"; - ss << "}"; -} - -void OpCombinA::BinInlineFun(std::set& decls, - std::set& funs) +void OpCoth::GenerateCode( outputstream& ss ) const { - decls.insert(bikDecl); - funs.insert(bik); + ss << " return local_coth(arg0);\n"; } -void OpCombinA::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) +void OpEven::GenerateCode( outputstream& ss ) const { - CHECK_PARAMETER_COUNT( 2, 2 ); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0 = get_global_id(0);\n"; - ss << " double tem;\n"; - ss << " double arg0,arg1;\n"; - for (size_t i = 0; i < vSubArguments.size(); i++) - { - FormulaToken *pCur = vSubArguments[i]->GetFormulaToken(); - assert(pCur); - ss << " arg"<GenSlidingWindowDeclRef(); - ss << ";\n"; - if(pCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* pSVR = - static_cast< const formula::SingleVectorRefToken* >(pCur); - ss << " if(isnan(arg" << i <<")||(gid0 >= "; - ss << pSVR->GetArrayLength(); - ss << "))\n"; - ss << " arg" << i << " = 0;\n"; - } - else if (pCur->GetType() == formula::svDouble) - { - ss << " if(isnan(arg" << i <<"))\n"; - ss << " arg" << i << " = 0;\n"; - } - } - ss << " arg0 = trunc(arg0);\n"; - ss << " arg1 = trunc(arg1);\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"; - ss << "}"; -} -void OpEven::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVR= static_cast(tmpCur); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss <<" int gid0=get_global_id(0);\n"; - ss << " double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss<< " if(isnan(arg0)||(gid0>="; - ss<GetArrayLength(); - ss<<"))\n"; - ss<<" arg0 = 0;\n"; - ss << " double tmp;\n"; - ss << " tmp = fabs(arg0 / 2);\n"; + ss << " double tmp = fabs(arg0 / 2);\n"; ss << " if ( trunc(tmp) == tmp )\n"; ss << " tmp = tmp * 2;\n"; ss << " else\n"; @@ -319,1056 +98,689 @@ void OpEven::GenSlidingWindowFunction(outputstream &ss, ss << " if (arg0 < 0)\n"; ss << " tmp = tmp * -1.0;\n"; ss << " return tmp;\n"; - ss << "}"; } -void OpMod::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) +void OpCsc::GenerateCode( outputstream& ss ) const { - CHECK_PARAMETER_COUNT( 2, 2 ); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss <<" int gid0=get_global_id(0);\n"; - ss << " double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " double arg1 =" << vSubArguments[1]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan(arg0)||arg0 == 0)\n"; - ss << " return 0;\n"; - ss << " if(isnan(arg1) || arg1 ==0)\n"; - ss << " return CreateDoubleError(DivisionByZero);\n"; - ss << " double tem;\n"; - ss << " if(arg0 < 0 && arg1 > 0)\n"; - ss << " while(arg0 < 0)\n"; - ss << " arg0 += arg1;\n"; - ss << " else if (arg0 > 0 && arg1 < 0)\n"; - ss << " while(arg0 > 0)\n"; - ss << " arg0 += arg1;\n"; - ss << " tem = fmod(arg0,arg1);\n"; - ss << " if(arg1 < 0 && tem > 0)\n"; - ss << " tem = -tem;\n"; - ss << " return tem;\n"; - ss << "}"; + ss << " return 1/sin(arg0);\n"; } -void OpLog::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) + +void OpCscH::GenerateCode( outputstream& ss ) const { - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0 = get_global_id(0);\n"; - ss << " double tem;\n"; - ss << " double arg0,arg1;\n"; - for (size_t i = 0; i < vSubArguments.size(); i++) - { - FormulaToken *pCur = vSubArguments[i]->GetFormulaToken(); - assert(pCur); - ss << " arg"<GenSlidingWindowDeclRef(); - ss << ";\n"; - if(pCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* pSVR = - static_cast< const formula::SingleVectorRefToken* >(pCur); - ss << " if(isnan(arg" << i <<")||(gid0 >= "; - ss << pSVR->GetArrayLength(); - ss << "))\n"; - if( i == 0) - ss << " arg0 = 0;\n"; - else if ( i == 1) - ss << " arg1 = 10;\n"; - } - else if (pCur->GetType() == formula::svDouble) - { - ss << " if(isnan(arg" << i <<"))\n"; - if( i == 0) - ss << " arg0 = 0;\n"; - else if ( i == 1) - ss << " arg1 = 10;\n"; - } - } - if (vSubArguments.size() < 2) - ss << " arg1 = 10;\n"; - ss << " tem = log10(arg0)/log10(arg1);;\n"; - ss << " return tem;\n"; - ss << "}"; + ss << " return 1/sinh(arg0);\n"; } -void OpCsc::GenSlidingWindowFunction( - outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) + +void OpExp::GenerateCode( outputstream& ss ) const { - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVR= static_cast(tmpCur); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n\t"; - ss <<"int gid0=get_global_id(0);\n\t"; - ss << "double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n\t"; - ss<< "if(isnan(arg0)||(gid0>="; - ss<GetArrayLength(); - ss<<"))\n\t\t"; - ss<<"arg0 = 0;\n\t"; - ss << "double tmp=1/sin(arg0);\n\t"; - ss << "return tmp;\n"; - ss << "}"; + ss << " return pow(M_E, arg0);\n"; } -void OpCountIfs::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) + +void OpLog10::GenerateCode( outputstream& ss ) const { - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - const formula::DoubleVectorRefToken*pCurDVR= static_cast(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 << " int tmp =0;\n"; - ss << " int loop;\n"; - GenTmpVariables(ss,vSubArguments); + ss << " return log10(arg0);\n"; +} - ss<< " int singleIndex =gid0;\n"; - int m=0; +void OpSinh::GenerateCode( outputstream& ss ) const +{ + ss << " return ( exp(arg0)-exp(-arg0) )/2;\n"; +} - outputstream tmpss; +void OpSin::GenerateCode( outputstream& ss ) const +{ + ss << " arg0 = arg0 * M_1_PI;\n"; + ss << " return sinpi(arg0);\n"; +} - for(size_t j=0;j& decls, + std::set& funs) +{ + decls.insert(atan2Decl); + funs.insert(atan2Content); } -void OpSumIfs::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) + +void OpArcCos::GenerateCode( outputstream& ss ) const { - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - const formula::DoubleVectorRefToken*pCurDVR= static_cast(tmpCur); - size_t nCurWindowSize = pCurDVR->GetArrayLength() < - pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength(): - pCurDVR->GetRefRowSize() ; + ss << " return arctan2(sqrt(1.0 - pow(arg0, 2)), arg0);\n"; +} - mNeedReductionKernel = vSubArguments[0]->NeedParallelReduction(); - if (mNeedReductionKernel) - { - // generate reduction functions +void OpArcCosHyp::GenerateCode( outputstream& ss ) const +{ + ss << " if( arg0 < 1 )\n"; + ss << " return CreateDoubleError(IllegalArgument);\n"; + ss << " return log( arg0 + pow( (pown(arg0, 2) - 1.0), 0.5));\n"; +} - 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"; +void OpTan::GenerateCode( outputstream& ss ) const +{ + ss << " arg0 = arg0 * M_1_PI;\n"; + ss << " return sinpi(arg0) / cospi(arg0);\n"; +} - ss << ")\n{\n"; - ss << " double tmp =0;\n"; - ss << " int i ;\n"; +void OpTanH::GenerateCode( outputstream& ss ) const +{ + ss << " return tanh(arg0);\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"; - else if (!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& decls, + std::set& funs) +{ + decls.insert(atan2Decl); + funs.insert(atan2Content); +} - 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"; +void OpArcSin::GenerateCode( outputstream& ss ) const +{ + ss << " return arctan2(arg0, sqrt(1.0 - pow(arg0, 2)));\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"; - } else if (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=0 && approx_equal( intTmp + 1, arg0 ))\n"; + ss << " ++intTmp;\n"; + // negative values are rounded down + ss << " if( arg0 < 0 && !approx_equal( intTmp, arg0 ))\n"; + ss << " --intTmp;\n"; + ss << " return intTmp;\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::BinInlineFun(std::set& decls, + std::set& funs) +{ + decls.insert(Math_IntgDecl); + funs.insert(Math_Intg); +} + +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 OpMROUND::GenerateCode( outputstream& ss ) const +{ + ss<<" if(arg1==0)\n"; + ss<<" return arg1;\n"; + ss<<" tmp=arg1 * round(arg0 / arg1);\n"; + ss<<" return tmp;\n"; +} + +void OpCombinA::BinInlineFun(std::set& decls, + std::set& funs) +{ + decls.insert(bikDecl); + funs.insert(bik); +} + +void OpCombinA::GenerateCode( outputstream& ss ) const +{ + ss << " arg0 = trunc(arg0);\n"; + ss << " arg1 = trunc(arg1);\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 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"; } -void OpCscH::GenSlidingWindowFunction( - outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) + +void OpMod::GenerateCode( outputstream& ss ) const { - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVR= static_cast(tmpCur); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n\t"; - ss <<"int gid0=get_global_id(0);\n\t"; - ss << "double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n\t"; - ss<< "if(isnan(arg0)||(gid0>="; - ss<GetArrayLength(); - ss<<"))\n\t\t"; - ss<<"arg0 = 0;\n\t"; - ss << "double tmp=1/sinh(arg0);\n\t"; - ss << "return tmp;\n"; - ss << "}"; + ss << " if(isnan(arg0)||arg0 == 0)\n"; + ss << " return 0;\n"; + ss << " if(isnan(arg1) || arg1 ==0)\n"; + ss << " return CreateDoubleError(DivisionByZero);\n"; + ss << " double tem;\n"; + ss << " if(arg0 < 0 && arg1 > 0)\n"; + ss << " while(arg0 < 0)\n"; + ss << " arg0 += arg1;\n"; + ss << " else if (arg0 > 0 && arg1 < 0)\n"; + ss << " while(arg0 > 0)\n"; + ss << " arg0 += arg1;\n"; + ss << " tem = fmod(arg0,arg1);\n"; + ss << " if(arg1 < 0 && tem > 0)\n"; + ss << " tem = -tem;\n"; + ss << " return tem;\n"; } -void OpExp::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) + +void OpPower::GenerateCode( outputstream& ss ) const { - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0=get_global_id(0);\n"; - ss << " double arg0 = 0.0f;\n"; - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - assert(tmpCur); - if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode()) - { - if(tmpCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken*tmpCurDVR= - static_cast - (tmpCur); - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ")||(gid0>="; - ss << tmpCurDVR->GetArrayLength(); - ss << "))\n"; - ss << " { arg0 = 0.0f; }\n"; - } - else if(tmpCur->GetType() == formula::svDouble) - { - ss << " arg0=" << tmpCur->GetDouble() << ";\n"; - } - } - else - { - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - } - ss << " return pow(M_E, arg0);\n"; - ss << "}"; + ss << " return pow(arg0,arg1);\n"; } -void OpAverageIfs::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) +void OpArcTan2::BinInlineFun(std::set& decls, + std::set& funs) { - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - const formula::DoubleVectorRefToken*pCurDVR= static_cast(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= 281474976710656.0 || arg1 >= 281474976710656.0 )\n"; + ss << " return CreateDoubleError(IllegalArgument);\n"; + ss << " return (long)arg0 & (long)arg1;\n"; } -void OpLog10::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) +void OpBitOr::GenerateCode( outputstream& ss ) const { - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVR= static_cast(tmpCur); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n\t"; - ss <<"int gid0=get_global_id(0);\n\t"; - ss << "double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n\t"; - ss<< "if(isnan(arg0)||(gid0>="; - ss<GetArrayLength(); - ss<<"))\n\t\t"; - ss<<"arg0 = 0;\n\t"; - ss << "double tmp=log10(arg0);\n\t"; - ss << "return tmp;\n"; - ss << "}"; + ss << " if( arg0 < 0 || arg1 < 0 || arg0 >= 281474976710656.0 || arg1 >= 281474976710656.0 )\n"; + ss << " return CreateDoubleError(IllegalArgument);\n"; + ss << " return (long)arg0 | (long)arg1;\n"; } -void OpSinh::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) +void OpBitXor::GenerateCode( outputstream& ss ) const { - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss <<" int gid0=get_global_id(0);\n"; - ss <<" double arg0 = " << - vSubArguments[0]->GenSlidingWindowDeclRef(); - ss <<";\n"; - ss<< " if(isnan(arg0))\n"; - ss<<" arg0 = 0;\n"; - ss << " double tmp=( exp(arg0)-exp(-arg0) )/2;\n"; - ss << " return tmp;\n"; - ss << "}"; + ss << " if( arg0 < 0 || arg1 < 0 || arg0 >= 281474976710656.0 || arg1 >= 281474976710656.0 )\n"; + ss << " return CreateDoubleError(IllegalArgument);\n"; + ss << " return (long)arg0 ^ (long)arg1;\n"; } -void OpSin::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) + +void OpBitLshift::GenerateCode( outputstream& ss ) const { - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0=get_global_id(0);\n"; - ss << " double arg0 = 0.0f;\n"; - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - assert(tmpCur); - if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode()) - { - if(tmpCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken*tmpCurDVR= - static_cast - (tmpCur); - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ")||(gid0>="; - ss << tmpCurDVR->GetArrayLength(); - ss << "))\n"; - ss << " { arg0 = 0.0f; }\n"; - } - else if(tmpCur->GetType() == formula::svDouble) - { - ss << " arg0=" << tmpCur->GetDouble() << ";\n"; - } - } - else - { - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - } - ss << " arg0 = arg0 * M_1_PI;\n"; - ss << " return sinpi(arg0);\n"; - ss << "}"; + ss << " double num = floor( arg0 );\n"; + ss << " double shift_amount = floor( arg1 );\n"; + ss << " if( num < 0 || num >= 281474976710656.0 )\n"; + ss << " return CreateDoubleError(IllegalArgument);\n"; + ss << " return floor(shift_amount >= 0 ? "; + ss << "num * pow(2.0, shift_amount) : "; + ss << "num / pow(2.0, fabs(shift_amount)));\n"; } -void OpAbs::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) +void OpBitRshift::GenerateCode( outputstream& ss ) const { - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0 = get_global_id(0);\n"; - ss << " double tmp = " << GetBottom() << ";\n"; - FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVR0= - static_cast(tmpCur0); - ss << " int buffer_len = "; - ss << tmpCurDVR0->GetArrayLength(); - ss << ";\n"; - ss << " if((gid0)>=buffer_len || isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << "))\n"; - ss << " tmp = 0.0;\n else \n"; - ss << " tmp = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " return fabs(tmp);\n"; - ss << "}"; + ss << " double num = floor( arg0 );\n"; + ss << " double shift_amount = floor( arg1 );\n"; + ss << " if( num < 0 || num >= 281474976710656.0 )\n"; + ss << " return CreateDoubleError(IllegalArgument);\n"; + ss << " return floor("; + ss << "shift_amount >= 0 ? num / pow(2.0, shift_amount) : "; + ss << "num * pow(2.0, fabs(shift_amount)));\n"; } -void OpArcCos::BinInlineFun(std::set& decls, - std::set& funs) + +void OpQuotient::GenerateCode( outputstream& ss ) const { - decls.insert(atan2Decl); - funs.insert(atan2Content); + ss << " return trunc(arg0/arg1);\n"; } -void OpArcCos::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) + +void OpLog::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"; - ss << " double tmp = " << GetBottom() << ";\n"; - FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVR0= - static_cast(tmpCur0); - ss << " int buffer_len = "<< tmpCurDVR0->GetArrayLength()<< ";\n"; - ss << " if((gid0)>=buffer_len || isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef()<< "))\n"; - ss << " tmp = 0.0;\n"; - ss << " else \n "; - ss << " tmp = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef()<< ";\n"; - ss << " return arctan2(sqrt(1.0 - pow(tmp, 2)), tmp);\n"; + GenerateArg( "arg0", 0, vSubArguments, ss ); + GenerateArgWithDefault( "arg1", 1, 10, vSubArguments, ss ); + ss << " return log10(arg0)/log10(arg1);;\n"; ss << "}"; } -void OpArcCosHyp::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 = " << GetBottom() << ";\n"; - FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken(); - assert(tmpCur0); - if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode()) - { - if(tmpCur0->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken*tmpCurDVR0= - static_cast(tmpCur0); - ss << " int buffer_len = "<GetArrayLength()<<";\n"; - ss << " if((gid0)>=buffer_len || isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n"; - ss << " tmp = 0.0;\n"; - ss << " else \n "; - ss << " tmp = " << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - } - else if(tmpCur0->GetType() == formula::svDouble) - { - ss << " tmp = " << tmpCur0->GetDouble() << ";\n"; - } - } - else - { - ss << " tmp = " << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - } - ss << " if( tmp < 1 )\n"; - ss << " return CreateDoubleError(IllegalArgument);\n"; - ss << " return log( tmp + pow( (pown(tmp, 2) - 1.0), 0.5));\n"; - ss << "}"; -} -void OpTan::GenSlidingWindowFunction(outputstream &ss, +void OpCountIfs::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) { + FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); + const formula::DoubleVectorRefToken*pCurDVR= static_cast(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 arg0 = 0.0f;\n"; - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - assert(tmpCur); - if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode()) + ss <<" int gid0=get_global_id(0);\n"; + ss << " int tmp =0;\n"; + ss << " int loop;\n"; + GenTmpVariables(ss,vSubArguments); + + ss<< " int singleIndex =gid0;\n"; + int m=0; + + outputstream tmpss; + + for(size_t j=0;jGetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken*tmpCurDVR= - static_cast - (tmpCur); - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ")||(gid0>="; - ss << tmpCurDVR->GetArrayLength(); - ss << "))\n"; - ss << " { arg0 = 0.0f; }\n"; - } - else if(tmpCur->GetType() == formula::svDouble) + for(int n = 0;nGetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVR= static_cast(tmpCur); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0=get_global_id(0);\n"; - ss << " double arg0 = "<< vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan(arg0)||(gid0>="; - ss << tmpCurDVR->GetArrayLength(); - ss << "))\n"; - ss << " arg0 = 0;\n"; - ss << " double tmp=tanh(arg0);\n"; - ss << " return tmp;\n"; - ss << "}"; -} -void OpPower::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 arg[2];\n"; - for( size_t i=0; i < vSubArguments.size(); ++i) + const formula::DoubleVectorRefToken*pCurDVR= static_cast(tmpCur); + size_t nCurWindowSize = pCurDVR->GetArrayLength() < + pCurDVR->GetRefRowSize() ? pCurDVR->GetArrayLength(): + pCurDVR->GetRefRowSize() ; + + mNeedReductionKernel = vSubArguments[0]->NeedParallelReduction(); + if (mNeedReductionKernel) { - FormulaToken *tmpCur = vSubArguments[i]->GetFormulaToken(); - assert(tmpCur); - if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode()) + // generate reduction functions + + ss << "__kernel void "; + ss << vSubArguments[0]->GetName(); + ss << "_SumIfs_reduction( "; + for (size_t i = 0; i < vSubArguments.size(); i++) { - if(tmpCur->GetType() == formula::svDoubleVectorRef) - { - const formula::DoubleVectorRefToken* tmpCurDVR = - static_cast< - const formula::DoubleVectorRefToken *>(tmpCur); - ss << " int i = 0;\n"; - ss << " arg["<GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan(arg["<="; - ss << tmpCurDVR->GetArrayLength(); - ss << "))\n"; - ss << " arg["<GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* tmpCurDVR= - static_cast< - const formula::SingleVectorRefToken *>(tmpCur); - ss << " arg["<GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan(arg["<="; - ss << tmpCurDVR->GetArrayLength(); - ss << "))\n"; - ss << " arg["<GetType() == formula::svDouble) - { - ss << " arg["<GetDouble() << ";\n"; - } + 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"; + else if (!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; lGetFormulaToken(); - assert(tmpCur); - if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode()) - { - if(tmpCur->GetType() == formula::svSingleVectorRef) + CheckSubArgumentIsNan2(ss,vSubArguments,0,p1); + ss << " tmp += tmp0;\n"; + for(size_t j=1;j(tmpCur); - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ")||(gid0>="; - ss << tmpCurDVR->GetArrayLength(); - ss << "))\n"; - ss << " { arg0 = 0; }\n"; + for(int n = 0;nGetType() == formula::svDouble) + mm=0; + for(size_t j=1;jGetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVR0= - static_cast(tmpCur0); - ss << " int buffer_len = " << tmpCurDVR0->GetArrayLength()<< ";\n"; - ss << " if((gid0)>=buffer_len || isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n"; - ss << " tmp = 0.0;\n"; - ss << " else \n "; - ss << " tmp = " << vSubArguments[0]->GenSlidingWindowDeclRef() <<";\n"; - ss << " return M_PI_2 - atan(tmp);\n"; - ss << "}"; -} -void OpArcCotHyp::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 arg0 = 0.0f;\n"; - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - assert(tmpCur); - if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode()) - { - if(tmpCur->GetType() == formula::svSingleVectorRef) + ss << " }\n"; + + ss << " else if (p1 < min(arrayLength, offset + windowSize)) {\n"; + mm=0; + for(size_t j=1;j(tmpCur); - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ")||(gid0>="; - ss << tmpCurDVR->GetArrayLength(); - ss << "))\n"; - ss << " { arg0 = 0.0f; }\n"; + CheckSubArgumentIsNan2(ss,vSubArguments,j,p1); + CheckSubArgumentIsNan2(ss,vSubArguments,j+1,p1); + + ss <<" if(isequal("; + ss <<"tmp"; + ss <GetType() == formula::svDouble) + CheckSubArgumentIsNan2(ss,vSubArguments,0,p1); + ss << " tmp += tmp0;\n"; + for(size_t j=1;j& decls, - std::set& funs) -{ - decls.insert(atan2Decl); - funs.insert(atan2Content); -} -void OpArcSin::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 = " << GetBottom() << ";\n"; - FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVR0= - static_cast(tmpCur0); - ss << " int buffer_len = " << tmpCurDVR0->GetArrayLength() << ";\n"; - ss << " if((gid0)>=buffer_len || isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n"; - ss << " tmp = 0.0;\n"; - ss << " else \n "; - ss << " tmp = " << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n"; - ss << " return arctan2(tmp, sqrt(1.0 - pow(tmp, 2)));\n"; - ss << "}"; -} -void OpArcSinHyp::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ + + 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 = " << GetBottom() << ";\n"; - FormulaToken *tmpCur0 = vSubArguments[0]->GetFormulaToken(); - assert(tmpCur0); - if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode()) + ss <<" int gid0=get_global_id(0);\n"; + ss << " double tmp =0;\n"; + if (!mNeedReductionKernel) { - if(tmpCur0->GetType() == formula::svSingleVectorRef) + ss << " int i ;\n"; + GenTmpVariables(ss,vSubArguments); + ss << " for (i = "; + if (!pCurDVR->IsStartFixed() && pCurDVR->IsEndFixed()) { + ss << "gid0; i < "<< nCurWindowSize <<"; i++)\n"; + } else if (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()) { - const formula::SingleVectorRefToken*tmpCurDVR0= - static_cast(tmpCur0); - ss << " int buffer_len = "<GetArrayLength()<<";\n"; - ss << " if((gid0)>=buffer_len || isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n"; - ss << " tmp = 0.0;\n"; - ss << " else \n "; - ss << " tmp = " << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; + 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;jGetType() == formula::svDouble) + CheckSubArgumentIsNan(ss,vSubArguments,0); + ss << " tmp += tmp0;\n"; + for(size_t j=1;j<=vSubArguments.size();j+=2,m--) { - ss << " tmp = " << tmpCur0->GetDouble() << ";\n"; + for(int n = 0;n& decls, - std::set& funs) -{ - decls.insert(atan2Decl); - funs.insert(atan2Content); -} -void OpArcTan2::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 x_num = " << GetBottom() << ";\n"; - ss << " double y_num = " << GetBottom() << ";\n"; - FormulaToken *iXNum = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVRX= - static_cast(iXNum); - FormulaToken *iYNum = vSubArguments[1]->GetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVRY= - static_cast(iYNum); - ss << " int buffer_x_len = " << tmpCurDVRX->GetArrayLength() << ";\n"; - ss << " int buffer_y_len = " << tmpCurDVRY->GetArrayLength() << ";\n"; - ss << " if((gid0)>=buffer_x_len || isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n"; - ss << " x_num = 0.0;\n"; - ss << " else \n "; - ss << " x_num = "<< vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n"; - ss << " if((gid0)>=buffer_y_len || isnan("; - ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n"; - ss << " y_num = 0.0;\n"; - ss << " else \n "; - ss << " y_num = "<< vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n"; - ss << " return arctan2(y_num, x_num);\n"; + ss << "return tmp;\n"; ss << "}"; } -void OpArcTan::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) + +void OpAverageIfs::GenSlidingWindowFunction(outputstream &ss, + const std::string &sSymName, SubArguments &vSubArguments) { + FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); + const formula::DoubleVectorRefToken*pCurDVR= static_cast(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 arg0 = 0.0f;\n"; - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - assert(tmpCur); - if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode()) + 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;jGetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken*tmpCurDVR= - static_cast - (tmpCur); - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ")||(gid0>="; - ss << tmpCurDVR->GetArrayLength(); - ss << "))\n"; - ss << " { arg0 = 0.0f; }\n"; - } - else if(tmpCur->GetType() == formula::svDouble) - { - ss << " arg0=" << tmpCur->GetDouble() << ";\n"; - } + CheckSubArgumentIsNan(tmpss,vSubArguments,j); + CheckSubArgumentIsNan(ss,vSubArguments,j+1); + tmpss <<" if(isequal("; + tmpss <<"tmp"; + tmpss <GetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVR0= - static_cast(tmpCur0); - ss << " int buffer_len = " << tmpCurDVR0->GetArrayLength() << ";\n"; - ss << " if((gid0)>=buffer_len || isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n"; - ss << " tmp = 0.0;\n"; - ss << " else \n "; - ss << " tmp = " << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n"; - ss << " double a = 1.0 + tmp;\n"; - ss << " double b = 1.0 - tmp;\n"; - ss << " return log(pow(a/b, 0.5));\n"; - ss << "}"; -} -void OpBitAnd::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ - CHECK_PARAMETER_COUNT( 2, 2 ); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0 = get_global_id(0);\n"; - ss << " double num1 = " << GetBottom() << ";\n"; - ss << " double num2 = " << GetBottom() << ";\n"; - FormulaToken *iNum1 = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken* tmpCurDVRNum1= - static_cast(iNum1); - FormulaToken *iNum2 = vSubArguments[1]->GetFormulaToken(); - const formula::SingleVectorRefToken* tmpCurDVRNum2= - static_cast(iNum2); - ss << " int buffer_num1_len = "<GetArrayLength()<<";\n"; - ss << " int buffer_num2_len = "<GetArrayLength()<<";\n"; - ss << " if((gid0)>=buffer_num1_len || isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n"; - ss << " num1 = 0.0;\n"; - ss << " else \n "; - ss << " num1 = " << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n"; - ss << " if((gid0)>=buffer_num2_len || isnan("; - ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n"; - ss << " num2 = 0.0;\n"; - ss << " else \n "; - ss << " num2 = " << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n"; - ss << " if( num1 < 0 || num2 < 0 || num1 >= 281474976710656.0 || num2 >= 281474976710656.0 )\n"; - ss << " return CreateDoubleError(IllegalArgument);\n"; - ss << " return (long)num1 & (long)num2;\n"; - ss << "}"; -} -void OpLn::GenSlidingWindowFunction( - outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) -{ - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0=get_global_id(0);\n"; - ss << " int singleIndex = gid0;\n"; - GenTmpVariables(ss,vSubArguments); - CheckAllSubArgumentIsNan(ss,vSubArguments); + UnrollDoubleVector(ss,tmpss,pCurDVR,nCurWindowSize); - ss << " double tmp=log1p(tmp0-1);\n"; - ss << " return tmp;\n"; + ss << " if(count!=0)\n"; + ss << " tmp=tmp/count;\n"; + ss << " else\n"; + ss << " tmp= 0 ;\n"; + ss << "return tmp;\n"; ss << "}"; } @@ -1400,6 +812,7 @@ void OpRound::GenSlidingWindowFunction(outputstream &ss, ss << " return tmp;\n"; ss << "}"; } + void OpRoundUp::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) { @@ -1435,6 +848,7 @@ void OpRoundUp::GenSlidingWindowFunction(outputstream &ss, ss << " return tmp;\n"; ss << "}"; } + void OpRoundDown::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) { @@ -1457,124 +871,17 @@ void OpRoundDown::GenSlidingWindowFunction(outputstream &ss, ss << " {\n"; ss << " double multiply = 1.0;\n"; ss << " for(int i=0;ishift;i--)\n"; - ss << " multiply /= 10;\n"; - ss << " intTmp = (int)(tmp0*multiply);\n"; - ss << " tmp = intTmp;\n"; - ss << " tmp /= multiply;\n"; - ss << " }\n"; - ss << " return tmp;\n"; - ss << "}"; -} -void OpInt::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0=get_global_id(0);\n"; - ss << " int singleIndex = gid0;\n"; - ss << " int intTmp;\n"; - ss << " double tmp;\n"; - GenTmpVariables(ss,vSubArguments); - CheckAllSubArgumentIsNan(ss,vSubArguments); - ss << " intTmp = (int)tmp0;\n"; - // check whether rounding error caused the float to be just less than the int value - ss << " if( tmp0 >=0 && approx_equal( intTmp + 1, tmp0 ))\n"; - ss << " ++intTmp;\n"; - // negative values are rounded down - ss << " if( tmp0 < 0 && !approx_equal( intTmp, tmp0 ))\n"; - ss << " --intTmp;\n"; - ss << " tmp = intTmp;\n"; - ss << " return tmp;\n"; - ss << "}"; -} -void OpNegSub::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0=get_global_id(0);\n"; - ss << " int singleIndex = gid0;\n"; - GenTmpVariables(ss,vSubArguments); - CheckAllSubArgumentIsNan(ss,vSubArguments); - ss << " return -tmp0;\n"; - ss << "}"; -} - -void OpRadians::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0=get_global_id(0);\n"; - ss << " int singleIndex = gid0;\n"; - ss << " double tmp;\n"; - GenTmpVariables(ss,vSubArguments); - CheckAllSubArgumentIsNan(ss,vSubArguments); - ss << " tmp = tmp0 * M_PI / 180.0;\n"; - ss << " return tmp;\n"; - ss << "}"; -} -void OpIsEven::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0=get_global_id(0);\n"; - ss << " int singleIndex = gid0;\n"; - ss << " double tmp;\n"; - GenTmpVariables(ss,vSubArguments); - CheckAllSubArgumentIsNan(ss,vSubArguments); - ss << " tmp = (fmod(floor(fabs(tmp0)), 2.0)<0.5);\n"; - ss << " return tmp;\n"; - ss << "}"; -} -void OpIsOdd::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0=get_global_id(0);\n"; - ss << " int singleIndex = gid0;\n"; - ss << " double tmp;\n"; - GenTmpVariables(ss,vSubArguments); - CheckAllSubArgumentIsNan(ss,vSubArguments); - ss << " tmp = !(fmod(floor(fabs(tmp0)), 2.0)<0.5);\n"; - ss << " return tmp;\n"; - ss << "}"; -} -void OpOdd::GenSlidingWindowFunction( - outputstream &ss, const std::string &sSymName, - SubArguments &vSubArguments) -{ - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken*tmpCurDVR= static_cast(tmpCur); - ss << Math_Intg_Str; - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss <<" int gid0=get_global_id(0);\n"; - ss << " double tmp=0;\n"; - ss << " double arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss<< " if(isnan(arg0)||(gid0>="; - ss<GetArrayLength(); - ss<<"))\n"; - ss<<" arg0 = 0;\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 if (arg0 == 0.0 )\n"; - ss << " tmp=1.0;\n"; + ss << " multiply *= 10;\n"; + ss << " for(int i=0;i>shift;i--)\n"; + ss << " multiply /= 10;\n"; + ss << " intTmp = (int)(tmp0*multiply);\n"; + ss << " tmp = intTmp;\n"; + ss << " tmp /= multiply;\n"; + ss << " }\n"; ss << " return tmp;\n"; ss << "}"; } + void OpCountIf::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) { @@ -1672,6 +979,7 @@ void OpCountIf::GenSlidingWindowFunction(outputstream &ss, ss << " return varc;\n"; ss << "}"; } + void OpSumIf::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) { @@ -1784,65 +1092,18 @@ void OpSumIf::GenSlidingWindowFunction(outputstream &ss, ss << " return sum;\n"; ss << "}"; } + void OpTrunc::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"; - ss << " double arg[2];\n"; - for( size_t i=0; i < vSubArguments.size(); ++i) - { - FormulaToken *tmpCur = vSubArguments[i]->GetFormulaToken(); - assert(tmpCur); - if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode()) - { - if(tmpCur->GetType() == formula::svDoubleVectorRef) - { - const formula::DoubleVectorRefToken* tmpCurDVR = - static_cast< - const formula::DoubleVectorRefToken *>(tmpCur); - ss << " int i = 0;\n"; - ss << " arg["<GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan(arg["<="; - ss << tmpCurDVR->GetArrayLength(); - ss << "))\n"; - ss << " arg["<GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* tmpCurDVR= - static_cast< - const formula::SingleVectorRefToken *>(tmpCur); - ss << " arg["<GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan(arg["<="; - ss << tmpCurDVR->GetArrayLength(); - ss << "))\n"; - ss << " arg["<GetType() == formula::svDouble) - { - ss << " arg["<GetDouble() << ";\n"; - } - } - else - { - ss << " arg["<GenSlidingWindowDeclRef(); - ss << ";\n"; - } - } - ss << " double argm = arg[0];\n"; - ss << " int n = (int)arg[1];\n"; + GenerateArg( "arg0", 0, vSubArguments, ss ); + GenerateArgWithDefault( "arg1", 1, 0, vSubArguments, ss ); + ss << " double argm = arg0;\n"; + ss << " int n = (int)arg1;\n"; ss << " double nn = 1.0f;\n"; ss << " for(int i = 0; i < n; ++i)\n"; ss << " {\n"; @@ -1856,8 +1117,9 @@ void OpTrunc::GenSlidingWindowFunction(outputstream &ss, ss << " }\n"; ss << " modf(argm, &argm);\n"; ss << " return argm / nn;\n"; - ss << "}"; + ss << "}\n"; } + void OpFloor::GenSlidingWindowFunction( outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) @@ -1866,16 +1128,9 @@ void OpFloor::GenSlidingWindowFunction( GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); ss << "{\n"; ss << " int gid0=get_global_id(0);\n"; - ss << " double arg0,arg1,arg2=0.0;\n"; - ss << " arg0 = " << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " arg1 = " << vSubArguments[1]->GenSlidingWindowDeclRef(); - ss << ";\n"; - if ( 3 == vSubArguments.size() ) - { - ss << " arg2 = " << vSubArguments[2]->GenSlidingWindowDeclRef(); - ss << ";\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"; @@ -1890,151 +1145,7 @@ void OpFloor::GenSlidingWindowFunction( ss << " return trunc(arg0/arg1)*arg1;\n"; ss << "}\n"; } -void OpBitOr::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ - CHECK_PARAMETER_COUNT( 2, 2 ); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0 = get_global_id(0);\n"; - ss << " double num1 = " << GetBottom() << ";\n"; - ss << " double num2 = " << GetBottom() << ";\n"; - FormulaToken *iNum1 = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken* tmpCurDVRNum1= - static_cast(iNum1); - FormulaToken *iNum2 = vSubArguments[1]->GetFormulaToken(); - const formula::SingleVectorRefToken* tmpCurDVRNum2= - static_cast(iNum2); - ss << " int buffer_num1_len = "<GetArrayLength()<<";\n"; - ss << " int buffer_num2_len = "<GetArrayLength()<<";\n"; - ss << " if((gid0)>=buffer_num1_len || isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n"; - ss << " num1 = 0.0;\n"; - ss << " else \n "; - ss << " num1 = floor(" << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ");\n"; - ss << " if((gid0)>=buffer_num2_len || isnan("; - ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n"; - ss << " num2 = 0.0;\n"; - ss << " else\n "; - ss << " num2 = floor(" << vSubArguments[1]->GenSlidingWindowDeclRef(); - ss << ");\n"; - ss << " if( num1 < 0 || num2 < 0 || num1 >= 281474976710656.0 || num2 >= 281474976710656.0 )\n"; - ss << " return CreateDoubleError(IllegalArgument);\n"; - ss << " return (long)num1 | (long)num2;\n"; - ss << "}"; -} -void OpBitXor::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ - CHECK_PARAMETER_COUNT( 2, 2 ); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0 = get_global_id(0);\n"; - ss << " double num1 = " << GetBottom() << ";\n"; - ss << " double num2 = " << GetBottom() << ";\n"; - FormulaToken *iNum1 = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken* tmpCurDVRNum1= - static_cast(iNum1); - FormulaToken *iNum2 = vSubArguments[1]->GetFormulaToken(); - const formula::SingleVectorRefToken* tmpCurDVRNum2= - static_cast(iNum2); - ss << " int buffer_num1_len = " << tmpCurDVRNum1->GetArrayLength() << ";\n"; - ss << " int buffer_num2_len = " << tmpCurDVRNum2->GetArrayLength() << ";\n"; - - ss << " if((gid0)>=buffer_num1_len || isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n"; - ss << " num1 = 0.0;\n"; - ss << " else\n "; - ss << " num1 = floor(" << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ");\n"; - ss << " if((gid0)>=buffer_num2_len || isnan("; - ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n"; - ss << " num2 = 0.0;\n"; - ss << " else\n "; - ss << " num2 = floor(" << vSubArguments[1]->GenSlidingWindowDeclRef(); - ss << ");\n"; - ss << " if( num1 < 0 || num2 < 0 || num1 >= 281474976710656.0 || num2 >= 281474976710656.0 )\n"; - ss << " return CreateDoubleError(IllegalArgument);\n"; - ss << " return (long)num1 ^ (long)num2;\n"; - ss << "}"; -} -void OpBitLshift::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ - CHECK_PARAMETER_COUNT( 2, 2 ); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0 = get_global_id(0);\n"; - ss << " double num = " << GetBottom() << ";\n"; - ss << " double shift_amount = " << GetBottom() << ";\n"; - FormulaToken *iNum = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken* tmpCurDVRNum= - static_cast(iNum); - FormulaToken *iShiftAmount = vSubArguments[1]->GetFormulaToken(); - const formula::SingleVectorRefToken* tmpCurDVRShiftAmount= - static_cast(iShiftAmount); - ss << " int buffer_num_len = "<< tmpCurDVRNum->GetArrayLength()<<";\n"; - ss << " int buffer_shift_amount_len = "; - ss << tmpCurDVRShiftAmount->GetArrayLength() << ";\n"; - ss << " if((gid0)>=buffer_num_len || isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n"; - ss << " num = 0.0;\n"; - ss << " else\n "; - ss << " num = floor("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ");\n"; - ss << " if((gid0)>=buffer_shift_amount_len || isnan("; - ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n"; - ss << " shift_amount = 0.0;\n"; - ss << " else\n "; - ss << " shift_amount = floor("; - ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ");\n"; - ss << " if( num < 0 || num >= 281474976710656.0 )\n"; - ss << " return CreateDoubleError(IllegalArgument);\n"; - ss << " return floor(shift_amount >= 0 ? "; - ss << "num * pow(2.0, shift_amount) : "; - ss << "num / pow(2.0, fabs(shift_amount)));\n"; - ss << "}"; -} -void OpBitRshift::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ - CHECK_PARAMETER_COUNT( 2, 2 ); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0 = get_global_id(0);\n"; - ss << " double num = " << GetBottom() << ";\n"; - ss << " double shift_amount = " << GetBottom() << ";\n"; - FormulaToken *iNum = vSubArguments[0]->GetFormulaToken(); - const formula::SingleVectorRefToken* tmpCurDVRNum= - static_cast(iNum); - FormulaToken *iShiftAmount = vSubArguments[1]->GetFormulaToken(); - const formula::SingleVectorRefToken* tmpCurDVRShiftAmount= - static_cast(iShiftAmount); - ss << " int buffer_num_len = "; - ss << tmpCurDVRNum->GetArrayLength() << ";\n"; - ss << " int buffer_shift_amount_len = "; - ss << tmpCurDVRShiftAmount->GetArrayLength() << ";\n"; - - ss << " if((gid0)>=buffer_num_len || isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n"; - ss << " num = 0.0;\n"; - ss << " else\n "; - ss << " num = floor("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef() << ");\n"; - ss << " if((gid0)>=buffer_shift_amount_len || isnan("; - ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n"; - ss << " shift_amount = " <GenSlidingWindowDeclRef() << ");\n"; - ss << " if( num < 0 || num >= 281474976710656.0 )\n"; - ss << " return CreateDoubleError(IllegalArgument);\n"; - ss << " return floor("; - ss << "shift_amount >= 0 ? num / pow(2.0, shift_amount) : "; - ss << "num * pow(2.0, fabs(shift_amount)));\n"; - ss << "}"; -} + void OpSumSQ::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) { @@ -2117,47 +1228,7 @@ void OpSumSQ::GenSlidingWindowFunction(outputstream &ss, ss << " return sum;\n"; ss << "}"; } -void OpSqrtPi::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 arg0 = 0.0f;\n"; - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - assert(tmpCur); - if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode()) - { - if(tmpCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken*tmpCurDVR= - static_cast - (tmpCur); - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ")||(gid0>="; - ss << tmpCurDVR->GetArrayLength(); - ss << "))\n"; - ss << " { arg0 = 0.0f; }\n"; - } - else if(tmpCur->GetType() == formula::svDouble) - { - ss << " arg0="; - ss << tmpCur->GetDouble() << ";\n"; - } - } - else - { - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - } - ss << " return (double)sqrt(arg0 * M_PI);\n"; - ss << "}"; -} + void OpCeil::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) { @@ -2165,45 +1236,9 @@ void OpCeil::GenSlidingWindowFunction(outputstream &ss, GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); ss << "{\n"; ss << " int gid0 = get_global_id(0);\n"; - ss << " double num = " << GetBottom() << ";\n"; - ss << " double significance = " << GetBottom() << ";\n"; - ss << " double bAbs = 0;\n"; - ss << " if(isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n"; - ss << " num = 0.0;\n"; - ss << " else\n "; - ss << " num = " << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n"; - ss << " if(isnan("; - ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n"; - ss << " return 0.0;\n"; - ss << " else\n "; - ss << " significance = "; - ss << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n"; - if (vSubArguments.size() > 2) - { - FormulaToken *bAbs = vSubArguments[2]->GetFormulaToken(); - if(bAbs->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* tmpCurSVRIsAbs= - static_cast(bAbs); - ss<< " if((gid0)>=" << tmpCurSVRIsAbs->GetArrayLength() << " ||"; - } - if(bAbs->GetType() == formula::svDoubleVectorRef) - { - const formula::DoubleVectorRefToken* tmpCurDVRIsAbs= - static_cast(bAbs); - ss<< " if((gid0)>=" << tmpCurDVRIsAbs->GetArrayLength() << " ||"; - } - if(bAbs->GetType() == formula::svDouble) - { - ss<< " if("; - } - ss << "isnan("; - ss << vSubArguments[2]->GenSlidingWindowDeclRef() << "))\n"; - ss << " bAbs = 0;\n"; - ss << " else\n "; - ss << " bAbs = "<GenSlidingWindowDeclRef()<<";\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"; @@ -2214,54 +1249,6 @@ void OpCeil::GenSlidingWindowFunction(outputstream &ss, ss << "*significance;\n"; ss << "}"; } -void OpCombin::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ - CHECK_PARAMETER_COUNT( 2, 2 ); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0 = get_global_id(0);\n"; - ss << " double result = -1.0;\n"; - GenerateArg( 0, vSubArguments, ss ); - GenerateArg( 1, vSubArguments, ss ); - 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 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"; - ss << "}\n"; -} void OpProduct::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) @@ -2339,6 +1326,7 @@ void OpProduct::GenSlidingWindowFunction(outputstream &ss, ss << " return product;\n"; ss << "}"; } + void OpAverageIf::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) { @@ -2490,128 +1478,7 @@ void OpAverageIf::GenSlidingWindowFunction(outputstream &ss, ss << " return tmp;\n"; ss << "}"; } -void OpDeg::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 arg0 = 0.0f;\n"; - FormulaToken *tmpCur = vSubArguments[0]->GetFormulaToken(); - assert(tmpCur); - if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode()) - { - if(tmpCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken*tmpCurDVR= - static_cast - (tmpCur); - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ")||(gid0>="; - ss << tmpCurDVR->GetArrayLength(); - ss << "))\n"; - ss << " { arg0 = 0.0f; }\n"; - } - else if(tmpCur->GetType() == formula::svDouble) - { - ss << " arg0="; - ss << tmpCur->GetDouble() << ";\n"; - } - } - else - { - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - } - ss << " return arg0 / M_PI * 180;;\n"; - ss << "}"; -} -void OpFact::GenSlidingWindowFunction(outputstream& ss, - const std::string &sSymName, SubArguments& vSubArguments) -{ - CHECK_PARAMETER_COUNT( 1, 1 ); - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " double tmp = " << GetBottom() << ";\n"; - ss << " int gid0 = get_global_id(0);\n"; - ss << " double arg0 = " << GetBottom() << ";\n"; - FormulaToken* pCur = vSubArguments[0]->GetFormulaToken(); - assert(pCur); - if(ocPush == vSubArguments[0]->GetFormulaToken()->GetOpCode()) - { - if(pCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken*pCurDVR= - static_cast - (pCur); - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if(isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ")||(gid0>="; - ss << pCurDVR->GetArrayLength(); - ss << "))\n"; - ss << " { arg0 = 0.0f; }\n"; - } - else if(pCur->GetType() == formula::svDouble) - { - ss << " arg0="; - ss << pCur->GetDouble() << ";\n"; - } - } - else - { - ss << " arg0 = "; - ss << vSubArguments[0]->GenSlidingWindowDeclRef(); - ss << ";\n"; - } - 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"; - ss << "}"; -} -void OpQuotient::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 num1 = 1.0;\n"; - ss << " double num2 = 1.0;\n"; - ss << " if(isnan("; - ss << vSubArguments[0]->GenSlidingWindowDeclRef() << "))\n"; - ss << " num1 = 1.0;\n"; - ss << " else \n "; - ss << " num1 = " << vSubArguments[0]->GenSlidingWindowDeclRef() << ";\n"; - ss << " if(isnan("; - ss << vSubArguments[1]->GenSlidingWindowDeclRef() << "))\n"; - ss << " num2 = 1.0;\n"; - ss << " else \n "; - ss << " num2 = " << vSubArguments[1]->GenSlidingWindowDeclRef() << ";\n"; - ss << " return trunc(num1/num2);\n"; - ss << "}"; -} void OpSeriesSum::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) { diff --git a/sc/source/core/opencl/op_math.hxx b/sc/source/core/opencl/op_math.hxx index 355a941daf72..82ef12643dd0 100644 --- a/sc/source/core/opencl/op_math.hxx +++ b/sc/source/core/opencl/op_math.hxx @@ -14,46 +14,61 @@ namespace sc::opencl { -class OpCos: public Normal +/// Implements functions in the form of FUNC(x), e.g. COS(). +/// The function should take one simple argument (i.e. no ranges). +class OpMathOneArgument : public Normal { -public: virtual void GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) override; - - virtual std::string BinFuncName() const override { return "Cos"; } + /// This writes out OpenCL code returning the computed value, the argument is "arg0". + virtual void GenerateCode( outputstream& ss ) const = 0; }; -class OpSec: public Normal + +/// Implements functions in the form of FUNC(x1, x2), e.g. ATAN2(). +/// The function should take exactly two simple arguments (i.e. no ranges). +class OpMathTwoArguments : public Normal { -public: virtual void GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) override; + /// This writes out OpenCL code returning the computed value, the arguments are "arg0" and "arg1". + virtual void GenerateCode( outputstream& ss ) const = 0; +}; - virtual std::string BinFuncName() const override { return "Sec"; } +class OpCos: public OpMathOneArgument +{ +public: + virtual std::string BinFuncName() const override { return "Cos"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpSecH: public Normal + +class OpSec: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; + virtual std::string BinFuncName() const override { return "Sec"; } + virtual void GenerateCode( outputstream& ss ) const override; +}; +class OpSecH: public OpMathOneArgument +{ +public: virtual std::string BinFuncName() const override { return "SecH"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpMROUND: public Normal + +class OpMROUND: public OpMathTwoArguments { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string BinFuncName() const override { return "MROUND"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpCsc: public Normal +class OpCsc: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "Csc"; } + virtual void GenerateCode( outputstream& ss ) const override; }; + class OpSumIfs final : public CheckVariables { public: @@ -65,103 +80,102 @@ public: private: bool mNeedReductionKernel; }; -class OpCosh: public Normal + +class OpCosh: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual void BinInlineFun(std::set& ,std::set& ) override; virtual std::string BinFuncName() const override { return "Cosh"; } + virtual void BinInlineFun(std::set& ,std::set& ) override; + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpSinh: public Normal + +class OpSinh: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "Sinh"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpSin: public Normal + +class OpSin: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "Sin"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpAbs:public Normal{ + +class OpAbs: public OpMathOneArgument +{ public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string GetBottom() override { return "0.0"; } virtual std::string BinFuncName() const override { return "ScAbs"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpArcCos:public Normal{ + +class OpArcCos: public OpMathOneArgument +{ public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string GetBottom() override { return "0.0"; } virtual std::string BinFuncName() const override { return "ScACos"; } virtual void BinInlineFun(std::set& ,std::set&) override; + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpArcCosHyp:public Normal{ + +class OpArcCosHyp : public OpMathOneArgument +{ public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string GetBottom() override { return "1.0"; } virtual std::string BinFuncName() const override { return "ScACosH"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpTan: public Normal + +class OpTan: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string BinFuncName() const override { return "Tan"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpTanH: public Normal + +class OpTanH: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string BinFuncName() const override { return "TanH"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpSqrt: public Normal + +class OpSqrt: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string BinFuncName() const override { return "Sqrt"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpArcCot:public Normal{ + +class OpArcCot : public OpMathOneArgument +{ public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string GetBottom() override { return "0.0"; } virtual std::string BinFuncName() const override { return "ScACot"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpArcCotHyp:public Normal{ + +class OpArcCotHyp : public OpMathOneArgument +{ public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string GetBottom() override { return "2.0"; } virtual std::string BinFuncName() const override { return "ScACotH"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpArcSin:public Normal{ + +class OpArcSin : public OpMathOneArgument +{ public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string GetBottom() override { return "0.0"; } virtual std::string BinFuncName() const override { return "ScASin"; } virtual void BinInlineFun(std::set& ,std::set&) override; + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpArcSinHyp:public Normal{ + +class OpArcSinHyp : public OpMathOneArgument +{ public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string GetBottom() override { return "0.0"; } virtual std::string BinFuncName() const override { return "ScASinH"; } + virtual void GenerateCode( outputstream& ss ) const override; }; + class OpTrunc: public Normal { public: @@ -170,70 +184,71 @@ public: virtual std::string BinFuncName() const override { return "Trunc"; } }; -class OpArcTan2:public Normal{ + +class OpArcTan2 : public OpMathTwoArguments +{ public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string GetBottom() override { return "0.0"; } virtual std::string BinFuncName() const override { return "ScATan2"; } virtual void BinInlineFun(std::set& ,std::set&) override; + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpArcTan:public Normal{ + +class OpArcTan : public OpMathOneArgument +{ public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string GetBottom() override { return "0.0"; } virtual std::string BinFuncName() const override { return "ScATan"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpArcTanH:public Normal{ + +class OpArcTanH : public OpMathOneArgument +{ public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string GetBottom() override { return "0.0"; } virtual std::string BinFuncName() const override { return "ScATanH"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpBitAnd:public Normal{ + +class OpBitAnd : public OpMathTwoArguments +{ public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string GetBottom() override { return "0.0"; } virtual std::string BinFuncName() const override { return "ScBitAnd"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpBitOr:public Normal{ + +class OpBitOr : public OpMathTwoArguments +{ public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string GetBottom() override { return "0.0"; } virtual std::string BinFuncName() const override { return "ScBitOr"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpBitXor:public Normal{ + +class OpBitXor : public OpMathTwoArguments +{ public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string GetBottom() override { return "0.0"; } virtual std::string BinFuncName() const override { return "ScBitXor"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpBitLshift:public Normal{ + +class OpBitLshift : public OpMathTwoArguments +{ public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string GetBottom() override { return "0.0"; } virtual std::string BinFuncName() const override { return "ScBitLshift"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpBitRshift:public Normal{ + +class OpBitRshift : public OpMathTwoArguments +{ public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string GetBottom() override { return "0.0"; } virtual std::string BinFuncName() const override { return "ScBitRshift"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpLn: public CheckVariables + +class OpLn: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "Ln"; } + virtual void GenerateCode( outputstream& ss ) const override; }; + class OpRound: public CheckVariables { public: @@ -255,42 +270,41 @@ public: const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "RoundDown"; } }; -class OpInt: public CheckVariables +class OpInt: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "Int"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpRadians: public CheckVariables + +class OpRadians: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "Radians"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpIsEven: public CheckVariables + +class OpIsEven: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "IsEven"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpIsOdd: public CheckVariables + +class OpIsOdd: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "IsOdd"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpCot: public Normal + +class OpCot: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string BinFuncName() const override { return "Cot"; } + virtual void GenerateCode( outputstream& ss ) const override; }; + class OpSumSQ: public Normal { public: @@ -299,29 +313,31 @@ public: virtual std::string BinFuncName() const override { return "SumSQ"; } }; -class OpCoth: public Normal + +class OpCoth: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual void BinInlineFun(std::set& , std::set& ) override; virtual std::string BinFuncName() const override { return "Coth"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpPower: public Normal + +class OpPower: public OpMathTwoArguments { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "Power"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpOdd: public Normal + +class OpOdd: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; + virtual void BinInlineFun(std::set& ,std::set&) override; virtual std::string BinFuncName() const override { return "Odd"; } + virtual void GenerateCode( outputstream& ss ) const override; }; + class OpFloor: public Normal { public: @@ -329,13 +345,14 @@ public: const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "Floor"; } }; -class OpCscH: public Normal + +class OpCscH: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "CscH"; } + virtual void GenerateCode( outputstream& ss ) const override; }; + class OpCeil:public Normal{ public: virtual void GenSlidingWindowFunction(outputstream &ss, @@ -343,28 +360,28 @@ public: virtual std::string GetBottom() override { return "0.0"; } virtual std::string BinFuncName() const override { return "ScCeil"; } }; -class OpExp: public Normal + +class OpExp: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "Exp"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpLog10: public Normal + +class OpLog10: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "Log10"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpEven: public Normal + +class OpEven: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string BinFuncName() const override { return "Even"; } + virtual void GenerateCode( outputstream& ss ) const override; }; + class OpAverageIfs: public CheckVariables { public: @@ -379,14 +396,13 @@ public: const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "CountIfs"; } }; -class OpMod: public Normal +class OpMod: public OpMathTwoArguments { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string BinFuncName() const override { return "Mod"; } + virtual void GenerateCode( outputstream& ss ) const override; }; + class OpProduct: public Normal { public: @@ -395,24 +411,22 @@ public: virtual std::string BinFuncName() const override { return "Product"; } virtual bool canHandleMultiVector() const override { return true; } }; -class OpSqrtPi: public Normal + +class OpSqrtPi: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string BinFuncName() const override { return "SqrtPi"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpCombinA: public Normal +class OpCombinA: public OpMathTwoArguments { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string BinFuncName() const override { return "Combina"; } virtual void BinInlineFun(std::set& ,std::set& ) override; + virtual void GenerateCode( outputstream& ss ) const override; }; + class OpLog: public Normal { public: @@ -421,13 +435,14 @@ public: virtual std::string BinFuncName() const override { return "Log"; } }; -class OpCombin: public Normal{ + +class OpCombin: public OpMathTwoArguments +{ public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string GetBottom() override { return "0.0"; } virtual std::string BinFuncName() const override { return "ScCombin"; } + virtual void GenerateCode( outputstream& ss ) const override; }; + class OpAverageIf: public CheckVariables { public: @@ -436,13 +451,13 @@ public: virtual std::string BinFuncName() const override { return "AverageIf"; } }; -class OpDeg: public Normal +class OpDeg: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "Degrees"; } + virtual void GenerateCode( outputstream& ss ) const override; }; + class OpCountIf: public Normal { public: @@ -450,13 +465,13 @@ public: const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "Countif"; } }; -class OpFact: public Normal{ +class OpFact : public OpMathOneArgument +{ public: - virtual void GenSlidingWindowFunction(outputstream& ss, - const std::string &sSymName, SubArguments& vSubArguments) override; - virtual std::string GetBottom() override { return "0.0"; } virtual std::string BinFuncName() const override { return "Fact"; } + virtual void GenerateCode( outputstream& ss ) const override; }; + class OpSeriesSum: public Normal { public: @@ -471,19 +486,19 @@ public: const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "SumIf"; } }; -class OpQuotient: public Normal + +class OpQuotient: public OpMathTwoArguments { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "Quotient"; } + virtual void GenerateCode( outputstream& ss ) const override; }; -class OpNegSub: public CheckVariables + +class OpNegSub: public OpMathOneArgument { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "NegSub"; } + virtual void GenerateCode( outputstream& ss ) const override; }; } diff --git a/sc/source/core/opencl/opbase.cxx b/sc/source/core/opencl/opbase.cxx index a10ba9f77b64..512e3176bf43 100644 --- a/sc/source/core/opencl/opbase.cxx +++ b/sc/source/core/opencl/opbase.cxx @@ -213,6 +213,15 @@ void SlidingFunctionBase::GenerateArg( int num, SubArguments& vSubArguments, out GenerateArg( buf, num, vSubArguments, ss ); } +void SlidingFunctionBase::GenerateArgWithDefault( const char* name, int num, double def, + SubArguments& vSubArguments, outputstream& ss ) +{ + if( int(vSubArguments.size()) > num ) + GenerateArg( name, num, vSubArguments, ss ); + else + ss << " double " << name << " = " << def << ";\n"; +} + void SlidingFunctionBase::GenerateFunctionDeclaration( const std::string& sSymName, SubArguments& vSubArguments, outputstream& ss ) { diff --git a/sc/source/core/opencl/opbase.hxx b/sc/source/core/opencl/opbase.hxx index 46b767062b9a..05208db73247 100644 --- a/sc/source/core/opencl/opbase.hxx +++ b/sc/source/core/opencl/opbase.hxx @@ -229,6 +229,10 @@ protected: static void GenerateArg( const char* name, int num, SubArguments& vSubArguments, outputstream& ss ); // overload, variable will be named "arg" static void GenerateArg( int num, SubArguments& vSubArguments, outputstream& ss ); + // generate code for "double = ;" from vSubArguments, if it exists, + // otherwise set to + static void GenerateArgWithDefault( const char* name, int num, double def, SubArguments& vSubArguments, + outputstream& ss ); void GenerateFunctionDeclaration( const std::string& sSymName, SubArguments& vSubArguments, outputstream& ss ); }; diff --git a/sc/source/core/opencl/opinlinefun_math.hxx b/sc/source/core/opencl/opinlinefun_math.hxx index 0160671ed164..cee3775773dd 100644 --- a/sc/source/core/opencl/opinlinefun_math.hxx +++ b/sc/source/core/opencl/opinlinefun_math.hxx @@ -11,16 +11,17 @@ #include -std::string Math_Intg_Str= -"\ndouble Intg(double n)\n\ -{\n\ - if(trunc(n)==n )\n\ - return n;\n\ - else if(n<0)\n\ - return trunc(n)-1;\n\ - else\n\ - return trunc(n)+1;\n\ -}\n"; +std::string Math_IntgDecl="double Intg(double n);\n"; +std::string Math_Intg= +"double Intg(double n)\n" +"{\n" +" if(trunc(n)==n )\n" +" return n;\n" +" else if(n<0)\n" +" return trunc(n)-1;\n" +" else\n" +" return trunc(n)+1;\n" +"}\n"; std::string bikDecl = "double bik(double n,double k);\n"; std::string bik = -- cgit v1.2.3