diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 78f930152..8cdf6ddcb 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) * [tensor.clip](framework/operators/tensor/tensor.clip.md) * [Neural Network](framework/operators/neural-network/README.md) * [nn.relu](framework/operators/neural-network/nn.relu.md) diff --git a/docs/framework/compatibility.md b/docs/framework/compatibility.md index 657b9c94d..a7b415cc6 100644 --- a/docs/framework/compatibility.md +++ b/docs/framework/compatibility.md @@ -55,6 +55,7 @@ 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: | | [Clip](operators/tensor/tensor.clip.md) | :white\_check\_mark: | Current Operators support: **50/156 (32%)** 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/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/README.md b/docs/framework/operators/tensor/README.md index 290396a97..b33f330c7 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. | | [`tensor.clip`](tensor.clip.md) | Clip operator limits the given input within an interval. | ## 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..8acb8c730 --- /dev/null +++ b/docs/framework/operators/tensor/tensor.sign.md @@ -0,0 +1,34 @@ +# tensor.sign + +```rust + fn sign(self: @Tensor) -> Tensor; +``` + +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 + +* `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 c0627803c..eb52c6c1c 100644 --- a/src/operators/tensor/core.cairo +++ b/src/operators/tensor/core.cairo @@ -76,6 +76,8 @@ impl TensorSerde, impl TDrop: Drop> of Serde { /// # tensor.new @@ -2638,9 +2640,46 @@ trait TensorTrait { /// ``` /// fn clip(self: @Tensor, min: Option, max: Option) -> Tensor; + /// # tensor.sign + /// + /// ```rust + /// fn sign(self: @Tensor) -> Tensor; + /// ``` + /// + /// 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 + /// + /// * `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); @@ -3120,6 +3159,39 @@ fn unsqueeze(self: @Tensor, axes: Span) -> Tensor { return Tensor:: { shape: output_shape.span(), data: *self.data }; } + +/// Cf: TensorTrait::sign docstring +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() }; + } + }; + } +} + /// Cf: TensorTrait::clip docstring fn clip, impl TDrop: Drop, impl TTensor: TensorTrait, impl TPartialOrd: PartialOrd, impl TNumber: NumberTrait>(self: @Tensor, min: Option, max: Option) -> Tensor { let min = match min { diff --git a/src/operators/tensor/implementations/tensor_fp16x16.cairo b/src/operators/tensor/implementations/tensor_fp16x16.cairo index a4605cc07..eb594dc8d 100644 --- a/src/operators/tensor/implementations/tensor_fp16x16.cairo +++ b/src/operators/tensor/implementations/tensor_fp16x16.cairo @@ -222,6 +222,10 @@ impl FP16x16Tensor of TensorTrait { core::unsqueeze(self, axes) } + fn sign(self: @Tensor) -> Tensor { + math::sign::sign(*self) + } + fn clip(self: @Tensor, min: Option, max: Option) -> Tensor { core::clip(self, min, max) } diff --git a/src/operators/tensor/implementations/tensor_fp32x32.cairo b/src/operators/tensor/implementations/tensor_fp32x32.cairo index 18b265199..0fda50672 100644 --- a/src/operators/tensor/implementations/tensor_fp32x32.cairo +++ b/src/operators/tensor/implementations/tensor_fp32x32.cairo @@ -223,6 +223,10 @@ impl FP32x32Tensor of TensorTrait { core::unsqueeze(self, axes) } + fn sign(self: @Tensor) -> Tensor { + math::sign::sign(*self) + } + fn clip(self: @Tensor, min: Option, max: Option) -> Tensor { core::clip(self, min, max) } diff --git a/src/operators/tensor/implementations/tensor_fp64x64.cairo b/src/operators/tensor/implementations/tensor_fp64x64.cairo index 20f9f9c83..8c42586ec 100644 --- a/src/operators/tensor/implementations/tensor_fp64x64.cairo +++ b/src/operators/tensor/implementations/tensor_fp64x64.cairo @@ -223,6 +223,10 @@ impl FP64x64Tensor of TensorTrait { core::unsqueeze(self, axes) } + fn sign(self: @Tensor) -> Tensor { + math::sign::sign(*self) + } + fn clip(self: @Tensor, min: Option, max: Option) -> Tensor { core::clip(self, min, max) } diff --git a/src/operators/tensor/implementations/tensor_fp8x23.cairo b/src/operators/tensor/implementations/tensor_fp8x23.cairo index ba9d57ed9..34553c057 100644 --- a/src/operators/tensor/implementations/tensor_fp8x23.cairo +++ b/src/operators/tensor/implementations/tensor_fp8x23.cairo @@ -222,6 +222,10 @@ impl FP8x23Tensor of TensorTrait { core::unsqueeze(self, axes) } + fn sign(self: @Tensor) -> Tensor { + math::sign::sign(*self) + } + fn clip(self: @Tensor, min: Option, max: Option) -> Tensor { core::clip(self, min, max) } diff --git a/src/operators/tensor/implementations/tensor_i32.cairo b/src/operators/tensor/implementations/tensor_i32.cairo index 151d53f2f..974e87c61 100644 --- a/src/operators/tensor/implementations/tensor_i32.cairo +++ b/src/operators/tensor/implementations/tensor_i32.cairo @@ -221,6 +221,10 @@ impl I32Tensor of TensorTrait { core::unsqueeze(self, axes) } + fn sign(self: @Tensor) -> Tensor { + math::sign::sign(*self) + } + fn clip(self: @Tensor, min: Option, max: Option) -> Tensor { core::clip(self, min, max) } diff --git a/src/operators/tensor/implementations/tensor_i8.cairo b/src/operators/tensor/implementations/tensor_i8.cairo index 5641d9c90..7d8c7c65d 100644 --- a/src/operators/tensor/implementations/tensor_i8.cairo +++ b/src/operators/tensor/implementations/tensor_i8.cairo @@ -220,6 +220,10 @@ impl I8Tensor of TensorTrait { core::unsqueeze(self, axes) } + fn sign(self: @Tensor) -> Tensor { + math::sign::sign(*self) + } + fn clip(self: @Tensor, min: Option, max: Option) -> Tensor { core::clip(self, min, max) } diff --git a/src/operators/tensor/implementations/tensor_u32.cairo b/src/operators/tensor/implementations/tensor_u32.cairo index 615dbb9f0..af43f58f7 100644 --- a/src/operators/tensor/implementations/tensor_u32.cairo +++ b/src/operators/tensor/implementations/tensor_u32.cairo @@ -214,6 +214,10 @@ impl U32Tensor of TensorTrait { core::unsqueeze(self, axes) } + fn sign(self: @Tensor) -> Tensor { + panic(array!['not supported!']) + } + fn clip(self: @Tensor, min: Option, max: Option) -> Tensor { core::clip(self, min, max) } 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 3704c5650..5fcded606 100644 --- a/src/tests/nodes.cairo +++ b/src/tests/nodes.cairo @@ -418,6 +418,11 @@ 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; mod clip_fp16x16_2d; mod clip_fp16x16_3d; mod clip_fp8x23_2d; 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