diff options
author | Tor Lillqvist <tml@collabora.com> | 2015-10-15 12:37:55 +0300 |
---|---|---|
committer | Tor Lillqvist <tml@collabora.com> | 2015-10-15 13:45:45 +0300 |
commit | 03eae494cfdb0c75188e6c2c85a4b59acba0ef12 (patch) | |
tree | af8bd5fcdb62fcb6e59dc351c0c3e36e3a7cce8f | |
parent | 5e0e953f8f8fc5b27db8421ba15e33cfa664fb7a (diff) |
tdf#94924: Return correct result 0 from OpenCL MIN and MAX when all args empty
Used the same style as existing code, added a new virtual isMinOrMax()
and add some special casing in Reduction::GenSlidingWindowFunction(),
and fsim_count() and fmax_count() functions that count how many
non-NaN numbers we actually see. As such, I am not sure at all that
this is an ideal way to do this, but will have to do for now.
Change-Id: I846a8d24f4563f8fae1a45971a4ce202ed918487
-rw-r--r-- | sc/source/core/opencl/formulagroupcl.cxx | 29 |
1 files changed, 24 insertions, 5 deletions
diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx index 82ef58d81e1c..8d0deea094b9 100644 --- a/sc/source/core/opencl/formulagroupcl.cxx +++ b/sc/source/core/opencl/formulagroupcl.cxx @@ -63,6 +63,18 @@ static const char* publicFunc = " (*p) += t?0:1;\n" " return t?b:a+b;\n" "}\n" + "double fmin_count(double a, double b, __private int *p) {\n" + " double result = fmin(a, b);\n" + " bool t = isnan(result);\n" + " (*p) += t?0:1;\n" + " return result;\n" + "}\n" + "double fmax_count(double a, double b, __private int *p) {\n" + " double result = fmax(a, b);\n" + " bool t = isnan(result);\n" + " (*p) += t?0:1;\n" + " return result;\n" + "}\n" "double fsum(double a, double b) { return isNan(a)?b:a+b; }\n" "double legalize(double a, double b) { return isNan(a)?b:a;}\n" "double fsub(double a, double b) { return a-b; }\n" @@ -1696,7 +1708,7 @@ public: ss << ") {\n"; ss << "double tmp = " << GetBottom() << ";\n"; ss << "int gid0 = get_global_id(0);\n"; - if (isAverage()) + if (isAverage() || isMinOrMax()) ss << "int nCount = 0;\n"; ss << "double tmpBottom;\n"; unsigned i = vSubArguments.size(); @@ -1783,12 +1795,17 @@ public: ss << "if (nCount==0)\n" " return CreateDoubleError(errDivisionByZero);\n"; + else if (isMinOrMax()) + ss << + "if (nCount==0)\n" + " return 0;\n"; ss << "return tmp"; if (isAverage()) ss << "*pow((double)nCount,-1.0)"; ss << ";\n}"; } virtual bool isAverage() const { return false; } + virtual bool isMinOrMax() const { return false; } virtual bool takeString() const override { return false; } virtual bool takeNumeric() const override { return true; } }; @@ -2203,12 +2220,13 @@ class OpMin : public Reduction public: OpMin( int nResultSize ) : Reduction(nResultSize) {} - virtual std::string GetBottom() override { return "MAXFLOAT"; } + virtual std::string GetBottom() override { return "NAN"; } virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override { - return "fmin(" + lhs + "," + rhs + ")"; + return "fmin_count(" + lhs + "," + rhs + ", &nCount)"; } virtual std::string BinFuncName() const override { return "min"; } + virtual bool isMinOrMax() const override { return true; } }; class OpMax : public Reduction @@ -2216,12 +2234,13 @@ class OpMax : public Reduction public: OpMax( int nResultSize ) : Reduction(nResultSize) {} - virtual std::string GetBottom() override { return "-MAXFLOAT"; } + virtual std::string GetBottom() override { return "NAN"; } virtual std::string Gen2( const std::string& lhs, const std::string& rhs ) const override { - return "fmax(" + lhs + "," + rhs + ")"; + return "fmax_count(" + lhs + "," + rhs + ", &nCount)"; } virtual std::string BinFuncName() const override { return "max"; } + virtual bool isMinOrMax() const override { return true; } }; class OpSumProduct : public SumOfProduct |