sc/source/core/opencl/op_logical.cxx | 5 +++ sc/source/core/opencl/op_math.cxx | 55 +++++++++++++++++++++++------------ sc/source/core/opencl/opbase.hxx | 10 +++++- 3 files changed, 50 insertions(+), 20 deletions(-)
New commits: commit 20caaffa82f701ef52900f4504227f88320d227f Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Thu Sep 1 14:01:53 2022 +0200 Commit: Luboš Luňák <l.lu...@collabora.com> CommitDate: Tue Sep 6 12:04:06 2022 +0200 check parameter count in opencl logical functions Change-Id: If77bd146bd9eafd54afa1b82203d378ab9cd26d1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139197 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lu...@collabora.com> diff --git a/sc/source/core/opencl/op_logical.cxx b/sc/source/core/opencl/op_logical.cxx index 969b63d0ee7b..1fa21e8250e6 100644 --- a/sc/source/core/opencl/op_logical.cxx +++ b/sc/source/core/opencl/op_logical.cxx @@ -18,6 +18,7 @@ namespace sc::opencl { void OpAnd::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) { + CHECK_PARAMETER_COUNT_MIN( 1 ); ss << "\ndouble " << sSymName; ss << "_"<< BinFuncName() <<"("; for (size_t i = 0; i < vSubArguments.size(); i++) @@ -103,6 +104,7 @@ void OpAnd::GenSlidingWindowFunction(outputstream &ss, void OpOr::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) { + CHECK_PARAMETER_COUNT_MIN( 1 ); ss << "\ndouble " << sSymName; ss << "_"<< BinFuncName() <<"("; for (size_t i = 0; i < vSubArguments.size(); i++) @@ -182,6 +184,7 @@ void OpOr::GenSlidingWindowFunction(outputstream &ss, void OpNot::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) { + CHECK_PARAMETER_COUNT( 1, 1 ); ss << "\ndouble " << sSymName; ss << "_"<< BinFuncName() <<"("; for (size_t i = 0; i < vSubArguments.size(); i++) @@ -219,6 +222,7 @@ void OpNot::GenSlidingWindowFunction(outputstream &ss, void OpXor::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) { + CHECK_PARAMETER_COUNT_MIN( 1 ); ss << "\ndouble " << sSymName; ss << "_"<< BinFuncName() <<"("; for (size_t i = 0; i < vSubArguments.size(); i++) @@ -298,6 +302,7 @@ void OpXor::GenSlidingWindowFunction(outputstream &ss, void OpIf::GenSlidingWindowFunction(outputstream &ss, const std::string &sSymName, SubArguments &vSubArguments) { + CHECK_PARAMETER_COUNT( 1, 3 ); ss << "\ndouble " << sSymName; ss << "_"<< BinFuncName() <<"("; for (size_t i = 0; i < vSubArguments.size(); i++) diff --git a/sc/source/core/opencl/opbase.hxx b/sc/source/core/opencl/opbase.hxx index 4262da8c35da..c56c02c855a3 100644 --- a/sc/source/core/opencl/opbase.hxx +++ b/sc/source/core/opencl/opbase.hxx @@ -70,14 +70,20 @@ public: int const mLineNumber; }; -// Helper macro to be used in code emitting OpenCL code for Calc functions. -// Requires the vSubArguments parameter. +// Helper macros to be used in code emitting OpenCL code for Calc functions. +// Require the vSubArguments parameter. #define CHECK_PARAMETER_COUNT(min, max) \ do { \ const int count = vSubArguments.size(); \ if( count < ( min ) || count > ( max )) \ throw InvalidParameterCount( count, __FILE__, __LINE__ ); \ } while( false ) +#define CHECK_PARAMETER_COUNT_MIN(min) \ + do { \ + const int count = vSubArguments.size(); \ + if( count < ( min )) \ + throw InvalidParameterCount( count, __FILE__, __LINE__ ); \ + } while( false ) typedef std::shared_ptr<FormulaTreeNode> FormulaTreeNodeRef; commit 08b0c3b848b8f2bd667fad00068f3c828c709ef5 Author: Luboš Luňák <l.lu...@collabora.com> AuthorDate: Thu Sep 1 13:59:50 2022 +0200 Commit: Luboš Luňák <l.lu...@collabora.com> CommitDate: Tue Sep 6 12:03:50 2022 +0200 fixes to opencl rounding functions Change-Id: I5cd99116a7230b8070051cbf6969a1fdd2f7fe62 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/139196 Tested-by: Jenkins Reviewed-by: Luboš Luňák <l.lu...@collabora.com> diff --git a/sc/source/core/opencl/op_math.cxx b/sc/source/core/opencl/op_math.cxx index 7cb632050aa4..edcc2b940bd6 100644 --- a/sc/source/core/opencl/op_math.cxx +++ b/sc/source/core/opencl/op_math.cxx @@ -1670,27 +1670,28 @@ void OpRoundUp::GenSlidingWindowFunction(outputstream &ss, ss << " int gid0=get_global_id(0);\n"; ss << " int singleIndex = gid0;\n"; ss << " int intTmp;\n"; - ss << " double doubleTmp;\n"; ss << " double tmp;\n"; GenTmpVariables(ss,vSubArguments); CheckAllSubArgumentIsNan(ss,vSubArguments); if( vSubArguments.size() == 1 ) ss << " double tmp1 = 0;\n"; - ss << " if(tmp1 >20 || tmp1 < -20)"; + ss << " int shift = (int)tmp1;\n"; + ss << " if(shift >20 || shift < -20)"; ss << " {\n"; ss << " tmp = NAN;\n"; ss << " }else\n"; ss << " {\n"; - ss << " for(int i=0;i<tmp1;i++)\n"; - ss << " tmp0 = tmp0 * 10;\n"; - ss << " intTmp = (int)tmp0;\n"; - ss << " doubleTmp = intTmp;\n"; - ss << " if(isequal(doubleTmp,tmp0))\n"; - ss << " tmp = doubleTmp;\n"; + ss << " double multiply = 1.0;\n"; + ss << " for(int i=0;i<shift;i++)\n"; + ss << " multiply *= 10;\n"; + ss << " for(int i=0;i>shift;i--)\n"; + ss << " multiply /= 10;\n"; + ss << " intTmp = (int)(tmp0*multiply);\n"; + ss << " if(tmp0 >= 0)\n"; + ss << " tmp = intTmp + 1;\n"; ss << " else\n"; - ss << " tmp = doubleTmp + 1;\n"; - ss << " for(int i=0;i<tmp1;i++)\n"; - ss << " tmp = tmp / 10;\n"; + ss << " tmp = intTmp - 1;\n"; + ss << " tmp /= multiply;\n"; ss << " }\n"; ss << " return tmp;\n"; ss << "}"; @@ -1716,17 +1717,20 @@ void OpRoundDown::GenSlidingWindowFunction(outputstream &ss, CheckAllSubArgumentIsNan(ss,vSubArguments); if( vSubArguments.size() == 1 ) ss << " double tmp1 = 0;\n"; - ss << " if(tmp1 >20 || tmp1 < -20)"; + ss << " int shift = (int)tmp1;\n"; + ss << " if(shift >20 || shift < -20)"; ss << " {\n"; ss << " tmp = NAN;\n"; ss << " }else\n"; ss << " {\n"; - ss << " for(int i=0;i<tmp1;i++)\n"; - ss << " tmp0 = tmp0 * 10;\n"; - ss << " intTmp = (int)tmp0;\n"; + ss << " double multiply = 1.0;\n"; + ss << " for(int i=0;i<shift;i++)\n"; + ss << " multiply *= 10;\n"; + ss << " for(int i=0;i>shift;i--)\n"; + ss << " multiply /= 10;\n"; + ss << " intTmp = (int)(tmp0*multiply);\n"; ss << " tmp = intTmp;\n"; - ss << " for(int i=0;i<tmp1;i++)\n"; - ss << " tmp = tmp / 10;\n"; + ss << " tmp /= multiply;\n"; ss << " }\n"; ss << " return tmp;\n"; ss << "}"; @@ -1750,6 +1754,12 @@ void OpInt::GenSlidingWindowFunction(outputstream &ss, GenTmpVariables(ss,vSubArguments); CheckAllSubArgumentIsNan(ss,vSubArguments); ss << " intTmp = (int)tmp0;\n"; + // check whether rounding error caused the float to be just less than the int value + ss << " if( tmp0 >=0 && approx_equal( intTmp + 1, tmp0 ))\n"; + ss << " ++intTmp;\n"; + // negative values are rounded down + ss << " if( tmp0 < 0 && !approx_equal( intTmp, tmp0 ))\n"; + ss << " --intTmp;\n"; ss << " tmp = intTmp;\n"; ss << " return tmp;\n"; ss << "}"; @@ -2173,6 +2183,11 @@ void OpTrunc::GenSlidingWindowFunction(outputstream &ss, ss << " argm = argm * 10;\n"; ss << " nn = nn * 10;\n"; ss << " }\n"; + ss << " for(int i = 0; i > n; --i)\n"; + ss << " {\n"; + ss << " argm = argm / 10;\n"; + ss << " nn = nn / 10;\n"; + ss << " }\n"; ss << " modf(argm, &argm);\n"; ss << " return argm / nn;\n"; ss << "}"; @@ -2207,7 +2222,9 @@ void OpFloor::GenSlidingWindowFunction( ss << " if(isnan(arg2))\n"; ss << " arg2 = 0.0;\n"; ss << " if(arg0*arg1<0)\n"; - ss << " return NAN;\n"; + ss << " return CreateDoubleError(IllegalArgument);\n"; + ss << " if(arg1 == 0.0)\n"; + ss << " return 0.0;\n"; ss << " else if(arg2==0.0&&arg0<0.0)\n"; ss << " return (trunc(arg0/arg1)+1)*arg1;\n"; ss << " else\n"; @@ -2574,6 +2591,8 @@ void OpCeil::GenSlidingWindowFunction(outputstream &ss, ss << " else\n "; ss << " bAbs = "<<vSubArguments[2]->GenSlidingWindowDeclRef()<<";\n"; } + ss << " if(num*significance < 0.0)\n"; + ss << " return CreateDoubleError(IllegalArgument);\n"; ss << " if(significance == 0.0)\n"; ss << " return 0.0;\n"; ss << " return ";