From 472405ceb335a47f1e4ffc1fafac37414ea19f45 Mon Sep 17 00:00:00 2001 From: yinengy <yinengy@utexas.edu> Date: Fri, 14 Apr 2023 05:48:14 +0000 Subject: [PATCH 1/3] fix: bug in reset coherence --- src/python/parla/common/parray/coherence.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/parla/common/parray/coherence.py b/src/python/parla/common/parray/coherence.py index 3f209b6d..512b2fdf 100644 --- a/src/python/parla/common/parray/coherence.py +++ b/src/python/parla/common/parray/coherence.py @@ -124,7 +124,7 @@ def reset(self, new_owner: int): """ for device_id in self._local_states.keys(): self._local_states[device_id] = self.INVALID - self._versions[device_id] = None + self._versions[device_id] = -1 self._is_complete[device_id] = None self._local_states[new_owner] = self.MODIFIED From d9d16eb2bf61f83a72ecded395d055ac3b31107f Mon Sep 17 00:00:00 2001 From: yinengy <yinengy@utexas.edu> Date: Fri, 14 Apr 2023 05:48:52 +0000 Subject: [PATCH 2/3] feat: support index by array --- src/python/parla/common/parray/core.py | 32 ++++++++++++++++++++------ testing/python/test_parray.py | 8 +++++++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/python/parla/common/parray/core.py b/src/python/parla/common/parray/core.py index cd0019fc..2d00e2e6 100644 --- a/src/python/parla/common/parray/core.py +++ b/src/python/parla/common/parray/core.py @@ -305,12 +305,27 @@ def print_overview(self) -> None: # slicing/indexing - def __getitem__(self, slices: SlicesType) -> PArray | Any: + def __getitem__(self, slices: SlicesType | numpy.ndarray | cupy.ndarray) -> PArray | Any: + """ + Acceptable Slices: Slice, Int, tuple of (Slice, Int, List of Int), ndarray of numpy/cupy + Example: + A[0] # int + A[:] # slice + A[0,:,10] # tuple of int slice int + A[2:10:2, 0, [1, 3, 5]] # tuple of slice int list of Int + + Note: `:` equals to slice(None, None, None) + Note: `None` or tuple of `None` is not acceptable (even if `numpy.ndarray` accept `None`) + # TODO: support `None` + """ if self._slices: # resolve saved slices first ret = self.array[slices] - else: - ret = self._array.get_by_global_slices( - self._current_device_index, slices) + + if isinstance(slices, numpy.ndarray) or isinstance(slices, cupy.ndarray): + slices = slices.tolist() + + ret = self._array.get_by_global_slices( + self._current_device_index, slices) # ndarray.__getitem__() may return a ndarray if ret is None: @@ -329,9 +344,9 @@ def __getitem__(self, slices: SlicesType) -> PArray | Any: else: return ret - def __setitem__(self, slices: SlicesType, value: PArray | ndarray | Any) -> None: + def __setitem__(self, slices: SlicesType | numpy.ndarray | cupy.ndarray, value: PArray | ndarray | Any) -> None: """ - Acceptable Slices: Slice, Int, tuple of (Slice, Int, List of Int) + Acceptable Slices: Slice, Int, tuple of (Slice, Int, List of Int), ndarray of numpy/cupy Example: A[0] # int A[:] # slice @@ -340,11 +355,14 @@ def __setitem__(self, slices: SlicesType, value: PArray | ndarray | Any) -> None Note: `:` equals to slice(None, None, None) Note: `None` or tuple of `None` is not acceptable (even if `numpy.ndarray` accept `None`) - # TODO: support `None` and `ndarray` as slices + # TODO: support `None` """ if isinstance(value, PArray): value = value.array + if isinstance(slices, numpy.ndarray) or isinstance(slices, cupy.ndarray): + slices = slices.tolist() + if self._slices: # resolve saved slices first self.array.__setitem__(slices, value) else: diff --git a/testing/python/test_parray.py b/testing/python/test_parray.py index 9d49e01d..0e9350cc 100644 --- a/testing/python/test_parray.py +++ b/testing/python/test_parray.py @@ -86,6 +86,14 @@ def check_array_update(): assert a[-1] == 4 assert a._coherence.owner == 1 + + @spawn(ts[5], dependencies=[ts[4]], placement=gpu(0), inout=[(a,0)]) + def check_array_indexing(): + a[np.array([0,2])] = 0 + assert len(a) == 4 + assert a[0] == 0 + assert a._coherence.owner == 0 + if __name__=="__main__": test_parray_creation() test_parray_task() From 92617c8259843b0c7c18a4f92dfb4608a1cf95de Mon Sep 17 00:00:00 2001 From: yinengy <yinengy@utexas.edu> Date: Fri, 14 Apr 2023 05:52:51 +0000 Subject: [PATCH 3/3] fix: minor bug in __getitem__ --- src/python/parla/common/parray/core.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/python/parla/common/parray/core.py b/src/python/parla/common/parray/core.py index 2d00e2e6..2aaeeab9 100644 --- a/src/python/parla/common/parray/core.py +++ b/src/python/parla/common/parray/core.py @@ -317,15 +317,15 @@ def __getitem__(self, slices: SlicesType | numpy.ndarray | cupy.ndarray) -> PArr Note: `:` equals to slice(None, None, None) Note: `None` or tuple of `None` is not acceptable (even if `numpy.ndarray` accept `None`) # TODO: support `None` - """ - if self._slices: # resolve saved slices first - ret = self.array[slices] - + """ if isinstance(slices, numpy.ndarray) or isinstance(slices, cupy.ndarray): slices = slices.tolist() - ret = self._array.get_by_global_slices( - self._current_device_index, slices) + if self._slices: # resolve saved slices first + ret = self.array[slices] + else: + ret = self._array.get_by_global_slices( + self._current_device_index, slices) # ndarray.__getitem__() may return a ndarray if ret is None: