Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: qlinear leaky relu #465

Merged
merged 2 commits into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
* [tensor.qlinear\_mul](framework/operators/tensor/tensor.qlinear\_mul.md)
* [tensor.qlinear\_matmul](framework/operators/tensor/tensor.qlinear\_matmul.md)
* [tensor.qlinear\_concat](framework/operators/tensor/tensor.qlinear\_concat.md)
* [tensor.qlinear\_leakyrelu](framework/operators/tensor/tensor.qlinear\_leakyrelu.md)
* [tensor.nonzero](framework/operators/tensor/tensor.nonzero.md)
* [tensor.squeeze](framework/operators/tensor/tensor.squeeze.md)
* [tensor.unsqueeze](framework/operators/tensor/tensor.unsqueeze.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 @@ -60,6 +60,7 @@ You can see below the list of current supported ONNX Operators:
| [QLinearConcat](operators/tensor/tensor.qlinear\_concat.md) | :white\_check\_mark: |
| [QlinearAdd](operators/tensor/tensor.qlinear\_add.md) | :white\_check\_mark: |
| [QlinearMul](operators/tensor/tensor.qlinear\_mul.md) | :white\_check\_mark: |
| [QLinearLeakyRelu](operators/tensor/tensor.qlinear\_leakyrelu.md) | :white\_check\_mark: |
| [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: |
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 @@ -84,6 +84,7 @@ use orion::operators::tensor::TensorTrait;
| [`tensor.qlinear_mul`](tensor.qlinear\_mul.md) | Performs the element-wise multiplication of quantized Tensors. |
| [`tensor.qlinear_matmul`](tensor.qlinear\_matmul.md) | Performs the product of two quantized i8 Tensors. |
| [`tensor.qlinear_concat`](tensor.qlinear\_concat.md) | Concatenate a list of tensors after dequantizing them with their respective scales and zero_points and returns the quantized result. |
| [`tensor.qlinear_leakyrelu`](tensor.qlinear\_leakyrelu.md) | Applies the Leaky Relu operator to a quantized Tensor |
| [`tensor.gather`](tensor.gather.md) | Gather entries of the axis dimension of data. |
| [`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. |
Expand Down
74 changes: 74 additions & 0 deletions docs/framework/operators/tensor/tensor.qlinear_leakyrelu.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# tensor.qlinear_leakyrelu

```rust
fn qlinear_leakyrelu(self: @Tensor<i8>, a_scale: @Tensor<T>, a_zero_point: @Tensor<T>, alpha: T) -> Tensor::<i8>;
```

Applies the Leaky Relu operator to a quantized Tensor

QLinar LeakyRelu takes as input a quantized Tensor, its scale and zero point and an scalar alpha, and produces one output data (a quantized Tensor)
where the function `f(x) = alpha * x for x < 0, f(x) = x for x >= 0`, is applied to the data tensor elementwise.
The quantization formula is y = saturate((x / y_scale) + y_zero_point).
Scale and zero point must have same shape and the same type. They must be either scalar (per tensor) or N-D tensor (per row for 'a' and per column for 'b').
Scalar refers to per tensor quantization whereas N-D refers to per row or per column quantization.

## Args

* `self`(`@Tensor<i8>`) - The first tensor to be multiplied (a).
* `a_scale`(`@Tensor<T>`) - Scale for input `a`.
* `a_zero_point`(`@Tensor<T>`) - Zero point for input `a`.
* `alpha`(`T`) - The factor multiplied to negative elements.

## Returns

A new `Tensor<i8>`, containing result of the Leaky Relu.

## Type Constraints

u32 tensor, not supported.
fp8x23wide tensor, not supported.
fp16x16wide tensor, not supported.
bool tensor, not supported.

## Example

```rust

use array::{ArrayTrait, SpanTrait};

use orion::operators::tensor::{TensorTrait, Tensor, I8Tensor, FP16x16Tensor};
use orion::numbers::{i8, FP16x16, FP16x16Impl, IntegerTrait, FixedTrait};


fn qlinear_leakyrelu_example() -> Tensor<i8> {
let a = TensorTrait::<
i8
>::new(
shape: array![2, 3].span(),
data: array![
IntegerTrait::<i8>::new(10_u8, true),
IntegerTrait::<i8>::new(10_u8, true),
IntegerTrait::<i8>::new(10_u8, true),
IntegerTrait::<i8>::new(10_u8, false),
IntegerTrait::<i8>::new(10_u8, false),
IntegerTrait::<i8>::new(10_u8, false)
]
.span(),
);

let a_scale = TensorTrait::<
FP16x16
>::new(shape: array![1].span(), data: array![FixedTrait::<FP16x16>::new(327680, false)].span(),);
let a_zero_point = TensorTrait::<
FP16x16
>::new(shape: array![1].span(), data: array![FixedTrait::<FP16x16>::new(131072, false)].span(),);

let alpha = FixedTrait::<FP16x16>::new(655360, false);

return = a
.qlinear_leakyrelu(
@a_scale, @a_zero_point, alpha
);
}

>>> [[-118, -118, -118], [10, 10, 10]]
79 changes: 79 additions & 0 deletions src/operators/tensor/core.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ impl TensorSerde<T, impl TSerde: Serde<T>, impl TDrop: Drop<T>> of Serde<Tensor<
/// qlinear_mul - Performs the element-wise multiplication of quantized Tensors.
/// qlinear_matmul - Performs the product of two quantized i8 Tensors.
/// qlinear_concat - Concatenate a list of tensors after dequantizing them with their respective scales and zero_points and returns the quantized result.
/// qlinear_leakyrelu - Applies the Leaky Relu operator to a quantized Tensor
/// gather - Gather entries of the axis dimension of data.
/// nonzero - Produces indices of the elements that are non-zero (in row-major order - by dimension).
/// squeeze - Removes dimensions of size 1 from the shape of a tensor.
Expand Down Expand Up @@ -3011,6 +3012,84 @@ trait TensorTrait<T> {
y_zero_point: @Tensor<T>,
axis: usize
) -> Tensor::<i8>;
/// # tensor.qlinear_leakyrelu
///
/// ```rust
/// fn qlinear_leakyrelu(self: @Tensor<i8>, a_scale: @Tensor<T>, a_zero_point: @Tensor<T>, alpha: T) -> Tensor::<i8>;
/// ```
///
/// Applies the Leaky Relu operator to a quantized Tensor
///
/// QLinar LeakyRelu takes as input a quantized Tensor, its scale and zero point and an scalar alpha, and produces one output data (a quantized Tensor)
/// where the function `f(x) = alpha * x for x < 0, f(x) = x for x >= 0`, is applied to the data tensor elementwise.
/// The quantization formula is y = saturate((x / y_scale) + y_zero_point).
/// Scale and zero point must have same shape and the same type. They must be either scalar (per tensor) or N-D tensor (per row for 'a' and per column for 'b').
/// Scalar refers to per tensor quantization whereas N-D refers to per row or per column quantization.
///
/// ## Args
///
/// * `self`(`@Tensor<i8>`) - The first tensor to be multiplied (a).
/// * `a_scale`(`@Tensor<T>`) - Scale for input `a`.
/// * `a_zero_point`(`@Tensor<T>`) - Zero point for input `a`.
/// * `alpha`(`T`) - The factor multiplied to negative elements.
///
/// ## Returns
///
/// A new `Tensor<i8>`, containing result of the Leaky Relu.
///
/// ## Type Constraints
///
/// u32 tensor, not supported.
/// fp8x23wide tensor, not supported.
/// fp16x16wide tensor, not supported.
/// bool tensor, not supported.
///
/// ## Example
///
/// ```rust

/// use array::{ArrayTrait, SpanTrait};
///
/// use orion::operators::tensor::{TensorTrait, Tensor, I8Tensor, FP16x16Tensor};
/// use orion::numbers::{i8, FP16x16, FP16x16Impl, IntegerTrait, FixedTrait};
///
///
/// fn qlinear_leakyrelu_example() -> Tensor<i8> {
/// let a = TensorTrait::<
/// i8
/// >::new(
/// shape: array![2, 3].span(),
/// data: array![
/// IntegerTrait::<i8>::new(10_u8, true),
/// IntegerTrait::<i8>::new(10_u8, true),
/// IntegerTrait::<i8>::new(10_u8, true),
/// IntegerTrait::<i8>::new(10_u8, false),
/// IntegerTrait::<i8>::new(10_u8, false),
/// IntegerTrait::<i8>::new(10_u8, false)
/// ]
/// .span(),
/// );
///
/// let a_scale = TensorTrait::<
/// FP16x16
/// >::new(shape: array![1].span(), data: array![FixedTrait::<FP16x16>::new(327680, false)].span(),);
/// let a_zero_point = TensorTrait::<
/// FP16x16
/// >::new(shape: array![1].span(), data: array![FixedTrait::<FP16x16>::new(131072, false)].span(),);
///
/// let alpha = FixedTrait::<FP16x16>::new(655360, false);
///
/// return = a
/// .qlinear_leakyrelu(
/// @a_scale, @a_zero_point, alpha
/// );
/// }
///
/// >>> [[-118, -118, -118], [10, 10, 10]]
///
fn qlinear_leakyrelu(
self: @Tensor<i8>, a_scale: @Tensor<T>, a_zero_point: @Tensor<T>, alpha: T
) -> Tensor::<i8>;
/// # tensor.slice
///
/// ```rust
Expand Down
6 changes: 6 additions & 0 deletions src/operators/tensor/implementations/tensor_bool.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,12 @@ impl BoolTensor of TensorTrait<bool> {
) -> Tensor::<i8> {
panic(array!['not supported!'])
}
fn qlinear_leakyrelu(
self: @Tensor<i8>, a_scale: @Tensor<bool>, a_zero_point: @Tensor<bool>, alpha: bool,
) -> Tensor::<i8> {
panic(array!['not supported!'])
}


fn round(self: @Tensor<bool>) -> Tensor<bool> {
panic(array!['not supported!'])
Expand Down
13 changes: 13 additions & 0 deletions src/operators/tensor/implementations/tensor_fp16x16.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,19 @@ impl FP16x16Tensor of TensorTrait<FP16x16> {
)
}

fn qlinear_leakyrelu(
self: @Tensor<i8>, a_scale: @Tensor<FP16x16>, a_zero_point: @Tensor<FP16x16>, alpha: FP16x16
) -> Tensor::<i8> {
quantization::qlinear_leakyrelu::qlinear_leakyrelu(
self,
a_scale,
a_zero_point,
alpha,
NumberTrait::new_unscaled(128, true),
NumberTrait::new_unscaled(127, false)
)
}

fn slice(
self: @Tensor<FP16x16>,
starts: Span<usize>,
Expand Down
9 changes: 9 additions & 0 deletions src/operators/tensor/implementations/tensor_fp16x16wide.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,15 @@ impl FP16x16WTensor of TensorTrait<FP16x16W> {
panic(array!['not supported!'])
}

fn qlinear_leakyrelu(
self: @Tensor<i8>,
a_scale: @Tensor<FP16x16W>,
a_zero_point: @Tensor<FP16x16W>,
alpha: FP16x16W
) -> Tensor::<i8> {
panic(array!['not supported!'])
}

fn slice(
self: @Tensor<FP16x16W>,
starts: Span<usize>,
Expand Down
13 changes: 13 additions & 0 deletions src/operators/tensor/implementations/tensor_fp32x32.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,19 @@ impl FP32x32Tensor of TensorTrait<FP32x32> {
)
}

fn qlinear_leakyrelu(
self: @Tensor<i8>, a_scale: @Tensor<FP32x32>, a_zero_point: @Tensor<FP32x32>, alpha: FP32x32
) -> Tensor::<i8> {
quantization::qlinear_leakyrelu::qlinear_leakyrelu(
self,
a_scale,
a_zero_point,
alpha,
NumberTrait::new_unscaled(128, true),
NumberTrait::new_unscaled(127, false)
)
}

fn slice(
self: @Tensor<FP32x32>,
starts: Span<usize>,
Expand Down
13 changes: 13 additions & 0 deletions src/operators/tensor/implementations/tensor_fp64x64.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,19 @@ impl FP64x64Tensor of TensorTrait<FP64x64> {
)
}

fn qlinear_leakyrelu(
self: @Tensor<i8>, a_scale: @Tensor<FP64x64>, a_zero_point: @Tensor<FP64x64>, alpha: FP64x64
) -> Tensor::<i8> {
quantization::qlinear_leakyrelu::qlinear_leakyrelu(
self,
a_scale,
a_zero_point,
alpha,
NumberTrait::new_unscaled(128, true),
NumberTrait::new_unscaled(127, false)
)
}

fn slice(
self: @Tensor<FP64x64>,
starts: Span<usize>,
Expand Down
14 changes: 14 additions & 0 deletions src/operators/tensor/implementations/tensor_fp8x23.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,20 @@ impl FP8x23Tensor of TensorTrait<FP8x23> {
)
}

fn qlinear_leakyrelu(
self: @Tensor<i8>, a_scale: @Tensor<FP8x23>, a_zero_point: @Tensor<FP8x23>, alpha: FP8x23
) -> Tensor::<i8> {
quantization::qlinear_leakyrelu::qlinear_leakyrelu(
self,
a_scale,
a_zero_point,
alpha,
NumberTrait::new_unscaled(128, true),
NumberTrait::new_unscaled(127, false)
)
}


fn slice(
self: @Tensor<FP8x23>,
starts: Span<usize>,
Expand Down
6 changes: 6 additions & 0 deletions src/operators/tensor/implementations/tensor_fp8x23wide.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,12 @@ impl FP8x23WTensor of TensorTrait<FP8x23W> {
panic(array!['not supported!'])
}

fn qlinear_leakyrelu(
self: @Tensor<i8>, a_scale: @Tensor<FP8x23W>, a_zero_point: @Tensor<FP8x23W>, alpha: FP8x23W
) -> Tensor::<i8> {
panic(array!['not supported!'])
}

fn slice(
self: @Tensor<FP8x23W>,
starts: Span<usize>,
Expand Down
12 changes: 12 additions & 0 deletions src/operators/tensor/implementations/tensor_i32.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,18 @@ impl I32Tensor of TensorTrait<i32> {
)
}

fn qlinear_leakyrelu(
self: @Tensor<i8>, a_scale: @Tensor<i32>, a_zero_point: @Tensor<i32>, alpha: i32
) -> Tensor::<i8> {
quantization::qlinear_leakyrelu::qlinear_leakyrelu(
self,
a_scale,
a_zero_point,
alpha,
NumberTrait::new_unscaled(128, true),
NumberTrait::new_unscaled(127, false)
)
}

fn slice(
self: @Tensor<i32>,
Expand Down
15 changes: 14 additions & 1 deletion src/operators/tensor/implementations/tensor_i8.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,20 @@ impl I8Tensor of TensorTrait<i8> {
zero_points,
y_scale,
y_zero_point,
axis,
axis,
NumberTrait::new_unscaled(128, true),
NumberTrait::new_unscaled(127, false)
)
}

fn qlinear_leakyrelu(
self: @Tensor<i8>, a_scale: @Tensor<i8>, a_zero_point: @Tensor<i8>, alpha: i8
) -> Tensor::<i8> {
quantization::qlinear_leakyrelu::qlinear_leakyrelu(
self,
a_scale,
a_zero_point,
alpha,
NumberTrait::new_unscaled(128, true),
NumberTrait::new_unscaled(127, false)
)
Expand Down
6 changes: 6 additions & 0 deletions src/operators/tensor/implementations/tensor_u32.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,12 @@ impl U32Tensor of TensorTrait<u32> {
panic(array!['not supported!'])
}

fn qlinear_leakyrelu(
self: @Tensor<i8>, a_scale: @Tensor<u32>, a_zero_point: @Tensor<u32>, alpha: u32
) -> Tensor::<i8> {
panic(array!['not supported!'])
}

fn slice(
self: @Tensor<u32>,
starts: Span<usize>,
Expand Down
1 change: 1 addition & 0 deletions src/operators/tensor/quantization.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ mod qlinear_matmul;
mod qlinear_concat;
mod qlinear_add;
mod qlinear_mul;
mod qlinear_leakyrelu;
Loading