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: