Kaydet (Commit) 03eae494 authored tarafından Tor Lillqvist's avatar Tor Lillqvist

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
üst 5e0e953f
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment