From 8ed7b659c23c81ab1623e9b83c5c07438044ba3e Mon Sep 17 00:00:00 2001 From: 0xd3bs Date: Wed, 4 Oct 2023 16:00:48 -0300 Subject: [PATCH 1/2] feat: add sign --- docs/SUMMARY.md | 3 + docs/framework/compatibility.md | 3 +- docs/framework/numbers/fixed-point/README.md | 1 + docs/framework/numbers/fixed-point/fp.sign.md | 30 +++++++ .../numbers/signed-integer/README.md | 1 + .../numbers/signed-integer/int.sign.md | 29 +++++++ docs/framework/operators/tensor/README.md | 1 + .../framework/operators/tensor/tensor.sign.md | 33 ++++++++ nodegen/node/sign.py | 82 +++++++++++++++++++ src/numbers.cairo | 41 ++++++++++ src/numbers/fixed_point/core.cairo | 33 ++++++++ .../implementations/fp16x16/core.cairo | 4 + .../implementations/fp16x16/math/core.cairo | 40 +++++++++ .../implementations/fp32x32/core.cairo | 4 + .../implementations/fp64x64/core.cairo | 4 + .../implementations/fp8x23/core.cairo | 4 + .../implementations/fp8x23/math/core.cairo | 38 +++++++++ src/numbers/signed_integer/i128.cairo | 13 +++ src/numbers/signed_integer/i16.cairo | 13 +++ src/numbers/signed_integer/i32.cairo | 13 +++ src/numbers/signed_integer/i64.cairo | 13 +++ src/numbers/signed_integer/i8.cairo | 13 +++ .../signed_integer/integer_trait.cairo | 32 ++++++++ src/operators/tensor/core.cairo | 71 +++++++++++++++- .../implementations/tensor_fp16x16.cairo | 4 + .../implementations/tensor_fp32x32.cairo | 4 + .../implementations/tensor_fp64x64.cairo | 4 + .../implementations/tensor_fp8x23.cairo | 4 + .../tensor/implementations/tensor_i32.cairo | 5 ++ .../tensor/implementations/tensor_i8.cairo | 4 + .../tensor/implementations/tensor_u32.cairo | 4 + src/operators/tensor/math.cairo | 3 +- src/operators/tensor/math/sign.cairo | 34 ++++++++ src/tests/nodes.cairo | 5 ++ src/tests/nodes/sign_fP16x16.cairo | 20 +++++ src/tests/nodes/sign_fP16x16/input_0.cairo | 24 ++++++ src/tests/nodes/sign_fP16x16/output_0.cairo | 24 ++++++ src/tests/nodes/sign_fP8x23.cairo | 20 +++++ src/tests/nodes/sign_fP8x23/input_0.cairo | 24 ++++++ src/tests/nodes/sign_fP8x23/output_0.cairo | 24 ++++++ src/tests/nodes/sign_fail.cairo | 21 +++++ src/tests/nodes/sign_fail/input_0.cairo | 23 ++++++ src/tests/nodes/sign_fail/output_0.cairo | 23 ++++++ src/tests/nodes/sign_i32.cairo | 20 +++++ src/tests/nodes/sign_i32/input_0.cairo | 23 ++++++ src/tests/nodes/sign_i32/output_0.cairo | 23 ++++++ src/tests/nodes/sign_i8.cairo | 20 +++++ src/tests/nodes/sign_i8/input_0.cairo | 23 ++++++ src/tests/nodes/sign_i8/output_0.cairo | 23 ++++++ 49 files changed, 922 insertions(+), 3 deletions(-) create mode 100644 docs/framework/numbers/fixed-point/fp.sign.md create mode 100644 docs/framework/numbers/signed-integer/int.sign.md create mode 100644 docs/framework/operators/tensor/tensor.sign.md create mode 100644 nodegen/node/sign.py create mode 100644 src/operators/tensor/math/sign.cairo create mode 100644 src/tests/nodes/sign_fP16x16.cairo create mode 100644 src/tests/nodes/sign_fP16x16/input_0.cairo create mode 100644 src/tests/nodes/sign_fP16x16/output_0.cairo create mode 100644 src/tests/nodes/sign_fP8x23.cairo create mode 100644 src/tests/nodes/sign_fP8x23/input_0.cairo create mode 100644 src/tests/nodes/sign_fP8x23/output_0.cairo create mode 100644 src/tests/nodes/sign_fail.cairo create mode 100644 src/tests/nodes/sign_fail/input_0.cairo create mode 100644 src/tests/nodes/sign_fail/output_0.cairo create mode 100644 src/tests/nodes/sign_i32.cairo create mode 100644 src/tests/nodes/sign_i32/input_0.cairo create mode 100644 src/tests/nodes/sign_i32/output_0.cairo create mode 100644 src/tests/nodes/sign_i8.cairo create mode 100644 src/tests/nodes/sign_i8/input_0.cairo create mode 100644 src/tests/nodes/sign_i8/output_0.cairo diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 405604e46..d975c0f8a 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -17,6 +17,7 @@ * [int.abs](framework/numbers/signed-integer/int.abs.md) * [int.max](framework/numbers/signed-integer/int.max.md) * [int.min](framework/numbers/signed-integer/int.min.md) + * [int.sign](framework/numbers/signed-integer/int.sign.md) * [Fixed Point](framework/numbers/fixed-point/README.md) * [fp.new](framework/numbers/fixed-point/fp.new.md) * [fp.new\_unscaled](framework/numbers/fixed-point/fp.new\_unscaled.md) @@ -34,6 +35,7 @@ * [fp.sqrt](framework/numbers/fixed-point/fp.sqrt.md) * [fp.sin](framework/numbers/fixed-point/fp.sin.md) * [fp.atan](framework/numbers/fixed-point/fp.atan.md) + * [fp.sign](framework/numbers/fixed-point/fp.sign.md) * [Operators](framework/operators/README.md) * [Tensor](framework/operators/tensor/README.md) * [tensor.new](framework/operators/tensor/tensor.new.md) @@ -82,6 +84,7 @@ * [tensor.nonzero](framework/operators/tensor/tensor.nonzero.md) * [tensor.squeeze](framework/operators/tensor/tensor.squeeze.md) * [tensor.unsqueeze](framework/operators/tensor/tensor.unsqueeze.md) + * [tensor.sign](framework/operators/tensor/tensor.sign.md) * [Neural Network](framework/operators/neural-network/README.md) * [nn.relu](framework/operators/neural-network/nn.relu.md) * [nn.leaky\_relu](framework/operators/neural-network/nn.leaky\_relu.md) diff --git a/docs/framework/compatibility.md b/docs/framework/compatibility.md index 73f4a677a..ba4e18166 100644 --- a/docs/framework/compatibility.md +++ b/docs/framework/compatibility.md @@ -55,5 +55,6 @@ You can see below the list of current supported ONNX Operators: | [Nonzero](operators/tensor/tensor.nonzero.md) | :white\_check\_mark: | | [Squeeze](operators/tensor/tensor.squeeze.md) | :white\_check\_mark: | | [Unsqueeze](operators/tensor/tensor.unsqueeze.md) | :white\_check\_mark: | +| [Sign](operators/tensor/tensor.sign.md) | :white\_check\_mark: | -Current Operators support: **49/156 (31%)** +Current Operators support: **51/156 (33%)** diff --git a/docs/framework/numbers/fixed-point/README.md b/docs/framework/numbers/fixed-point/README.md index 805c37813..f30122676 100644 --- a/docs/framework/numbers/fixed-point/README.md +++ b/docs/framework/numbers/fixed-point/README.md @@ -68,6 +68,7 @@ use orion::numbers::fixed_point::core::FixedTrait; | [`fp.cosh`](fp.cosh.md) | Returns the value of the hyperbolic cosine of the fixed point number. | | [`fp.sinh`](fp.sinh.md) | Returns the value of the hyperbolic sine of the fixed point number. | | [`fp.tanh`](fp.tanh.md) | Returns the value of the hyperbolic tangent of the fixed point number. | +| [`fp.sign`](fp.sign.md) | Returns the element-wise indication of the sign of the input fixed point number. | ### Arithmetic & Comparison operators diff --git a/docs/framework/numbers/fixed-point/fp.sign.md b/docs/framework/numbers/fixed-point/fp.sign.md new file mode 100644 index 000000000..3187de3a1 --- /dev/null +++ b/docs/framework/numbers/fixed-point/fp.sign.md @@ -0,0 +1,30 @@ +# fp.sign + +```rust +fn sign(self: T) -> T; +``` + +Returns the element-wise indication of the sign of the input fixed point number. + +## Args + +* `self`(`T`) - The input fixed point + +## Returns + +The element-wise indication of the sign of the input fixed point number. + +## Examples + +```rust +use orion::numbers::{FP16x16, FP16x16Impl, FixedTrait}; + +fn sign_fp_example() -> FP16x16 { + // We instantiate fixed point here. + let fp = FixedTrait::new_unscaled(2, true); + + // We can call `sign` function as follows. + fp.sign() +} +>>> {mag: 65536, sign: true} // = -1 +``` diff --git a/docs/framework/numbers/signed-integer/README.md b/docs/framework/numbers/signed-integer/README.md index 64c714bf8..2ae0a6c5e 100644 --- a/docs/framework/numbers/signed-integer/README.md +++ b/docs/framework/numbers/signed-integer/README.md @@ -43,6 +43,7 @@ use orion::numbers::signed_integer::IntegerTrait; | [`int.abs`](int.abs.md) | Computes the absolute value of the given `signed_integer` | | [`int.max`](int.max.md) | Returns the maximum between two `signed_integer` | | [`int.min`](int.min.md) | Returns the minimum between two `signed_integer` | +| [`int.sign`](int.sign.md) | Returns an element-wise indication of the given `signed_integer` | ### Arithmetic & Comparison operators diff --git a/docs/framework/numbers/signed-integer/int.sign.md b/docs/framework/numbers/signed-integer/int.sign.md new file mode 100644 index 000000000..76ad6bb52 --- /dev/null +++ b/docs/framework/numbers/signed-integer/int.sign.md @@ -0,0 +1,29 @@ +# int.sign + +```rust +fn sign(self: T, other: T) -> T; +``` + +Returns an element-wise indication of the given signed_integer. + +## Args + +`self`(`T`) - The input value to which the signed value is applied. + +## Returns + +An element-wise indication of the sign of a number. + +## Examples + + +```rust +fn sign_example() -> i32 { + // We instantiate signed integer here. + let a = IntegerTrait::::new(42, true); + + // We can call `sign` function as follows. + a.sign() +} +>>> {mag: 1, sign: true} +``` diff --git a/docs/framework/operators/tensor/README.md b/docs/framework/operators/tensor/README.md index d99426183..ceb43dcf2 100644 --- a/docs/framework/operators/tensor/README.md +++ b/docs/framework/operators/tensor/README.md @@ -80,6 +80,7 @@ use orion::operators::tensor::TensorTrait; | [`tensor.nonzero`](tensor.nonzero.md) | Produces indices of the elements that are non-zero (in row-major order - by dimension). | | [`tensor.squeeze`](tensor.squeeze.md) | Removes dimensions of size 1 from the shape of a tensor. | | [`tensor.unsqueeze`](tensor.unsqueeze.md) | Inserts single-dimensional entries to the shape of an input tensor. | +| [`tensor.sign`](tensor.sign.md) | Calculates the sign of the given input tensor element-wise. | ## Arithmetic Operations diff --git a/docs/framework/operators/tensor/tensor.sign.md b/docs/framework/operators/tensor/tensor.sign.md new file mode 100644 index 000000000..ef35104f5 --- /dev/null +++ b/docs/framework/operators/tensor/tensor.sign.md @@ -0,0 +1,33 @@ +# tensor.sign + +```rust + fn sign(self: @Tensor) -> Tensor; +``` + +Calculates the sign of the given input tensor element-wise. + +## Args + +* `self`(`@Tensor`) - Tensor of data to calculates the sign of the given input tensor element-wise. + +## Returns + +A new `Tensor` of the same shape as the input tensor with The sign of the input tensor computed element-wise. + +## Example + +```rust +use array::{ArrayTrait, SpanTrait}; + +use orion::operators::tensor::{TensorTrait, Tensor, FP8x23Tensor}; + +fn sign_example() -> Tensor { + let tensor = TensorTrait::::new( + shape: array![11].span(), + data: array![-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5].span(), + ); + + return tensor.sign(); +} +>>> [-1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1] +``` diff --git a/nodegen/node/sign.py b/nodegen/node/sign.py new file mode 100644 index 000000000..a9003f342 --- /dev/null +++ b/nodegen/node/sign.py @@ -0,0 +1,82 @@ +import numpy as np +from nodegen.node import RunAll +from ..helpers import make_node, make_test, to_fp, Tensor, Dtype, FixedImpl + +class Sign(RunAll): + @staticmethod + def sign_i8(): + def sign(): + x = np.array(range(-5, 6)).astype(np.int8) + y = np.array([-1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1]).astype(np.int8) + + x = Tensor(Dtype.I8, x.shape, x.flatten()) + y = Tensor(Dtype.I8, y.shape, y.flatten()) + + name = "sign_i8" + make_node([x], [y], name) + make_test( + [x], y, "input_0.sign()", name) + sign() + + @staticmethod + def sign_i32(): + def sign(): + x = np.array(range(-5, 6)).astype(np.int32) + y = np.array([-1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1]).astype(np.int32) + + x = Tensor(Dtype.I32, x.shape, x.flatten()) + y = Tensor(Dtype.I32, y.shape, y.flatten()) + + name = "sign_i32" + make_node([x], [y], name) + make_test( + [x], y, "input_0.sign()", name) + sign() + + @staticmethod + def sign_fail(): + def sign(): + + x = np.array(range(-5, 6)).astype(np.int32) + y = np.array([1, -1, -1, -1, -1, 0, 1, 1, 1, 1, -1]).astype(np.int32) + + x = Tensor(Dtype.I32, x.shape, x.flatten()) + y = Tensor(Dtype.I32, y.shape, y.flatten()) + + name = "sign_fail" + make_node([x], [y], name) + make_test( + [x], y, "input_0.sign()", name) + sign() + + @staticmethod + def sign_fP16x16(): + def sign(): + + x = to_fp (np.array(range(-5, 6)).astype(np.int64), FixedImpl.FP16x16) + y = to_fp (np.array([-1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1]).astype(np.int64), FixedImpl.FP16x16) + + x = Tensor(Dtype.FP16x16, x.shape, x.flatten()) + y = Tensor(Dtype.FP16x16, y.shape, y.flatten()) + + name = "sign_fP16x16" + make_node([x], [y], name) + make_test( + [x], y, "input_0.sign()", name) + sign() + + @staticmethod + def sign_fP8x23(): + def sign(): + + x = to_fp (np.array(range(-5, 6)).astype(np.int64), FixedImpl.FP8x23) + y = to_fp (np.array([-1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1]).astype(np.int64), FixedImpl.FP8x23) + + x = Tensor(Dtype.FP8x23, x.shape, x.flatten()) + y = Tensor(Dtype.FP8x23, y.shape, y.flatten()) + + name = "sign_fP8x23" + make_node([x], [y], name) + make_test( + [x], y, "input_0.sign()", name) + sign() \ No newline at end of file diff --git a/src/numbers.cairo b/src/numbers.cairo index b8fc69cb8..51def1c68 100644 --- a/src/numbers.cairo +++ b/src/numbers.cairo @@ -45,6 +45,7 @@ trait NumberTrait { fn is_neg(self: T) -> bool; fn xor(lhs: T, rhs: T) -> bool; fn or(lhs: T, rhs: T) -> bool; + fn sign(self: T) -> T; } use orion::numbers::fixed_point::implementations::fp8x23::core::{FP8x23Impl, FP8x23}; @@ -206,6 +207,10 @@ impl FP8x23Number of NumberTrait { fn or(lhs: FP8x23, rhs: FP8x23) -> bool { comp_fp8x23::or(lhs, rhs) } + + fn sign(self: FP8x23) -> FP8x23 { + core_fp8x23::sign(self) + } } use orion::numbers::fixed_point::implementations::fp16x16::core::{FP16x16Impl, FP16x16}; @@ -367,6 +372,10 @@ impl FP16x16Number of NumberTrait { fn or(lhs: FP16x16, rhs: FP16x16) -> bool { comp_fp16x16::or(lhs, rhs) } + + fn sign(self: FP16x16) -> FP16x16 { + core_fp16x16::sign(self) + } } use orion::numbers::fixed_point::implementations::fp64x64::core::{FP64x64Impl, FP64x64}; @@ -529,6 +538,10 @@ impl FP64x64Number of NumberTrait { fn or(lhs: FP64x64, rhs: FP64x64) -> bool { comp_fp64x64::or(lhs, rhs) } + + fn sign(self: FP64x64) -> FP64x64 { + FP64x64Impl::sign(self) + } } use orion::numbers::fixed_point::implementations::fp32x32::core::{FP32x32Impl, FP32x32}; @@ -691,6 +704,10 @@ impl FP32x32Number of NumberTrait { fn or(lhs: FP32x32, rhs: FP32x32) -> bool { comp_fp32x32::or(lhs, rhs) } + + fn sign(self: FP32x32) -> FP32x32 { + FP32x32Impl::sign(self) + } } use orion::numbers::signed_integer::i8 as i8_core; @@ -859,6 +876,10 @@ impl I8Number of NumberTrait { return true; } } + + fn sign(self: i8) -> i8 { + i8_core::i8_sign(self) + } } use orion::numbers::signed_integer::i16 as i16_core; @@ -1027,6 +1048,10 @@ impl i16Number of NumberTrait { return true; } } + + fn sign(self: i16) -> i16 { + i16_core::i16_sign(self) + } } use orion::numbers::signed_integer::i32 as i32_core; @@ -1195,6 +1220,10 @@ impl i32Number of NumberTrait { return true; } } + + fn sign(self: i32) -> i32 { + i32_core::i32_sign(self) + } } use orion::numbers::signed_integer::i64 as i64_core; @@ -1363,6 +1392,10 @@ impl i64Number of NumberTrait { return true; } } + + fn sign(self: i64) -> i64 { + i64_core::i64_sign(self) + } } use orion::numbers::signed_integer::i128 as i128_core; @@ -1532,6 +1565,10 @@ impl i128Number of NumberTrait { return true; } } + + fn sign(self: i128) -> i128 { + i128_core::i128_sign(self) + } } impl u32Number of NumberTrait { @@ -1706,4 +1743,8 @@ impl u32Number of NumberTrait { return true; } } + + fn sign(self: u32) -> u32 { + panic(array!['not supported!']) + } } diff --git a/src/numbers/fixed_point/core.cairo b/src/numbers/fixed_point/core.cairo index 8b33980c8..2aefbc4a7 100644 --- a/src/numbers/fixed_point/core.cairo +++ b/src/numbers/fixed_point/core.cairo @@ -33,6 +33,7 @@ /// cosh - Returns the value of the hyperbolic cosine of the fixed point number. /// sinh - Returns the value of the hyperbolic sine of the fixed point number. /// tanh - Returns the value of the hyperbolic tangent of the fixed point number. +/// sign - Returns the element-wise indication of the sign of the input fixed point number. /// trait FixedTrait { /// # FixedTrait::new @@ -1066,6 +1067,38 @@ trait FixedTrait { /// ``` /// fn tanh(self: T) -> T; + /// # fp.sign + /// + /// ```rust + /// fn sign(self: T) -> T; + /// ``` + /// + /// Returns the element-wise indication of the sign of the input fixed point number. + /// + /// ## Args + /// + /// * `self`(`T`) - The input fixed point + /// + /// ## Returns + /// + /// The element-wise indication of the sign of the input fixed point number. + /// + /// ## Examples + /// + /// ```rust + /// use orion::numbers::{FP16x16, FP16x16Impl, FixedTrait}; + /// + /// fn sign_fp_example() -> FP16x16 { + /// // We instantiate fixed point here. + /// let fp = FixedTrait::new_unscaled(2, true); + /// + /// // We can call `sign` function as follows. + /// fp.sign() + /// } + /// >>> {mag: 65536, sign: true} // = -1 + /// ``` + /// + fn sign(self: T) -> T; fn ZERO() -> T; fn ONE() -> T; diff --git a/src/numbers/fixed_point/implementations/fp16x16/core.cairo b/src/numbers/fixed_point/implementations/fp16x16/core.cairo index 8e41df649..e6a472489 100644 --- a/src/numbers/fixed_point/implementations/fp16x16/core.cairo +++ b/src/numbers/fixed_point/implementations/fp16x16/core.cairo @@ -178,6 +178,10 @@ impl FP16x16Impl of FixedTrait { fn tanh(self: FP16x16) -> FP16x16 { return hyp::tanh(self); } + + fn sign(self: FP16x16) -> FP16x16 { + return core::sign(self); + } } diff --git a/src/numbers/fixed_point/implementations/fp16x16/math/core.cairo b/src/numbers/fixed_point/implementations/fp16x16/math/core.cairo index db517475c..3e6608484 100644 --- a/src/numbers/fixed_point/implementations/fp16x16/math/core.cairo +++ b/src/numbers/fixed_point/implementations/fp16x16/math/core.cairo @@ -282,6 +282,16 @@ fn sub(a: FP16x16, b: FP16x16) -> FP16x16 { return add(a, -b); } +fn sign(a: FP16x16) -> FP16x16 { + + if a.mag == 0 { + FixedTrait::new(0, false) + } + else { + FixedTrait::new(ONE, a.sign) + } +} + // Tests -------------------------------------------------------------------------------------------------------------- use orion::numbers::fixed_point::implementations::fp16x16::helpers::{ @@ -622,3 +632,33 @@ fn test_tan() { let a = FixedTrait::::new(HALF_PI / 2, false); assert(a.tan().mag == 65536, 'invalid quarter pi'); } + +#[test] +#[available_gas(2000000)] +fn test_sign() { + + let a = FixedTrait::::new(0, false); + assert(a.sign().mag == 0 && !a.sign().sign, 'invalid sign (0, true)'); + + let a = FixedTrait::::new(HALF, true); + assert(a.sign().mag == ONE && a.sign().sign, 'invalid sign (HALF, true)'); + + let a = FixedTrait::::new(HALF, false); + assert(a.sign().mag == ONE && !a.sign().sign, 'invalid sign (HALF, false)'); + + + let a = FixedTrait::::new(ONE, true); + assert(a.sign().mag == ONE && a.sign().sign, 'invalid sign (ONE, true)'); + + let a = FixedTrait::::new(ONE, false); + assert(a.sign().mag == ONE && !a.sign().sign, 'invalid sign (ONE, false)'); + +} + +#[test] +#[should_panic] +#[available_gas(2000000)] +fn test_sign_fail() { + let a = FixedTrait::::new(HALF, true); + assert(a.sign().mag != ONE && !a.sign().sign, 'invalid sign (HALF, true)'); +} \ No newline at end of file diff --git a/src/numbers/fixed_point/implementations/fp32x32/core.cairo b/src/numbers/fixed_point/implementations/fp32x32/core.cairo index 3d06ed815..ce7652984 100644 --- a/src/numbers/fixed_point/implementations/fp32x32/core.cairo +++ b/src/numbers/fixed_point/implementations/fp32x32/core.cairo @@ -169,6 +169,10 @@ impl FP32x32Impl of FixedTrait { fn tanh(self: FP32x32) -> FP32x32 { return fp32x32::hyp::tanh(self); } + + fn sign(self: FP32x32) -> FP32x32 { + panic(array!['not supported!']) + } } diff --git a/src/numbers/fixed_point/implementations/fp64x64/core.cairo b/src/numbers/fixed_point/implementations/fp64x64/core.cairo index f019400f6..bb62732e3 100644 --- a/src/numbers/fixed_point/implementations/fp64x64/core.cairo +++ b/src/numbers/fixed_point/implementations/fp64x64/core.cairo @@ -167,6 +167,10 @@ impl FP64x64Impl of FixedTrait { fn tanh(self: FP64x64) -> FP64x64 { return fp64x64::hyp::tanh(self); } + + fn sign(self: FP64x64) -> FP64x64 { + panic(array!['not supported!']) + } } diff --git a/src/numbers/fixed_point/implementations/fp8x23/core.cairo b/src/numbers/fixed_point/implementations/fp8x23/core.cairo index ffb1e479c..532730acf 100644 --- a/src/numbers/fixed_point/implementations/fp8x23/core.cairo +++ b/src/numbers/fixed_point/implementations/fp8x23/core.cairo @@ -178,6 +178,10 @@ impl FP8x23Impl of FixedTrait { fn tanh(self: FP8x23) -> FP8x23 { return hyp::tanh(self); } + + fn sign(self: FP8x23) -> FP8x23 { + return core::sign(self); + } } diff --git a/src/numbers/fixed_point/implementations/fp8x23/math/core.cairo b/src/numbers/fixed_point/implementations/fp8x23/math/core.cairo index 82bfda0b9..4b72b3da9 100644 --- a/src/numbers/fixed_point/implementations/fp8x23/math/core.cairo +++ b/src/numbers/fixed_point/implementations/fp8x23/math/core.cairo @@ -283,6 +283,16 @@ fn sub(a: FP8x23, b: FP8x23) -> FP8x23 { return add(a, -b); } +fn sign(a: FP8x23) -> FP8x23 { + + if a.mag == 0 { + FixedTrait::new(0, false) + } + else { + FixedTrait::new(ONE, a.sign) + } +} + // Tests -------------------------------------------------------------------------------------------------------------- use orion::numbers::fixed_point::implementations::fp8x23::helpers::{ @@ -623,3 +633,31 @@ fn test_tan() { let a = FixedTrait::::new(HALF_PI / 2, false); assert(a.tan().mag == 8388608, 'invalid quarter pi'); } + +#[test] +#[available_gas(2000000)] +fn test_sign() { + let a = FixedTrait::::new(0, false); + assert(a.sign().mag == 0 && !a.sign().sign, 'invalid sign (0, true)'); + + let a = FixedTrait::::new(HALF, true); + assert(a.sign().mag == ONE && a.sign().sign, 'invalid sign (HALF, true)'); + + let a = FixedTrait::::new(HALF, false); + assert(a.sign().mag == ONE && !a.sign().sign, 'invalid sign (HALF, false)'); + + + let a = FixedTrait::::new(ONE, true); + assert(a.sign().mag == ONE && a.sign().sign, 'invalid sign (ONE, true)'); + + let a = FixedTrait::::new(ONE, false); + assert(a.sign().mag == ONE && !a.sign().sign, 'invalid sign (ONE, false)'); +} + +#[test] +#[should_panic] +#[available_gas(2000000)] +fn test_sign_fail() { + let a = FixedTrait::::new(HALF, true); + assert(a.sign().mag != ONE && !a.sign().sign, 'invalid sign (HALF, true)'); +} \ No newline at end of file diff --git a/src/numbers/signed_integer/i128.cairo b/src/numbers/signed_integer/i128.cairo index 865ebbc45..3866e7da0 100644 --- a/src/numbers/signed_integer/i128.cairo +++ b/src/numbers/signed_integer/i128.cairo @@ -33,6 +33,10 @@ impl i128Impl of IntegerTrait { fn min(self: i128, other: i128) -> i128 { i128_min(self, other) } + + fn sign(self: i128) -> i128 { + i128_sign(self) + } } // Implements the Into trait for i128. @@ -457,3 +461,12 @@ fn ensure_non_negative_zero(mag: u128, sign: bool) -> i128 { IntegerTrait::::new(mag, sign) } } + +fn i128_sign(a: i128) -> i128 { + if a.mag == 0 { + IntegerTrait::::new(0, false) + } + else { + IntegerTrait::::new(1, a.sign) + } +} \ No newline at end of file diff --git a/src/numbers/signed_integer/i16.cairo b/src/numbers/signed_integer/i16.cairo index 7dbbe0d5b..d617ceb89 100644 --- a/src/numbers/signed_integer/i16.cairo +++ b/src/numbers/signed_integer/i16.cairo @@ -33,6 +33,10 @@ impl i16Impl of IntegerTrait { fn min(self: i16, other: i16) -> i16 { i16_min(self, other) } + + fn sign(self: i16) -> i16 { + i16_sign(self) + } } // Implements the Into trait for i16. @@ -457,3 +461,12 @@ fn ensure_non_negative_zero(mag: u16, sign: bool) -> i16 { IntegerTrait::::new(mag, sign) } } + +fn i16_sign(a: i16) -> i16 { + if a.mag == 0 { + IntegerTrait::::new(0, false) + } + else { + IntegerTrait::::new(1, a.sign) + } +} \ No newline at end of file diff --git a/src/numbers/signed_integer/i32.cairo b/src/numbers/signed_integer/i32.cairo index 2434a2963..8a7cdd9ee 100644 --- a/src/numbers/signed_integer/i32.cairo +++ b/src/numbers/signed_integer/i32.cairo @@ -36,6 +36,10 @@ impl i32Impl of IntegerTrait { fn min(self: i32, other: i32) -> i32 { i32_min(self, other) } + + fn sign(self: i32) -> i32 { + i32_sign(self) + } } // Implements the Into trait for i32. @@ -489,3 +493,12 @@ fn ensure_non_negative_zero(mag: u32, sign: bool) -> i32 { IntegerTrait::::new(mag, sign) } } + +fn i32_sign(a: i32) -> i32 { + if a.mag == 0 { + IntegerTrait::::new(0, false) + } + else { + IntegerTrait::::new(1, a.sign) + } +} \ No newline at end of file diff --git a/src/numbers/signed_integer/i64.cairo b/src/numbers/signed_integer/i64.cairo index 27624d6a9..c12cf6dcb 100644 --- a/src/numbers/signed_integer/i64.cairo +++ b/src/numbers/signed_integer/i64.cairo @@ -33,6 +33,10 @@ impl i64Impl of IntegerTrait { fn min(self: i64, other: i64) -> i64 { i64_min(self, other) } + + fn sign(self: i64) -> i64 { + i64_sign(self) + } } // Implements the Into trait for i64. @@ -457,3 +461,12 @@ fn ensure_non_negative_zero(mag: u64, sign: bool) -> i64 { IntegerTrait::::new(mag, sign) } } + +fn i64_sign(a: i64) -> i64 { + if a.mag == 0 { + IntegerTrait::::new(0, false) + } + else { + IntegerTrait::::new(1, a.sign) + } +} \ No newline at end of file diff --git a/src/numbers/signed_integer/i8.cairo b/src/numbers/signed_integer/i8.cairo index 21ff97219..6767da7cb 100644 --- a/src/numbers/signed_integer/i8.cairo +++ b/src/numbers/signed_integer/i8.cairo @@ -39,6 +39,10 @@ impl i8Impl of IntegerTrait { fn min(self: i8, other: i8) -> i8 { i8_min(self, other) } + + fn sign(self: i8) -> i8 { + i8_sign(self) + } } // Implements the Into trait for i8. @@ -534,3 +538,12 @@ fn ensure_non_negative_zero(mag: u8, sign: bool) -> i8 { IntegerTrait::::new(mag, sign) } } + +fn i8_sign(a: i8) -> i8 { + if a.mag == 0 { + IntegerTrait::::new(0, false) + } + else { + IntegerTrait::::new(1, a.sign) + } +} diff --git a/src/numbers/signed_integer/integer_trait.cairo b/src/numbers/signed_integer/integer_trait.cairo index 5f56bc363..5ecb974fe 100644 --- a/src/numbers/signed_integer/integer_trait.cairo +++ b/src/numbers/signed_integer/integer_trait.cairo @@ -5,6 +5,7 @@ /// abs - Computes the absolute value of the given `signed_integer` /// max - Returns the maximum between two `signed_integer` /// min - Returns the minimum between two `signed_integer` +/// sign - Returns an element-wise indication of the given `signed_integer` trait IntegerTrait { /// # IntegerTrait::new /// @@ -177,5 +178,36 @@ trait IntegerTrait { /// ``` /// fn min(self: T, other: T) -> T; + /// # int.sign + /// + /// ```rust + /// fn sign(self: T, other: T) -> T; + /// ``` + /// + /// Returns an element-wise indication of the given signed_integer. + /// + /// ## Args + /// + /// `self`(`T`) - The input value to which the signed value is applied. + /// + /// ## Returns + /// + /// An element-wise indication of the sign of a number. + /// + /// ## Examples + /// + /// + /// ```rust + /// fn sign_example() -> i32 { + /// // We instantiate signed integer here. + /// let a = IntegerTrait::::new(42, true); + /// + /// // We can call `sign` function as follows. + /// a.sign() + /// } + /// >>> {mag: 1, sign: true} + /// ``` + /// + fn sign(self: T) -> T; } diff --git a/src/operators/tensor/core.cairo b/src/operators/tensor/core.cairo index e7eea84e0..637ed3a2f 100644 --- a/src/operators/tensor/core.cairo +++ b/src/operators/tensor/core.cairo @@ -76,6 +76,7 @@ impl TensorSerde, impl TDrop: Drop> of Serde { /// # tensor.new @@ -2597,9 +2598,45 @@ trait TensorTrait { self: @Tensor, axes: Option> ) -> Tensor; + /// # tensor.sign + /// + /// ```rust + /// fn sign(self: @Tensor) -> Tensor; + /// ``` + /// + /// Calculates the sign of the given input tensor element-wise. + /// + /// ## Args + /// + /// * `self`(`@Tensor`) - Tensor of data to calculates the sign of the given input tensor element-wise. + /// + /// ## Returns + /// + /// A new `Tensor` of the same shape as the input tensor with The sign of the input tensor computed element-wise. + /// + /// ## Example + /// + /// ```rust + /// use array::{ArrayTrait, SpanTrait}; + /// + /// use orion::operators::tensor::{TensorTrait, Tensor, FP8x23Tensor}; + /// + /// fn sign_example() -> Tensor { + /// let tensor = TensorTrait::::new( + /// shape: array![11].span(), + /// data: array![-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5].span(), + /// ); + /// + /// return tensor.sign(); + /// } + /// >>> [-1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1] + /// ``` + /// + fn sign( + self: @Tensor + ) -> Tensor; } - /// Cf: TensorTrait::new docstring fn new_tensor(shape: Span, data: Span) -> Tensor { check_shape::(shape, data); @@ -3079,3 +3116,35 @@ fn unsqueeze(self: @Tensor, axes: Span) -> Tensor { return Tensor:: { shape: output_shape.span(), data: *self.data }; } + + +fn sign, + impl TPartialEq: PartialEq, + impl TDrop: Drop, + impl TCopy: Copy, + >(self: @Tensor) -> Tensor { + + let mut sign_data_array: Array = ArrayTrait::new(); + let mut data = *self.data; + + loop { + match data.pop_front() { + Option::Some(data) => { + let sign_data = if *data == NumberTrait::zero() { + NumberTrait::zero() + } else if NumberTrait::is_neg(*data) { + NumberTrait::neg_one() + } + else { + NumberTrait::one() + }; + sign_data_array.append(sign_data); + }, + Option::None(_) => { + break Tensor::{ shape: *self.shape, data: sign_data_array.span() }; + } + }; + } +} \ No newline at end of file diff --git a/src/operators/tensor/implementations/tensor_fp16x16.cairo b/src/operators/tensor/implementations/tensor_fp16x16.cairo index 949487435..c504a050f 100644 --- a/src/operators/tensor/implementations/tensor_fp16x16.cairo +++ b/src/operators/tensor/implementations/tensor_fp16x16.cairo @@ -221,6 +221,10 @@ impl FP16x16Tensor of TensorTrait { fn unsqueeze(self: @Tensor, axes: Span) -> Tensor { core::unsqueeze(self, axes) } + + fn sign(self: @Tensor) -> Tensor { + math::sign::sign(*self) + } } /// Implements addition for `Tensor` using the `Add` trait. diff --git a/src/operators/tensor/implementations/tensor_fp32x32.cairo b/src/operators/tensor/implementations/tensor_fp32x32.cairo index 8b0abb387..307b6d3ad 100644 --- a/src/operators/tensor/implementations/tensor_fp32x32.cairo +++ b/src/operators/tensor/implementations/tensor_fp32x32.cairo @@ -222,6 +222,10 @@ impl FP32x32Tensor of TensorTrait { fn unsqueeze(self: @Tensor, axes: Span) -> Tensor { core::unsqueeze(self, axes) } + + fn sign(self: @Tensor) -> Tensor { + math::sign::sign(*self) + } } /// Implements addition for `Tensor` using the `Add` trait. diff --git a/src/operators/tensor/implementations/tensor_fp64x64.cairo b/src/operators/tensor/implementations/tensor_fp64x64.cairo index f5cedc039..9f8852cae 100644 --- a/src/operators/tensor/implementations/tensor_fp64x64.cairo +++ b/src/operators/tensor/implementations/tensor_fp64x64.cairo @@ -222,6 +222,10 @@ impl FP64x64Tensor of TensorTrait { fn unsqueeze(self: @Tensor, axes: Span) -> Tensor { core::unsqueeze(self, axes) } + + fn sign(self: @Tensor) -> Tensor { + math::sign::sign(*self) + } } /// Implements addition for `Tensor` using the `Add` trait. diff --git a/src/operators/tensor/implementations/tensor_fp8x23.cairo b/src/operators/tensor/implementations/tensor_fp8x23.cairo index 520c84b19..2ef77a225 100644 --- a/src/operators/tensor/implementations/tensor_fp8x23.cairo +++ b/src/operators/tensor/implementations/tensor_fp8x23.cairo @@ -221,6 +221,10 @@ impl FP8x23Tensor of TensorTrait { fn unsqueeze(self: @Tensor, axes: Span) -> Tensor { core::unsqueeze(self, axes) } + + fn sign(self: @Tensor) -> Tensor { + math::sign::sign(*self) + } } /// Implements addition for `Tensor` using the `Add` trait. diff --git a/src/operators/tensor/implementations/tensor_i32.cairo b/src/operators/tensor/implementations/tensor_i32.cairo index ec8584d00..1684fe60c 100644 --- a/src/operators/tensor/implementations/tensor_i32.cairo +++ b/src/operators/tensor/implementations/tensor_i32.cairo @@ -220,6 +220,11 @@ impl I32Tensor of TensorTrait { fn unsqueeze(self: @Tensor, axes: Span) -> Tensor { core::unsqueeze(self, axes) } + + fn sign(self: @Tensor) -> Tensor { + math::sign::sign(*self) + } + } /// Implements addition for `Tensor` using the `Add` trait. diff --git a/src/operators/tensor/implementations/tensor_i8.cairo b/src/operators/tensor/implementations/tensor_i8.cairo index 08720f55f..722ffa92e 100644 --- a/src/operators/tensor/implementations/tensor_i8.cairo +++ b/src/operators/tensor/implementations/tensor_i8.cairo @@ -219,6 +219,10 @@ impl I8Tensor of TensorTrait { fn unsqueeze(self: @Tensor, axes: Span) -> Tensor { core::unsqueeze(self, axes) } + + fn sign(self: @Tensor) -> Tensor { + math::sign::sign(*self) + } } /// Implements addition for `Tensor` using the `Add` trait. diff --git a/src/operators/tensor/implementations/tensor_u32.cairo b/src/operators/tensor/implementations/tensor_u32.cairo index 2e129b7c6..2c59a9756 100644 --- a/src/operators/tensor/implementations/tensor_u32.cairo +++ b/src/operators/tensor/implementations/tensor_u32.cairo @@ -213,6 +213,10 @@ impl U32Tensor of TensorTrait { fn unsqueeze(self: @Tensor, axes: Span) -> Tensor { core::unsqueeze(self, axes) } + + fn sign(self: @Tensor) -> Tensor { + panic(array!['not supported!']) + } } /// Implements addition for `Tensor` using the `Add` trait. diff --git a/src/operators/tensor/math.cairo b/src/operators/tensor/math.cairo index 4c1ea8aaa..af079a923 100644 --- a/src/operators/tensor/math.cairo +++ b/src/operators/tensor/math.cairo @@ -30,4 +30,5 @@ mod acos; mod onehot; mod sqrt; mod concat; -mod gather; \ No newline at end of file +mod gather; +mod sign; \ No newline at end of file diff --git a/src/operators/tensor/math/sign.cairo b/src/operators/tensor/math/sign.cairo new file mode 100644 index 000000000..0897a95ac --- /dev/null +++ b/src/operators/tensor/math/sign.cairo @@ -0,0 +1,34 @@ +use array::ArrayTrait; +use array::SpanTrait; +use option::OptionTrait; +use traits::Into; + +use orion::numbers::NumberTrait; +use orion::operators::tensor::core::{Tensor, TensorTrait}; + + +fn sign< + T, + MAG, + impl TNumberTrait: NumberTrait, + impl FTensor: TensorTrait, + impl FCopy: Copy, + impl FDrop: Drop, +>( + mut self: Tensor +) -> Tensor { + let mut result = ArrayTrait::new(); + + loop { + match self.data.pop_front() { + Option::Some(item) => { + result.append((*item).sign()); + }, + Option::None(_) => { + break; + } + }; + }; + + return TensorTrait::new(self.shape, result.span()); +} diff --git a/src/tests/nodes.cairo b/src/tests/nodes.cairo index dd9e793e8..287837161 100644 --- a/src/tests/nodes.cairo +++ b/src/tests/nodes.cairo @@ -418,3 +418,8 @@ mod unsqueeze_i8_2d; mod unsqueeze_i8_3d; mod unsqueeze_u32_2d; mod unsqueeze_u32_3d; +mod sign_fP16x16; +mod sign_fP8x23; +mod sign_fail; +mod sign_i32; +mod sign_i8; diff --git a/src/tests/nodes/sign_fP16x16.cairo b/src/tests/nodes/sign_fP16x16.cairo new file mode 100644 index 000000000..1a3e40888 --- /dev/null +++ b/src/tests/nodes/sign_fP16x16.cairo @@ -0,0 +1,20 @@ +mod input_0; +mod output_0; + + +use array::{ArrayTrait, SpanTrait}; +use orion::operators::tensor::TensorTrait; +use orion::operators::tensor::FP16x16Tensor; +use orion::operators::tensor::FP16x16TensorPartialEq; +use orion::utils::assert_eq; + +#[test] +#[available_gas(2000000000)] +fn test_sign_fP16x16() { + let input_0 = input_0::input_0(); + let z = output_0::output_0(); + + let y = input_0.sign(); + + assert_eq(y, z); +} \ No newline at end of file diff --git a/src/tests/nodes/sign_fP16x16/input_0.cairo b/src/tests/nodes/sign_fP16x16/input_0.cairo new file mode 100644 index 000000000..adf2a7cca --- /dev/null +++ b/src/tests/nodes/sign_fP16x16/input_0.cairo @@ -0,0 +1,24 @@ +use array::{ArrayTrait, SpanTrait}; +use orion::operators::tensor::{TensorTrait, Tensor}; +use orion::operators::tensor::FP16x16Tensor; +use orion::numbers::FixedTrait; +use orion::numbers::FP16x16; + +fn input_0() -> Tensor { + let mut shape = ArrayTrait::::new(); + shape.append(11); + + let mut data = ArrayTrait::new(); + data.append(FP16x16 { mag: 327680, sign: true }); + data.append(FP16x16 { mag: 262144, sign: true }); + data.append(FP16x16 { mag: 196608, sign: true }); + data.append(FP16x16 { mag: 131072, sign: true }); + data.append(FP16x16 { mag: 65536, sign: true }); + data.append(FP16x16 { mag: 0, sign: false }); + data.append(FP16x16 { mag: 65536, sign: false }); + data.append(FP16x16 { mag: 131072, sign: false }); + data.append(FP16x16 { mag: 196608, sign: false }); + data.append(FP16x16 { mag: 262144, sign: false }); + data.append(FP16x16 { mag: 327680, sign: false }); + TensorTrait::new(shape.span(), data.span()) +} \ No newline at end of file diff --git a/src/tests/nodes/sign_fP16x16/output_0.cairo b/src/tests/nodes/sign_fP16x16/output_0.cairo new file mode 100644 index 000000000..6ad6981ee --- /dev/null +++ b/src/tests/nodes/sign_fP16x16/output_0.cairo @@ -0,0 +1,24 @@ +use array::{ArrayTrait, SpanTrait}; +use orion::operators::tensor::{TensorTrait, Tensor}; +use orion::operators::tensor::FP16x16Tensor; +use orion::numbers::FixedTrait; +use orion::numbers::FP16x16; + +fn output_0() -> Tensor { + let mut shape = ArrayTrait::::new(); + shape.append(11); + + let mut data = ArrayTrait::new(); + data.append(FP16x16 { mag: 65536, sign: true }); + data.append(FP16x16 { mag: 65536, sign: true }); + data.append(FP16x16 { mag: 65536, sign: true }); + data.append(FP16x16 { mag: 65536, sign: true }); + data.append(FP16x16 { mag: 65536, sign: true }); + data.append(FP16x16 { mag: 0, sign: false }); + data.append(FP16x16 { mag: 65536, sign: false }); + data.append(FP16x16 { mag: 65536, sign: false }); + data.append(FP16x16 { mag: 65536, sign: false }); + data.append(FP16x16 { mag: 65536, sign: false }); + data.append(FP16x16 { mag: 65536, sign: false }); + TensorTrait::new(shape.span(), data.span()) +} \ No newline at end of file diff --git a/src/tests/nodes/sign_fP8x23.cairo b/src/tests/nodes/sign_fP8x23.cairo new file mode 100644 index 000000000..1eae6e5e7 --- /dev/null +++ b/src/tests/nodes/sign_fP8x23.cairo @@ -0,0 +1,20 @@ +mod input_0; +mod output_0; + + +use array::{ArrayTrait, SpanTrait}; +use orion::operators::tensor::TensorTrait; +use orion::operators::tensor::FP8x23Tensor; +use orion::operators::tensor::FP8x23TensorPartialEq; +use orion::utils::assert_eq; + +#[test] +#[available_gas(2000000000)] +fn test_sign_fP8x23() { + let input_0 = input_0::input_0(); + let z = output_0::output_0(); + + let y = input_0.sign(); + + assert_eq(y, z); +} \ No newline at end of file diff --git a/src/tests/nodes/sign_fP8x23/input_0.cairo b/src/tests/nodes/sign_fP8x23/input_0.cairo new file mode 100644 index 000000000..8f1e044bd --- /dev/null +++ b/src/tests/nodes/sign_fP8x23/input_0.cairo @@ -0,0 +1,24 @@ +use array::{ArrayTrait, SpanTrait}; +use orion::operators::tensor::{TensorTrait, Tensor}; +use orion::operators::tensor::FP8x23Tensor; +use orion::numbers::FixedTrait; +use orion::numbers::FP8x23; + +fn input_0() -> Tensor { + let mut shape = ArrayTrait::::new(); + shape.append(11); + + let mut data = ArrayTrait::new(); + data.append(FP8x23 { mag: 41943040, sign: true }); + data.append(FP8x23 { mag: 33554432, sign: true }); + data.append(FP8x23 { mag: 25165824, sign: true }); + data.append(FP8x23 { mag: 16777216, sign: true }); + data.append(FP8x23 { mag: 8388608, sign: true }); + data.append(FP8x23 { mag: 0, sign: false }); + data.append(FP8x23 { mag: 8388608, sign: false }); + data.append(FP8x23 { mag: 16777216, sign: false }); + data.append(FP8x23 { mag: 25165824, sign: false }); + data.append(FP8x23 { mag: 33554432, sign: false }); + data.append(FP8x23 { mag: 41943040, sign: false }); + TensorTrait::new(shape.span(), data.span()) +} \ No newline at end of file diff --git a/src/tests/nodes/sign_fP8x23/output_0.cairo b/src/tests/nodes/sign_fP8x23/output_0.cairo new file mode 100644 index 000000000..90f2d495a --- /dev/null +++ b/src/tests/nodes/sign_fP8x23/output_0.cairo @@ -0,0 +1,24 @@ +use array::{ArrayTrait, SpanTrait}; +use orion::operators::tensor::{TensorTrait, Tensor}; +use orion::operators::tensor::FP8x23Tensor; +use orion::numbers::FixedTrait; +use orion::numbers::FP8x23; + +fn output_0() -> Tensor { + let mut shape = ArrayTrait::::new(); + shape.append(11); + + let mut data = ArrayTrait::new(); + data.append(FP8x23 { mag: 8388608, sign: true }); + data.append(FP8x23 { mag: 8388608, sign: true }); + data.append(FP8x23 { mag: 8388608, sign: true }); + data.append(FP8x23 { mag: 8388608, sign: true }); + data.append(FP8x23 { mag: 8388608, sign: true }); + data.append(FP8x23 { mag: 0, sign: false }); + data.append(FP8x23 { mag: 8388608, sign: false }); + data.append(FP8x23 { mag: 8388608, sign: false }); + data.append(FP8x23 { mag: 8388608, sign: false }); + data.append(FP8x23 { mag: 8388608, sign: false }); + data.append(FP8x23 { mag: 8388608, sign: false }); + TensorTrait::new(shape.span(), data.span()) +} \ No newline at end of file diff --git a/src/tests/nodes/sign_fail.cairo b/src/tests/nodes/sign_fail.cairo new file mode 100644 index 000000000..833b11072 --- /dev/null +++ b/src/tests/nodes/sign_fail.cairo @@ -0,0 +1,21 @@ +mod input_0; +mod output_0; + + +use array::{ArrayTrait, SpanTrait}; +use orion::operators::tensor::TensorTrait; +use orion::operators::tensor::I32Tensor; +use orion::operators::tensor::I32TensorPartialEq; +use orion::utils::assert_eq; + +#[test] +#[should_panic] +#[available_gas(2000000000)] +fn test_sign_fail() { + let input_0 = input_0::input_0(); + let z = output_0::output_0(); + + let y = input_0.sign(); + + assert_eq(y, z); +} \ No newline at end of file diff --git a/src/tests/nodes/sign_fail/input_0.cairo b/src/tests/nodes/sign_fail/input_0.cairo new file mode 100644 index 000000000..0d0562934 --- /dev/null +++ b/src/tests/nodes/sign_fail/input_0.cairo @@ -0,0 +1,23 @@ +use array::{ArrayTrait, SpanTrait}; +use orion::operators::tensor::{TensorTrait, Tensor}; +use orion::operators::tensor::I32Tensor; +use orion::numbers::{IntegerTrait, i32}; + +fn input_0() -> Tensor { + let mut shape = ArrayTrait::::new(); + shape.append(11); + + let mut data = ArrayTrait::new(); + data.append(i32 { mag: 5, sign: true }); + data.append(i32 { mag: 4, sign: true }); + data.append(i32 { mag: 3, sign: true }); + data.append(i32 { mag: 2, sign: true }); + data.append(i32 { mag: 1, sign: true }); + data.append(i32 { mag: 0, sign: false }); + data.append(i32 { mag: 1, sign: false }); + data.append(i32 { mag: 2, sign: false }); + data.append(i32 { mag: 3, sign: false }); + data.append(i32 { mag: 4, sign: false }); + data.append(i32 { mag: 5, sign: false }); + TensorTrait::new(shape.span(), data.span()) +} \ No newline at end of file diff --git a/src/tests/nodes/sign_fail/output_0.cairo b/src/tests/nodes/sign_fail/output_0.cairo new file mode 100644 index 000000000..27ab8422c --- /dev/null +++ b/src/tests/nodes/sign_fail/output_0.cairo @@ -0,0 +1,23 @@ +use array::{ArrayTrait, SpanTrait}; +use orion::operators::tensor::{TensorTrait, Tensor}; +use orion::operators::tensor::I32Tensor; +use orion::numbers::{IntegerTrait, i32}; + +fn output_0() -> Tensor { + let mut shape = ArrayTrait::::new(); + shape.append(11); + + let mut data = ArrayTrait::new(); + data.append(i32 { mag: 1, sign: false }); + data.append(i32 { mag: 1, sign: true }); + data.append(i32 { mag: 1, sign: true }); + data.append(i32 { mag: 1, sign: true }); + data.append(i32 { mag: 1, sign: true }); + data.append(i32 { mag: 0, sign: false }); + data.append(i32 { mag: 1, sign: false }); + data.append(i32 { mag: 1, sign: false }); + data.append(i32 { mag: 1, sign: false }); + data.append(i32 { mag: 1, sign: false }); + data.append(i32 { mag: 1, sign: true }); + TensorTrait::new(shape.span(), data.span()) +} \ No newline at end of file diff --git a/src/tests/nodes/sign_i32.cairo b/src/tests/nodes/sign_i32.cairo new file mode 100644 index 000000000..ec39a944f --- /dev/null +++ b/src/tests/nodes/sign_i32.cairo @@ -0,0 +1,20 @@ +mod input_0; +mod output_0; + + +use array::{ArrayTrait, SpanTrait}; +use orion::operators::tensor::TensorTrait; +use orion::operators::tensor::I32Tensor; +use orion::operators::tensor::I32TensorPartialEq; +use orion::utils::assert_eq; + +#[test] +#[available_gas(2000000000)] +fn test_sign_i32() { + let input_0 = input_0::input_0(); + let z = output_0::output_0(); + + let y = input_0.sign(); + + assert_eq(y, z); +} \ No newline at end of file diff --git a/src/tests/nodes/sign_i32/input_0.cairo b/src/tests/nodes/sign_i32/input_0.cairo new file mode 100644 index 000000000..0d0562934 --- /dev/null +++ b/src/tests/nodes/sign_i32/input_0.cairo @@ -0,0 +1,23 @@ +use array::{ArrayTrait, SpanTrait}; +use orion::operators::tensor::{TensorTrait, Tensor}; +use orion::operators::tensor::I32Tensor; +use orion::numbers::{IntegerTrait, i32}; + +fn input_0() -> Tensor { + let mut shape = ArrayTrait::::new(); + shape.append(11); + + let mut data = ArrayTrait::new(); + data.append(i32 { mag: 5, sign: true }); + data.append(i32 { mag: 4, sign: true }); + data.append(i32 { mag: 3, sign: true }); + data.append(i32 { mag: 2, sign: true }); + data.append(i32 { mag: 1, sign: true }); + data.append(i32 { mag: 0, sign: false }); + data.append(i32 { mag: 1, sign: false }); + data.append(i32 { mag: 2, sign: false }); + data.append(i32 { mag: 3, sign: false }); + data.append(i32 { mag: 4, sign: false }); + data.append(i32 { mag: 5, sign: false }); + TensorTrait::new(shape.span(), data.span()) +} \ No newline at end of file diff --git a/src/tests/nodes/sign_i32/output_0.cairo b/src/tests/nodes/sign_i32/output_0.cairo new file mode 100644 index 000000000..dbe758941 --- /dev/null +++ b/src/tests/nodes/sign_i32/output_0.cairo @@ -0,0 +1,23 @@ +use array::{ArrayTrait, SpanTrait}; +use orion::operators::tensor::{TensorTrait, Tensor}; +use orion::operators::tensor::I32Tensor; +use orion::numbers::{IntegerTrait, i32}; + +fn output_0() -> Tensor { + let mut shape = ArrayTrait::::new(); + shape.append(11); + + let mut data = ArrayTrait::new(); + data.append(i32 { mag: 1, sign: true }); + data.append(i32 { mag: 1, sign: true }); + data.append(i32 { mag: 1, sign: true }); + data.append(i32 { mag: 1, sign: true }); + data.append(i32 { mag: 1, sign: true }); + data.append(i32 { mag: 0, sign: false }); + data.append(i32 { mag: 1, sign: false }); + data.append(i32 { mag: 1, sign: false }); + data.append(i32 { mag: 1, sign: false }); + data.append(i32 { mag: 1, sign: false }); + data.append(i32 { mag: 1, sign: false }); + TensorTrait::new(shape.span(), data.span()) +} \ No newline at end of file diff --git a/src/tests/nodes/sign_i8.cairo b/src/tests/nodes/sign_i8.cairo new file mode 100644 index 000000000..f1d258898 --- /dev/null +++ b/src/tests/nodes/sign_i8.cairo @@ -0,0 +1,20 @@ +mod input_0; +mod output_0; + + +use array::{ArrayTrait, SpanTrait}; +use orion::operators::tensor::TensorTrait; +use orion::operators::tensor::I8Tensor; +use orion::operators::tensor::I8TensorPartialEq; +use orion::utils::assert_eq; + +#[test] +#[available_gas(2000000000)] +fn test_sign_i8() { + let input_0 = input_0::input_0(); + let z = output_0::output_0(); + + let y = input_0.sign(); + + assert_eq(y, z); +} \ No newline at end of file diff --git a/src/tests/nodes/sign_i8/input_0.cairo b/src/tests/nodes/sign_i8/input_0.cairo new file mode 100644 index 000000000..631bae825 --- /dev/null +++ b/src/tests/nodes/sign_i8/input_0.cairo @@ -0,0 +1,23 @@ +use array::{ArrayTrait, SpanTrait}; +use orion::operators::tensor::{TensorTrait, Tensor}; +use orion::operators::tensor::I8Tensor; +use orion::numbers::{IntegerTrait, i8}; + +fn input_0() -> Tensor { + let mut shape = ArrayTrait::::new(); + shape.append(11); + + let mut data = ArrayTrait::new(); + data.append(i8 { mag: 5, sign: true }); + data.append(i8 { mag: 4, sign: true }); + data.append(i8 { mag: 3, sign: true }); + data.append(i8 { mag: 2, sign: true }); + data.append(i8 { mag: 1, sign: true }); + data.append(i8 { mag: 0, sign: false }); + data.append(i8 { mag: 1, sign: false }); + data.append(i8 { mag: 2, sign: false }); + data.append(i8 { mag: 3, sign: false }); + data.append(i8 { mag: 4, sign: false }); + data.append(i8 { mag: 5, sign: false }); + TensorTrait::new(shape.span(), data.span()) +} \ No newline at end of file diff --git a/src/tests/nodes/sign_i8/output_0.cairo b/src/tests/nodes/sign_i8/output_0.cairo new file mode 100644 index 000000000..4da3f87c0 --- /dev/null +++ b/src/tests/nodes/sign_i8/output_0.cairo @@ -0,0 +1,23 @@ +use array::{ArrayTrait, SpanTrait}; +use orion::operators::tensor::{TensorTrait, Tensor}; +use orion::operators::tensor::I8Tensor; +use orion::numbers::{IntegerTrait, i8}; + +fn output_0() -> Tensor { + let mut shape = ArrayTrait::::new(); + shape.append(11); + + let mut data = ArrayTrait::new(); + data.append(i8 { mag: 1, sign: true }); + data.append(i8 { mag: 1, sign: true }); + data.append(i8 { mag: 1, sign: true }); + data.append(i8 { mag: 1, sign: true }); + data.append(i8 { mag: 1, sign: true }); + data.append(i8 { mag: 0, sign: false }); + data.append(i8 { mag: 1, sign: false }); + data.append(i8 { mag: 1, sign: false }); + data.append(i8 { mag: 1, sign: false }); + data.append(i8 { mag: 1, sign: false }); + data.append(i8 { mag: 1, sign: false }); + TensorTrait::new(shape.span(), data.span()) +} \ No newline at end of file From 031c25e04740645ff2c714c613bc381eddedc168 Mon Sep 17 00:00:00 2001 From: raphaelDkhn Date: Fri, 6 Oct 2023 15:25:51 +0200 Subject: [PATCH 2/2] update doc --- .../operators/machine-learning/tree-regressor/README.md | 1 + .../operators/machine-learning/tree-regressor/tree.predict.md | 4 ++-- docs/framework/operators/tensor/tensor.sign.md | 1 + src/operators/tensor/core.cairo | 2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/framework/operators/machine-learning/tree-regressor/README.md b/docs/framework/operators/machine-learning/tree-regressor/README.md index e2e69b355..7df2112c4 100644 --- a/docs/framework/operators/machine-learning/tree-regressor/README.md +++ b/docs/framework/operators/machine-learning/tree-regressor/README.md @@ -20,3 +20,4 @@ Orion supports currently only fixed point data types for `TreeRegressorTrait`. | --- | --- | | [`tree.fit`](tree.fit.md) | Constructs a decision tree regressor based on the provided data and target values. | | [`tree.predict`](tree.predict.md) | Given a set of features, predicts the target value using the constructed decision tree. | + diff --git a/docs/framework/operators/machine-learning/tree-regressor/tree.predict.md b/docs/framework/operators/machine-learning/tree-regressor/tree.predict.md index 0d14f381a..28d4a027c 100644 --- a/docs/framework/operators/machine-learning/tree-regressor/tree.predict.md +++ b/docs/framework/operators/machine-learning/tree-regressor/tree.predict.md @@ -1,6 +1,6 @@ -# tree.predict +# TreeRegressorTrait::predict -```rust +```rust fn predict(ref self: TreeNode, features: Span) -> T; ``` diff --git a/docs/framework/operators/tensor/tensor.sign.md b/docs/framework/operators/tensor/tensor.sign.md index ef35104f5..8acb8c730 100644 --- a/docs/framework/operators/tensor/tensor.sign.md +++ b/docs/framework/operators/tensor/tensor.sign.md @@ -5,6 +5,7 @@ ``` Calculates the sign of the given input tensor element-wise. +If input > 0, output 1. if input < 0, output -1. if input == 0, output 0. ## Args diff --git a/src/operators/tensor/core.cairo b/src/operators/tensor/core.cairo index 0d658ed53..eb52c6c1c 100644 --- a/src/operators/tensor/core.cairo +++ b/src/operators/tensor/core.cairo @@ -77,6 +77,7 @@ impl TensorSerde, impl TDrop: Drop> of Serde { /// # tensor.new @@ -2646,6 +2647,7 @@ trait TensorTrait { /// ``` /// /// Calculates the sign of the given input tensor element-wise. + /// If input > 0, output 1. if input < 0, output -1. if input == 0, output 0. /// /// ## Args ///