[Libreoffice-commits] core.git: sc/source

Tor Lillqvist tml at collabora.com
Mon Feb 9 09:52:21 PST 2015


 sc/source/core/opencl/formulagroupcl.cxx |   56 ++++++++++++++++++++++++++-----
 1 file changed, 47 insertions(+), 9 deletions(-)

New commits:
commit f5e7207053b857b6903a0ab9c161bed9ad7bcee9
Author: Tor Lillqvist <tml at collabora.com>
Date:   Mon Feb 9 16:44:45 2015 +0200

    Handle zero and empty cells (which also means zero) in OpenCL for division
    
    Not sure if it makes sense to keep having OpDiv a subclass of Reduction. There
    is no DIV() function that would take a range of cells, so it isn't really
    comparable to the other Reducion subclasses. But let's keep that as it is for
    now.
    
    We need to handle three cases specially in the OpenCL: Dividing by an empty
    cell which should produce an #DIV/0! error, dividing an empty cell by zero
    which also should produce #DIV/0!, and dividing an empty cell with anything
    else number which should produce 0.
    
    Change-Id: I86d86f652047d6f9e3c095c3ef135a8f5396b000

diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index df56591..b1fb0b1 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -1661,6 +1661,11 @@ public:
     typedef DynamicKernelSlidingArgument<DynamicKernelStringArgument> StringRange;
     typedef ParallelReductionVectorRef<VectorRef> ParallelNumericRange;
 
+    virtual bool HandleNaNArgument( std::stringstream&, unsigned, SubArguments& ) const
+    {
+        return false;
+    }
+
     virtual void GenSlidingWindowFunction( std::stringstream& ss,
         const std::string& sSymName, SubArguments& vSubArguments ) SAL_OVERRIDE
     {
@@ -1724,18 +1729,25 @@ public:
             }
             if (ocPush == vSubArguments[i]->GetFormulaToken()->GetOpCode())
             {
+                bool bNanHandled = HandleNaNArgument(ss, i, vSubArguments);
+
                 ss << "tmpBottom = " << GetBottom() << ";\n";
-                ss << "if (isNan(";
-                ss << vSubArguments[i]->GenSlidingWindowDeclRef();
-                ss << "))\n";
-                if (ZeroReturnZero())
-                    ss << "    return 0;\n";
-                else
+
+                if (!bNanHandled)
                 {
-                    ss << "    tmp = ";
-                    ss << Gen2("tmpBottom", "tmp") << ";\n";
+                    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 << "else{\n";
+                ss << "{";
                 ss << "        tmp = ";
                 ss << Gen2(vSubArguments[i]->GenSlidingWindowDeclRef(), "tmp");
                 ss << ";\n";
@@ -2147,6 +2159,32 @@ public:
         return "(" + rhs + "==0 ? CreateDoubleError(errDivisionByZero) : (" + lhs + "/" + rhs + ") )";
     }
     virtual std::string BinFuncName() const SAL_OVERRIDE { return "fdiv"; }
+
+    virtual bool HandleNaNArgument( std::stringstream& ss, unsigned argno, SubArguments& vSubArguments ) const SAL_OVERRIDE
+    {
+        if (argno == 1)
+        {
+            ss <<
+                "if (isnan(" << vSubArguments[argno]->GetName() << "[gid0])) {\n"
+                "    if (GetDoubleErrorValue(" << vSubArguments[argno]->GetName() << "[gid0]) == errNoValue)\n"
+                "        return CreateDoubleError(errDivisionByZero);\n"
+                "}\n";
+            return true;
+        }
+        else if (argno == 0)
+        {
+            ss <<
+                "if (isnan(" << vSubArguments[argno]->GetName() << "[gid0])) {\n"
+                "    if (GetDoubleErrorValue(" << vSubArguments[argno]->GetName() << "[gid0]) == errNoValue) {\n"
+                "        if (" << vSubArguments[1]->GetName() << "[gid0] == 0)\n"
+                "            return CreateDoubleError(errDivisionByZero);\n"
+                "        return 0;\n"
+                "    }\n"
+                "}\n";
+        }
+        return false;
+    }
+
 };
 
 class OpMin : public Reduction


More information about the Libreoffice-commits mailing list