Repository: mars-project/mars

Issue:
[BUG][TENSOR] Different slice on the same tensor generate same operand key
**Describe the bug**

Different slice on the same tensor generate same operand key which must be different.

**To Reproduce**

```python
In [22]: base_arr = np.random.random((4000, 2))                                 

In [23]: a = mt.array(base_arr)                                                 

In [24]: a[:400].op.key                                                         
Out[24]: '52efbfe8840294880d82da453025296b'

In [25]: a[400: 800].op.key                                                     
Out[25]: '52efbfe8840294880d82da453025296b'
```




Discussion:

Resolving patch:
diff --git a/mars/tensor/expressions/indexing/getitem.py b/mars/tensor/expressions/indexing/getitem.py
--- a/mars/tensor/expressions/indexing/getitem.py
+++ b/mars/tensor/expressions/indexing/getitem.py
@@ -44,13 +44,11 @@ def _handle_params(self, inputs, indexes):
         from operand itself and replace tensor-liked indexes by new one in `inputs`.
         """
         if indexes is not None:
+            self._indexes = indexes
             indexes_inputs = [ind for ind in indexes if isinstance(ind, (BaseWithKey, Entity))]
             inputs = inputs + indexes_inputs
         yield inputs
 
-        if indexes is not None:
-            self._indexes = indexes
-
         inputs_iter = iter(self._inputs[1:])
         new_indexes = [next(inputs_iter) if isinstance(index, (BaseWithKey, Entity)) else index
                        for index in self._indexes]
diff --git a/mars/tensor/expressions/indexing/setitem.py b/mars/tensor/expressions/indexing/setitem.py
--- a/mars/tensor/expressions/indexing/setitem.py
+++ b/mars/tensor/expressions/indexing/setitem.py
@@ -39,16 +39,15 @@ def _handle_params(self, inputs, indexes, value):
         from operand itself and replace tensor-liked objects by iterating over inputs.
         """
         if indexes is not None and value is not None:
+            self._indexes = indexes
+            self._value = value
+
             indexes_inputs = [ind for ind in indexes if isinstance(ind, TENSOR_TYPE + CHUNK_TYPE)]
             inputs += indexes_inputs
             if isinstance(value, TENSOR_TYPE + CHUNK_TYPE):
                 inputs += [value]
         yield inputs
 
-        if indexes is not None:
-            self._indexes = indexes
-        if value is not None:
-            self._value = value
         inputs_iter = iter(self._inputs[1:])
         new_indexes = [next(inputs_iter) if isinstance(index, (BaseWithKey, Entity)) else index
                        for index in self._indexes]


Test patch:
diff --git a/mars/deploy/local/tests/test_cluster.py b/mars/deploy/local/tests/test_cluster.py
--- a/mars/deploy/local/tests/test_cluster.py
+++ b/mars/deploy/local/tests/test_cluster.py
@@ -196,6 +196,26 @@ def testIndexTensorExecute(self):
 
                 np.testing.assert_array_equal(r, np.ones((5, 5)) * 2)
 
+            with new_session(cluster.endpoint) as session3:
+                a = mt.random.rand(100, 5)
+
+                slice1 = a[:10]
+                slice2 = a[10:20]
+                r1, r2, expected = session3.run(slice1, slice2, a)
+
+                np.testing.assert_array_equal(r1, expected[:10])
+                np.testing.assert_array_equal(r2, expected[10:20])
+
+            with new_session(cluster.endpoint) as session4:
+                a = mt.random.rand(100, 5)
+
+                a[:10] = mt.ones((10, 5))
+                a[10:20] = 2
+                r = session4.run(a)
+
+                np.testing.assert_array_equal(r[:10], np.ones((10, 5)))
+                np.testing.assert_array_equal(r[10:20], np.ones((10, 5)) * 2)
+
     def testExecutableTuple(self):
         with new_cluster(scheduler_n_process=2, worker_n_process=2, web=True) as cluster:
             with new_session('http://' + cluster._web_endpoint).as_default():
diff --git a/mars/tensor/expressions/tests/test_indexing.py b/mars/tensor/expressions/tests/test_indexing.py
--- a/mars/tensor/expressions/tests/test_indexing.py
+++ b/mars/tensor/expressions/tests/test_indexing.py
@@ -215,3 +215,10 @@ def testNonzero(self):
         y = nonzero(x)
 
         self.assertEqual(len(y), 2)
+
+    def testOperandKey(self):
+        t = ones((10, 2), chunk_size=5)
+        t_slice1 = t[:5]
+        t_slice2 = t[5:]
+
+        self.assertNotEqual(t_slice1.op.key, t_slice2.op.key)