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

Refactor reduce sum #616

Merged
merged 5 commits into from
Mar 25, 2024
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
15 changes: 6 additions & 9 deletions docs/framework/operators/tensor/tensor.reduce_sum.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
## tensor.reduce_sum

```rust
fn reduce_sum(self: @Tensor<T>, axis: usize, keepdims: bool) -> Tensor<T>;
fn reduce_sum(self: @Tensor<T>, axes: Option<Span<i32>>, keepdims: Option<bool>, noop_with_empty_axes: Option<bool>) -> Tensor<T>;
```

Reduces a tensor by summing its elements along a specified axis.

## Args

* `self`(`@Tensor<T>`) - The input tensor.
* `axis`(`usize`) - The dimension to reduce.
* `keepdims`(`bool`) - If true, retains reduced dimensions with length 1.

## Panics

* Panics if axis is not in the range of the input tensor's dimensions.
* `axes`(`Option<Span<i32>>`) - Optional input list of integers, along which to reduce. The default is to reduce over all the dimensions of the input tensor if 'noop_with_empty_axes' is false, else act as an Identity op when 'noop_with_empty_axes' is true.
* `keepdims`(`Option<bool>`) - Keep the reduced dimension or not, default 1 means keep reduced dimension.
* `noop_with_empty_axes`(`Option<bool>`) - Defines behavior if 'axes' is empty. Default behavior with 'false' is to reduce all axes. When axes is empty and this attribute is set to true, input tensor will not be reduced,and the output tensor would be equivalent to input tensor.

## Returns

A new `Tensor<T>` instance with the specified axis reduced by summing its elements.
Reduced output tensor.

## Examples

Expand All @@ -33,7 +30,7 @@ fn reduce_sum_example() -> Tensor<u32> {
);

// We can call `reduce_sum` function as follows.
return tensor.reduce_sum(axis: 0, keepdims: false);
return tensor.reduce_sum(axes: Option::None, keepdims: false);
}
>>> [[4,6],[8,10]]
```
314 changes: 54 additions & 260 deletions nodegen/node/reduce_sum.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,285 +4,79 @@


class Reduce_sum(RunAll):
@staticmethod
def reduce_sum_u32():
def reduce_sum_1D():
x = np.array([0, 1, 2,]).astype(np.uint32)
y = np.array([3]).astype(np.uint32)

x = Tensor(Dtype.U32, x.shape, x.flatten())
y = Tensor(Dtype.U32, y.shape, y.flatten())

name = "reduce_sum_u32_1D"
make_test(
[x], y, "input_0.reduce_sum(0, false)", name)

def reduce_sum_2D():
def default():
x = np.array([0, 1, 2, 3]).astype(np.uint32).reshape(2, 2)
y = np.array([2, 4]).astype(np.uint32)

x = Tensor(Dtype.U32, x.shape, x.flatten())
y = Tensor(Dtype.U32, y.shape, y.flatten())

name = "reduce_sum_u32_2D_default"
make_test(
[x], y, "input_0.reduce_sum(0, false)", name)

def keepdims():
x = np.array([0, 1, 2, 3]).astype(np.uint32).reshape(2, 2)
y = np.array([2, 4]).astype(np.uint32).reshape(1, 2)

x = Tensor(Dtype.U32, x.shape, x.flatten())
y = Tensor(Dtype.U32, y.shape, y.flatten())

name = "reduce_sum_u32_2D_keepdims"
make_test(
[x], y, "input_0.reduce_sum(0, true)", name)

def axis_1():
x = np.array([0, 1, 2, 3]).astype(np.uint32).reshape(2, 2)
y = np.array([1, 5]).astype(np.uint32)

x = Tensor(Dtype.U32, x.shape, x.flatten())
y = Tensor(Dtype.U32, y.shape, y.flatten())

name = "reduce_sum_u32_2D_axis_1"
make_test(
[x], y, "input_0.reduce_sum(1, false)", name)

default()
keepdims()
axis_1()
reduce_sum_1D()
reduce_sum_2D()

@staticmethod
def reduce_sum_i32():
def reduce_sum_1D():
x = np.array([0, 1, 2,]).astype(np.int32)
y = np.array([3]).astype(np.int32)
def reduce_sum_no_keep_dims():
axes = np.array([1], dtype=np.uint32)
keepdims = 0

x = Tensor(Dtype.I32, x.shape, x.flatten())
y = Tensor(Dtype.I32, y.shape, y.flatten())
x = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]], [
[9, 10], [11, 12]]]).astype(np.uint32)
y = np.sum(x, axis=tuple(axes.tolist()), keepdims=keepdims == 1)

name = "reduce_sum_i32_1D"
make_test(
[x], y, "input_0.reduce_sum(0, false)", name)
x = Tensor(Dtype.U32, x.shape, x.flatten())
y = Tensor(Dtype.U32, y.shape, y.flatten())

def reduce_sum_2D():
def default():
x = np.array([0, 1, 2, 3]).astype(np.int32).reshape(2, 2)
y = np.array([2, 4]).astype(np.int32)

x = Tensor(Dtype.I32, x.shape, x.flatten())
y = Tensor(Dtype.I32, y.shape, y.flatten())

name = "reduce_sum_i32_2D_default"
make_test(
[x], y, "input_0.reduce_sum(0, false)", name)

def keepdims():
x = np.array([0, 1, 2, 3]).astype(np.int32).reshape(2, 2)
y = np.array([2, 4]).astype(np.int32).reshape(1, 2)

x = Tensor(Dtype.I32, x.shape, x.flatten())
y = Tensor(Dtype.I32, y.shape, y.flatten())

name = "reduce_sum_i32_2D_keepdims"
make_test(
[x], y, "input_0.reduce_sum(0, true)", name)

def axis_1():
x = np.array([0, 1, 2, 3]).astype(np.int32).reshape(2, 2)
y = np.array([1, 5]).astype(np.int32)

x = Tensor(Dtype.I32, x.shape, x.flatten())
y = Tensor(Dtype.I32, y.shape, y.flatten())

name = "reduce_sum_i32_2D_axis_1"
make_test(
[x], y, "input_0.reduce_sum(1, false)", name)

default()
keepdims()
axis_1()
reduce_sum_1D()
reduce_sum_2D()
name = "reduce_sum_no_keep_dims"
make_test(
[x], y, "input_0.reduce_sum(Option::Some(array![1].span()), Option::Some(false), Option::None)", name)

@staticmethod
def reduce_sum_i8():
def reduce_sum_1D():
x = np.array([0, 1, 2,]).astype(np.int8)
y = np.array([3]).astype(np.int8)

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

name = "reduce_sum_i8_1D"
make_test(
[x], y, "input_0.reduce_sum(0, false)", name)

def reduce_sum_2D():
def default():
x = np.array([0, 1, 2, 3]).astype(np.int8).reshape(2, 2)
y = np.array([2, 4]).astype(np.int8)
def reduce_sum_keep_dims():
axes = np.array([1], dtype=np.uint32)
keepdims = 1

x = Tensor(Dtype.FP8x23, x.shape, x.flatten())
y = Tensor(Dtype.FP8x23, y.shape, y.flatten())
x = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]], [
[9, 10], [11, 12]]]).astype(np.uint32)
y = np.sum(x, axis=tuple(axes.tolist()), keepdims=keepdims == 1)

name = "reduce_sum_i8_2D_default"
make_test(
[x], y, "input_0.reduce_sum(0, false)", name)
x = Tensor(Dtype.U32, x.shape, x.flatten())
y = Tensor(Dtype.U32, y.shape, y.flatten())

def keepdims():
x = np.array([0, 1, 2, 3]).astype(np.int8).reshape(2, 2)
y = np.array([2, 4]).astype(np.int8).reshape(1, 2)

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

name = "reduce_sum_i8_2D_keepdims"
make_test(
[x], y, "input_0.reduce_sum(0, true)", name)

def axis_1():
x = np.array([0, 1, 2, 3]).astype(np.int8).reshape(2, 2)
y = np.array([1, 5]).astype(np.int8)

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

name = "reduce_sum_i8_2D_axis_1"
make_test(
[x], y, "input_0.reduce_sum(1, false)", name)

default()
keepdims()
axis_1()
reduce_sum_1D()
reduce_sum_2D()
name = "reduce_sum_keep_dims"
make_test(
[x], y, "input_0.reduce_sum(Option::Some(array![1].span()), Option::Some(true), Option::None)", name)

@staticmethod
def reduce_sum_fp8x23():
def reduce_sum_1D():
x = np.array([0, 1, 2,]).astype(np.int64)
y = np.array([3]).astype(np.int64)

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 = "reduce_sum_fp8x23_1D"
make_test(
[x], y, "input_0.reduce_sum(0, false)", name)

def reduce_sum_2D():
def default():
x = np.array([0, 1, 2, 3]).astype(np.int64).reshape(2, 2)
y = np.array([2, 4]).astype(np.int64)

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 = "reduce_sum_fp8x23_2D_default"
make_test(
[x], y, "input_0.reduce_sum(0, false)", name)

def keepdims():
x = np.array([0, 1, 2, 3]).astype(np.int64).reshape(2, 2)
y = np.array([2, 4]).astype(np.int64).reshape(1, 2)
def reduce_sum_default_axes_keepdims():
keepdims = 1

x = Tensor(Dtype.FP8x23, x.shape, to_fp(
x.flatten(), FixedImpl.FP8x23))
y = Tensor(Dtype.FP8x23, y.shape, to_fp(
y.flatten(), FixedImpl.FP8x23))
x = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]], [
[9, 10], [11, 12]]]).astype(np.uint32)
y = np.sum(x, axis=None, keepdims=keepdims == 1)

name = "reduce_sum_fp8x23_2D_keepdims"
make_test(
[x], y, "input_0.reduce_sum(0, true)", name)

def axis_1():
x = np.array([0, 1, 2, 3]).astype(np.int64).reshape(2, 2)
y = np.array([1, 5]).astype(np.int64)

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 = "reduce_sum_fp8x23_2D_axis_1"
make_test(
[x], y, "input_0.reduce_sum(1, false)", name)

default()
keepdims()
axis_1()

reduce_sum_1D()
reduce_sum_2D()
x = Tensor(Dtype.U32, x.shape, x.flatten())
y = Tensor(Dtype.U32, y.shape, y.flatten())

name = "reduce_sum_default_axes_keepdims"
make_test(
[x], y, "input_0.reduce_sum(Option::Some(array![].span()), Option::Some(true), Option::None)", name)

@staticmethod
def reduce_sum_fp16x16():
def reduce_sum_1D():
x = np.array([0, 1, 2,]).astype(np.int64)
y = np.array([3]).astype(np.int64)

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 = "reduce_sum_fp16x16_1D"
make_test(
[x], y, "input_0.reduce_sum(0, false)", name)
def reduce_sum_negative_axes_keepdims():
axes = np.array([-2], dtype=np.int64)
keepdims = 1

def reduce_sum_2D():
def default():
x = np.array([0, 1, 2, 3]).astype(np.int64).reshape(2, 2)
y = np.array([2, 4]).astype(np.int64)
x = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]], [
[9, 10], [11, 12]]]).astype(np.uint32)
y = np.sum(x, axis=tuple(axes.tolist()), keepdims=keepdims == 1)

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

name = "reduce_sum_fp16x16_2D_default"
make_test(
[x], y, "input_0.reduce_sum(0, false)", name)
name = "reduce_sum_negative_axes_keepdims"
make_test(
[x], y, "input_0.reduce_sum(Option::Some(array![-2].span()), Option::Some(true), Option::None)", name)

def keepdims():
x = np.array([0, 1, 2, 3]).astype(np.int64).reshape(2, 2)
y = np.array([2, 4]).astype(np.int64).reshape(1, 2)

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 = "reduce_sum_fp16x16_2D_keepdims"
make_test(
[x], y, "input_0.reduce_sum(0, true)", name)

def axis_1():
x = np.array([0, 1, 2, 3]).astype(np.int64).reshape(2, 2)
y = np.array([1, 5]).astype(np.int64)

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 = "reduce_sum_fp16x16_2D_axis_1"
make_test(
[x], y, "input_0.reduce_sum(1, false)", name)
@staticmethod
def reduce_sum_empty_axes_input_noop():
x = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]], [
[9, 10], [11, 12]]]).astype(np.uint32)
y = np.array(x)

default()
keepdims()
axis_1()
x = Tensor(Dtype.U32, x.shape, x.flatten())
y = Tensor(Dtype.U32, y.shape, y.flatten())

reduce_sum_1D()
reduce_sum_2D()
name = "reduce_sum_empty_axes_input_noop"
make_test(
[x], y, "input_0.reduce_sum(Option::None, Option::Some(true), Option::Some(true))", name)
Loading
Loading