From 6626c2c8828206e369775c1fe62a31372d80fff9 Mon Sep 17 00:00:00 2001 From: Seonmyeong Bak Date: Tue, 7 Jun 2022 16:34:59 -0700 Subject: [PATCH 01/11] Atleast_{1,2,3}d the first implementation --- cunumeric/module.py | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/cunumeric/module.py b/cunumeric/module.py index 5b48855f26..6d3603da9f 100644 --- a/cunumeric/module.py +++ b/cunumeric/module.py @@ -991,6 +991,53 @@ def reshape(a, newshape, order="C"): return a.reshape(newshape, order=order) +def _reshape_recur(ndim, arr): + if arr.ndim < ndim: + arr = _reshape_recur(ndim - 1, arr) + if ndim == 2: + arr = arr.reshape((1,) + arr.shape) + else: + arr = arr.reshape(arr.shape + (1,)) + + return arr + + +def _atleast_nd(ndim, arys): + arys = list(convert_to_cunumeric_ndarray(arr) for arr in arys) + inputs = list(arr.view() for arr in arys) + result = list(_reshape_recur(ndim, arr) for arr in inputs) + # if the number of arrys in `arys` is 1, the return value is a single array + if len(result) == 1: + result = result[0] + """ + if ndim > 1: + arys = atleast_nd(ndim - 1, arys) + if ndim == 2: + arys = list( + arr.reshape((1,) + arr.shape) if arr.ndim < ndim else arr + for arr in arys + ) + else: + arys = list( + arr.reshape(arr.shape + (1,)) if arr.ndim < ndim else arr + for arr in arys + ) + """ + return result + + +def atleast_1d(*arys): + return _atleast_nd(1, arys) + + +def atleast_2d(*arys): + return _atleast_nd(2, arys) + + +def atleast_3d(*arys): + return _atleast_nd(3, arys) + + # Transpose-like operations From b5719f3681fe0041a6b97ee5f08754646227b6f0 Mon Sep 17 00:00:00 2001 From: Seonmyeong Bak Date: Tue, 14 Jun 2022 16:27:10 -0700 Subject: [PATCH 02/11] Added a test for atleast_nd routines --- tests/integration/test_atleast_nd.py | 90 ++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 tests/integration/test_atleast_nd.py diff --git a/tests/integration/test_atleast_nd.py b/tests/integration/test_atleast_nd.py new file mode 100644 index 0000000000..3680ddc931 --- /dev/null +++ b/tests/integration/test_atleast_nd.py @@ -0,0 +1,90 @@ +# Copyright 2022 NVIDIA Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import numpy as np +import pytest + +import cunumeric as num + + +def _check(a, routine, sizes): + b = getattr(np, routine)(*a) + c = getattr(num, routine)(*a) + is_equal = True + err_arr = [b, c] + + if len(b) != len(c): + is_equal = False + err_arr = [b, c] + else: + for each in zip(b, c): + if not np.array_equal(*each): + err_arr = each + is_equal = False + break + print_msg = f"np.{routine}({sizes})" + assert is_equal, ( + f"Failed, {print_msg}\n" + f"numpy result: {err_arr[0]}\n" + f"cunumeric_result: {err_arr[1]}\n" + f"cunumeric and numpy shows" + f" different result\n" + ) + print(f"Passed, {print_msg}, np: {b}" f", cunumeric: {c}") + + +DIM = 10 + +SIZE_CASES = [ + (0,), # empty array + (1,), # singlton array + (10,), # scalar + (DIM, 1), # 1D array + (DIM, DIM), # 2D array + (DIM, DIM, DIM), # 3D array + (DIM, DIM, DIM, DIM), # 4D array +] + + +# test to run atleast_nd w/ a single array +@pytest.mark.parametrize("size", SIZE_CASES, ids=str) +def test_atleast_1d(size): + a = [np.arange(np.prod(size)).reshape(size)] + _check(a, "atleast_1d", size) + + +@pytest.mark.parametrize("size", SIZE_CASES, ids=str) +def test_atleast_2d(size): + a = [np.arange(np.prod(size)).reshape(size)] + _check(a, "atleast_2d", size) + + +@pytest.mark.parametrize("size", SIZE_CASES, ids=str) +def test_atleast_3d(size): + a = [np.arange(np.prod(size)).reshape(size)] + _check(a, "atleast_3d", size) + + +# test to run atleast_nd w/ list of arrays +@pytest.mark.parametrize("dim", range(1, 4)) +def test_atleast_nd(dim): + a = list(np.arange(np.prod(size)).reshape(size) for size in SIZE_CASES) + _check(a, f"atleast_{dim}d", SIZE_CASES) + + +if __name__ == "__main__": + import sys + + sys.exit(pytest.main(sys.argv)) From 2e698d8427307071eafc35a8539c70f1767cc2d9 Mon Sep 17 00:00:00 2001 From: Seonmyeong Bak Date: Tue, 14 Jun 2022 16:28:18 -0700 Subject: [PATCH 03/11] Applied atleast_nd routines to `vstack` and `hstack` --- cunumeric/module.py | 35 +++++++---------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/cunumeric/module.py b/cunumeric/module.py index 6d3603da9f..8f274ccd88 100644 --- a/cunumeric/module.py +++ b/cunumeric/module.py @@ -1002,27 +1002,14 @@ def _reshape_recur(ndim, arr): return arr -def _atleast_nd(ndim, arys): - arys = list(convert_to_cunumeric_ndarray(arr) for arr in arys) - inputs = list(arr.view() for arr in arys) +def _atleast_nd(ndim, arys, view=True): + inputs = arys = list(convert_to_cunumeric_ndarray(arr) for arr in arys) + if view: + inputs = list(arr.view() for arr in arys) result = list(_reshape_recur(ndim, arr) for arr in inputs) # if the number of arrys in `arys` is 1, the return value is a single array if len(result) == 1: result = result[0] - """ - if ndim > 1: - arys = atleast_nd(ndim - 1, arys) - if ndim == 2: - arys = list( - arr.reshape((1,) + arr.shape) if arr.ndim < ndim else arr - for arr in arys - ) - else: - arys = list( - arr.reshape(arr.shape + (1,)) if arr.ndim < ndim else arr - for arr in arys - ) - """ return result @@ -1628,10 +1615,7 @@ def vstack(tup): """ # Reshape arrays in the `array_list` if needed before concatenation inputs = list(convert_to_cunumeric_ndarray(inp) for inp in tup) - reshaped = list( - inp.reshape([1, inp.shape[0]]) if inp.ndim == 1 else inp - for inp in inputs - ) + reshaped = _atleast_nd(2, inputs, False) tup, common_info = check_shape_dtype(reshaped, vstack.__name__, 0) common_info.shape = tup[0].shape @@ -1721,14 +1705,9 @@ def dstack(tup): Multiple GPUs, Multiple CPUs """ # Reshape arrays to (1,N,1) for ndim ==1 or (M,N,1) for ndim == 2: - reshaped = [] + # reshaped = [] inputs = list(convert_to_cunumeric_ndarray(inp) for inp in tup) - for arr in inputs: - if arr.ndim == 1: - arr = arr.reshape((1,) + arr.shape + (1,)) - elif arr.ndim == 2: - arr = arr.reshape(arr.shape + (1,)) - reshaped.append(arr) + reshaped = _atleast_nd(3, inputs, False) tup, common_info = check_shape_dtype(reshaped, dstack.__name__, 2) return _concatenate( From b715a79193e2e6c83e55c3f99c8f3001dff909eb Mon Sep 17 00:00:00 2001 From: Seonmyeong Bak Date: Wed, 15 Jun 2022 16:34:53 -0700 Subject: [PATCH 04/11] Added description of atleast_nd routines --- cunumeric/module.py | 151 +++++++++++++++++++++++++++++++++----------- 1 file changed, 115 insertions(+), 36 deletions(-) diff --git a/cunumeric/module.py b/cunumeric/module.py index 8f274ccd88..45f80b3e9e 100644 --- a/cunumeric/module.py +++ b/cunumeric/module.py @@ -991,40 +991,6 @@ def reshape(a, newshape, order="C"): return a.reshape(newshape, order=order) -def _reshape_recur(ndim, arr): - if arr.ndim < ndim: - arr = _reshape_recur(ndim - 1, arr) - if ndim == 2: - arr = arr.reshape((1,) + arr.shape) - else: - arr = arr.reshape(arr.shape + (1,)) - - return arr - - -def _atleast_nd(ndim, arys, view=True): - inputs = arys = list(convert_to_cunumeric_ndarray(arr) for arr in arys) - if view: - inputs = list(arr.view() for arr in arys) - result = list(_reshape_recur(ndim, arr) for arr in inputs) - # if the number of arrys in `arys` is 1, the return value is a single array - if len(result) == 1: - result = result[0] - return result - - -def atleast_1d(*arys): - return _atleast_nd(1, arys) - - -def atleast_2d(*arys): - return _atleast_nd(2, arys) - - -def atleast_3d(*arys): - return _atleast_nd(3, arys) - - # Transpose-like operations @@ -1136,6 +1102,120 @@ def moveaxis(a, source, destination): # Changing number of dimensions +def _reshape_recur(ndim, arr): + if arr.ndim < ndim: + arr = _reshape_recur(ndim - 1, arr) + if ndim == 2: + arr = arr.reshape((1,) + arr.shape) + else: + arr = arr.reshape(arr.shape + (1,)) + + return arr + + +def _atleast_nd(ndim, arys, view=True): + inputs = arys = list(convert_to_cunumeric_ndarray(arr) for arr in arys) + if view: + inputs = list(arr.view() for arr in arys) + result = list(_reshape_recur(ndim, arr) for arr in inputs) + # if the number of arrys in `arys` is 1, the return value is a single array + if len(result) == 1: + result = result[0] + return result + + +def atleast_1d(*arys): + """ + + Convert inputs to arrays with at least one dimension. + Scalar inputs are converted to 1-dimensional arrays, + whilst higher-dimensional inputs are preserved. + + Parameters + ---------- + arys1, arys2, … : array_like + One or more input arrays. + + Returns + ------- + ret : ndarray + An array, or list of arrays, each with a.ndim >= 1. + Copies are made only if necessary. + + See Also + -------- + numpy.atleast_1d + + Availability + -------- + Multiple GPUs, Multiple CPUs + """ + return _atleast_nd(1, arys) + + +def atleast_2d(*arys): + """ + + View inputs as arrays with at least two dimensions. + + Parameters + ---------- + arys1, arys2, … : array_like + One or more array-like sequences. + Non-array inputs are converted to arrays. + Arrays that already have two or more dimensions are preserved. + + Returns + ------- + res, res2, … : ndarray + An array, or list of arrays, each with a.ndim >= 2. + Copies are avoided where possible, and + views with two or more dimensions are returned. + + See Also + -------- + numpy.atleast_2d + + Availability + -------- + Multiple GPUs, Multiple CPUs + """ + return _atleast_nd(2, arys) + + +def atleast_3d(*arys): + """ + + View inputs as arrays with at least three dimensions. + + Parameters + ---------- + arys1, arys2, … : array_like + One or more array-like sequences. + Non-array inputs are converted to arrays. + Arrays that already have two or more dimensions are preserved. + + Returns + ------- + res, res2, … : ndarray + An array, or list of arrays, each with a.ndim >= 3. + Copies are avoided where possible, and + views with three or more dimensions are returned. + For example, a 1-D array of shape (N,) becomes + a view of shape (1, N, 1), and a 2-D array of shape (M, N) + becomes a view of shape (M, N, 1). + + See Also + -------- + numpy.atleast_3d + + Availability + -------- + Multiple GPUs, Multiple CPUs + """ + return _atleast_nd(3, arys) + + @add_boilerplate("a") def squeeze(a, axis=None): """ @@ -1704,9 +1784,8 @@ def dstack(tup): -------- Multiple GPUs, Multiple CPUs """ - # Reshape arrays to (1,N,1) for ndim ==1 or (M,N,1) for ndim == 2: - # reshaped = [] inputs = list(convert_to_cunumeric_ndarray(inp) for inp in tup) + # Reshape arrays to (1,N,1) for ndim ==1 or (M,N,1) for ndim == 2: reshaped = _atleast_nd(3, inputs, False) tup, common_info = check_shape_dtype(reshaped, dstack.__name__, 2) From f67361f8aa19f800482f9daafd882798358d3b58 Mon Sep 17 00:00:00 2001 From: Seonmyeong Bak Date: Wed, 22 Jun 2022 15:04:52 -0700 Subject: [PATCH 05/11] Modified to do 'reshape' only once for each arr after collecting the final shapes of arrays --- cunumeric/module.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/cunumeric/module.py b/cunumeric/module.py index 45f80b3e9e..9a329375e8 100644 --- a/cunumeric/module.py +++ b/cunumeric/module.py @@ -1104,20 +1104,25 @@ def moveaxis(a, source, destination): def _reshape_recur(ndim, arr): if arr.ndim < ndim: - arr = _reshape_recur(ndim - 1, arr) + cur_shape = _reshape_recur(ndim - 1, arr) if ndim == 2: - arr = arr.reshape((1,) + arr.shape) + cur_shape = (1,) + cur_shape else: - arr = arr.reshape(arr.shape + (1,)) - - return arr + cur_shape = cur_shape + (1,) + else: + cur_shape = arr.shape + return cur_shape def _atleast_nd(ndim, arys, view=True): inputs = arys = list(convert_to_cunumeric_ndarray(arr) for arr in arys) if view: inputs = list(arr.view() for arr in arys) - result = list(_reshape_recur(ndim, arr) for arr in inputs) + result_shapes = list(_reshape_recur(ndim, arr) for arr in inputs) + # 'reshape' change the shape of arrays only when arr.shape != shape + result = list( + arr.reshape(shape) for arr, shape in zip(inputs, result_shapes) + ) # if the number of arrys in `arys` is 1, the return value is a single array if len(result) == 1: result = result[0] From 4581e8f6a96a3bf8661f64c34f06cd2653972856 Mon Sep 17 00:00:00 2001 From: Seonmyeong Bak Date: Wed, 29 Jun 2022 01:22:38 -0700 Subject: [PATCH 06/11] Changed the 'atleast_nd' routines to use type annotations and modified 'test_atleast_nd.py' to use LEGATE_MAX_DIM --- cunumeric/module.py | 20 ++++++++++---------- tests/integration/test_atleast_nd.py | 10 ++++------ 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/cunumeric/module.py b/cunumeric/module.py index a7b3025d16..7fb57aa8ae 100644 --- a/cunumeric/module.py +++ b/cunumeric/module.py @@ -1138,7 +1138,7 @@ def moveaxis( # Changing number of dimensions -def _reshape_recur(ndim, arr): +def _reshape_recur(ndim: int, arr: ndarray) -> tuple[int]: if arr.ndim < ndim: cur_shape = _reshape_recur(ndim - 1, arr) if ndim == 2: @@ -1150,22 +1150,22 @@ def _reshape_recur(ndim, arr): return cur_shape -def _atleast_nd(ndim, arys, view=True): +def _atleast_nd( + ndim: int, arys: Sequence[ndarray], view: Optional[bool] = True +) -> Union(list[ndarray], ndarray): inputs = arys = list(convert_to_cunumeric_ndarray(arr) for arr in arys) if view: inputs = list(arr.view() for arr in arys) - result_shapes = list(_reshape_recur(ndim, arr) for arr in inputs) - # 'reshape' change the shape of arrays only when arr.shape != shape - result = list( - arr.reshape(shape) for arr, shape in zip(inputs, result_shapes) - ) + # 'reshape' change the shape of arrays + # only when arr.shape != _reshape_recur(ndim,arr) + result = list(arr.reshape(_reshape_recur(ndim, arr)) for arr in inputs) # if the number of arrys in `arys` is 1, the return value is a single array if len(result) == 1: result = result[0] return result -def atleast_1d(*arys): +def atleast_1d(*arys: Sequence[ndarray]) -> Union(list[ndarray], ndarray): """ Convert inputs to arrays with at least one dimension. @@ -1194,7 +1194,7 @@ def atleast_1d(*arys): return _atleast_nd(1, arys) -def atleast_2d(*arys): +def atleast_2d(*arys: Sequence[ndarray]) -> Union(list[ndarray], ndarray): """ View inputs as arrays with at least two dimensions. @@ -1224,7 +1224,7 @@ def atleast_2d(*arys): return _atleast_nd(2, arys) -def atleast_3d(*arys): +def atleast_3d(*arys: Sequence[ndarray]) -> Union(list[ndarray], ndarray): """ View inputs as arrays with at least three dimensions. diff --git a/tests/integration/test_atleast_nd.py b/tests/integration/test_atleast_nd.py index 3680ddc931..67c29f65d6 100644 --- a/tests/integration/test_atleast_nd.py +++ b/tests/integration/test_atleast_nd.py @@ -17,6 +17,7 @@ import pytest import cunumeric as num +from legate.core import LEGATE_MAX_DIM def _check(a, routine, sizes): @@ -47,14 +48,11 @@ def _check(a, routine, sizes): DIM = 10 -SIZE_CASES = [ +SIZE_CASES = list((DIM,) * ndim for ndim in range(LEGATE_MAX_DIM + 1)) + +SIZE_CASES += [ (0,), # empty array (1,), # singlton array - (10,), # scalar - (DIM, 1), # 1D array - (DIM, DIM), # 2D array - (DIM, DIM, DIM), # 3D array - (DIM, DIM, DIM, DIM), # 4D array ] From fb72962851ab82ef3ff2a97870e13b5c55275308 Mon Sep 17 00:00:00 2001 From: Seonmyeong Bak Date: Tue, 19 Jul 2022 14:24:10 -0700 Subject: [PATCH 07/11] Made a change with reference to comments on PR regarding description of functions --- cunumeric/module.py | 8 ++++---- docs/cunumeric/source/api/manipulation.rst | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/cunumeric/module.py b/cunumeric/module.py index 7fb57aa8ae..ff0e7f84e9 100644 --- a/cunumeric/module.py +++ b/cunumeric/module.py @@ -1174,7 +1174,7 @@ def atleast_1d(*arys: Sequence[ndarray]) -> Union(list[ndarray], ndarray): Parameters ---------- - arys1, arys2, … : array_like + *arys : array_like One or more input arrays. Returns @@ -1201,7 +1201,7 @@ def atleast_2d(*arys: Sequence[ndarray]) -> Union(list[ndarray], ndarray): Parameters ---------- - arys1, arys2, … : array_like + *arys : array_like One or more array-like sequences. Non-array inputs are converted to arrays. Arrays that already have two or more dimensions are preserved. @@ -1231,10 +1231,10 @@ def atleast_3d(*arys: Sequence[ndarray]) -> Union(list[ndarray], ndarray): Parameters ---------- - arys1, arys2, … : array_like + *arys : array_like One or more array-like sequences. Non-array inputs are converted to arrays. - Arrays that already have two or more dimensions are preserved. + Arrays that already have three or more dimensions are preserved. Returns ------- diff --git a/docs/cunumeric/source/api/manipulation.rst b/docs/cunumeric/source/api/manipulation.rst index c930792050..bed086f10b 100644 --- a/docs/cunumeric/source/api/manipulation.rst +++ b/docs/cunumeric/source/api/manipulation.rst @@ -40,7 +40,9 @@ Changing number of dimensions :toctree: generated/ squeeze - + atleast_1d + atleast_2d + atleast_3d Changing kind of array ---------------------- From b071937ba4db3fe24343a9e9dff76f641a624bb6 Mon Sep 17 00:00:00 2001 From: Seonmyeong Bak Date: Tue, 19 Jul 2022 16:31:05 -0700 Subject: [PATCH 08/11] Made the `view` arugment in `_atleast_nd` not to use `Optional` --- cunumeric/module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cunumeric/module.py b/cunumeric/module.py index ff0e7f84e9..041465a71c 100644 --- a/cunumeric/module.py +++ b/cunumeric/module.py @@ -1151,7 +1151,7 @@ def _reshape_recur(ndim: int, arr: ndarray) -> tuple[int]: def _atleast_nd( - ndim: int, arys: Sequence[ndarray], view: Optional[bool] = True + ndim: int, arys: Sequence[ndarray], view: bool = True ) -> Union(list[ndarray], ndarray): inputs = arys = list(convert_to_cunumeric_ndarray(arr) for arr in arys) if view: From b32c24b7f7313c325119a53d3b85abe2db3c50eb Mon Sep 17 00:00:00 2001 From: Seonmyeong Bak Date: Wed, 20 Jul 2022 15:33:49 -0700 Subject: [PATCH 09/11] Fixed the bug w/ singleton arrays for `vstack` and `dstack` after `_atleast_nd` is applied Added a test case for singleton arrays in `test_concatenate_stack` --- cunumeric/module.py | 18 +++++++--------- tests/integration/test_concatenate_stack.py | 24 ++++++++++++++------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/cunumeric/module.py b/cunumeric/module.py index be0ced7992..7e4bc3ffac 100644 --- a/cunumeric/module.py +++ b/cunumeric/module.py @@ -1153,7 +1153,7 @@ def _reshape_recur(ndim: int, arr: ndarray) -> tuple[int]: def _atleast_nd( ndim: int, arys: Sequence[ndarray], view: bool = True ) -> Union(list[ndarray], ndarray): - inputs = arys = list(convert_to_cunumeric_ndarray(arr) for arr in arys) + inputs = list(convert_to_cunumeric_ndarray(arr) for arr in arys) if view: inputs = list(arr.view() for arr in arys) # 'reshape' change the shape of arrays @@ -1714,8 +1714,7 @@ def stack( " of input arrays" ) - shape = list(common_info.shape) - shape.insert(axis, 1) + shape = common_info.shape[:axis] + (1,) + common_info.shape[axis:] arrays = [arr.reshape(shape) for arr in arrays] common_info.shape = tuple(shape) return _concatenate(arrays, common_info, axis, out=out) @@ -1755,11 +1754,10 @@ def vstack(tup: Sequence[ndarray]) -> ndarray: Multiple GPUs, Multiple CPUs """ # Reshape arrays in the `array_list` if needed before concatenation - inputs = list(convert_to_cunumeric_ndarray(inp) for inp in tup) - reshaped = _atleast_nd(2, inputs, False) + reshaped = _atleast_nd(2, tup, False) + if not isinstance(reshaped, list): + reshaped = [reshaped] tup, common_info = check_shape_dtype(reshaped, vstack.__name__, 0) - common_info.shape = tup[0].shape - return _concatenate( tup, common_info, @@ -1845,11 +1843,11 @@ def dstack(tup: Sequence[ndarray]) -> ndarray: -------- Multiple GPUs, Multiple CPUs """ - inputs = list(convert_to_cunumeric_ndarray(inp) for inp in tup) # Reshape arrays to (1,N,1) for ndim ==1 or (M,N,1) for ndim == 2: - reshaped = _atleast_nd(3, inputs, False) + reshaped = _atleast_nd(3, tup, False) + if not isinstance(reshaped, list): + reshaped = [reshaped] tup, common_info = check_shape_dtype(reshaped, dstack.__name__, 2) - return _concatenate( tup, common_info, diff --git a/tests/integration/test_concatenate_stack.py b/tests/integration/test_concatenate_stack.py index 5d3e7be084..6ecc5b45ec 100644 --- a/tests/integration/test_concatenate_stack.py +++ b/tests/integration/test_concatenate_stack.py @@ -68,6 +68,8 @@ def run_test(arr, routine, input_size): DIM = 10 +NUM_ARR = [1, 3] + SIZES = [ (0,), (0, 10), @@ -81,40 +83,46 @@ def run_test(arr, routine, input_size): @pytest.fixture(autouse=True) -def a(size): - return [np.random.randint(low=0, high=100, size=size) for _ in range(3)] +def a(size, num): + return [np.random.randint(low=0, high=100, size=size) for _ in range(num)] +@pytest.mark.parametrize("num", NUM_ARR, ids=str) @pytest.mark.parametrize("size", SIZES, ids=str) -def test_concatenate(size, a): +def test_concatenate(size, num, a): run_test(tuple(a), "concatenate", size) +@pytest.mark.parametrize("num", NUM_ARR, ids=str) @pytest.mark.parametrize("size", SIZES, ids=str) -def test_stack(size, a): +def test_stack(size, num, a): run_test(tuple(a), "stack", size) +@pytest.mark.parametrize("num", NUM_ARR, ids=str) @pytest.mark.parametrize("size", SIZES, ids=str) -def test_hstack(size, a): +def test_hstack(size, num, a): run_test(tuple(a), "hstack", size) +@pytest.mark.parametrize("num", NUM_ARR, ids=str) @pytest.mark.parametrize("size", SIZES, ids=str) -def test_column_stack(size, a): +def test_column_stack(size, num, a): run_test(tuple(a), "column_stack", size) +@pytest.mark.parametrize("num", NUM_ARR, ids=str) @pytest.mark.parametrize("size", SIZES, ids=str) -def test_column_vstack(size, a): +def test_vstack(size, num, a): # exception for 1d array on vstack if len(size) == 2 and size == (1, DIM): a.append(np.random.randint(low=0, high=100, size=(DIM,))) run_test(tuple(a), "vstack", size) +@pytest.mark.parametrize("num", NUM_ARR, ids=str) @pytest.mark.parametrize("size", SIZES, ids=str) -def test_column_dstack(size, a): +def test_dstack(size, num, a): # exception for 1d array on dstack if len(size) == 2 and size == (1, DIM): a.append(np.random.randint(low=0, high=100, size=(DIM,))) From 1b87236458080a904e87ba20b1954d904af48091 Mon Sep 17 00:00:00 2001 From: Seonmyeong Bak Date: Thu, 21 Jul 2022 11:09:40 -0700 Subject: [PATCH 10/11] Minor change for the output format in `tests/integration/test_atleast_nd.py` --- tests/integration/test_atleast_nd.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/integration/test_atleast_nd.py b/tests/integration/test_atleast_nd.py index 67c29f65d6..88599ff30d 100644 --- a/tests/integration/test_atleast_nd.py +++ b/tests/integration/test_atleast_nd.py @@ -40,8 +40,7 @@ def _check(a, routine, sizes): f"Failed, {print_msg}\n" f"numpy result: {err_arr[0]}\n" f"cunumeric_result: {err_arr[1]}\n" - f"cunumeric and numpy shows" - f" different result\n" + f"cunumeric and numpy shows different result\n" ) print(f"Passed, {print_msg}, np: {b}" f", cunumeric: {c}") From 22f77b855aa855ec8aee4f79bd5e92ef2cd74e55 Mon Sep 17 00:00:00 2001 From: Seonmyeong Bak Date: Fri, 22 Jul 2022 12:19:33 -0700 Subject: [PATCH 11/11] Delete unnecessary codes regarding `view` --- cunumeric/module.py | 8 +++----- tests/integration/test_atleast_nd.py | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/cunumeric/module.py b/cunumeric/module.py index 7e4bc3ffac..81a68309ab 100644 --- a/cunumeric/module.py +++ b/cunumeric/module.py @@ -1151,11 +1151,9 @@ def _reshape_recur(ndim: int, arr: ndarray) -> tuple[int]: def _atleast_nd( - ndim: int, arys: Sequence[ndarray], view: bool = True + ndim: int, arys: Sequence[ndarray] ) -> Union(list[ndarray], ndarray): inputs = list(convert_to_cunumeric_ndarray(arr) for arr in arys) - if view: - inputs = list(arr.view() for arr in arys) # 'reshape' change the shape of arrays # only when arr.shape != _reshape_recur(ndim,arr) result = list(arr.reshape(_reshape_recur(ndim, arr)) for arr in inputs) @@ -1754,7 +1752,7 @@ def vstack(tup: Sequence[ndarray]) -> ndarray: Multiple GPUs, Multiple CPUs """ # Reshape arrays in the `array_list` if needed before concatenation - reshaped = _atleast_nd(2, tup, False) + reshaped = _atleast_nd(2, tup) if not isinstance(reshaped, list): reshaped = [reshaped] tup, common_info = check_shape_dtype(reshaped, vstack.__name__, 0) @@ -1844,7 +1842,7 @@ def dstack(tup: Sequence[ndarray]) -> ndarray: Multiple GPUs, Multiple CPUs """ # Reshape arrays to (1,N,1) for ndim ==1 or (M,N,1) for ndim == 2: - reshaped = _atleast_nd(3, tup, False) + reshaped = _atleast_nd(3, tup) if not isinstance(reshaped, list): reshaped = [reshaped] tup, common_info = check_shape_dtype(reshaped, dstack.__name__, 2) diff --git a/tests/integration/test_atleast_nd.py b/tests/integration/test_atleast_nd.py index 88599ff30d..4cc011d637 100644 --- a/tests/integration/test_atleast_nd.py +++ b/tests/integration/test_atleast_nd.py @@ -42,7 +42,7 @@ def _check(a, routine, sizes): f"cunumeric_result: {err_arr[1]}\n" f"cunumeric and numpy shows different result\n" ) - print(f"Passed, {print_msg}, np: {b}" f", cunumeric: {c}") + print(f"Passed, {print_msg}, np: {b}, cunumeric: {c}") DIM = 10