sc/source/core/opencl/op_math.cxx         |   34 +++++++++++++++++-------------
 sc/source/core/opencl/op_math.hxx         |    1 
 sc/source/core/opencl/op_math_helpers.hxx |   26 ++++++++++++++++++++++
 3 files changed, 47 insertions(+), 14 deletions(-)

New commits:
commit af5aaddee5e752fcb38cf1550d8152089443196e
Author:     Luboš Luňák <l.lu...@collabora.com>
AuthorDate: Thu Sep 22 09:55:05 2022 +0200
Commit:     Luboš Luňák <l.lu...@collabora.com>
CommitDate: Thu Sep 22 17:59:53 2022 +0200

    fix opencl ocMod
    
    Basically copied from core.
    
    Change-Id: Ic46e6ed77d1e75fcd4dfb8c641a8f592d577cab0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140370
    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 cd2f2f8b5396..5e88f8f67a8e 100644
--- a/sc/source/core/opencl/op_math.cxx
+++ b/sc/source/core/opencl/op_math.cxx
@@ -391,23 +391,29 @@ void OpCombin::GenerateCode( outputstream& ss ) const
     ss << "    return result;\n";
 }
 
+void OpMod::BinInlineFun(std::set<std::string>& decls,std::set<std::string>& 
funs)
+{
+    decls.insert(is_representable_integerDecl);
+    funs.insert(is_representable_integer);
+    decls.insert(approx_equalDecl);
+    funs.insert(approx_equal);
+    decls.insert(fsub_approxDecl);
+    funs.insert(fsub_approx);
+    decls.insert(value_approxDecl);
+    funs.insert(value_approx);
+}
+
 void OpMod::GenerateCode( outputstream& ss ) const
 {
-    ss << "    if(isnan(arg0)||arg0 == 0)\n";
-    ss << "        return 0;\n";
-    ss << "    if(isnan(arg1) || arg1 ==0)\n";
+    ss << "    double fNum = arg0;\n";
+    ss << "    double fDenom = arg1;\n";
+    ss << "    if(fDenom == 0)\n";
     ss << "        return CreateDoubleError(DivisionByZero);\n";
-    ss << "    double tem;\n";
-    ss << "        if(arg0 < 0 && arg1 > 0)\n";
-    ss << "            while(arg0 < 0)\n";
-    ss << "                arg0 += arg1;\n";
-    ss << "        else if (arg0 > 0 && arg1 < 0)\n";
-    ss << "            while(arg0 > 0)\n";
-    ss << "                arg0 += arg1;\n";
-    ss << "        tem = fmod(arg0,arg1);\n";
-    ss << "    if(arg1 < 0 && tem > 0)\n";
-    ss << "        tem = -tem;\n";
-    ss << "    return tem;\n";
+    ss << "    double fRes = fsub_approx( fNum, floor( value_approx( fNum / 
fDenom )) * fDenom );\n";
+    ss << "    if ( ( fDenom > 0 && fRes >= 0 && fRes < fDenom ) ||\n";
+    ss << "             ( fDenom < 0 && fRes <= 0 && fRes > fDenom ) )\n";
+    ss << "        return fRes;\n";
+    ss << "    return CreateDoubleError(NoValue);\n";
 }
 
 void OpPower::GenerateCode( outputstream& ss ) const
diff --git a/sc/source/core/opencl/op_math.hxx 
b/sc/source/core/opencl/op_math.hxx
index 9ff5253d0ad5..a5adec2cb8aa 100644
--- a/sc/source/core/opencl/op_math.hxx
+++ b/sc/source/core/opencl/op_math.hxx
@@ -405,6 +405,7 @@ class OpMod: public OpMathTwoArguments
 public:
     virtual std::string BinFuncName() const override { return "Mod"; }
     virtual void GenerateCode( outputstream& ss ) const override;
+    virtual void BinInlineFun(std::set<std::string>& ,std::set<std::string>& ) 
override;
 };
 
 class OpProduct: public Normal
diff --git a/sc/source/core/opencl/op_math_helpers.hxx 
b/sc/source/core/opencl/op_math_helpers.hxx
index 015afcf547fb..6a751dd9c35b 100644
--- a/sc/source/core/opencl/op_math_helpers.hxx
+++ b/sc/source/core/opencl/op_math_helpers.hxx
@@ -163,4 +163,30 @@ const char fsub_approx[] =
 "    return a - b;\n"
 "}\n";
 
+const char value_approxDecl[] = "double value_approx( double fValue );\n";
+const char value_approx[] =
+"double value_approx( double fValue )\n"
+"{\n"
+"    const double fBigInt = 2199023255552.0;\n"
+"    if (fValue == 0.0 || fValue == HUGE_VAL || !isfinite(fValue))\n"
+"        return fValue;\n"
+"    double fOrigValue = fValue;\n"
+"    fValue = fabs(fValue);\n"
+"    if (fValue > fBigInt)\n"
+"        return fOrigValue;\n"
+"    if (is_representable_integer(fValue))\n" // TODO? || 
getBitsInFracPart(fValue) <= 11)\n"
+"        return fOrigValue;\n"
+"    int nExp = (int)(floor(log10(fValue)));\n"
+"    nExp = 14 - nExp;\n"
+"    double fExpValue = pow(10.0,nExp);\n"
+"    fValue *= fExpValue;\n"
+"    if (!isfinite(fValue))\n"
+"        return fOrigValue;\n"
+"    fValue = round(fValue);\n"
+"    fValue /= fExpValue;\n"
+"    if (!isfinite(fValue))\n"
+"        return fOrigValue;\n"
+"    return copysign(fValue, fOrigValue);\n"
+"}\n";
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to