Skip to content

Commit

Permalink
Merge pull request #616 from gizatechxyz/refactor-reduce-sum
Browse files Browse the repository at this point in the history
Refactor reduce sum
  • Loading branch information
raphaelDkhn authored Mar 25, 2024
2 parents fff7da6 + 0d4bacb commit 2dfec7d
Show file tree
Hide file tree
Showing 79 changed files with 590 additions and 1,120 deletions.
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

0 comments on commit 2dfec7d

Please sign in to comment.