Repository: mars-project/mars

Issue:
[BUG] Chunk size of TensorSlice in SVD is not correct
**Describe the bug**
When executing

```python
import mars.tensor as mt
n = 10000000
A = mt.asarray(mt.random.random(size=(n, 10), chunk_size=1250000))
B = mt.linalg.svd(A)
from mars.graph import DAG
g = DAG()
for b in B:
    b.build_graph(g, tiled=True)
slices = [n for n in g if type(n.op).__name__ == 'TensorSlice']
```

The value of ```slices[0].inputs[0].shape``` is ```(80, 10)```. However, the value of ```slices[0].shape``` is ```(1250000, 10)``` which is obviously wrong.

**To Reproduce**
We use the latest master of Mars and run the code above.

**Expected behavior**
The sum of shapes in slices should be equal to the shape of ```TensorQR```.



Discussion:

Resolving patch:
diff --git a/mars/tensor/linalg/core.py b/mars/tensor/linalg/core.py
--- a/mars/tensor/linalg/core.py
+++ b/mars/tensor/linalg/core.py
@@ -139,9 +139,10 @@ def tile(cls, op):
         stage2_q_chunks = []
         for c, s in zip(stage1_q_chunks, q_slices):
             slice_op = TensorSlice(slices=[s], dtype=c.dtype)
+            slice_length = s.stop - (s.start or 0)
             stage2_q_chunks.append(slice_op.new_chunk([stage2_q_chunk], index=c.index,
                                                       order=TensorOrder.C_ORDER,
-                                                      shape=(c.shape[0], stage2_q_chunk.shape[1])))
+                                                      shape=(slice_length, stage2_q_chunk.shape[1])))
         stage3_q_chunks = []
         for c1, c2 in izip(stage1_q_chunks, stage2_q_chunks):
             dot_op = TensorDot(dtype=q_dtype)


Test patch:
diff --git a/mars/tensor/linalg/tests/test_linalg.py b/mars/tensor/linalg/tests/test_linalg.py
--- a/mars/tensor/linalg/tests/test_linalg.py
+++ b/mars/tensor/linalg/tests/test_linalg.py
@@ -42,6 +42,27 @@ def testQR(self):
         self.assertEqual(q.nsplits, ((3, 3, 3), (6,)))
         self.assertEqual(r.nsplits, ((6,), (6,)))
 
+        self.assertEqual(q.chunks[0].shape, (3, 6))
+        self.assertEqual(q.chunks[0].inputs[0].shape, (3, 3))
+        self.assertEqual(q.chunks[0].inputs[1].shape, (3, 6))
+
+        a = mt.random.rand(18, 6, chunk_size=(9, 6))
+        q, r = mt.linalg.qr(a)
+
+        self.assertEqual(q.shape, (18, 6))
+        self.assertEqual(r.shape, (6, 6))
+
+        q.tiles()
+
+        self.assertEqual(len(q.chunks), 2)
+        self.assertEqual(len(r.chunks), 1)
+        self.assertEqual(q.nsplits, ((9, 9), (6,)))
+        self.assertEqual(r.nsplits, ((6,), (6,)))
+
+        self.assertEqual(q.chunks[0].shape, (9, 6))
+        self.assertEqual(q.chunks[0].inputs[0].shape, (9, 6))
+        self.assertEqual(q.chunks[0].inputs[1].shape, (6, 6))
+
         # for Short-and-Fat QR
         a = mt.random.rand(6, 18, chunk_size=(6, 6))
         q, r = mt.linalg.qr(a, method='sfqr')
@@ -113,6 +134,10 @@ def testSVD(self):
         self.assertEqual(len(V.chunks), 1)
         self.assertEqual(V.chunks[0].shape, (6, 6))
 
+        self.assertEqual(U.chunks[0].inputs[0].shape, (3, 6))
+        self.assertEqual(U.chunks[0].inputs[0].inputs[0].shape, (3, 3))
+        self.assertEqual(U.chunks[0].inputs[0].inputs[1].shape, (3, 6))
+
         self.assertEqual(s.ndim, 1)
         self.assertEqual(len(s.chunks[0].index), 1)