Repository: mars-project/mars

Issue:
How to perform all tensor on np.array packages
Example：
```
import mars.tensor as mt
import numpy as np

def test_x():
    X1 = mt.tensor([0, 1])
    X2 = mt.tensor([2, 3])
    X = np.array([X1,X2])
    print(X.execute())
```
How to calculate X？
How to perform all tensor on np.array packages
Example：
```
import mars.tensor as mt
import numpy as np

def test_x():
    X1 = mt.tensor([0, 1])
    X2 = mt.tensor([2, 3])
    X = np.array([X1,X2])
    print(X.execute())
```
How to calculate X？


Discussion:
```python
X = np.array([X1, X2])
```
is not supported, so does

```python
X = mt.array([X1, X2])
```

Try to use `mt.stack` instead.

```python
In [32]: X = mt.stack([X1, X2])                                                     

In [33]: X.execute()                                                                
Out[33]: 
array([[0, 1],
       [2, 3]])
```

Maybe we can detect the argument for `mt.tensor` which `mt.array` calls internally, if it's a list/tuple and all object is a tensor-compatible object, call `mt.stack` to create a tensor.

I think if you are interested in this job, how about trying to solve it and opening a PR? Thanks in advance.
Ok, I will try it!
Sorry to find that some relative code already exists, but not considered the `list` type, cc https://github.com/mars-project/mars/blob/00fc3a04616c233d9616030bb93323da1a56100e/mars/tensor/expressions/datasource/array.py#L126

Fix it is rather simpler, anyway, worth for firstly participating the development of Mars.
I found that this part of code is lack of unittest(refer to [coverage](https://coveralls.io/builds/21803662/source?filename=mars/tensor/expressions/datasource/array.py#L121)), since the fix itself is quite simple, come up with more tests please.

Unittests can be added to https://github.com/mars-project/mars/blob/00fc3a04616c233d9616030bb93323da1a56100e/mars/tensor/expressions/tests/test_core.py#L266
```python
X = np.array([X1, X2])
```
is not supported, so does

```python
X = mt.array([X1, X2])
```

Try to use `mt.stack` instead.

```python
In [32]: X = mt.stack([X1, X2])                                                     

In [33]: X.execute()                                                                
Out[33]: 
array([[0, 1],
       [2, 3]])
```

Maybe we can detect the argument for `mt.tensor` which `mt.array` calls internally, if it's a list/tuple and all object is a tensor-compatible object, call `mt.stack` to create a tensor.

I think if you are interested in this job, how about trying to solve it and opening a PR? Thanks in advance.
Ok, I will try it!
Sorry to find that some relative code already exists, but not considered the `list` type, cc https://github.com/mars-project/mars/blob/00fc3a04616c233d9616030bb93323da1a56100e/mars/tensor/expressions/datasource/array.py#L126

Fix it is rather simpler, anyway, worth for firstly participating the development of Mars.
I found that this part of code is lack of unittest(refer to [coverage](https://coveralls.io/builds/21803662/source?filename=mars/tensor/expressions/datasource/array.py#L121)), since the fix itself is quite simple, come up with more tests please.

Unittests can be added to https://github.com/mars-project/mars/blob/00fc3a04616c233d9616030bb93323da1a56100e/mars/tensor/expressions/tests/test_core.py#L266

Resolving patch:
diff --git a/mars/tensor/expressions/datasource/array.py b/mars/tensor/expressions/datasource/array.py
--- a/mars/tensor/expressions/datasource/array.py
+++ b/mars/tensor/expressions/datasource/array.py
@@ -129,7 +129,7 @@ def tensor(data, dtype=None, chunk_size=None, gpu=None, sparse=False):
         if dtype is not None and data.dtype != dtype:
             return data.astype(dtype)
         return data
-    elif isinstance(data, tuple) and all(isinstance(d, TENSOR_TYPE) for d in data):
+    elif isinstance(data, (tuple, list)) and all(isinstance(d, TENSOR_TYPE) for d in data):
         from ..merge import stack
 
         data = stack(data)


Test patch:
diff --git a/mars/tensor/expressions/tests/test_datasource.py b/mars/tensor/expressions/tests/test_datasource.py
--- a/mars/tensor/expressions/tests/test_datasource.py
+++ b/mars/tensor/expressions/tests/test_datasource.py
@@ -23,10 +23,20 @@
     tiledb = None
 
 from mars.tests.core import TestBase
-from mars.tensor.expressions.datasource import fromtiledb, TensorTileDBDataSource
+from mars.tensor.expressions.datasource import array, fromtiledb, TensorTileDBDataSource
 
 
 class Test(TestBase):
+    def testFromArray(self):
+        x = array([1, 2, 3])
+        self.assertEqual(x.shape, (3,))
+
+        y = array([x, x])
+        self.assertEqual(y.shape, (2, 3))
+
+        z = array((x, x, x))
+        self.assertEqual(z.shape, (3, 3))
+
     @unittest.skipIf(tiledb is None, 'TileDB not installed')
     def testFromTileDB(self):
         ctx = tiledb.Ctx()