Skip to content

Commit

Permalink
Merge pull request #414 from andresmayorca/develop
Browse files Browse the repository at this point in the history
add round
  • Loading branch information
raphaelDkhn authored Oct 31, 2023
2 parents 9122dfd + 62a7820 commit 1ae894e
Show file tree
Hide file tree
Showing 24 changed files with 337 additions and 2 deletions.
1 change: 1 addition & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
* [tensor.identity](framework/operators/tensor/tensor.identity.md)
* [tensor.and](framework/operators/tensor/tensor.and.md)
* [tensor.where](framework/operators/tensor/tensor.where.md)
* [tensor.round](framework/operators/tensor/tensor.round.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)
Expand Down
1 change: 1 addition & 0 deletions docs/framework/compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ You can see below the list of current supported ONNX Operators:
| [MinInTensor](operators/tensor/tensor.min\_in\_tensor.md) | :white\_check\_mark: |
| [Min](operators/tensor/tensor.min.md) | :white\_check\_mark: |
| [Where](operators/tensor/tensor.where.md) | :white\_check\_mark: |
| [Round](operators/tensor/tensor.round.md) | :white\_check\_mark: |
| [MaxInTensor](operators/tensor/tensor.max\_in\_tensor.md) | :white\_check\_mark: |
| [Max](operators/tensor/tensor.max.md) | :white\_check\_mark: |

Expand Down
1 change: 1 addition & 0 deletions docs/framework/operators/tensor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ use orion::operators::tensor::TensorTrait;
| [`tensor.and`](tensor.and.md) | Computes the logical AND of two tensors element-wise. |
| [`tensor.identity`](tensor.identity.md) | Return a Tensor with the same shape and contents as input. |
| [`tensor.where`](tensor.where.md) | Return elements chosen from x or y depending on condition. |
| [`tensor.round`](tensor.round.md) | Computes the round value of all elements in the input tensor. |

## Arithmetic Operations

Expand Down
39 changes: 39 additions & 0 deletions docs/framework/operators/tensor/tensor.round.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#tensor.round

```rust
fn round(self: @Tensor<T>) -> Tensor<T>;
```

Computes the round value of all elements in the input tensor.

## Args

* `self`(`@Tensor<T>`) - The input tensor.


## Returns

A new `Tensor<T>` of the same shape as the input tensor with
the round value of all elements in the input tensor.

## Example

```rust
use array::{ArrayTrait, SpanTrait};

use orion::operators::tensor::{TensorTrait, Tensor, FP16x16Tensor};
use orion::numbers::{FixedTrait, FP16x16};

fn round_example() -> Tensor<FP16x16> {
let tensor = TensorTrait::<FP16x16>::new(
shape: array![3].span(),
data: array![
FixedTrait::new(190054, false), // 2.9
]
.span(),
);

return tensor.round();
}
>>> [3]
```
29 changes: 29 additions & 0 deletions nodegen/node/round.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import numpy as np
from nodegen.node import RunAll
from ..helpers import make_node, make_test, to_fp, Tensor, Dtype, FixedImpl

class Round(RunAll):

@staticmethod
def round_fp8x23():
x = np.array([0.1, 0.5, 0.9, 1.2, 1.5, 1.8, 2.3, 2.5, 2.7, -1.1, -1.5, -1.9, -2.2, -2.5, -2.8]).astype(np.float64)
y = np.array([0.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 3.0, -1.0, -2.0, -2.0, -2.0, -3.0, -3.0]).astype(np.float64)

x = Tensor(Dtype.FP8x23, x.shape, to_fp(x.flatten(), FixedImpl.FP8x23))
y = Tensor(Dtype.FP8x23, y.shape, to_fp(y.flatten(), FixedImpl.FP8x23))

name = "round_fp8x23"
make_node([x], [y], name)
make_test([x], y, "input_0.round()", name)

@staticmethod
def round_fp16x16():
x = np.array([0.1, 0.5, 0.9, 1.2, 1.5, 1.8, 2.3, 2.5, 2.7, -1.1, -1.5, -1.9, -2.2, -2.5, -2.8]).astype(np.float64)
y = np.array([0.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 3.0, 3.0, -1.0, -2.0, -2.0, -2.0, -3.0, -3.0]).astype(np.float64)

x = Tensor(Dtype.FP16x16, x.shape, to_fp(x.flatten(), FixedImpl.FP16x16))
y = Tensor(Dtype.FP16x16, y.shape, to_fp(y.flatten(), FixedImpl.FP16x16))

name = "round_fp16x16"
make_node([x], [y], name)
make_test([x], y, "input_0.round()", name)
43 changes: 42 additions & 1 deletion src/operators/tensor/core.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl TensorSerde<T, impl TSerde: Serde<T>, impl TDrop: Drop<T>> of Serde<Tensor<
/// and - Computes the logical AND of two tensors element-wise.
/// identity - Return a Tensor with the same shape and contents as input.
/// where - Return elements chosen from x or y depending on condition.
///
/// round - Computes the round value of all elements in the input tensor.
trait TensorTrait<T> {
/// # tensor.new
///
Expand Down Expand Up @@ -3000,6 +3000,47 @@ trait TensorTrait<T> {
/// ```
///
fn where(self: @Tensor<T>, x: @Tensor<T>, y: @Tensor<T>) -> Tensor<T>;
/// #tensor.round
///
/// ```rust
/// fn round(self: @Tensor<T>) -> Tensor<T>;
/// ```
///
/// Computes the round value of all elements in the input tensor.
///
/// ## Args
///
/// * `self`(`@Tensor<T>`) - The input tensor.
///
///
/// ## Returns
///
/// A new `Tensor<T>` of the same shape as the input tensor with
/// the round value of all elements in the input tensor.
///
/// ## Example
///
/// ```rust
/// use array::{ArrayTrait, SpanTrait};
///
/// use orion::operators::tensor::{TensorTrait, Tensor, FP16x16Tensor};
/// use orion::numbers::{FixedTrait, FP16x16};
///
/// fn round_example() -> Tensor<FP16x16> {
/// let tensor = TensorTrait::<FP16x16>::new(
/// shape: array![3].span(),
/// data: array![
/// FixedTrait::new(190054, false), // 2.9
/// ]
/// .span(),
/// );
///
/// return tensor.round();
/// }
/// >>> [3]
/// ```
///
fn round(self: @Tensor<T>) -> Tensor<T>;
}

/// Cf: TensorTrait::new docstring
Expand Down
5 changes: 5 additions & 0 deletions src/operators/tensor/implementations/tensor_fp16x16.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,11 @@ impl FP16x16Tensor of TensorTrait<FP16x16> {
fn where(self: @Tensor<FP16x16>, x: @Tensor<FP16x16>, y: @Tensor<FP16x16>) -> Tensor<FP16x16> {
math::where::where(self, x, y)
}

fn round(self: @Tensor<FP16x16>) -> Tensor<FP16x16> {
math::round::round(*self)
}

}

/// Implements addition for `Tensor<FP16x16>` using the `Add` trait.
Expand Down
4 changes: 4 additions & 0 deletions src/operators/tensor/implementations/tensor_fp16x16wide.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,10 @@ impl FP16x16WTensor of TensorTrait<FP16x16W> {
) -> Tensor<FP16x16W> {
math::where::where(self, x, y)
}

fn round(self: @Tensor<FP16x16W>) -> Tensor<FP16x16W> {
math::round::round(*self)
}
}

/// Implements addition for `Tensor<FP16x16W>` using the `Add` trait.
Expand Down
4 changes: 4 additions & 0 deletions src/operators/tensor/implementations/tensor_fp32x32.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ impl FP32x32Tensor of TensorTrait<FP32x32> {
fn where(self: @Tensor<FP32x32>, x: @Tensor<FP32x32>, y: @Tensor<FP32x32>) -> Tensor<FP32x32> {
math::where::where(self, x, y)
}

fn round(self: @Tensor<FP32x32>) -> Tensor<FP32x32> {
math::round::round(*self)
}
}

/// Implements addition for `Tensor<FP32x32>` using the `Add` trait.
Expand Down
4 changes: 4 additions & 0 deletions src/operators/tensor/implementations/tensor_fp64x64.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ impl FP64x64Tensor of TensorTrait<FP64x64> {
fn where(self: @Tensor<FP64x64>, x: @Tensor<FP64x64>, y: @Tensor<FP64x64>) -> Tensor<FP64x64> {
math::where::where(self, x, y)
}

fn round(self: @Tensor<FP64x64>) -> Tensor<FP64x64> {
math::round::round(*self)
}
}

/// Implements addition for `Tensor<FP64x64>` using the `Add` trait.
Expand Down
4 changes: 4 additions & 0 deletions src/operators/tensor/implementations/tensor_fp8x23.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,10 @@ impl FP8x23Tensor of TensorTrait<FP8x23> {
fn where(self: @Tensor<FP8x23>, x: @Tensor<FP8x23>, y: @Tensor<FP8x23>) -> Tensor<FP8x23> {
math::where::where(self, x, y)
}

fn round(self: @Tensor<FP8x23>) -> Tensor<FP8x23> {
math::round::round(*self)
}
}

/// Implements addition for `Tensor<FP8x23>` using the `Add` trait.
Expand Down
7 changes: 6 additions & 1 deletion src/operators/tensor/implementations/tensor_fp8x23wide.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,12 @@ impl FP8x23WTensor of TensorTrait<FP8x23W> {
fn where(self: @Tensor<FP8x23W>, x: @Tensor<FP8x23W>, y: @Tensor<FP8x23W>) -> Tensor<FP8x23W> {
math::where::where(self, x, y)
}
}

fn round(self: @Tensor<FP8x23W>) -> Tensor<FP8x23W> {
math::round::round(*self)
}

}

/// Implements addition for `Tensor<FP8x23W>` using the `Add` trait.
impl FP8x23WTensorAdd<
Expand Down
4 changes: 4 additions & 0 deletions src/operators/tensor/implementations/tensor_i32.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,10 @@ impl I32Tensor of TensorTrait<i32> {
fn where(self: @Tensor<i32>, x: @Tensor<i32>, y: @Tensor<i32>) -> Tensor<i32> {
math::where::where(self, x, y)
}

fn round(self: @Tensor<i32>) -> Tensor<i32> {
math::round::round(*self)
}
}

/// Implements addition for `Tensor<i32>` using the `Add` trait.
Expand Down
4 changes: 4 additions & 0 deletions src/operators/tensor/implementations/tensor_i8.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ impl I8Tensor of TensorTrait<i8> {
fn where(self: @Tensor<i8>, x: @Tensor<i8>, y: @Tensor<i8>) -> Tensor<i8> {
math::where::where(self, x, y)
}

fn round(self: @Tensor<i8>) -> Tensor<i8> {
math::round::round(*self)
}
}

/// Implements addition for `Tensor<i8>` using the `Add` trait.
Expand Down
4 changes: 4 additions & 0 deletions src/operators/tensor/implementations/tensor_u32.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ impl U32Tensor of TensorTrait<u32> {
fn where(self: @Tensor<u32>, x: @Tensor<u32>, y: @Tensor<u32>) -> Tensor<u32> {
math::where::where(self, x, y)
}

fn round(self: @Tensor<u32>) -> Tensor<u32> {
math::round::round(*self)
}
}

/// Implements addition for `Tensor<u32>` using the `Add` trait.
Expand Down
1 change: 1 addition & 0 deletions src/operators/tensor/math.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ mod sign;
mod and;
mod neg;
mod where;
mod round;
30 changes: 30 additions & 0 deletions src/operators/tensor/math/round.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use array::ArrayTrait;
use array::SpanTrait;
use option::OptionTrait;
use traits::Into;

use orion::numbers::NumberTrait;
use orion::operators::tensor::core::{Tensor, TensorTrait};


fn round<
T,
MAG,
impl TNumberTrait: NumberTrait<T, MAG>,
impl FTensor: TensorTrait<T>,
impl FCopy: Copy<T>,
impl FDrop: Drop<T>
>(
mut self: Tensor<T>
) -> Tensor<T> {
let mut result = ArrayTrait::new();

loop {
match self.data.pop_front() {
Option::Some(item) => { result.append((*item).round()); },
Option::None(_) => { break; }
};
};

return TensorTrait::new(self.shape, result.span());
}
2 changes: 2 additions & 0 deletions tests/nodes.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,8 @@ mod where_i8;
mod where_i8_broadcast;
mod where_u32;
mod where_u32_broadcast;
mod round_fp16x16;
mod round_fp8x23;
mod max_fp16x16_three_tensors;
mod max_fp16x16_broadcast_three_tensors;
mod max_fp16x16_two_tensors;
Expand Down
20 changes: 20 additions & 0 deletions tests/nodes/round_fp16x16.cairo
Original file line number Diff line number Diff line change
@@ -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_round_fp16x16() {
let input_0 = input_0::input_0();
let z = output_0::output_0();

let y = input_0.round();

assert_eq(y, z);
}
28 changes: 28 additions & 0 deletions tests/nodes/round_fp16x16/input_0.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
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<FP16x16> {
let mut shape = ArrayTrait::<usize>::new();
shape.append(15);

let mut data = ArrayTrait::new();
data.append(FP16x16 { mag: 6553, sign: false });
data.append(FP16x16 { mag: 32768, sign: false });
data.append(FP16x16 { mag: 58982, sign: false });
data.append(FP16x16 { mag: 78643, sign: false });
data.append(FP16x16 { mag: 98304, sign: false });
data.append(FP16x16 { mag: 117964, sign: false });
data.append(FP16x16 { mag: 150732, sign: false });
data.append(FP16x16 { mag: 163840, sign: false });
data.append(FP16x16 { mag: 176947, sign: false });
data.append(FP16x16 { mag: 72089, sign: true });
data.append(FP16x16 { mag: 98304, sign: true });
data.append(FP16x16 { mag: 124518, sign: true });
data.append(FP16x16 { mag: 144179, sign: true });
data.append(FP16x16 { mag: 163840, sign: true });
data.append(FP16x16 { mag: 183500, sign: true });
TensorTrait::new(shape.span(), data.span())
}
28 changes: 28 additions & 0 deletions tests/nodes/round_fp16x16/output_0.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
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<FP16x16> {
let mut shape = ArrayTrait::<usize>::new();
shape.append(15);

let mut data = ArrayTrait::new();
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: 131072, sign: false });
data.append(FP16x16 { mag: 131072, sign: false });
data.append(FP16x16 { mag: 131072, sign: false });
data.append(FP16x16 { mag: 196608, sign: false });
data.append(FP16x16 { mag: 196608, sign: false });
data.append(FP16x16 { mag: 65536, sign: true });
data.append(FP16x16 { mag: 131072, sign: true });
data.append(FP16x16 { mag: 131072, sign: true });
data.append(FP16x16 { mag: 131072, sign: true });
data.append(FP16x16 { mag: 196608, sign: true });
data.append(FP16x16 { mag: 196608, sign: true });
TensorTrait::new(shape.span(), data.span())
}
Loading

0 comments on commit 1ae894e

Please sign in to comment.