sc/source/core/opencl/op_financial.cxx   |    7 ---
 sc/source/core/opencl/op_financial.hxx   |    3 -
 sc/source/core/opencl/op_math.cxx        |    2 
 sc/source/core/opencl/op_statistical.cxx |   66 ++++++++++++++++++-------------
 4 files changed, 45 insertions(+), 33 deletions(-)

New commits:
commit 2e983926e868bcb2182c84348b60ad7085588b96
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Tue Sep 20 18:08:23 2022 +0200
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Wed Sep 21 10:23:03 2022 +0200

    various small opencl code fixes and error checking
    
    Change-Id: I9f1d109887faf11a86be83da050983292e99da49
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140252
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/sc/source/core/opencl/op_financial.cxx 
b/sc/source/core/opencl/op_financial.cxx
index 4e248902dbc6..c80f58cf72d1 100644
--- a/sc/source/core/opencl/op_financial.cxx
+++ b/sc/source/core/opencl/op_financial.cxx
@@ -845,12 +845,7 @@ void OpNPV::GenSlidingWindowFunction(outputstream &ss,
     ss << "    int nCount = 1;\n";
     GenerateArg( 0, vSubArguments, ss );
     GenerateRangeArgs( 1, vSubArguments.size() - 1, vSubArguments, ss, 
SkipEmpty,
-        "        double temp1=1.0;\n"
-        "        for(int i=1;i<nCount;i+=2)\n"
-        "            temp1*=pow(1.0f + arg0,2);\n"
-        "        if(nCount%2)\n"
-        "            temp1*=1.0f + arg0;\n"
-        "        tmp += arg / temp1;\n"
+        "        tmp += arg / pow( 1 + arg0, nCount );\n"
         "        nCount += 1;\n"
         );
     ss << "    return tmp;\n";
diff --git a/sc/source/core/opencl/op_financial.hxx 
b/sc/source/core/opencl/op_financial.hxx
index bd3c6bed116b..82c21b321d17 100644
--- a/sc/source/core/opencl/op_financial.hxx
+++ b/sc/source/core/opencl/op_financial.hxx
@@ -330,7 +330,8 @@ public:
     virtual void GenSlidingWindowFunction(outputstream &ss,
             const std::string &sSymName, SubArguments &vSubArguments) override;
     virtual std::string BinFuncName() const override { return "NPV"; }
-    virtual bool canHandleMultiVector() const override { return true; }
+    // doesn't handle svDoubleVectorRef properly, it should iterate 
horizontally
+    // virtual bool canHandleMultiVector() const override { return true; }
 };
 
 class OpPrice: public Normal
diff --git a/sc/source/core/opencl/op_math.cxx 
b/sc/source/core/opencl/op_math.cxx
index 70a87261c502..430f8734f5f0 100644
--- a/sc/source/core/opencl/op_math.cxx
+++ b/sc/source/core/opencl/op_math.cxx
@@ -331,6 +331,8 @@ void OpCombinA::GenerateCode( outputstream& ss ) const
 {
     ss << "    arg0 = trunc(arg0);\n";
     ss << "    arg1 = trunc(arg1);\n";
+    ss << "    if (arg0 < 0.0 || arg1 < 0.0 || arg1 > arg0)\n";
+    ss << "        return CreateDoubleError(IllegalArgument);\n";
     ss << "    double tem;\n";
     ss << "    if(arg0 >= arg1 && arg0 > 0 && arg1 > 0)\n";
     ss << "        tem = bik(arg0+arg1-1,arg1);\n";
diff --git a/sc/source/core/opencl/op_statistical.cxx 
b/sc/source/core/opencl/op_statistical.cxx
index 68b1e447c039..03e81c4dd034 100644
--- a/sc/source/core/opencl/op_statistical.cxx
+++ b/sc/source/core/opencl/op_statistical.cxx
@@ -337,8 +337,8 @@ void OpStandard::GenSlidingWindowFunction(outputstream &ss,
     ss << "{\n";
     ss << "    int gid0 = get_global_id(0);\n";
     GenerateArg( "x", 0, vSubArguments, ss );
-    GenerateArg( "mu", 0, vSubArguments, ss );
-    GenerateArg( "sigma", 0, vSubArguments, ss );
+    GenerateArg( "mu", 1, vSubArguments, ss );
+    GenerateArg( "sigma", 2, vSubArguments, ss );
     ss << "    if(sigma < 0.0)\n";
     ss << "        return CreateDoubleError(IllegalArgument);\n";
     ss << "    else if(sigma == 0.0)\n";
@@ -590,19 +590,20 @@ void OpNegbinomdist::GenSlidingWindowFunction(
 {
     CHECK_PARAMETER_COUNT( 3, 3 );
     GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
-    ss << "{\n\t";
-    ss << " int gid0=get_global_id(0);\n";
+    ss << "{\n";
+    ss << "    int gid0=get_global_id(0);\n";
     GenerateArg( "f", 0, vSubArguments, ss );
-    GenerateArg( "s", 0, vSubArguments, ss );
-    GenerateArg( "p", 0, vSubArguments, ss );
-    ss << " double q = 1.0 - p;\n\t";
-    ss << " double fFactor = pow(p,s);\n\t";
-    ss << " for(int i=0; i<f; i++)\n\t";
-    ss << " {\n\t";
-    ss << "  fFactor *= ((double)i+s)*pow(((double)i+1.0),-1.0)/pow(q,-1);\n";
-    ss << " }\n\t";
-    ss << " double temp=fFactor;\n\t";
-    ss << " return temp;\n";
+    GenerateArg( "s", 1, vSubArguments, ss );
+    GenerateArg( "p", 2, vSubArguments, ss );
+    ss << "    f = floor( f );\n";
+    ss << "    s = floor( s );\n";
+    ss << "    if ((f + s) <= 1.0 || p < 0.0 || p > 1.0)\n";
+    ss << "        return CreateDoubleError(IllegalArgument);\n";
+    ss << "    double q = 1.0 - p;\n";
+    ss << "    double fFactor = pow(p,s);\n";
+    ss << "    for(int i=0; i<f; i++)\n";
+    ss << "        fFactor *= (i+s)/(i+1.0)*q;\n";
+    ss << "    return fFactor;\n";
     ss << "}\n";
 }
 
@@ -812,6 +813,8 @@ vSubArguments)
     ss << "    int length;\n";
     ss << "    int totallength=0;\n";
     GenerateRangeArgs( vSubArguments, ss, SkipEmpty,
+        "        if( arg <= 0 )\n"
+        "            return CreateDoubleError(IllegalArgument);\n"
         "        nVal += (1.0 / arg);\n"
         "        ++totallength;\n"
         );
@@ -836,8 +839,8 @@ void OpConfidence::GenSlidingWindowFunction(outputstream& 
ss,
     ss << "    double tmp = " << GetBottom() <<";\n";
     ss << "    int gid0 = get_global_id(0);\n";
     GenerateArg( "alpha", 0, vSubArguments, ss );
-    GenerateArg( "sigma", 0, vSubArguments, ss );
-    GenerateArg( "size", 0, vSubArguments, ss );
+    GenerateArg( "sigma", 1, vSubArguments, ss );
+    GenerateArg( "size", 2, vSubArguments, ss );
     ss << "    double rn = floor(size);\n";
     ss << "    if(sigma <= 0.0 || alpha <= 0.0 || alpha >= 1.0";
     ss << "|| rn < 1.0)\n";
@@ -867,9 +870,13 @@ void OpCritBinom::GenSlidingWindowFunction(outputstream& 
ss,
     GenerateArg( "p", 1, vSubArguments, ss );
     GenerateArg( "alpha", 2, vSubArguments, ss );
     ss << "    double rn = floor(n);\n";
-    ss << "    if (rn < 0.0 || alpha <= 0.0 || alpha >= 1.0 || p < 0.0";
+    ss << "    if (rn < 0.0 || alpha < 0.0 || alpha > 1.0 || p < 0.0";
     ss << " || p > 1.0)\n";
     ss << "        return CreateDoubleError(IllegalArgument);\n";
+    ss << "    else if ( alpha == 0 )\n";
+    ss << "        return 0;\n";
+    ss << "    else if ( alpha == 1 )\n";
+    ss << "        return p == 0 ? 0 : rn;\n";
     ss << "    else\n";
     ss << "    {\n";
     ss << "        double rq = (0.5 - p) + 0.5;\n";
@@ -1166,6 +1173,8 @@ void OpKurt:: GenSlidingWindowFunction(outputstream &ss,
         "        fSum += arg;\n"
         "        totallength +=1;\n"
         );
+    ss << "    if( totallength < 4 )\n";
+    ss << "        return CreateDoubleError(DivisionByZero);\n";
     ss << "    double fMean = fSum / totallength;\n";
     GenerateRangeArgs( vSubArguments, ss, SkipEmpty,
         "        vSum += (arg-fMean)*(arg-fMean);\n"
@@ -1217,22 +1226,27 @@ void 
OpLogNormDist::GenSlidingWindowFunction(outputstream &ss,
     GenerateFunctionDeclaration( sSymName, vSubArguments, ss );
     ss << "{\n";
     ss << "    int gid0=get_global_id(0);\n";
-    GenerateArg( 0, vSubArguments, ss );
-    GenerateArgWithDefault( "arg1", 1, 0, vSubArguments, ss );
-    GenerateArgWithDefault( "arg2", 2, 1, vSubArguments, ss );
-    GenerateArgWithDefault( "arg3", 3, 1, vSubArguments, ss );
+    GenerateArg( "x", 0, vSubArguments, ss );
+    GenerateArgWithDefault( "mue", 1, 0, vSubArguments, ss );
+    GenerateArgWithDefault( "sigma", 2, 1, vSubArguments, ss );
+    GenerateArgWithDefault( "fCumulative", 3, 1, vSubArguments, ss );
+    ss << "    if (sigma <= 0.0)\n";
+    ss << "        return CreateDoubleError(IllegalArgument);\n";
     ss << "    double tmp;\n";
-    ss << "    double temp = (log(arg0)-arg1)/arg2;\n";
-    ss << "    if(arg3)\n";
+    ss << "    double temp = (log(x)-mue)/sigma;\n";
+    ss << "    if(fCumulative != 0)\n";
     ss << "    {\n";
-    ss << "        if(arg0<=0)\n";
+    ss << "        if(x<=0)\n";
     ss << "            tmp = 0.0;\n";
     ss << "        else\n";
     ss << "            tmp = 0.5 * erfc(-temp * 0.7071067811865475);\n";
     ss << "    }\n";
     ss << "    else\n";
-    ss << "        tmp = (0.39894228040143268 * exp((-1)*pow(temp, 2)";
-    ss << " / 2.0))/(arg2*arg0);\n";
+    ss << "        if(x<=0)\n";
+    ss << "            return CreateDoubleError(IllegalArgument);\n";
+    ss << "        else\n";
+    ss << "            tmp = (0.39894228040143268 * exp((-1)*pow(temp, 2)";
+    ss << " / 2.0))/(sigma*x);\n";
     ss << "    return tmp;\n";
     ss << "}\n";
 }

Reply via email to