diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx index 87c34f53ef1c..46e40d357464 100644 --- a/sc/source/core/opencl/formulagroupcl.cxx +++ b/sc/source/core/opencl/formulagroupcl.cxx @@ -108,6 +108,7 @@ OUString LimitedString( const OUString& str ) return OUString::Concat("\"") + str.subView( 0, 20 ) + "\"..."; } +const int MAX_PEEK_ELEMENTS = 5; // Returns formatted contents of the data (possibly shortened), to be used in debug output. std::string DebugPeekData(const FormulaToken* ref, int doubleRefIndex = 0) { @@ -117,16 +118,19 @@ std::string DebugPeekData(const FormulaToken* ref, int doubleRefIndex = 0) static_cast(ref); outputstream buf; buf << "SingleRef {"; - for( size_t i = 0; i < std::min< size_t >( 4, pSVR->GetArrayLength()); ++i ) + for( size_t i = 0; i < std::min< size_t >( MAX_PEEK_ELEMENTS, pSVR->GetArrayLength()); ++i ) { if( i != 0 ) buf << ","; - if( pSVR->GetArray().mpNumericArray != nullptr ) - buf << pSVR->GetArray().mpNumericArray[ i ]; - else if( pSVR->GetArray().mpStringArray != nullptr ) + if( pSVR->GetArray().mpStringArray != nullptr + && pSVR->GetArray().mpStringArray[ i ] != nullptr ) + { buf << LimitedString( OUString( pSVR->GetArray().mpStringArray[ i ] )); + } + else if( pSVR->GetArray().mpNumericArray != nullptr ) + buf << pSVR->GetArray().mpNumericArray[ i ]; } - if( pSVR->GetArrayLength() > 4 ) + if( pSVR->GetArrayLength() > MAX_PEEK_ELEMENTS ) buf << ",..."; buf << "}"; return buf.str(); @@ -137,16 +141,19 @@ std::string DebugPeekData(const FormulaToken* ref, int doubleRefIndex = 0) static_cast(ref); outputstream buf; buf << "DoubleRef {"; - for( size_t i = 0; i < std::min< size_t >( 4, pDVR->GetArrayLength()); ++i ) + for( size_t i = 0; i < std::min< size_t >( MAX_PEEK_ELEMENTS, pDVR->GetArrayLength()); ++i ) { if( i != 0 ) buf << ","; - if( pDVR->GetArrays()[doubleRefIndex].mpNumericArray != nullptr ) - buf << pDVR->GetArrays()[doubleRefIndex].mpNumericArray[ i ]; - else if( pDVR->GetArrays()[doubleRefIndex].mpStringArray != nullptr ) + if( pDVR->GetArrays()[doubleRefIndex].mpStringArray != nullptr + && pDVR->GetArrays()[doubleRefIndex].mpStringArray[ i ] != nullptr ) + { buf << LimitedString( OUString( pDVR->GetArrays()[doubleRefIndex].mpStringArray[ i ] )); + } + else if( pDVR->GetArrays()[doubleRefIndex].mpNumericArray != nullptr ) + buf << pDVR->GetArrays()[doubleRefIndex].mpNumericArray[ i ]; } - if( pDVR->GetArrayLength() > 4 ) + if( pDVR->GetArrayLength() > MAX_PEEK_ELEMENTS ) buf << ",..."; buf << "}"; return buf.str(); @@ -172,13 +179,13 @@ std::string DebugPeekDoubles(const double* data, int size) { outputstream buf; buf << "{"; - for( int i = 0; i < std::min( 4, size ); ++i ) + for( int i = 0; i < std::min( MAX_PEEK_ELEMENTS, size ); ++i ) { if( i != 0 ) buf << ","; buf << data[ i ]; } - if( size > 4 ) + if( size > MAX_PEEK_ELEMENTS ) buf << ",..."; buf << "}"; return buf.str(); @@ -200,7 +207,21 @@ size_t VectorRef::Marshal( cl_kernel k, int argno, int, cl_program ) SAL_INFO("sc.opencl", "SingleVectorRef len=" << pSVR->GetArrayLength() << " mpNumericArray=" << pSVR->GetArray().mpNumericArray << " (mpStringArray=" << pSVR->GetArray().mpStringArray << ")"); - pHostBuffer = const_cast(pSVR->GetArray().mpNumericArray); + if( forceStringsToZero && pSVR->GetArray().mpStringArray != nullptr ) + { + dataBuffer.resize( pSVR->GetArrayLength()); + for( size_t i = 0; i < pSVR->GetArrayLength(); ++i ) + if( pSVR->GetArray().mpStringArray[ i ] != nullptr ) + dataBuffer[ i ] = 0; + else + dataBuffer[ i ] = pSVR->GetArray().mpNumericArray[ i ]; + pHostBuffer = dataBuffer.data(); + SAL_INFO("sc.opencl", "Forced strings to zero : " << DebugPeekDoubles( pHostBuffer, pSVR->GetArrayLength())); + } + else + { + pHostBuffer = const_cast(pSVR->GetArray().mpNumericArray); + } szHostBuffer = pSVR->GetArrayLength() * sizeof(double); } else if (ref->GetType() == formula::svDoubleVectorRef) @@ -210,8 +231,21 @@ size_t VectorRef::Marshal( cl_kernel k, int argno, int, cl_program ) SAL_INFO("sc.opencl", "DoubleVectorRef index=" << mnIndex << " len=" << pDVR->GetArrayLength() << " mpNumericArray=" << pDVR->GetArrays()[mnIndex].mpNumericArray << " (mpStringArray=" << pDVR->GetArrays()[mnIndex].mpStringArray << ")"); - pHostBuffer = const_cast( - pDVR->GetArrays()[mnIndex].mpNumericArray); + if( forceStringsToZero && pDVR->GetArrays()[mnIndex].mpStringArray != nullptr ) + { + dataBuffer.resize( pDVR->GetArrayLength()); + for( size_t i = 0; i < pDVR->GetArrayLength(); ++i ) + if( pDVR->GetArrays()[mnIndex].mpStringArray[ i ] != nullptr ) + dataBuffer[ i ] = 0; + else + dataBuffer[ i ] = pDVR->GetArrays()[mnIndex].mpNumericArray[ i ]; + pHostBuffer = dataBuffer.data(); + SAL_INFO("sc.opencl", "Forced strings to zero : " << DebugPeekDoubles( pHostBuffer, pDVR->GetArrayLength())); + } + else + { + pHostBuffer = const_cast(pDVR->GetArrays()[mnIndex].mpNumericArray); + } szHostBuffer = pDVR->GetArrayLength() * sizeof(double); } else @@ -333,57 +367,6 @@ public: } }; -/// Arguments that are actually compile-time constants -class DynamicKernelConstantArgument : public DynamicKernelArgument -{ -public: - DynamicKernelConstantArgument( const ScCalcConfig& config, const std::string& s, - const FormulaTreeNodeRef& ft ) : - DynamicKernelArgument(config, s, ft) { } - /// Generate declaration - virtual void GenDecl( outputstream& ss ) const override - { - ss << "double " << mSymName; - } - virtual void GenDeclRef( outputstream& ss ) const override - { - ss << mSymName; - } - virtual void GenSlidingWindowDecl( outputstream& ss ) const override - { - GenDecl(ss); - } - virtual std::string GenSlidingWindowDeclRef( bool = false ) const override - { - if (GetFormulaToken()->GetType() != formula::svDouble) - throw Unhandled(__FILE__, __LINE__); - return mSymName; - } - virtual size_t GetWindowSize() const override - { - return 1; - } - double GetDouble() const - { - FormulaToken* Tok = GetFormulaToken(); - if (Tok->GetType() != formula::svDouble) - throw Unhandled(__FILE__, __LINE__); - return Tok->GetDouble(); - } - /// Create buffer and pass the buffer to a given kernel - virtual size_t Marshal( cl_kernel k, int argno, int, cl_program ) override - { - OpenCLZone zone; - double tmp = GetDouble(); - // Pass the scalar result back to the rest of the formula kernel - SAL_INFO("sc.opencl", "Kernel " << k << " arg " << argno << ": double: " << preciseFloat( tmp )); - cl_int err = clSetKernelArg(k, argno, sizeof(double), static_cast(&tmp)); - if (CL_SUCCESS != err) - throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__); - return 1; - } -}; - class DynamicKernelPiArgument : public DynamicKernelArgument { public: @@ -1109,6 +1092,7 @@ size_t DynamicKernelSlidingArgument::GenReductionLoopHeader( outputstream& } template class DynamicKernelSlidingArgument; +template class DynamicKernelSlidingArgument; template class DynamicKernelSlidingArgument; namespace { @@ -2070,26 +2054,38 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config, } else if (pDVR->GetArrays()[j].mpNumericArray && pCodeGen->takeNumeric() && - (AllStringsAreNull(pDVR->GetArrays()[j].mpStringArray, pDVR->GetArrayLength()) || mCalcConfig.meStringConversion == ScCalcConfig::StringConversion::ZERO)) + (AllStringsAreNull(pDVR->GetArrays()[j].mpStringArray, pDVR->GetArrayLength()) + || mCalcConfig.meStringConversion == ScCalcConfig::StringConversion::ZERO + || pCodeGen->forceStringsToZero())) { // Function takes numbers, and either there // are no strings, or there are strings but // they are to be treated as zero SAL_INFO("sc.opencl", "Numbers (no strings or strings treated as zero)"); - mvSubArguments.push_back( - VectorRefFactory(mCalcConfig, - ts, ft->Children[i], mpCodeGen, j)); + if(!AllStringsAreNull(pDVR->GetArrays()[j].mpStringArray, pDVR->GetArrayLength())) + { + mvSubArguments.push_back( + VectorRefFactory(mCalcConfig, + ts, ft->Children[i], mpCodeGen, j)); + } + else + { + mvSubArguments.push_back( + VectorRefFactory(mCalcConfig, + ts, ft->Children[i], mpCodeGen, j)); + } } else if (pDVR->GetArrays()[j].mpNumericArray == nullptr && pCodeGen->takeNumeric() && pDVR->GetArrays()[j].mpStringArray && - mCalcConfig.meStringConversion == ScCalcConfig::StringConversion::ZERO) + ( mCalcConfig.meStringConversion == ScCalcConfig::StringConversion::ZERO + || pCodeGen->forceStringsToZero())) { // Function takes numbers, and there are only // strings, but they are to be treated as zero SAL_INFO("sc.opencl", "Only strings even if want numbers but should be treated as zero"); mvSubArguments.push_back( - VectorRefFactory(mCalcConfig, + VectorRefFactory(mCalcConfig, ts, ft->Children[i], mpCodeGen, j)); } else if (pDVR->GetArrays()[j].mpStringArray && @@ -2145,26 +2141,34 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config, } else if (pSVR->GetArray().mpNumericArray && pCodeGen->takeNumeric() && - (AllStringsAreNull(pSVR->GetArray().mpStringArray, pSVR->GetArrayLength()) || mCalcConfig.meStringConversion == ScCalcConfig::StringConversion::ZERO)) + (AllStringsAreNull(pSVR->GetArray().mpStringArray, pSVR->GetArrayLength()) + || mCalcConfig.meStringConversion == ScCalcConfig::StringConversion::ZERO + || pCodeGen->forceStringsToZero())) { // Function takes numbers, and either there // are no strings, or there are strings but // they are to be treated as zero SAL_INFO("sc.opencl", "Numbers (no strings or strings treated as zero)"); - mvSubArguments.push_back( - std::make_shared(mCalcConfig, ts, - ft->Children[i])); + if( !AllStringsAreNull(pSVR->GetArray().mpStringArray, pSVR->GetArrayLength())) + mvSubArguments.push_back( + std::make_shared(mCalcConfig, ts, + ft->Children[i])); + else + mvSubArguments.push_back( + std::make_shared(mCalcConfig, ts, + ft->Children[i])); } else if (pSVR->GetArray().mpNumericArray == nullptr && pCodeGen->takeNumeric() && pSVR->GetArray().mpStringArray && - mCalcConfig.meStringConversion == ScCalcConfig::StringConversion::ZERO) + (mCalcConfig.meStringConversion == ScCalcConfig::StringConversion::ZERO + || pCodeGen->forceStringsToZero())) { // Function takes numbers, and there are only // strings, but they are to be treated as zero SAL_INFO("sc.opencl", "Only strings even if want numbers but should be treated as zero"); mvSubArguments.push_back( - std::make_shared(mCalcConfig, ts, + std::make_shared(mCalcConfig, ts, ft->Children[i])); } else if (pSVR->GetArray().mpStringArray && @@ -2208,6 +2212,16 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config, std::make_shared(mCalcConfig, ts, ft->Children[i])); } + else if (pChild->GetType() == formula::svString + && !pCodeGen->takeString() + && pCodeGen->takeNumeric() + && pCodeGen->forceStringsToZero()) + { + SAL_INFO("sc.opencl", "Constant string case, treated as zero"); + mvSubArguments.push_back( + DynamicKernelArgumentRef(new DynamicKernelStringToZeroArgument(mCalcConfig, ts, + ft->Children[i]))); + } else { SAL_INFO("sc.opencl", "Unhandled operand, rejecting for OpenCL"); @@ -2230,15 +2244,27 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config, case ocAverage: mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared(nResultSize), nResultSize)); break; + case ocAverageA: + mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared(nResultSize), nResultSize)); + break; case ocMin: mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared(nResultSize), nResultSize)); break; + case ocMinA: + mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared(nResultSize), nResultSize)); + break; case ocMax: mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared(nResultSize), nResultSize)); break; + case ocMaxA: + mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared(nResultSize), nResultSize)); + break; case ocCount: mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared(nResultSize), nResultSize)); break; + case ocCount2: + mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared(nResultSize), nResultSize)); + break; case ocSumProduct: mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared(), nResultSize)); break; @@ -2849,22 +2875,6 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config, mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared(), nResultSize)); break; - case ocMinA: - mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, - ft->Children[i], std::make_shared(), nResultSize)); - break; - case ocCount2: - mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, - ft->Children[i], std::make_shared(), nResultSize)); - break; - case ocMaxA: - mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, - ft->Children[i], std::make_shared(), nResultSize)); - break; - case ocAverageA: - mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, - ft->Children[i], std::make_shared(), nResultSize)); - break; case ocVarA: mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], std::make_shared(), nResultSize)); diff --git a/sc/source/core/opencl/op_math.cxx b/sc/source/core/opencl/op_math.cxx index 249a03416bb5..3ffae0d27f42 100644 --- a/sc/source/core/opencl/op_math.cxx +++ b/sc/source/core/opencl/op_math.cxx @@ -1650,102 +1650,6 @@ void SumOfProduct::GenSlidingWindowFunction( outputstream& ss, ss << "}"; } -void Reduction::GenSlidingWindowFunction( outputstream& ss, - const std::string& sSymName, SubArguments& vSubArguments ) -{ - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << "double tmp = " << GetBottom() << ";\n"; - ss << "int gid0 = get_global_id(0);\n"; - if (isAverage() || isMinOrMax()) - ss << "int nCount = 0;\n"; - ss << "double tmpBottom;\n"; - unsigned i = vSubArguments.size(); - while (i--) - { - if (NumericRange* NR = dynamic_cast(vSubArguments[i].get())) - { - bool needBody; - NR->GenReductionLoopHeader(ss, needBody); - if (!needBody) - continue; - } - else if (ParallelNumericRange* PNR = dynamic_cast(vSubArguments[i].get())) - { - //did not handle yet - bool bNeedBody = false; - PNR->GenReductionLoopHeader(ss, mnResultSize, bNeedBody); - if (!bNeedBody) - continue; - } - else if (StringRange* SR = dynamic_cast(vSubArguments[i].get())) - { - //did not handle yet - bool needBody; - SR->GenReductionLoopHeader(ss, needBody); - if (!needBody) - continue; - } - else - { - FormulaToken* pCur = vSubArguments[i]->GetFormulaToken(); - assert(pCur); - assert(pCur->GetType() != formula::svDoubleVectorRef); - - if (pCur->GetType() == formula::svSingleVectorRef || - pCur->GetType() == formula::svDouble) - { - ss << "{\n"; - } - } - if (ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode()) - { - bool bNanHandled = HandleNaNArgument(ss, i, vSubArguments); - - ss << "tmpBottom = " << GetBottom() << ";\n"; - - if (!bNanHandled) - { - ss << "if (isnan("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << "))\n"; - if (ZeroReturnZero()) - ss << " return 0;\n"; - else - { - ss << " tmp = "; - ss << Gen2("tmpBottom", "tmp") << ";\n"; - } - ss << "else\n"; - } - ss << "{"; - ss << " tmp = "; - ss << Gen2(vSubArguments[i]->GenSlidingWindowDeclRef(), "tmp"); - ss << ";\n"; - ss << " }\n"; - ss << "}\n"; - } - else - { - ss << "tmp = "; - ss << Gen2(vSubArguments[i]->GenSlidingWindowDeclRef(), "tmp"); - ss << ";\n"; - } - } - if (isAverage()) - ss << - "if (nCount==0)\n" - " return CreateDoubleError(DivisionByZero);\n"; - else if (isMinOrMax()) - ss << - "if (nCount==0)\n" - " return 0;\n"; - ss << "return tmp"; - if (isAverage()) - ss << "/(double)nCount"; - ss << ";\n}"; -} - void OpSum::BinInlineFun(std::set& decls,std::set& funs) { decls.insert(is_representable_integerDecl); @@ -1756,12 +1660,6 @@ void OpSum::BinInlineFun(std::set& decls,std::set& fun funs.insert(fsum_approx); } -void OpAverage::BinInlineFun(std::set& decls,std::set& funs) -{ - decls.insert(fsum_countDecl); - funs.insert(fsum_count); -} - void OpSub::BinInlineFun(std::set& decls,std::set& funs) { decls.insert(is_representable_integerDecl); @@ -1772,18 +1670,6 @@ void OpSub::BinInlineFun(std::set& decls,std::set& fun funs.insert(fsub_approx); } -void OpMin::BinInlineFun(std::set& decls,std::set& funs) -{ - decls.insert(fmin_countDecl); - funs.insert(fmin_count); -} - -void OpMax::BinInlineFun(std::set& decls,std::set& funs) -{ - decls.insert(fmax_countDecl); - funs.insert(fmax_count); -} - } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/opencl/op_math.hxx b/sc/source/core/opencl/op_math.hxx index 5e1649a7d6ed..ae5af5d6c0ac 100644 --- a/sc/source/core/opencl/op_math.hxx +++ b/sc/source/core/opencl/op_math.hxx @@ -570,29 +570,6 @@ public: virtual std::string BinFuncName() const override { return "fsop"; } }; -class Reduction : public SlidingFunctionBase -{ - int const mnResultSize; -public: - explicit Reduction(int nResultSize) : mnResultSize(nResultSize) {} - - typedef DynamicKernelSlidingArgument NumericRange; - typedef DynamicKernelSlidingArgument StringRange; - typedef ParallelReductionVectorRef ParallelNumericRange; - - virtual bool HandleNaNArgument( outputstream&, unsigned, SubArguments& ) const - { - return false; - } - - virtual void GenSlidingWindowFunction( outputstream& ss, - const std::string& sSymName, SubArguments& vSubArguments ) override; - virtual bool isAverage() const { return false; } - virtual bool isMinOrMax() const { return false; } - virtual bool takeString() const override { return false; } - virtual bool takeNumeric() const override { return true; } -}; - /// operator traits class OpNop : public Reduction { @@ -607,22 +584,6 @@ public: virtual std::string BinFuncName() const override { return "nop"; } }; -class OpCount : public Reduction -{ -public: - explicit OpCount(int nResultSize) : Reduction(nResultSize) {} - - virtual std::string GetBottom() override { return "0"; } - virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override - { - outputstream ss; - ss << "(isnan(" << lhs << ")?" << rhs << ":" << rhs << "+1.0)"; - return ss.str(); - } - virtual std::string BinFuncName() const override { return "fcount"; } - virtual bool canHandleMultiVector() const override { return true; } -}; - class OpSum : public Reduction { public: @@ -641,24 +602,6 @@ public: virtual bool canHandleMultiVector() const override { return true; } }; -class OpAverage : public Reduction -{ -public: - explicit OpAverage(int nResultSize) : Reduction(nResultSize) {} - - virtual std::string GetBottom() override { return "0"; } - virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override - { - outputstream ss; - ss << "fsum_count(" << lhs << "," << rhs << ", &nCount)"; - return ss.str(); - } - virtual void BinInlineFun(std::set& decls,std::set& funs) override; - virtual std::string BinFuncName() const override { return "average"; } - virtual bool isAverage() const override { return true; } - virtual bool canHandleMultiVector() const override { return true; } -}; - class OpSub : public Reduction { public: @@ -723,39 +666,6 @@ public: }; -class OpMin : public Reduction -{ -public: - explicit OpMin(int nResultSize) : Reduction(nResultSize) {} - - virtual std::string GetBottom() override { return "NAN"; } - virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override - { - return "fmin_count(" + lhs + "," + rhs + ", &nCount)"; - } - virtual void BinInlineFun(std::set& decls,std::set& funs) override; - virtual std::string BinFuncName() const override { return "min"; } - virtual bool isMinOrMax() const override { return true; } - virtual bool canHandleMultiVector() const override { return true; } -}; - -class OpMax : public Reduction -{ -public: - explicit OpMax(int nResultSize) : Reduction(nResultSize) {} - - virtual std::string GetBottom() override { return "NAN"; } - virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override - { - return "fmax_count(" + lhs + "," + rhs + ", &nCount)"; - } - virtual void BinInlineFun(std::set& decls,std::set& funs) override; - virtual std::string BinFuncName() const override { return "max"; } - virtual bool isMinOrMax() const override { return true; } - virtual bool canHandleMultiVector() const override { return true; } -}; - - } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/opencl/op_math_helpers.hxx b/sc/source/core/opencl/op_math_helpers.hxx index ada1cf8f50c6..94e2e0a280c5 100644 --- a/sc/source/core/opencl/op_math_helpers.hxx +++ b/sc/source/core/opencl/op_math_helpers.hxx @@ -86,32 +86,6 @@ const char atan2Content[] = " return a;\n" "}\n"; -const char fsum_countDecl[] = "double fsum_count(double a, double b, __private int *p);\n"; -const char fsum_count[] = -"double fsum_count(double a, double b, __private int *p) {\n" -" bool t = isnan(a);\n" -" (*p) += t?0:1;\n" -" return t?b:a+b;\n" -"}\n"; - -const char fmin_countDecl[] = "double fmin_count(double a, double b, __private int *p);\n"; -const char fmin_count[] = -"double fmin_count(double a, double b, __private int *p) {\n" -" double result = fmin(a, b);\n" -" bool t = isnan(result);\n" -" (*p) += t?0:1;\n" -" return result;\n" -"}\n"; - -const char fmax_countDecl[] = "double fmax_count(double a, double b, __private int *p);\n"; -const char fmax_count[] = -"double fmax_count(double a, double b, __private int *p) {\n" -" double result = fmax(a, b);\n" -" bool t = isnan(result);\n" -" (*p) += t?0:1;\n" -" return result;\n" -"}\n"; - const char is_representable_integerDecl[] = "int is_representable_integer(double a);\n"; const char is_representable_integer[] = "int is_representable_integer(double a) {\n" diff --git a/sc/source/core/opencl/op_statistical.cxx b/sc/source/core/opencl/op_statistical.cxx index 459057f80e8f..b2f645f1e378 100644 --- a/sc/source/core/opencl/op_statistical.cxx +++ b/sc/source/core/opencl/op_statistical.cxx @@ -2466,2010 +2466,22 @@ void OpRsq::GenSlidingWindowFunction( ); } -namespace { - -enum MixDoubleString +void OpMin::BinInlineFun(std::set& decls,std::set& funs) { - svDoubleVectorRefDoubleString, - svDoubleVectorRefDouble, - svDoubleVectorRefString, - svDoubleVectorRefNULL, - svSingleVectorRefDoubleString, - svSingleVectorRefDouble, - svSingleVectorRefString, - svSingleVectorRefNULL, - svDoubleDouble -}; - + decls.insert(fmin_countDecl); + funs.insert(fmin_count); } -void OpMinA::GenSlidingWindowFunction( - outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) +void OpMax::BinInlineFun(std::set& decls,std::set& funs) { - int isMixed = 0; - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0=get_global_id(0);\n"; - ss << " double tmp0 = 1.79769e+308;\n"; - ss <<"\n"; - for (size_t i = 0; i < vSubArguments.size(); i++) - { - FormulaToken *pCur = vSubArguments[i]->GetFormulaToken(); - assert(pCur); - if (pCur->GetType() == formula::svDoubleVectorRef) - { - const formula::DoubleVectorRefToken* pDVR = - static_cast(pCur); - if(pDVR->GetArrays()[0].mpNumericArray - && pDVR->GetArrays()[0].mpStringArray) - isMixed = svDoubleVectorRefDoubleString; - else if(pDVR->GetArrays()[0].mpNumericArray) - isMixed = svDoubleVectorRefDouble; - else if(pDVR->GetArrays()[0].mpStringArray) - isMixed = svDoubleVectorRefString; - else - isMixed = svDoubleVectorRefNULL; - size_t nCurWindowSize = pDVR->GetRefRowSize(); - ss << " for (int i = "; - if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) { - ss << "gid0; i < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++){\n"; - } else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) { - ss << "0; i < " << pDVR->GetArrayLength(); - ss << " && i < gid0+"<< nCurWindowSize << "; i++){\n"; - } else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()){ - ss << "0; i + gid0 < " << pDVR->GetArrayLength(); - ss << " && i < "<< nCurWindowSize << "; i++){\n"; - } - else { - ss << "0; i < "<< nCurWindowSize << "; i++){\n"; - } - } - else if (pCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* pSVR = - static_cast< const formula::SingleVectorRefToken* >(pCur); - - if(pSVR->GetArray().mpNumericArray - && pSVR->GetArray().mpStringArray) - isMixed = svSingleVectorRefDoubleString; - else if(pSVR->GetArray().mpNumericArray) - isMixed = svSingleVectorRefDouble; - else if(pSVR->GetArray().mpStringArray) - isMixed = svSingleVectorRefString; - else - isMixed = svSingleVectorRefNULL; - ss << " if (gid0 < " << pSVR->GetArrayLength() << "){\n"; - } - else if (pCur->GetType() == formula::svDouble) - { - ss << " {\n"; - isMixed = svDoubleDouble; - } - - if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode()) - { - if(isMixed == svDoubleVectorRefDoubleString - || isMixed == svSingleVectorRefDoubleString) - { - ss << " if (!isnan("; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << "))\n"; - ss << " tmp0 = tmp0 > "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << " ? "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << " : tmp0;\n"; - ss << " else if(isnan("; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ") && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " tmp0 = tmp0 > 0.0 ? 0.0 : tmp0;\n"; - ss << " }\n"; - } - else if(isMixed == svDoubleVectorRefDouble - || isMixed == svSingleVectorRefDouble) - { - ss << " if (!isnan("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << "))\n"; - ss << " tmp0 = tmp0 > "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " ? " << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " : tmp0;"; - ss <<"\n }\n"; - } - else if(isMixed == svDoubleVectorRefString) - { - ss << " if("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " == 0)\n continue;\n"; - ss << " tmp0 = tmp0 > 0.0 ? 0.0 : tmp0;\n"; - ss << " }\n"; - } - else if(isMixed == svSingleVectorRefString) - { - ss << " if("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " tmp0 = tmp0 > 0.0 ? 0.0 : tmp0;\n"; - ss << " }\n"; - } - else if(isMixed == svDoubleDouble) - { - ss << " tmp0 = tmp0 > "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " ? " << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " : tmp0;\n }\n"; - } - else - { - ss << " }\n"; - } - } - else - { - ss << " tmp0 = tmp0 > "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " ? " << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " : tmp0;"; - ss <<"\n }\n"; - } - } - ss << " return tmp0 == 1.79769e+308 ? 0.0 : tmp0;\n"; - ss << "}\n"; -} -void OpCountA::GenSlidingWindowFunction( - outputstream &ss, const std::string &sSymName, SubArguments & -vSubArguments) -{ - int isMixed = 0; - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0=get_global_id(0);\n"; - ss << " double nCount = 0.0;\n"; - - ss <<"\n"; - for (size_t i = 0; i < vSubArguments.size(); i++) - { - FormulaToken *pCur = vSubArguments[i]->GetFormulaToken(); - assert(pCur); - if (pCur->GetType() == formula::svDoubleVectorRef) - { - const formula::DoubleVectorRefToken* pDVR = - static_cast(pCur); - if(pDVR->GetArrays()[0].mpNumericArray - && pDVR->GetArrays()[0].mpStringArray) - isMixed = svDoubleVectorRefDoubleString; - else if(pDVR->GetArrays()[0].mpNumericArray) - isMixed = svDoubleVectorRefDouble; - else if(pDVR->GetArrays()[0].mpStringArray) - isMixed = svDoubleVectorRefString; - else - isMixed = svDoubleVectorRefNULL; - size_t nCurWindowSize = pDVR->GetRefRowSize(); - ss << " for (int i = "; - if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) { - ss << "gid0; i < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++){\n"; - } else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) { - ss << "0; i < " << pDVR->GetArrayLength(); - ss << " && i < gid0+"<< nCurWindowSize << "; i++){\n"; - } else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()){ - ss << "0; i + gid0 < " << pDVR->GetArrayLength(); - ss << " && i < "<< nCurWindowSize << "; i++){\n"; - } - else { - ss << "0; i < "<< nCurWindowSize << "; i++){\n"; - } - } - else if (pCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* pSVR = - static_cast< const formula::SingleVectorRefToken* >(pCur); - - if(pSVR->GetArray().mpNumericArray - && pSVR->GetArray().mpStringArray) - isMixed = svSingleVectorRefDoubleString; - else if(pSVR->GetArray().mpNumericArray) - isMixed = svSingleVectorRefDouble; - else if(pSVR->GetArray().mpStringArray) - isMixed = svSingleVectorRefString; - else - isMixed = svSingleVectorRefNULL; - ss << " if (gid0 < " << pSVR->GetArrayLength() << "){\n"; - } - else if (pCur->GetType() == formula::svDouble) - { - ss << " {\n"; - isMixed = svDoubleDouble; - } - - if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode()) - { - if(isMixed == svDoubleVectorRefDoubleString - || isMixed == svSingleVectorRefDoubleString) - { - ss << " if (!isnan("; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ")){\n"; - ss << " nCount+=1.0;\n"; - ss << " }\n"; - ss << " else if(isnan("; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ") && "; - ss<< vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " nCount+=1.0;\n"; - ss << " }\n"; - } - else if(isMixed == svDoubleVectorRefDouble - || isMixed == svSingleVectorRefDouble) - { - ss << " if (!isnan("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << ")){\n"; - ss << " nCount+=1.0;\n"; - ss <<"}\n }\n"; - } - else if(isMixed == svDoubleVectorRefString) - { - ss << " if (!isnan("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << "))\n"; - ss << " nCount+=1.0;\n"; - ss <<"\n }\n"; - } - else if(isMixed == svSingleVectorRefString) - { - ss << " if("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " nCount+=1.0;\n"; - ss << " }\n"; - } - else if(isMixed == svDoubleDouble) - { - ss << " nCount+=1.0;\n"; - ss << " }\n"; - } - else - { - ss << " }\n"; - } - } - else - { - ss << " nCount+=1.0;\n"; - ss << " }\n"; - } - } - ss << " return nCount;\n"; - ss << "}\n"; -} -void OpMaxA::GenSlidingWindowFunction( - outputstream &ss, const std::string &sSymName, SubArguments & -vSubArguments) -{ - int isMixed = 0; - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0=get_global_id(0);\n"; - ss << " double tmp0 = 2.22507e-308;\n"; - - ss <<"\n"; - for (size_t i = 0; i < vSubArguments.size(); i++) - { - FormulaToken *pCur = vSubArguments[i]->GetFormulaToken(); - assert(pCur); - if (pCur->GetType() == formula::svDoubleVectorRef) - { - const formula::DoubleVectorRefToken* pDVR = - static_cast(pCur); - if(pDVR->GetArrays()[0].mpNumericArray - && pDVR->GetArrays()[0].mpStringArray) - isMixed = svDoubleVectorRefDoubleString; - else if(pDVR->GetArrays()[0].mpNumericArray) - isMixed = svDoubleVectorRefDouble; - else if(pDVR->GetArrays()[0].mpStringArray) - isMixed = svDoubleVectorRefString; - else - isMixed = svDoubleVectorRefNULL; - size_t nCurWindowSize = pDVR->GetRefRowSize(); - ss << " for (int i = "; - if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) { - ss << "gid0; i < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++){\n"; - } else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) { - ss << "0; i < " << pDVR->GetArrayLength(); - ss << " && i < gid0+"<< nCurWindowSize << "; i++){\n"; - } else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()){ - ss << "0; i + gid0 < " << pDVR->GetArrayLength(); - ss << " && i < "<< nCurWindowSize << "; i++){\n"; - } - else { - ss << "0; i < "<< nCurWindowSize << "; i++){\n"; - } - } - else if (pCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* pSVR = - static_cast< const formula::SingleVectorRefToken* >(pCur); - - if(pSVR->GetArray().mpNumericArray - && pSVR->GetArray().mpStringArray) - isMixed = svSingleVectorRefDoubleString; - else if(pSVR->GetArray().mpNumericArray) - isMixed = svSingleVectorRefDouble; - else if(pSVR->GetArray().mpStringArray) - isMixed = svSingleVectorRefString; - else - isMixed = svSingleVectorRefNULL; - ss << " if (gid0 < " << pSVR->GetArrayLength() << "){\n"; - } - else if (pCur->GetType() == formula::svDouble) - { - ss << " {\n"; - isMixed = svDoubleDouble; - } - - if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode()) - { - if(isMixed == svDoubleVectorRefDoubleString - || isMixed == svSingleVectorRefDoubleString) - { - ss << " if (!isnan("; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << "))\n"; - ss << " tmp0 = tmp0 < "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << " ? "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << " : tmp0;\n"; - ss << " else if(isnan("; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ") && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " tmp0 = tmp0 < 0.0 ? 0.0 : tmp0;\n"; - ss << " }\n"; - } - else if(isMixed == svDoubleVectorRefDouble - || isMixed == svSingleVectorRefDouble) - { - ss << " if (!isnan("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << "))\n"; - ss << " tmp0 = tmp0 < "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " ? " << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " : tmp0;"; - ss <<"\n }\n"; - } - else if(isMixed == svDoubleVectorRefString) - { - ss << " if("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " == 0)\n continue;\n"; - ss << " tmp0 = tmp0 < 0.0 ? 0.0 : tmp0;\n"; - ss << " }\n"; - } - else if(isMixed == svSingleVectorRefString) - { - ss << " if("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " tmp0 = tmp0 < 0.0 ? 0.0 : tmp0;\n"; - ss << " }\n"; - } - else if(isMixed == svDoubleDouble) - { - ss << " tmp0 = tmp0 < "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " ? " << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " : tmp0;\n }\n"; - } - else - { - ss << " }\n"; - } - } - else - { - ss << " tmp0 = tmp0 < "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " ? " << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " : tmp0;"; - ss <<"\n }\n"; - } - } - ss << " return tmp0 == 2.22507e-308 ? 0.0 : tmp0;\n"; - ss << "}\n"; -} -void OpAverageA::GenSlidingWindowFunction( - outputstream &ss, const std::string &sSymName, SubArguments & -vSubArguments) -{ - int isMixed = 0; - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0=get_global_id(0);\n"; - ss << " double tmp0 = 0.0;\n"; - ss << " double nCount = 0.0;\n"; - ss <<"\n"; - for (size_t i = 0; i < vSubArguments.size(); i++) - { - FormulaToken *pCur = vSubArguments[i]->GetFormulaToken(); - assert(pCur); - if (pCur->GetType() == formula::svDoubleVectorRef) - { - const formula::DoubleVectorRefToken* pDVR = - static_cast(pCur); - if(pDVR->GetArrays()[0].mpNumericArray - && pDVR->GetArrays()[0].mpStringArray) - isMixed = svDoubleVectorRefDoubleString; - else if(pDVR->GetArrays()[0].mpNumericArray) - isMixed = svDoubleVectorRefDouble; - else if(pDVR->GetArrays()[0].mpStringArray) - isMixed = svDoubleVectorRefString; - else - isMixed = svDoubleVectorRefNULL; - size_t nCurWindowSize = pDVR->GetRefRowSize(); - ss << " for (int i = "; - if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) { - ss << "gid0; i < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++){\n"; - } else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) { - ss << "0; i < " << pDVR->GetArrayLength(); - ss << " && i < gid0+"<< nCurWindowSize << "; i++){\n"; - } else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()){ - ss << "0; i + gid0 < " << pDVR->GetArrayLength(); - ss << " && i < "<< nCurWindowSize << "; i++){\n"; - } - else { - ss << "0; i < "<< nCurWindowSize << "; i++){\n"; - } - } - else if (pCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* pSVR = - static_cast< const formula::SingleVectorRefToken* >(pCur); - - if(pSVR->GetArray().mpNumericArray - && pSVR->GetArray().mpStringArray) - isMixed = svSingleVectorRefDoubleString; - else if(pSVR->GetArray().mpNumericArray) - isMixed = svSingleVectorRefDouble; - else if(pSVR->GetArray().mpStringArray) - isMixed = svSingleVectorRefString; - else - isMixed = svSingleVectorRefNULL; - ss << " if (gid0 < " << pSVR->GetArrayLength() << "){\n"; - } - else if (pCur->GetType() == formula::svDouble) - { - ss << " {\n"; - isMixed = svDoubleDouble; - } - - if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode()) - { - if(isMixed == svDoubleVectorRefDoubleString - || isMixed == svSingleVectorRefDoubleString) - { - ss << " if (!isnan("; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ")){\n"; - ss << " tmp0 +="; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " nCount+=1.0;\n"; - ss << " }\n"; - ss << " else if(isnan("; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ") && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " nCount+=1.0;\n"; - ss << " }\n"; - } - else if(isMixed == svDoubleVectorRefDouble - || isMixed == svSingleVectorRefDouble) - { - ss << " if (!isnan("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << ")){\n"; - ss << " tmp0 +="; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " nCount+=1.0;\n"; - ss <<"}\n }\n"; - } - else if(isMixed == svDoubleVectorRefString) - { - ss << " if (!isnan("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << "))\n"; - ss << " nCount+=1.0;\n"; - ss <<"\n }\n"; - } - else if(isMixed == svSingleVectorRefString) - { - ss << " if("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " nCount+=1.0;\n"; - ss << " }\n"; - } - else if(isMixed == svDoubleDouble) - { - ss << " tmp0 +="; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " nCount+=1.0;\n"; - ss << " }\n"; - } - else - { - ss << " }\n"; - } - } - else - { - ss << " tmp0 +="; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " nCount+=1.0;\n"; - ss << " }\n"; - } - } - ss << " return tmp0/nCount;\n"; - ss << "}\n"; -} -void OpVarA::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ - int isMixedDV = 0; - int isMixedSV = 0; - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0 = get_global_id(0);\n"; - ss << " double fSum = 0.0;\n"; - ss << " double fMean = 0.0;\n"; - ss << " double vSum = 0.0;\n"; - ss << " double fCount = 0.0;\n"; - ss << " double arg = 0.0;\n"; - unsigned i = vSubArguments.size(); - while (i--) - { - FormulaToken *pCur = vSubArguments[i]->GetFormulaToken(); - assert(pCur); - - if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode()) - { - if (pCur->GetType() == formula::svDoubleVectorRef) - { - const formula::DoubleVectorRefToken* pDVR = - static_cast(pCur); - assert(pDVR); - if(pDVR->GetArrays()[0].mpNumericArray - && pDVR->GetArrays()[0].mpStringArray) - isMixedDV = svDoubleVectorRefDoubleString; - else if(pDVR->GetArrays()[0].mpNumericArray) - isMixedDV = svDoubleVectorRefDouble; - else if(pDVR->GetArrays()[0].mpStringArray) - isMixedDV = svDoubleVectorRefString; - else - isMixedDV = svDoubleVectorRefNULL; - - size_t nCurWindowSize = pDVR->GetRefRowSize(); - ss << " for (int i = "; - if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) - { - ss << "gid0; i < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) - { - ss << "0; i < " << pDVR->GetArrayLength(); - ss << " && i < gid0+" << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()) - { - ss << "0; i + gid0 < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else - { - ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n"; - ss << " {\n"; - } - - if(isMixedDV == svDoubleVectorRefDoubleString) - { - ss << " arg = "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " == 0)\n"; - ss << " continue;\n"; - ss << " if(isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " {\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " continue;\n"; - ss << " }\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else if(isMixedDV == svDoubleVectorRefDouble) - { - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(arg))\n"; - ss << " continue;\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else if(isMixedDV == svDoubleVectorRefString) - { - ss << " if ("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " == 0)\n"; - ss << " continue;\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else - { - ss << " continue;\n"; - ss << " }\n"; - } - - } - else if (pCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* pSVR = - static_cast< const formula::SingleVectorRefToken* >(pCur); - assert(pSVR); - if(pSVR->GetArray().mpNumericArray - && pSVR->GetArray().mpStringArray) - isMixedSV = svSingleVectorRefDoubleString; - else if(pSVR->GetArray().mpNumericArray) - isMixedSV = svSingleVectorRefDouble; - else if(pSVR->GetArray().mpStringArray) - isMixedSV = svSingleVectorRefString; - else - isMixedSV = svSingleVectorRefNULL; - - if(isMixedSV == svSingleVectorRefDoubleString) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " arg = "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (!isnan(arg))\n"; - ss << " {\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - ss << " if (isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else if(isMixedSV == svSingleVectorRefDouble) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n"; - ss << " if (!isnan(arg))\n"; - ss << " {\n"; - ss << " fSum += arg;\n"; - ss << " fCount += 1.0;\n"; - ss << " }\n"; - ss << " }\n"; - } - else if(isMixedSV == svSingleVectorRefString) - { - - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " if ("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else - { - ss << " arg =0.0;\n"; - } - } - else - { - ss << " arg = " << pCur->GetDouble() << ";\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - } - } - else - { - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - } - if (i == 0) - { - ss << " fMean = fSum / fCount;\n"; - } - } - i = vSubArguments.size(); - while (i--) - { - FormulaToken *pCur = vSubArguments[i]->GetFormulaToken(); - assert(pCur); - - if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode()) - { - if (pCur->GetType() == formula::svDoubleVectorRef) - { - const formula::DoubleVectorRefToken* pDVR = - static_cast(pCur); - if(pDVR->GetArrays()[0].mpNumericArray - && pDVR->GetArrays()[0].mpStringArray) - isMixedDV = svDoubleVectorRefDoubleString; - else if(pDVR->GetArrays()[0].mpNumericArray) - isMixedDV = svDoubleVectorRefDouble; - else if(pDVR->GetArrays()[0].mpStringArray) - isMixedDV = svDoubleVectorRefString; - else - isMixedDV = svDoubleVectorRefNULL; - - size_t nCurWindowSize = pDVR->GetRefRowSize(); - ss << " for (int i = "; - if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) - { - ss << "gid0; i < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) - { - ss << "0; i < " << pDVR->GetArrayLength(); - ss << " && i < gid0+" << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()) - { - ss << "0; i + gid0 < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else - { - ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n"; - ss << " {\n"; - } - if(isMixedDV == svDoubleVectorRefDoubleString) - { - ss << " arg = "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " == 0)\n"; - ss << " continue;\n"; - ss << " if(isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " arg = 0.0;\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - ss << " }\n"; - - } - else if(isMixedDV == svDoubleVectorRefDouble) - { - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(arg))\n"; - ss << " continue;\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - ss << " }\n"; - - } - else if(isMixedDV == svDoubleVectorRefString) - { - ss << " if ("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " == 0)\n"; - ss << " continue;\n"; - ss << " arg = 0.0;\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - ss << " }\n"; - } - else - { - ss << " continue;\n"; - ss << " }\n"; - } - } - else if (pCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* pSVR = - static_cast< const formula::SingleVectorRefToken* >(pCur); - if(pSVR->GetArray().mpNumericArray - && pSVR->GetArray().mpStringArray) - isMixedSV = svSingleVectorRefDoubleString; - else if(pSVR->GetArray().mpNumericArray) - isMixedSV = svSingleVectorRefDouble; - else if(pSVR->GetArray().mpStringArray) - isMixedSV = svSingleVectorRefString; - else - isMixedSV = svSingleVectorRefNULL; - - if(isMixedSV == svSingleVectorRefDoubleString) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " arg = "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (!isnan(arg))\n"; - ss << " vSum += (arg - fMean)*(arg - fMean);\n"; - ss << " if (isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " {\n"; - ss << " arg = 0.0;\n"; - ss << " vSum += (arg - fMean)*(arg - fMean);\n"; - ss << " }\n"; - ss << " }\n"; - } - else if(isMixedSV == svSingleVectorRefDouble) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n"; - ss << " if (!isnan(arg))\n"; - ss << " {\n"; - ss << " vSum += (arg - fMean)*(arg - fMean);\n"; - ss << " }\n"; - ss << " }\n"; - } - else if(isMixedSV == svSingleVectorRefString) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " if ("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " {\n"; - ss << " arg = 0.0;\n"; - ss << " vSum += (arg - fMean)*(arg - fMean);\n"; - ss << " }\n"; - ss << " }\n"; - } - else - { - ss << " arg = 0.0;\n"; - } - } - else - { - ss << " arg = " << pCur->GetDouble() << ";\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - } - } - else - { - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - } - } - ss << " if (fCount <= 1.0)\n"; - ss << " return DBL_MAX;\n"; - ss << " else\n"; - ss << " return vSum / (fCount - 1.0);\n"; - ss << "}\n"; + decls.insert(fmax_countDecl); + funs.insert(fmax_count); } -void OpVarPA::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) +void OpAverage::BinInlineFun(std::set& decls,std::set& funs) { - int isMixedDV = 0; - int isMixedSV = 0; - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0 = get_global_id(0);\n"; - ss << " double fSum = 0.0;\n"; - ss << " double fMean = 0.0;\n"; - ss << " double vSum = 0.0;\n"; - ss << " double fCount = 0.0;\n"; - ss << " double arg = 0.0;\n"; - unsigned i = vSubArguments.size(); - while (i--) - { - FormulaToken *pCur = vSubArguments[i]->GetFormulaToken(); - assert(pCur); - - if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode()) - { - if (pCur->GetType() == formula::svDoubleVectorRef) - { - const formula::DoubleVectorRefToken* pDVR = - static_cast(pCur); - if(pDVR->GetArrays()[0].mpNumericArray - && pDVR->GetArrays()[0].mpStringArray) - isMixedDV = svDoubleVectorRefDoubleString; - else if(pDVR->GetArrays()[0].mpNumericArray) - isMixedDV = svDoubleVectorRefDouble; - else if(pDVR->GetArrays()[0].mpStringArray) - isMixedDV = svDoubleVectorRefString; - else - isMixedDV = svDoubleVectorRefNULL; - - size_t nCurWindowSize = pDVR->GetRefRowSize(); - ss << " for (int i = "; - if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) - { - ss << "gid0; i < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) - { - ss << "0; i < " << pDVR->GetArrayLength(); - ss << " && i < gid0+" << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()) - { - ss << "0; i + gid0 < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else - { - ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n"; - ss << " {\n"; - } - - if(isMixedDV == svDoubleVectorRefDoubleString) - { - ss << " arg = "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " == 0)\n"; - ss << " continue;\n"; - ss << " if(isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " {\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " continue;\n"; - ss << " }\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else if(isMixedDV == svDoubleVectorRefDouble) - { - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(arg))\n"; - ss << " continue;\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else if(isMixedDV == svDoubleVectorRefString) - { - ss << " if ("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " == 0)\n"; - ss << " continue;\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else - { - ss << " continue;\n"; - ss << " }\n"; - } - - } - else if (pCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* pSVR = - static_cast< const formula::SingleVectorRefToken* >(pCur); - if(pSVR->GetArray().mpNumericArray - && pSVR->GetArray().mpStringArray) - isMixedSV = svSingleVectorRefDoubleString; - else if(pSVR->GetArray().mpNumericArray) - isMixedSV = svSingleVectorRefDouble; - else if(pSVR->GetArray().mpStringArray) - isMixedSV = svSingleVectorRefString; - else - isMixedSV = svSingleVectorRefNULL; - - if(isMixedSV == svSingleVectorRefDoubleString) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " arg = "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (!isnan(arg))\n"; - ss << " {\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - ss << " if (isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else if(isMixedSV == svSingleVectorRefDouble) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n"; - ss << " if (!isnan(arg))\n"; - ss << " {\n"; - ss << " fSum += arg;\n"; - ss << " fCount += 1.0;\n"; - ss << " }\n"; - ss << " }\n"; - } - else if(isMixedSV == svSingleVectorRefString) - { - - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " if ("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else - { - ss << " arg =0.0;\n"; - } - } - else - { - ss << " arg = " << pCur->GetDouble() << ";\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - } - } - else - { - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - } - if (i == 0) - { - ss << " fMean = fSum / fCount;\n"; - } - } - i = vSubArguments.size(); - while (i--) - { - FormulaToken *pCur = vSubArguments[i]->GetFormulaToken(); - assert(pCur); - - if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode()) - { - if (pCur->GetType() == formula::svDoubleVectorRef) - { - const formula::DoubleVectorRefToken* pDVR = - static_cast(pCur); - if(pDVR->GetArrays()[0].mpNumericArray - && pDVR->GetArrays()[0].mpStringArray) - isMixedDV = svDoubleVectorRefDoubleString; - else if(pDVR->GetArrays()[0].mpNumericArray) - isMixedDV = svDoubleVectorRefDouble; - else if(pDVR->GetArrays()[0].mpStringArray) - isMixedDV = svDoubleVectorRefString; - else - isMixedDV = svDoubleVectorRefNULL; - - size_t nCurWindowSize = pDVR->GetRefRowSize(); - ss << " for (int i = "; - if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) - { - ss << "gid0; i < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) - { - ss << "0; i < " << pDVR->GetArrayLength(); - ss << " && i < gid0+" << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()) - { - ss << "0; i + gid0 < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else - { - ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n"; - ss << " {\n"; - } - if(isMixedDV == svDoubleVectorRefDoubleString) - { - ss << " arg = "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " == 0)\n"; - ss << " continue;\n"; - ss << " if(isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " arg = 0.0;\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - ss << " }\n"; - - } - else if(isMixedDV == svDoubleVectorRefDouble) - { - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(arg))\n"; - ss << " continue;\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - ss << " }\n"; - - } - else if(isMixedDV == svDoubleVectorRefString) - { - ss << " if ("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " == 0)\n"; - ss << " continue;\n"; - ss << " arg = 0.0;\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - ss << " }\n"; - } - else - { - ss << " continue;\n"; - ss << " }\n"; - } - } - else if (pCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* pSVR = - static_cast< const formula::SingleVectorRefToken* >(pCur); - if(pSVR->GetArray().mpNumericArray - && pSVR->GetArray().mpStringArray) - isMixedSV = svSingleVectorRefDoubleString; - else if(pSVR->GetArray().mpNumericArray) - isMixedSV = svSingleVectorRefDouble; - else if(pSVR->GetArray().mpStringArray) - isMixedSV = svSingleVectorRefString; - else - isMixedSV = svSingleVectorRefNULL; - - if(isMixedSV == svSingleVectorRefDoubleString) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " arg = "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (!isnan(arg))\n"; - ss << " vSum += (arg - fMean)*(arg - fMean);\n"; - ss << " if (isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " {\n"; - ss << " arg = 0.0;\n"; - ss << " vSum += (arg - fMean)*(arg - fMean);\n"; - ss << " }\n"; - ss << " }\n"; - } - else if(isMixedSV == svSingleVectorRefDouble) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n"; - ss << " if (!isnan(arg))\n"; - ss << " {\n"; - ss << " vSum += (arg - fMean)*(arg - fMean);\n"; - ss << " }\n"; - ss << " }\n"; - } - else if(isMixedSV == svSingleVectorRefString) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " if ("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " {\n"; - ss << " arg = 0.0;\n"; - ss << " vSum += (arg - fMean)*(arg - fMean);\n"; - ss << " }\n"; - ss << " }\n"; - } - else - { - ss << " arg = 0.0;\n"; - } - } - else - { - ss << " arg = " << pCur->GetDouble() << ";\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - } - } - else - { - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - } - } - ss << " if (fCount == 0.0)\n"; - ss << " return DBL_MAX;\n"; - ss << " else\n"; - ss << " return vSum / fCount;\n"; - ss << "}\n"; -} -void OpStDevA::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ - int isMixedDV = 0; - int isMixedSV = 0; - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0 = get_global_id(0);\n"; - ss << " double fSum = 0.0;\n"; - ss << " double fMean = 0.0;\n"; - ss << " double vSum = 0.0;\n"; - ss << " double fCount = 0.0;\n"; - ss << " double arg = 0.0;\n"; - unsigned i = vSubArguments.size(); - while (i--) - { - FormulaToken *pCur = vSubArguments[i]->GetFormulaToken(); - assert(pCur); - - if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode()) - { - if (pCur->GetType() == formula::svDoubleVectorRef) - { - const formula::DoubleVectorRefToken* pDVR = - static_cast(pCur); - if(pDVR->GetArrays()[0].mpNumericArray - && pDVR->GetArrays()[0].mpStringArray) - isMixedDV = svDoubleVectorRefDoubleString; - else if(pDVR->GetArrays()[0].mpNumericArray) - isMixedDV = svDoubleVectorRefDouble; - else if(pDVR->GetArrays()[0].mpStringArray) - isMixedDV = svDoubleVectorRefString; - else - isMixedDV = svDoubleVectorRefNULL; - - size_t nCurWindowSize = pDVR->GetRefRowSize(); - ss << " for (int i = "; - if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) - { - ss << "gid0; i < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) - { - ss << "0; i < " << pDVR->GetArrayLength(); - ss << " && i < gid0+" << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()) - { - ss << "0; i + gid0 < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else - { - ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n"; - ss << " {\n"; - } - - if(isMixedDV == svDoubleVectorRefDoubleString) - { - ss << " arg = "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " == 0)\n"; - ss << " continue;\n"; - ss << " if(isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " {\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " continue;\n"; - ss << " }\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else if(isMixedDV == svDoubleVectorRefDouble) - { - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(arg))\n"; - ss << " continue;\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else if(isMixedDV == svDoubleVectorRefString) - { - ss << " if ("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " == 0)\n"; - ss << " continue;\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else - { - ss << " continue;\n"; - ss << " }\n"; - } - - } - else if (pCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* pSVR = - static_cast< const formula::SingleVectorRefToken* >(pCur); - if(pSVR->GetArray().mpNumericArray - && pSVR->GetArray().mpStringArray) - isMixedSV = svSingleVectorRefDoubleString; - else if(pSVR->GetArray().mpNumericArray) - isMixedSV = svSingleVectorRefDouble; - else if(pSVR->GetArray().mpStringArray) - isMixedSV = svSingleVectorRefString; - else - isMixedSV = svSingleVectorRefNULL; - - if(isMixedSV == svSingleVectorRefDoubleString) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " arg = "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (!isnan(arg))\n"; - ss << " {\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - ss << " if (isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else if(isMixedSV == svSingleVectorRefDouble) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n"; - ss << " if (!isnan(arg))\n"; - ss << " {\n"; - ss << " fSum += arg;\n"; - ss << " fCount += 1.0;\n"; - ss << " }\n"; - ss << " }\n"; - } - else if(isMixedSV == svSingleVectorRefString) - { - - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " if ("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else - { - ss << " arg =0.0;\n"; - } - } - else - { - ss << " arg = " << pCur->GetDouble() << ";\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - } - } - else - { - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - } - if (i == 0) - { - ss << " fMean = fSum / fCount;\n"; - } - } - i = vSubArguments.size(); - while (i--) - { - FormulaToken *pCur = vSubArguments[i]->GetFormulaToken(); - assert(pCur); - - if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode()) - { - if (pCur->GetType() == formula::svDoubleVectorRef) - { - const formula::DoubleVectorRefToken* pDVR = - static_cast(pCur); - if(pDVR->GetArrays()[0].mpNumericArray - && pDVR->GetArrays()[0].mpStringArray) - isMixedDV = svDoubleVectorRefDoubleString; - else if(pDVR->GetArrays()[0].mpNumericArray) - isMixedDV = svDoubleVectorRefDouble; - else if(pDVR->GetArrays()[0].mpStringArray) - isMixedDV = svDoubleVectorRefString; - else - isMixedDV = svDoubleVectorRefNULL; - - size_t nCurWindowSize = pDVR->GetRefRowSize(); - ss << " for (int i = "; - if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) - { - ss << "gid0; i < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) - { - ss << "0; i < " << pDVR->GetArrayLength(); - ss << " && i < gid0+" << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()) - { - ss << "0; i + gid0 < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else - { - ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n"; - ss << " {\n"; - } - if(isMixedDV == svDoubleVectorRefDoubleString) - { - ss << " arg = "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " == 0)\n"; - ss << " continue;\n"; - ss << " if(isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " arg = 0.0;\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - ss << " }\n"; - - } - else if(isMixedDV == svDoubleVectorRefDouble) - { - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(arg))\n"; - ss << " continue;\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - ss << " }\n"; - - } - else if(isMixedDV == svDoubleVectorRefString) - { - ss << " if ("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " == 0)\n"; - ss << " continue;\n"; - ss << " arg = 0.0;\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - ss << " }\n"; - } - else - { - ss << " continue;\n"; - ss << " }\n"; - } - } - else if (pCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* pSVR = - static_cast< const formula::SingleVectorRefToken* >(pCur); - if(pSVR->GetArray().mpNumericArray - && pSVR->GetArray().mpStringArray) - isMixedSV = svSingleVectorRefDoubleString; - else if(pSVR->GetArray().mpNumericArray) - isMixedSV = svSingleVectorRefDouble; - else if(pSVR->GetArray().mpStringArray) - isMixedSV = svSingleVectorRefString; - else - isMixedSV = svSingleVectorRefNULL; - - if(isMixedSV == svSingleVectorRefDoubleString) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " arg = "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (!isnan(arg))\n"; - ss << " vSum += (arg - fMean)*(arg - fMean);\n"; - ss << " if (isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " {\n"; - ss << " arg = 0.0;\n"; - ss << " vSum += (arg - fMean)*(arg - fMean);\n"; - ss << " }\n"; - ss << " }\n"; - } - else if(isMixedSV == svSingleVectorRefDouble) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n"; - ss << " if (!isnan(arg))\n"; - ss << " {\n"; - ss << " vSum += (arg - fMean)*(arg - fMean);\n"; - ss << " }\n"; - ss << " }\n"; - } - else if(isMixedSV == svSingleVectorRefString) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " if ("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " {\n"; - ss << " arg = 0.0;\n"; - ss << " vSum += (arg - fMean)*(arg - fMean);\n"; - ss << " }\n"; - ss << " }\n"; - } - else - { - ss << " arg = 0.0;\n"; - } - } - else - { - ss << " arg = " << pCur->GetDouble() << ";\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - } - } - else - { - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - } - } - ss << " if (fCount <= 1.0)\n"; - ss << " return DBL_MAX;\n"; - ss << " else\n"; - ss << " return sqrt(vSum / (fCount - 1.0));\n"; - ss << "}\n"; -} - -void OpStDevPA::GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) -{ - int isMixedDV = 0; - int isMixedSV = 0; - GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); - ss << "{\n"; - ss << " int gid0 = get_global_id(0);\n"; - ss << " double fSum = 0.0;\n"; - ss << " double fMean = 0.0;\n"; - ss << " double vSum = 0.0;\n"; - ss << " double fCount = 0.0;\n"; - ss << " double arg = 0.0;\n"; - unsigned i = vSubArguments.size(); - while (i--) - { - FormulaToken *pCur = vSubArguments[i]->GetFormulaToken(); - assert(pCur); - - if(ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode()) - { - if (pCur->GetType() == formula::svDoubleVectorRef) - { - const formula::DoubleVectorRefToken* pDVR = - static_cast(pCur); - if(pDVR->GetArrays()[0].mpNumericArray - && pDVR->GetArrays()[0].mpStringArray) - isMixedDV = svDoubleVectorRefDoubleString; - else if(pDVR->GetArrays()[0].mpNumericArray) - isMixedDV = svDoubleVectorRefDouble; - else if(pDVR->GetArrays()[0].mpStringArray) - isMixedDV = svDoubleVectorRefString; - else - isMixedDV = svDoubleVectorRefNULL; - - size_t nCurWindowSize = pDVR->GetRefRowSize(); - ss << " for (int i = "; - if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) - { - ss << "gid0; i < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) - { - ss << "0; i < " << pDVR->GetArrayLength(); - ss << " && i < gid0+" << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()) - { - ss << "0; i + gid0 < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else - { - ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n"; - ss << " {\n"; - } - - if(isMixedDV == svDoubleVectorRefDoubleString) - { - ss << " arg = "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " == 0)\n"; - ss << " continue;\n"; - ss << " if(isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " {\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " continue;\n"; - ss << " }\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else if(isMixedDV == svDoubleVectorRefDouble) - { - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(arg))\n"; - ss << " continue;\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else if(isMixedDV == svDoubleVectorRefString) - { - ss << " if ("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " == 0)\n"; - ss << " continue;\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else - { - ss << " continue;\n"; - ss << " }\n"; - } - - } - else if (pCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* pSVR = - static_cast< const formula::SingleVectorRefToken* >(pCur); - if(pSVR->GetArray().mpNumericArray - && pSVR->GetArray().mpStringArray) - isMixedSV = svSingleVectorRefDoubleString; - else if(pSVR->GetArray().mpNumericArray) - isMixedSV = svSingleVectorRefDouble; - else if(pSVR->GetArray().mpStringArray) - isMixedSV = svSingleVectorRefString; - else - isMixedSV = svSingleVectorRefNULL; - - if(isMixedSV == svSingleVectorRefDoubleString) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " arg = "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (!isnan(arg))\n"; - ss << " {\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - ss << " if (isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else if(isMixedSV == svSingleVectorRefDouble) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n"; - ss << " if (!isnan(arg))\n"; - ss << " {\n"; - ss << " fSum += arg;\n"; - ss << " fCount += 1.0;\n"; - ss << " }\n"; - ss << " }\n"; - } - else if(isMixedSV == svSingleVectorRefString) - { - - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " if ("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " fCount = fCount + 1.0;\n"; - ss << " }\n"; - } - else - { - ss << " arg =0.0;\n"; - } - } - else - { - ss << " arg = " << pCur->GetDouble() << ";\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - } - } - else - { - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n"; - ss << " fSum += arg;\n"; - ss << " fCount = fCount + 1.0;\n"; - } - if (i == 0) - { - ss << " fMean = fSum / fCount;\n"; - } - } - i = vSubArguments.size(); - while (i--) - { - FormulaToken *pCur = vSubArguments[i]->GetFormulaToken(); - assert(pCur); - - if(ocPush==vSubArguments[i]->GetFormulaToken()->GetOpCode()) - { - if (pCur->GetType() == formula::svDoubleVectorRef) - { - const formula::DoubleVectorRefToken* pDVR = - static_cast(pCur); - if(pDVR->GetArrays()[0].mpNumericArray - && pDVR->GetArrays()[0].mpStringArray) - isMixedDV = svDoubleVectorRefDoubleString; - else if(pDVR->GetArrays()[0].mpNumericArray) - isMixedDV = svDoubleVectorRefDouble; - else if(pDVR->GetArrays()[0].mpStringArray) - isMixedDV = svDoubleVectorRefString; - else - isMixedDV = svDoubleVectorRefNULL; - - size_t nCurWindowSize = pDVR->GetRefRowSize(); - ss << " for (int i = "; - if (!pDVR->IsStartFixed() && pDVR->IsEndFixed()) - { - ss << "gid0; i < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else if (pDVR->IsStartFixed() && !pDVR->IsEndFixed()) - { - ss << "0; i < " << pDVR->GetArrayLength(); - ss << " && i < gid0+" << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else if (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()) - { - ss << "0; i + gid0 < " << pDVR->GetArrayLength(); - ss << " && i < " << nCurWindowSize << "; i++)\n"; - ss << " {\n"; - } - else - { - ss << "0; i < " << pDVR->GetArrayLength() << "; i++)\n"; - ss << " {\n"; - } - if(isMixedDV == svDoubleVectorRefDoubleString) - { - ss << " arg = "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " == 0)\n"; - ss << " continue;\n"; - ss << " if(isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " arg = 0.0;\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - ss << " }\n"; - - } - else if(isMixedDV == svDoubleVectorRefDouble) - { - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (isnan(arg))\n"; - ss << " continue;\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - ss << " }\n"; - - } - else if(isMixedDV == svDoubleVectorRefString) - { - ss << " if ("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " == 0)\n"; - ss << " continue;\n"; - ss << " arg = 0.0;\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - ss << " }\n"; - } - else - { - ss << " continue;\n"; - ss << " }\n"; - } - } - else if (pCur->GetType() == formula::svSingleVectorRef) - { - const formula::SingleVectorRefToken* pSVR = - static_cast< const formula::SingleVectorRefToken* >(pCur); - if(pSVR->GetArray().mpNumericArray - && pSVR->GetArray().mpStringArray) - isMixedSV = svSingleVectorRefDoubleString; - else if(pSVR->GetArray().mpNumericArray) - isMixedSV = svSingleVectorRefDouble; - else if(pSVR->GetArray().mpStringArray) - isMixedSV = svSingleVectorRefString; - else - isMixedSV = svSingleVectorRefNULL; - - if(isMixedSV == svSingleVectorRefDoubleString) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " arg = "; - ss << vSubArguments[i]->GenDoubleSlidingWindowDeclRef(); - ss << ";\n"; - ss << " if (!isnan(arg))\n"; - ss << " vSum += (arg - fMean)*(arg - fMean);\n"; - ss << " if (isnan(arg) && "; - ss << vSubArguments[i]->GenStringSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " {\n"; - ss << " arg = 0.0;\n"; - ss << " vSum += (arg - fMean)*(arg - fMean);\n"; - ss << " }\n"; - ss << " }\n"; - } - else if(isMixedSV == svSingleVectorRefDouble) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n"; - ss << " if (!isnan(arg))\n"; - ss << " {\n"; - ss << " vSum += (arg - fMean)*(arg - fMean);\n"; - ss << " }\n"; - ss << " }\n"; - } - else if(isMixedSV == svSingleVectorRefString) - { - ss << " if (gid0 < " << pSVR->GetArrayLength() << ")\n"; - ss << " {\n"; - ss << " if ("; - ss << vSubArguments[i]->GenSlidingWindowDeclRef(); - ss << " != 0)\n"; - ss << " {\n"; - ss << " arg = 0.0;\n"; - ss << " vSum += (arg - fMean)*(arg - fMean);\n"; - ss << " }\n"; - ss << " }\n"; - } - else - { - ss << " arg = 0.0;\n"; - } - } - else - { - ss << " arg = " << pCur->GetDouble() << ";\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - } - } - else - { - ss << " arg = "; - ss << vSubArguments[i]->GenSlidingWindowDeclRef() << ";\n"; - ss << " vSum += (arg - fMean) * (arg - fMean);\n"; - } - } - ss << " if (fCount == 1.0)\n"; - ss << " return DBL_MAX;\n"; - ss << " else\n"; - ss << " return sqrt(vSum / fCount);\n"; - ss << "}\n"; + decls.insert(fsum_countDecl); + funs.insert(fsum_count); } } diff --git a/sc/source/core/opencl/op_statistical.hxx b/sc/source/core/opencl/op_statistical.hxx index d2b685976fa8..e235231ee121 100644 --- a/sc/source/core/opencl/op_statistical.hxx +++ b/sc/source/core/opencl/op_statistical.hxx @@ -503,83 +503,123 @@ public: virtual std::string BinFuncName() const override { return "OpRsq"; } }; -class OpMinA: public Normal +class OpMin : public Reduction { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; - virtual std::string BinFuncName() const override { return "OpMinA"; } - virtual bool takeString() const override { return true; } - virtual bool takeNumeric() const override { return true; } + explicit OpMin(int nResultSize) : Reduction(nResultSize) {} + + virtual std::string GetBottom() override { return "NAN"; } + virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override + { + return "fmin_count(" + lhs + "," + rhs + ", &nCount)"; + } + virtual void BinInlineFun(std::set& decls,std::set& funs) override; + virtual std::string BinFuncName() const override { return "min"; } + virtual bool isMinOrMax() const override { return true; } virtual bool canHandleMultiVector() const override { return true; } }; -class OpCountA: public Normal + +class OpMax : public Reduction { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; + explicit OpMax(int nResultSize) : Reduction(nResultSize) {} + + virtual std::string GetBottom() override { return "NAN"; } + virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override + { + return "fmax_count(" + lhs + "," + rhs + ", &nCount)"; + } + virtual void BinInlineFun(std::set& decls,std::set& funs) override; + virtual std::string BinFuncName() const override { return "max"; } + virtual bool isMinOrMax() const override { return true; } + virtual bool canHandleMultiVector() const override { return true; } +}; + +class OpAverage : public Reduction +{ +public: + explicit OpAverage(int nResultSize) : Reduction(nResultSize) {} + + virtual std::string GetBottom() override { return "0"; } + virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override + { + outputstream ss; + ss << "fsum_count(" << lhs << "," << rhs << ", &nCount)"; + return ss.str(); + } + virtual void BinInlineFun(std::set& decls,std::set& funs) override; + virtual std::string BinFuncName() const override { return "average"; } + virtual bool isAverage() const override { return true; } + virtual bool canHandleMultiVector() const override { return true; } +}; + +class OpCount : public Reduction +{ +public: + explicit OpCount(int nResultSize) : Reduction(nResultSize) {} + + virtual std::string GetBottom() override { return "0"; } + virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override + { + outputstream ss; + ss << "(isnan(" << lhs << ")?" << rhs << ":" << rhs << "+1.0)"; + return ss.str(); + } + virtual std::string BinFuncName() const override { return "fcount"; } + virtual bool canHandleMultiVector() const override { return true; } +}; + +class OpCountA: public OpCount +{ +public: + explicit OpCountA(int nResultSize) : OpCount(nResultSize) {} virtual std::string BinFuncName() const override { return "OpCountA"; } - virtual bool takeString() const override { return true; } - virtual bool takeNumeric() const override { return true; } - virtual bool canHandleMultiVector() const override { return true; } + virtual bool forceStringsToZero() const override { return true; } }; -class OpMaxA: public Normal +class OpMaxA: public OpMax { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; + explicit OpMaxA(int nResultSize) : OpMax(nResultSize) {} virtual std::string BinFuncName() const override { return "OpMaxA"; } - virtual bool takeString() const override { return true; } - virtual bool takeNumeric() const override { return true; } - virtual bool canHandleMultiVector() const override { return true; } + virtual bool forceStringsToZero() const override { return true; } }; -class OpVarA: public Normal +class OpMinA : public OpMin +{ +public: + explicit OpMinA(int nResultSize) : OpMin(nResultSize) {} + virtual std::string BinFuncName() const override { return "OpMinA"; } + virtual bool forceStringsToZero() const override { return true; } +}; +class OpVarA: public OpVar { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "OpVarA"; } - virtual bool takeString() const override { return true; } - virtual bool takeNumeric() const override { return true; } - virtual bool canHandleMultiVector() const override { return true; } + virtual bool forceStringsToZero() const override { return true; } }; -class OpVarPA: public Normal +class OpVarPA: public OpVarP { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "OpVarPA"; } - virtual bool takeString() const override { return true; } - virtual bool takeNumeric() const override { return true; } - virtual bool canHandleMultiVector() const override { return true; } + virtual bool forceStringsToZero() const override { return true; } }; -class OpStDevPA: public Normal +class OpStDevPA: public OpStDevP { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "OpStDevPA"; } - virtual bool takeString() const override { return true; } - virtual bool takeNumeric() const override { return true; } + virtual bool forceStringsToZero() const override { return true; } }; -class OpAverageA: public Normal +class OpAverageA: public OpAverage { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; + explicit OpAverageA(int nResultSize) : OpAverage(nResultSize) {} virtual std::string BinFuncName() const override { return "OpAverageA"; } - virtual bool takeString() const override { return true; } - virtual bool takeNumeric() const override { return true; } - virtual bool canHandleMultiVector() const override { return true; } + virtual bool forceStringsToZero() const override { return true; } }; -class OpStDevA: public Normal +class OpStDevA: public OpStDev { public: - virtual void GenSlidingWindowFunction(outputstream &ss, - const std::string &sSymName, SubArguments &vSubArguments) override; virtual std::string BinFuncName() const override { return "OpStDevA"; } - virtual bool takeString() const override { return true; } - virtual bool takeNumeric() const override { return true; } + virtual bool forceStringsToZero() const override { return true; } }; } diff --git a/sc/source/core/opencl/op_statistical_helpers.hxx b/sc/source/core/opencl/op_statistical_helpers.hxx index 5fb2f787eefb..54914e11274f 100644 --- a/sc/source/core/opencl/op_statistical_helpers.hxx +++ b/sc/source/core/opencl/op_statistical_helpers.hxx @@ -23,6 +23,29 @@ const char GetValue[] = "{\n" " return fp - 2 * GetTDist(x, fDF);\n" "}\n"; +const char fmin_countDecl[] = "double fmin_count(double a, double b, __private int *p);\n"; +const char fmin_count[] = +"double fmin_count(double a, double b, __private int *p) {\n" +" double result = fmin(a, b);\n" +" bool t = isnan(result);\n" +" (*p) += t?0:1;\n" +" return result;\n" +"}\n"; +const char fmax_countDecl[] = "double fmax_count(double a, double b, __private int *p);\n"; +const char fmax_count[] = +"double fmax_count(double a, double b, __private int *p) {\n" +" double result = fmax(a, b);\n" +" bool t = isnan(result);\n" +" (*p) += t?0:1;\n" +" return result;\n" +"}\n"; +const char fsum_countDecl[] = "double fsum_count(double a, double b, __private int *p);\n"; +const char fsum_count[] = +"double fsum_count(double a, double b, __private int *p) {\n" +" bool t = isnan(a);\n" +" (*p) += t?0:1;\n" +" return t?b:a+b;\n" +"}\n"; const char GetGammaSeriesDecl[] = "double GetGammaSeries( double fA, double fX );\n"; const char GetGammaSeries[] = diff --git a/sc/source/core/opencl/opbase.cxx b/sc/source/core/opencl/opbase.cxx index fe98b4c09dd3..bbb9638948cd 100644 --- a/sc/source/core/opencl/opbase.cxx +++ b/sc/source/core/opencl/opbase.cxx @@ -84,7 +84,7 @@ bool DynamicKernelArgument::NeedParallelReduction() const } VectorRef::VectorRef( const ScCalcConfig& config, const std::string& s, const FormulaTreeNodeRef& ft, int idx ) : - DynamicKernelArgument(config, s, ft), mpClmem(nullptr), mnIndex(idx) + DynamicKernelArgument(config, s, ft), mpClmem(nullptr), mnIndex(idx), forceStringsToZero( false ) { if (mnIndex) { @@ -174,6 +174,13 @@ bool VectorRef::NeedParallelReduction() const return false; } +VectorRefStringsToZero::VectorRefStringsToZero( const ScCalcConfig& config, const std::string& s, + const FormulaTreeNodeRef& ft, int index ) + : VectorRef( config, s, ft, index ) +{ + forceStringsToZero = true; +} + void SlidingFunctionBase::GenerateArg( const char* name, int arg, SubArguments& vSubArguments, outputstream& ss ) { assert( arg < int( vSubArguments.size())); @@ -196,6 +203,11 @@ void SlidingFunctionBase::GenerateArg( const char* name, int arg, SubArguments& } else if(token->GetType() == formula::svDouble) ss << " " << name << " = " << token->GetDouble() << ";\n"; + else if(token->GetType() == formula::svString) + { + assert( dynamic_cast(vSubArguments[arg].get())); + ss << " " << name << " = 0.0;\n"; + } else throw Unhandled( __FILE__, __LINE__ ); } @@ -259,13 +271,23 @@ void SlidingFunctionBase::GenerateRangeArgs( int firstArg, int lastArg, SubArgum ss << code; ss << " }\n"; } - else + else if(token->GetType() == formula::svDouble) { ss << " {\n"; ss << " double arg = " << token->GetDouble() << ";\n"; ss << code; ss << " }\n"; } + else if(token->GetType() == formula::svString) + { + assert( dynamic_cast(vSubArguments[i].get())); + ss << " {\n"; + ss << " double arg = 0.0;\n"; + ss << code; + ss << " }\n"; + } + else + throw Unhandled( __FILE__, __LINE__ ); } else { @@ -611,6 +633,104 @@ void CheckVariables::UnrollDoubleVector( outputstream& ss, ss << " }\n"; } +void Reduction::GenSlidingWindowFunction( outputstream& ss, + const std::string& sSymName, SubArguments& vSubArguments ) +{ + GenerateFunctionDeclaration( sSymName, vSubArguments, ss ); + ss << "{\n"; + ss << "double tmp = " << GetBottom() << ";\n"; + ss << "int gid0 = get_global_id(0);\n"; + if (isAverage() || isMinOrMax()) + ss << "int nCount = 0;\n"; + ss << "double tmpBottom;\n"; + unsigned i = vSubArguments.size(); + while (i--) + { + if (NumericRange* NR = dynamic_cast(vSubArguments[i].get())) + { + bool needBody; + NR->GenReductionLoopHeader(ss, needBody); + if (!needBody) + continue; + } + else if (NumericRangeStringsToZero* NRS = dynamic_cast(vSubArguments[i].get())) + { + bool needBody; + NRS->GenReductionLoopHeader(ss, needBody); + if (!needBody) + continue; + } + else if (ParallelNumericRange* PNR = dynamic_cast(vSubArguments[i].get())) + { + //did not handle yet + bool bNeedBody = false; + PNR->GenReductionLoopHeader(ss, mnResultSize, bNeedBody); + if (!bNeedBody) + continue; + } + else if (StringRange* SR = dynamic_cast(vSubArguments[i].get())) + { + //did not handle yet + bool needBody; + SR->GenReductionLoopHeader(ss, needBody); + if (!needBody) + continue; + } + else + { + FormulaToken* pCur = vSubArguments[i]->GetFormulaToken(); + if( pCur == nullptr || pCur->GetType() == formula::svDoubleVectorRef ) + { + throw Unhandled(__FILE__, __LINE__); + } + ss << "{\n"; + } + if (ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode()) + { + bool bNanHandled = HandleNaNArgument(ss, i, vSubArguments); + + ss << " tmpBottom = " << GetBottom() << ";\n"; + + if (!bNanHandled) + { + ss << " if (isnan("; + ss << vSubArguments[i]->GenSlidingWindowDeclRef(); + ss << "))\n"; + if (ZeroReturnZero()) + ss << " return 0;\n"; + else + { + ss << " tmp = "; + ss << Gen2("tmpBottom", "tmp") << ";\n"; + } + ss << " else\n"; + } + ss << " tmp = "; + ss << Gen2(vSubArguments[i]->GenSlidingWindowDeclRef(), "tmp"); + ss << ";\n"; + } + else + { + ss << " tmp = "; + ss << Gen2(vSubArguments[i]->GenSlidingWindowDeclRef(), "tmp"); + ss << ";\n"; + } + ss << "}\n"; + } + if (isAverage()) + ss << + "if (nCount==0)\n" + " return CreateDoubleError(DivisionByZero);\n"; + else if (isMinOrMax()) + ss << + "if (nCount==0)\n" + " return 0;\n"; + ss << "return tmp"; + if (isAverage()) + ss << "/(double)nCount"; + ss << ";\n}"; +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/opencl/opbase.hxx b/sc/source/core/opencl/opbase.hxx index aa2770cd20aa..c274eeaf2024 100644 --- a/sc/source/core/opencl/opbase.hxx +++ b/sc/source/core/opencl/opbase.hxx @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include #include @@ -94,7 +96,7 @@ public: } while( false ) #define CHECK_PARAMETER_DOUBLEVECTORREF(arg) \ do { \ - FormulaToken *token = vSubArguments[arg]->GetFormulaToken(); \ + formula::FormulaToken *token = vSubArguments[arg]->GetFormulaToken(); \ if (token == nullptr || token->GetType() != formula::svDoubleVectorRef) \ throw Unhandled(__FILE__, __LINE__); \ } while( false ) @@ -206,6 +208,17 @@ protected: cl_mem mpClmem; // index in multiple double vector refs that have multiple ranges const int mnIndex; + // Makes Marshall convert strings to 0 values. + bool forceStringsToZero; + // Used for storing when the data needs to be modified before sending to OpenCL. + std::vector< double > dataBuffer; +}; + +// Sets VectorRef::forceStringsToZero. +class VectorRefStringsToZero : public VectorRef +{ +public: + VectorRefStringsToZero( const ScCalcConfig& config, const std::string& s, const FormulaTreeNodeRef& ft, int index = 0 ); }; /// A vector of strings @@ -229,6 +242,72 @@ public: virtual size_t Marshal( cl_kernel, int, int, cl_program ) override; }; +/// Arguments that are actually compile-time constants +class DynamicKernelConstantArgument : public DynamicKernelArgument +{ +public: + DynamicKernelConstantArgument( const ScCalcConfig& config, const std::string& s, + const FormulaTreeNodeRef& ft ) : + DynamicKernelArgument(config, s, ft) { } + /// Generate declaration + virtual void GenDecl( outputstream& ss ) const override + { + ss << "double " << mSymName; + } + virtual void GenDeclRef( outputstream& ss ) const override + { + ss << mSymName; + } + virtual void GenSlidingWindowDecl( outputstream& ss ) const override + { + GenDecl(ss); + } + virtual std::string GenSlidingWindowDeclRef( bool = false ) const override + { + if (GetFormulaToken()->GetType() != formula::svDouble) + throw Unhandled(__FILE__, __LINE__); + return mSymName; + } + virtual size_t GetWindowSize() const override + { + return 1; + } + virtual double GetDouble() const + { + formula::FormulaToken* Tok = GetFormulaToken(); + if (Tok->GetType() != formula::svDouble) + throw Unhandled(__FILE__, __LINE__); + return Tok->GetDouble(); + } + /// Create buffer and pass the buffer to a given kernel + virtual size_t Marshal( cl_kernel k, int argno, int, cl_program ) override + { + OpenCLZone zone; + double tmp = GetDouble(); + // Pass the scalar result back to the rest of the formula kernel + SAL_INFO("sc.opencl", "Kernel " << k << " arg " << argno << ": double: " << preciseFloat( tmp )); + cl_int err = clSetKernelArg(k, argno, sizeof(double), static_cast(&tmp)); + if (CL_SUCCESS != err) + throw OpenCLError("clSetKernelArg", err, __FILE__, __LINE__); + return 1; + } +}; + +// Constant 0 argument when a string is forced to zero. +class DynamicKernelStringToZeroArgument : public DynamicKernelConstantArgument +{ +public: + DynamicKernelStringToZeroArgument( const ScCalcConfig& config, const std::string& s, + const FormulaTreeNodeRef& ft ) : + DynamicKernelConstantArgument(config, s, ft) { } + virtual std::string GenSlidingWindowDeclRef( bool = false ) const override + { + return mSymName; + } + virtual double GetDouble() const override { return 0; } +}; + + /// Abstract class for code generation class OpBase { @@ -250,6 +329,8 @@ public: //Continue process 'Zero' or Not(like OpMul, not continue process when meet // 'Zero' virtual bool ZeroReturnZero() { return false;} + // For use with COUNTA() etc, input strings will be converted to 0 in data. + virtual bool forceStringsToZero() const { return false; } virtual ~OpBase() { } }; @@ -393,6 +474,30 @@ protected: cl_mem mpClmem2; }; +class Reduction : public SlidingFunctionBase +{ + int const mnResultSize; +public: + explicit Reduction(int nResultSize) : mnResultSize(nResultSize) {} + + typedef DynamicKernelSlidingArgument NumericRange; + typedef DynamicKernelSlidingArgument NumericRangeStringsToZero; + typedef DynamicKernelSlidingArgument StringRange; + typedef ParallelReductionVectorRef ParallelNumericRange; + + virtual bool HandleNaNArgument( outputstream&, unsigned, SubArguments& ) const + { + return false; + } + + virtual void GenSlidingWindowFunction( outputstream& ss, + const std::string& sSymName, SubArguments& vSubArguments ) override; + virtual bool isAverage() const { return false; } + virtual bool isMinOrMax() const { return false; } + virtual bool takeString() const override { return false; } + virtual bool takeNumeric() const override { return true; } +}; + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */