sc/source/core/opencl/op_logical.cxx |    5 +++
 sc/source/core/opencl/op_math.cxx    |   55 +++++++++++++++++++++++------------
 sc/source/core/opencl/opbase.hxx     |   10 +++++-
 3 files changed, 50 insertions(+), 20 deletions(-)

New commits:
commit 20caaffa82f701ef52900f4504227f88320d227f
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Thu Sep 1 14:01:53 2022 +0200
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Tue Sep 6 12:04:06 2022 +0200

    check parameter count in opencl logical functions
    
    Change-Id: If77bd146bd9eafd54afa1b82203d378ab9cd26d1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139197
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/sc/source/core/opencl/op_logical.cxx 
b/sc/source/core/opencl/op_logical.cxx
index 969b63d0ee7b..1fa21e8250e6 100644
--- a/sc/source/core/opencl/op_logical.cxx
+++ b/sc/source/core/opencl/op_logical.cxx
@@ -18,6 +18,7 @@ namespace sc::opencl {
 void OpAnd::GenSlidingWindowFunction(outputstream &ss,
     const std::string &sSymName, SubArguments &vSubArguments)
 {
+    CHECK_PARAMETER_COUNT_MIN( 1 );
     ss << "\ndouble " << sSymName;
     ss << "_"<< BinFuncName() <<"(";
     for (size_t i = 0; i < vSubArguments.size(); i++)
@@ -103,6 +104,7 @@ void OpAnd::GenSlidingWindowFunction(outputstream &ss,
 void OpOr::GenSlidingWindowFunction(outputstream &ss,
     const std::string &sSymName, SubArguments &vSubArguments)
 {
+    CHECK_PARAMETER_COUNT_MIN( 1 );
     ss << "\ndouble " << sSymName;
     ss << "_"<< BinFuncName() <<"(";
     for (size_t i = 0; i < vSubArguments.size(); i++)
@@ -182,6 +184,7 @@ void OpOr::GenSlidingWindowFunction(outputstream &ss,
 void OpNot::GenSlidingWindowFunction(outputstream &ss,
     const std::string &sSymName, SubArguments &vSubArguments)
 {
+    CHECK_PARAMETER_COUNT( 1, 1 );
     ss << "\ndouble " << sSymName;
     ss << "_"<< BinFuncName() <<"(";
     for (size_t i = 0; i < vSubArguments.size(); i++)
@@ -219,6 +222,7 @@ void OpNot::GenSlidingWindowFunction(outputstream &ss,
 void OpXor::GenSlidingWindowFunction(outputstream &ss,
     const std::string &sSymName, SubArguments &vSubArguments)
 {
+    CHECK_PARAMETER_COUNT_MIN( 1 );
     ss << "\ndouble " << sSymName;
     ss << "_"<< BinFuncName() <<"(";
     for (size_t i = 0; i < vSubArguments.size(); i++)
@@ -298,6 +302,7 @@ void OpXor::GenSlidingWindowFunction(outputstream &ss,
 void OpIf::GenSlidingWindowFunction(outputstream &ss,
     const std::string &sSymName, SubArguments &vSubArguments)
 {
+    CHECK_PARAMETER_COUNT( 1, 3 );
     ss << "\ndouble " << sSymName;
     ss << "_"<< BinFuncName() <<"(";
     for (size_t i = 0; i < vSubArguments.size(); i++)
diff --git a/sc/source/core/opencl/opbase.hxx b/sc/source/core/opencl/opbase.hxx
index 4262da8c35da..c56c02c855a3 100644
--- a/sc/source/core/opencl/opbase.hxx
+++ b/sc/source/core/opencl/opbase.hxx
@@ -70,14 +70,20 @@ public:
     int const mLineNumber;
 };
 
-// Helper macro to be used in code emitting OpenCL code for Calc functions.
-// Requires the vSubArguments parameter.
+// Helper macros to be used in code emitting OpenCL code for Calc functions.
+// Require the vSubArguments parameter.
 #define CHECK_PARAMETER_COUNT(min, max) \
     do { \
         const int count = vSubArguments.size(); \
         if( count < ( min ) || count > ( max )) \
             throw InvalidParameterCount( count, __FILE__, __LINE__ ); \
     } while( false )
+#define CHECK_PARAMETER_COUNT_MIN(min) \
+    do { \
+        const int count = vSubArguments.size(); \
+        if( count < ( min )) \
+            throw InvalidParameterCount( count, __FILE__, __LINE__ ); \
+    } while( false )
 
 typedef std::shared_ptr<FormulaTreeNode> FormulaTreeNodeRef;
 
commit 08b0c3b848b8f2bd667fad00068f3c828c709ef5
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Thu Sep 1 13:59:50 2022 +0200
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Tue Sep 6 12:03:50 2022 +0200

    fixes to opencl rounding functions
    
    Change-Id: I5cd99116a7230b8070051cbf6969a1fdd2f7fe62
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139196
    Tested-by: Jenkins
    Reviewed-by: Luboš Luňák <l.lu...@collabora.com>

diff --git a/sc/source/core/opencl/op_math.cxx 
b/sc/source/core/opencl/op_math.cxx
index 7cb632050aa4..edcc2b940bd6 100644
--- a/sc/source/core/opencl/op_math.cxx
+++ b/sc/source/core/opencl/op_math.cxx
@@ -1670,27 +1670,28 @@ void OpRoundUp::GenSlidingWindowFunction(outputstream 
&ss,
     ss << "    int gid0=get_global_id(0);\n";
     ss << "    int singleIndex =  gid0;\n";
     ss << "    int intTmp;\n";
-    ss << "    double doubleTmp;\n";
     ss << "    double tmp;\n";
     GenTmpVariables(ss,vSubArguments);
     CheckAllSubArgumentIsNan(ss,vSubArguments);
     if( vSubArguments.size() == 1 )
         ss << "    double tmp1 = 0;\n";
-    ss << "    if(tmp1 >20 || tmp1 < -20)";
+    ss << "    int shift = (int)tmp1;\n";
+    ss << "    if(shift >20 || shift < -20)";
     ss << "    {\n";
     ss << "        tmp = NAN;\n";
     ss << "    }else\n";
     ss << "    {\n";
-    ss << "        for(int i=0;i<tmp1;i++)\n";
-    ss << "            tmp0 = tmp0 * 10;\n";
-    ss << "        intTmp = (int)tmp0;\n";
-    ss << "        doubleTmp = intTmp;\n";
-    ss << "        if(isequal(doubleTmp,tmp0))\n";
-    ss << "            tmp = doubleTmp;\n";
+    ss << "        double multiply = 1.0;\n";
+    ss << "        for(int i=0;i<shift;i++)\n";
+    ss << "            multiply *= 10;\n";
+    ss << "        for(int i=0;i>shift;i--)\n";
+    ss << "            multiply /= 10;\n";
+    ss << "        intTmp = (int)(tmp0*multiply);\n";
+    ss << "        if(tmp0 >= 0)\n";
+    ss << "            tmp = intTmp + 1;\n";
     ss << "        else\n";
-    ss << "            tmp = doubleTmp + 1;\n";
-    ss << "        for(int i=0;i<tmp1;i++)\n";
-    ss << "            tmp = tmp / 10;\n";
+    ss << "            tmp = intTmp - 1;\n";
+    ss << "        tmp /= multiply;\n";
     ss << "    }\n";
     ss << "    return tmp;\n";
     ss << "}";
@@ -1716,17 +1717,20 @@ void OpRoundDown::GenSlidingWindowFunction(outputstream 
&ss,
     CheckAllSubArgumentIsNan(ss,vSubArguments);
     if( vSubArguments.size() == 1 )
         ss << "    double tmp1 = 0;\n";
-    ss << "    if(tmp1 >20 || tmp1 < -20)";
+    ss << "    int shift = (int)tmp1;\n";
+    ss << "    if(shift >20 || shift < -20)";
     ss << "    {\n";
     ss << "        tmp = NAN;\n";
     ss << "    }else\n";
     ss << "    {\n";
-    ss << "        for(int i=0;i<tmp1;i++)\n";
-    ss << "            tmp0 = tmp0 * 10;\n";
-    ss << "        intTmp = (int)tmp0;\n";
+    ss << "        double multiply = 1.0;\n";
+    ss << "        for(int i=0;i<shift;i++)\n";
+    ss << "            multiply *= 10;\n";
+    ss << "        for(int i=0;i>shift;i--)\n";
+    ss << "            multiply /= 10;\n";
+    ss << "        intTmp = (int)(tmp0*multiply);\n";
     ss << "        tmp = intTmp;\n";
-    ss << "        for(int i=0;i<tmp1;i++)\n";
-    ss << "            tmp = tmp / 10;\n";
+    ss << "        tmp /= multiply;\n";
     ss << "    }\n";
     ss << "    return tmp;\n";
     ss << "}";
@@ -1750,6 +1754,12 @@ void OpInt::GenSlidingWindowFunction(outputstream &ss,
     GenTmpVariables(ss,vSubArguments);
     CheckAllSubArgumentIsNan(ss,vSubArguments);
     ss << "    intTmp = (int)tmp0;\n";
+    // check whether rounding error caused the float to be just less than the 
int value
+    ss << "    if( tmp0 >=0 && approx_equal( intTmp + 1, tmp0 ))\n";
+    ss << "        ++intTmp;\n";
+    // negative values are rounded down
+    ss << "    if( tmp0 < 0 && !approx_equal( intTmp, tmp0 ))\n";
+    ss << "        --intTmp;\n";
     ss << "    tmp = intTmp;\n";
     ss << "    return tmp;\n";
     ss << "}";
@@ -2173,6 +2183,11 @@ void OpTrunc::GenSlidingWindowFunction(outputstream &ss,
     ss << "        argm = argm * 10;\n";
     ss << "        nn = nn * 10;\n";
     ss << "    }\n";
+    ss << "    for(int i = 0; i > n; --i)\n";
+    ss << "    {\n";
+    ss << "        argm = argm / 10;\n";
+    ss << "        nn = nn / 10;\n";
+    ss << "    }\n";
     ss << "    modf(argm, &argm);\n";
     ss << "    return argm / nn;\n";
     ss << "}";
@@ -2207,7 +2222,9 @@ void OpFloor::GenSlidingWindowFunction(
     ss << "    if(isnan(arg2))\n";
     ss << "        arg2 = 0.0;\n";
     ss << "    if(arg0*arg1<0)\n";
-    ss << "        return NAN;\n";
+    ss << "        return CreateDoubleError(IllegalArgument);\n";
+    ss << "    if(arg1 == 0.0)\n";
+    ss << "        return 0.0;\n";
     ss << "    else if(arg2==0.0&&arg0<0.0)\n";
     ss << "        return (trunc(arg0/arg1)+1)*arg1;\n";
     ss << "    else\n";
@@ -2574,6 +2591,8 @@ void OpCeil::GenSlidingWindowFunction(outputstream &ss,
         ss << "    else\n    ";
         ss << "    bAbs = 
"<<vSubArguments[2]->GenSlidingWindowDeclRef()<<";\n";
     }
+    ss << "    if(num*significance < 0.0)\n";
+    ss << "        return CreateDoubleError(IllegalArgument);\n";
     ss << "    if(significance == 0.0)\n";
     ss << "        return 0.0;\n";
     ss << "    return ";

Reply via email to