summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2015-10-15 12:37:55 +0300
committerTor Lillqvist <tml@collabora.com>2015-10-15 13:45:45 +0300
commit03eae494cfdb0c75188e6c2c85a4b59acba0ef12 (patch)
treeaf8bd5fcdb62fcb6e59dc351c0c3e36e3a7cce8f /sc
parent5e0e953f8f8fc5b27db8421ba15e33cfa664fb7a (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
Diffstat (limited to 'sc')
-rw-r--r--sc/source/core/opencl/formulagroupcl.cxx29
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