sc/source/core/opencl/formulagroupcl.cxx | 56 ++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 9 deletions(-)
New commits: commit f5e7207053b857b6903a0ab9c161bed9ad7bcee9 Author: Tor Lillqvist <t...@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 _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits