From c854d958d440e58e473d329595a5fccba235c150 Mon Sep 17 00:00:00 2001 From: Patrick Damme Date: Fri, 12 Jul 2024 00:41:05 +0200 Subject: [PATCH] Minor improvements. - Renamed the new category of unary ops to "Comparison". - Removed special floating-point values like nan and inf from test cases with integer value types. - Removed comment on missing isNan() from guidelines on porting from Numpy to DaphneLib. - Some more minor changes. --- doc/DaphneDSL/Builtins.md | 6 +++--- doc/DaphneLib/APIRef.md | 1 + doc/DaphneLib/Numpy2DaphneLib.md | 2 -- src/api/python/daphne/operator/nodes/matrix.py | 6 +++--- src/ir/daphneir/DaphneOps.td | 7 ++++++- src/parser/daphnedsl/DaphneDSLBuiltins.cpp | 4 ++-- src/runtime/local/kernels/EwUnarySca.h | 4 ++-- src/runtime/local/kernels/UnaryOpCode.h | 2 +- test/api/cli/operations/OperationsTest.cpp | 4 ++-- test/api/python/matrix_ewunary.daphne | 4 +++- test/api/python/matrix_ewunary.py | 5 ++++- test/api/python/scalar_ewunary.daphne | 4 +++- test/api/python/scalar_ewunary.py | 5 ++++- test/runtime/local/kernels/EwUnaryMatTest.cpp | 13 +++---------- test/runtime/local/kernels/EwUnaryScaTest.cpp | 7 ++----- 15 files changed, 39 insertions(+), 35 deletions(-) diff --git a/doc/DaphneDSL/Builtins.md b/doc/DaphneDSL/Builtins.md index 917458201..59360a724 100644 --- a/doc/DaphneDSL/Builtins.md +++ b/doc/DaphneDSL/Builtins.md @@ -143,11 +143,11 @@ The following built-in functions all follow the same scheme: | **`floor`** | round down | | **`ceil`** | round up | -### Other Utilities +### Comparison | function | meaning | -| ----- | -------------------------------------- | -|**`isNan`**| returns 1 if argument is nan, 0 otherwise | +| ----- | ----- | +| **`isNan`** | `1` if argument is NaN, `0` otherwise | ## Elementwise binary diff --git a/doc/DaphneLib/APIRef.md b/doc/DaphneLib/APIRef.md index 18aa566c2..584831e16 100644 --- a/doc/DaphneLib/APIRef.md +++ b/doc/DaphneLib/APIRef.md @@ -223,6 +223,7 @@ In the following, we describe only the latter. - **`sinh`**`()` - **`cosh`**`()` - **`tanh`**`()` +- **`isNan`**`()` **Elementwise binary:** diff --git a/doc/DaphneLib/Numpy2DaphneLib.md b/doc/DaphneLib/Numpy2DaphneLib.md index 0c1436a7d..3267adfe5 100644 --- a/doc/DaphneLib/Numpy2DaphneLib.md +++ b/doc/DaphneLib/Numpy2DaphneLib.md @@ -216,8 +216,6 @@ Porting for other Numpy versions may be possible by following similar lines of t - `numpy.`**`isnan`**`(x, /, out=None, *, where=True, casting='same_kind', order='K', dtype=None, subok=True[, signature]) = ` - *Note: `isNan()` is not supported in DAPHNE yet (see #768).* - *Parameters* - `x`: supported diff --git a/src/api/python/daphne/operator/nodes/matrix.py b/src/api/python/daphne/operator/nodes/matrix.py index 5c78a6ac2..c69b37081 100644 --- a/src/api/python/daphne/operator/nodes/matrix.py +++ b/src/api/python/daphne/operator/nodes/matrix.py @@ -193,10 +193,10 @@ def sqrt(self) -> 'OperationNode': return Matrix(self.daphne_context,'sqrt', [self]) def isNan(self) -> 'OperationNode': - """Checks if argument is of type Nan. Returns 1 if argument is Nan, 0 otherwise. - :return: `Matrix` representing operation + """Elementwise check for NaN values in this matrix (resulting in 1 if the element is NaN, 0 otherwise). + :return: `Matrix` A node representing the isNan operation. """ - return Matrix(self.daphne_context,'isNan', [self]) + return Matrix(self.daphne_context, 'isNan', [self]) def round(self) -> 'OperationNode': return Matrix(self.daphne_context, 'round', [self]) diff --git a/src/ir/daphneir/DaphneOps.td b/src/ir/daphneir/DaphneOps.td index e1b5e7519..471c1ba9a 100644 --- a/src/ir/daphneir/DaphneOps.td +++ b/src/ir/daphneir/DaphneOps.td @@ -215,7 +215,6 @@ def Daphne_EwSignOp : Daphne_EwUnaryOp<"ewSign", NumScalar, [ValueTypeFromFirstA def Daphne_EwExpOp : Daphne_EwUnaryOp<"ewExp", NumScalar, [ValueTypeFromArgsFP]>; def Daphne_EwLnOp : Daphne_EwUnaryOp<"ewLn", NumScalar, [ValueTypeFromArgsFP]>; def Daphne_EwSqrtOp : Daphne_EwUnaryOp<"ewSqrt", NumScalar, [ValueTypeFromArgsFP, DeclareOpInterfaceMethods]>; -def Daphne_EwIsNanOp : Daphne_EwUnaryOp<"ewIsnan", NumScalar, [ValueTypeFromFirstArg]>; // ---------------------------------------------------------------------------- // Logical @@ -245,6 +244,12 @@ def Daphne_EwAsinOp : Daphne_EwUnaryOp<"ewAsin", NumScalar, [ValueTypeFromArgsFP def Daphne_EwAcosOp : Daphne_EwUnaryOp<"ewAcos", NumScalar, [ValueTypeFromArgsFP]>; def Daphne_EwAtanOp : Daphne_EwUnaryOp<"ewAtan", NumScalar, [ValueTypeFromArgsFP]>; +// ---------------------------------------------------------------------------- +// Comparison +// ---------------------------------------------------------------------------- + +def Daphne_EwIsNanOp : Daphne_EwUnaryOp<"ewIsnan", NumScalar, [ValueTypeFromFirstArg]>; + // **************************************************************************** // Elementwise binary // **************************************************************************** diff --git a/src/parser/daphnedsl/DaphneDSLBuiltins.cpp b/src/parser/daphnedsl/DaphneDSLBuiltins.cpp index e6f0831a8..3c1b3179a 100644 --- a/src/parser/daphnedsl/DaphneDSLBuiltins.cpp +++ b/src/parser/daphnedsl/DaphneDSLBuiltins.cpp @@ -521,12 +521,12 @@ antlrcpp::Any DaphneDSLBuiltins::build(mlir::Location loc, const std::string & f return createUnaryOp(loc, func, args); // -------------------------------------------------------------------- - // Other Utility Functions + // Comparison // -------------------------------------------------------------------- + if (func == "isNan") return createUnaryOp(loc, func, args); - // ******************************************************************** // Elementwise binary // ******************************************************************** diff --git a/src/runtime/local/kernels/EwUnarySca.h b/src/runtime/local/kernels/EwUnarySca.h index 59d97bf7a..eb90e0b44 100644 --- a/src/runtime/local/kernels/EwUnarySca.h +++ b/src/runtime/local/kernels/EwUnarySca.h @@ -81,7 +81,7 @@ EwUnaryScaFuncPtr getEwUnaryScaFuncPtr(UnaryOpCode opCode) { MAKE_CASE(UnaryOpCode::FLOOR) MAKE_CASE(UnaryOpCode::CEIL) MAKE_CASE(UnaryOpCode::ROUND) - // Other utilities + // Comparison. MAKE_CASE(UnaryOpCode::ISNAN) #undef MAKE_CASE default: @@ -169,7 +169,7 @@ MAKE_EW_UNARY_SCA(UnaryOpCode::TANH, tanh(arg)); MAKE_EW_UNARY_SCA(UnaryOpCode::FLOOR, floor(arg)); MAKE_EW_UNARY_SCA(UnaryOpCode::CEIL, std::ceil(arg)); MAKE_EW_UNARY_SCA(UnaryOpCode::ROUND, round(arg)); -// Other Utilities +// Comparison. MAKE_EW_UNARY_SCA(UnaryOpCode::ISNAN, std::isnan(arg)); #undef MAKE_EW_UNARY_SCA_CLOSED_DOMAIN_ERROR diff --git a/src/runtime/local/kernels/UnaryOpCode.h b/src/runtime/local/kernels/UnaryOpCode.h index 2e0c79640..ecb518ac3 100644 --- a/src/runtime/local/kernels/UnaryOpCode.h +++ b/src/runtime/local/kernels/UnaryOpCode.h @@ -41,7 +41,7 @@ enum class UnaryOpCode { FLOOR, CEIL, ROUND, - // Other Utilities + // Comparison. ISNAN }; diff --git a/test/api/cli/operations/OperationsTest.cpp b/test/api/cli/operations/OperationsTest.cpp index 5bce5b9d5..c968fb4e0 100644 --- a/test/api/cli/operations/OperationsTest.cpp +++ b/test/api/cli/operations/OperationsTest.cpp @@ -43,6 +43,7 @@ MAKE_TEST_CASE("ctable", 1) MAKE_TEST_CASE("gemv", 1) MAKE_TEST_CASE("idxMax", 1) MAKE_TEST_CASE("idxMin", 1) +MAKE_TEST_CASE("isNan", 1) MAKE_TEST_CASE("mean", 1) MAKE_TEST_CASE("operator_at", 2) MAKE_TEST_CASE("operator_eq", 2) @@ -58,5 +59,4 @@ MAKE_TEST_CASE("seq", 2) MAKE_TEST_CASE("solve", 1) MAKE_TEST_CASE("sqrt", 1) MAKE_TEST_CASE("sum", 1) -MAKE_TEST_CASE("syrk", 1) -MAKE_TEST_CASE("isNan", 1) \ No newline at end of file +MAKE_TEST_CASE("syrk", 1) \ No newline at end of file diff --git a/test/api/python/matrix_ewunary.daphne b/test/api/python/matrix_ewunary.daphne index 556341207..4cc8a828c 100644 --- a/test/api/python/matrix_ewunary.daphne +++ b/test/api/python/matrix_ewunary.daphne @@ -39,4 +39,6 @@ print(atan(m)); print(sinh(m)); print(cosh(m)); print(tanh(m)); -print(isNan(m)); \ No newline at end of file + +print(isNan(m)); +print(isNan([nan])); \ No newline at end of file diff --git a/test/api/python/matrix_ewunary.py b/test/api/python/matrix_ewunary.py index de96b19f8..f0d15504f 100644 --- a/test/api/python/matrix_ewunary.py +++ b/test/api/python/matrix_ewunary.py @@ -13,6 +13,7 @@ # limitations under the License. from daphne.context.daphne_context import DaphneContext +import math dc = DaphneContext() @@ -43,4 +44,6 @@ m.sinh().print().compute() m.cosh().print().compute() m.tanh().print().compute() -m.isNan().print().compute() \ No newline at end of file + +m.isNan().print().compute() +dc.fill(math.nan, 1, 1).isNan().print().compute() \ No newline at end of file diff --git a/test/api/python/scalar_ewunary.daphne b/test/api/python/scalar_ewunary.daphne index bf4244acb..626de18a6 100644 --- a/test/api/python/scalar_ewunary.daphne +++ b/test/api/python/scalar_ewunary.daphne @@ -39,4 +39,6 @@ print(atan(s)); print(sinh(s)); print(cosh(s)); print(tanh(s)); -print(isNan(s)); \ No newline at end of file + +print(isNan(s)); +print(isNan(nan)); \ No newline at end of file diff --git a/test/api/python/scalar_ewunary.py b/test/api/python/scalar_ewunary.py index 0bcd24286..ddbf7a159 100644 --- a/test/api/python/scalar_ewunary.py +++ b/test/api/python/scalar_ewunary.py @@ -13,6 +13,7 @@ # limitations under the License. from daphne.context.daphne_context import DaphneContext +import math dc = DaphneContext() @@ -46,4 +47,6 @@ s.sum().sinh().print().compute() s.sum().cosh().print().compute() s.sum().tanh().print().compute() -s.sum().isNan().print().compute() \ No newline at end of file + +s.sum().isNan().print().compute() +dc.fill(math.nan, 1, 1).cbind(dc.fill(1.0, 1, 1)).sum().isNan().print().compute() \ No newline at end of file diff --git a/test/runtime/local/kernels/EwUnaryMatTest.cpp b/test/runtime/local/kernels/EwUnaryMatTest.cpp index 77b08ea72..30cd78365 100644 --- a/test/runtime/local/kernels/EwUnaryMatTest.cpp +++ b/test/runtime/local/kernels/EwUnaryMatTest.cpp @@ -549,27 +549,20 @@ TEMPLATE_PRODUCT_TEST_CASE(TEST_NAME("round, floating-point-specific"), TAG_KERN } // **************************************************************************** -// Other Utilities +// Comparison // **************************************************************************** TEMPLATE_PRODUCT_TEST_CASE(TEST_NAME("isNan"), TAG_KERNELS, (DATA_TYPES), (int32_t)) { using DT = TestType; - using VT = typename DT::VT; - auto arg = genGivenVals
(7, { + auto arg = genGivenVals
(4, { 1, - std::numeric_limits::quiet_NaN(), 0, - std::numeric_limits::infinity(), - -std::numeric_limits::infinity(), 99, -99, }); - auto exp = genGivenVals
(7, { - 0, - 0, - 0, + auto exp = genGivenVals
(4, { 0, 0, 0, diff --git a/test/runtime/local/kernels/EwUnaryScaTest.cpp b/test/runtime/local/kernels/EwUnaryScaTest.cpp index 97aa4145a..91dd76215 100644 --- a/test/runtime/local/kernels/EwUnaryScaTest.cpp +++ b/test/runtime/local/kernels/EwUnaryScaTest.cpp @@ -237,18 +237,15 @@ TEMPLATE_TEST_CASE(TEST_NAME("round, floating-point-specific"), TAG_KERNELS, FP_ } // **************************************************************************** -// Other Utilities +// Comparison // **************************************************************************** + TEMPLATE_TEST_CASE(TEST_NAME("isNan"), TAG_KERNELS, SI_VALUE_TYPES) { using VT = TestType; checkEwUnarySca(1, 0); - checkEwUnarySca(std::numeric_limits::quiet_NaN(), 0); - checkEwUnarySca(std::numeric_limits::infinity(), 0); - checkEwUnarySca(-std::numeric_limits::infinity(), 0); checkEwUnarySca(99, 0); checkEwUnarySca(-99, 0); checkEwUnarySca(0, 0); - checkEwUnarySca(std::numeric_limits::denorm_min(), 0); } TEMPLATE_TEST_CASE(TEST_NAME("isNan, floating-point-specific"), TAG_KERNELS, FP_VALUE_TYPES) {