Repository: mars-project/mars

Issue:
[BUG] mt.linalg.norm failed and raises TypeError
<!--
Thank you for your contribution!

Please review https://github.com/mars-project/mars/blob/master/CONTRIBUTING.rst before opening an issue.
-->

**Describe the bug**

`mt.linalg.norm` failed and raises `TypeError: copy() got an unexpected keyword argument 'order'
`

**To Reproduce**
To help us reproducing this bug, please provide information below:
1. Your Python version
2. The version of Mars you use
3. Versions of crucial packages, such as numpy, scipy and protobuf
4. Full stack of the error.
5. Minimized code to reproduce the error.

```
In [2]: import mars.tensor as mt                                                

In [3]: t = mt.random.rand(10, 10, chunk_size=5)                                

In [4]: mt.linalg.norm(t).execute()                                             
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-900a2d2bec75> in <module>
----> 1 mt.linalg.norm(t).execute()

~/Workspace/mars/mars/core.py in execute(self, session, **kw)
    559 
    560     def execute(self, session=None, **kw):
--> 561         self._data.execute(session, **kw)
    562         return self
    563 

~/Workspace/mars/mars/core.py in execute(self, session, **kw)
    368 
    369         # no more fetch, thus just fire run
--> 370         session.run(self, **kw)
    371         # return Tileable or ExecutableTuple itself
    372         return self

~/Workspace/mars/mars/session.py in run(self, *tileables, **kw)
    404         tileables = tuple(mt.tensor(t) if not isinstance(t, (Entity, Base)) else t
    405                           for t in tileables)
--> 406         result = self._sess.run(*tileables, **kw)
    407 
    408         for t in tileables:

~/Workspace/mars/mars/session.py in run(self, *tileables, **kw)
    102             # set number of running cores
    103             self.context.set_ncores(kw['n_parallel'])
--> 104             res = self._executor.execute_tileables(tileables, **kw)
    105             return res
    106 

~/Workspace/mars/mars/utils.py in _wrapped(*args, **kwargs)
    387                 _kernel_mode.eager = False
    388             _kernel_mode.eager_count = enter_eager_count + 1
--> 389             return func(*args, **kwargs)
    390         finally:
    391             _kernel_mode.eager_count -= 1

~/Workspace/mars/mars/utils.py in inner(*args, **kwargs)
    481     def inner(*args, **kwargs):
    482         with build_mode():
--> 483             return func(*args, **kwargs)
    484     return inner
    485 

~/Workspace/mars/mars/executor.py in execute_tileables(self, tileables, fetch, n_parallel, n_thread, print_progress, mock, compose)
    825                 # build chunk graph, tile will be done during building
    826                 chunk_graph = chunk_graph_builder.build(
--> 827                     tileables, tileable_graph=tileable_graph)
    828                 tileable_graph = chunk_graph_builder.prev_tileable_graph
    829                 temp_result_keys = set(result_keys)

~/Workspace/mars/mars/utils.py in _wrapped(*args, **kwargs)
    387                 _kernel_mode.eager = False
    388             _kernel_mode.eager_count = enter_eager_count + 1
--> 389             return func(*args, **kwargs)
    390         finally:
    391             _kernel_mode.eager_count -= 1

~/Workspace/mars/mars/utils.py in inner(*args, **kwargs)
    481     def inner(*args, **kwargs):
    482         with build_mode():
--> 483             return func(*args, **kwargs)
    484     return inner
    485 

~/Workspace/mars/mars/tiles.py in build(self, tileables, tileable_graph)
    340 
    341         chunk_graph = super().build(
--> 342             tileables, tileable_graph=tileable_graph)
    343         self._iterative_chunk_graphs.append(chunk_graph)
    344         if len(self._interrupted_ops) == 0:

~/Workspace/mars/mars/utils.py in _wrapped(*args, **kwargs)
    387                 _kernel_mode.eager = False
    388             _kernel_mode.eager_count = enter_eager_count + 1
--> 389             return func(*args, **kwargs)
    390         finally:
    391             _kernel_mode.eager_count -= 1

~/Workspace/mars/mars/utils.py in inner(*args, **kwargs)
    481     def inner(*args, **kwargs):
    482         with build_mode():
--> 483             return func(*args, **kwargs)
    484     return inner
    485 

~/Workspace/mars/mars/tiles.py in build(self, tileables, tileable_graph)
    253                     # for further execution
    254                     partial_tiled_chunks = \
--> 255                         self._on_tile_failure(tileable_data.op, exc_info)
    256                     if partial_tiled_chunks is not None and \
    257                             len(partial_tiled_chunks) > 0:

~/Workspace/mars/mars/tiles.py in inner(op, exc_info)
    292                     on_tile_failure(op, exc_info)
    293                 else:
--> 294                     raise exc_info[1].with_traceback(exc_info[2]) from None
    295         return inner
    296 

~/Workspace/mars/mars/tiles.py in build(self, tileables, tileable_graph)
    233                 continue
    234             try:
--> 235                 tiled = self._tile(tileable_data, tileable_graph)
    236                 tiled_op.add(tileable_data.op)
    237                 for t, td in zip(tileable_data.op.outputs, tiled):

~/Workspace/mars/mars/tiles.py in _tile(self, tileable_data, tileable_graph)
    328         if any(inp.op in self._interrupted_ops for inp in tileable_data.inputs):
    329             raise TilesError('Tile fail due to failure of inputs')
--> 330         return super()._tile(tileable_data, tileable_graph)
    331 
    332     @kernel_mode

~/Workspace/mars/mars/tiles.py in _tile(self, tileable_data, tileable_graph)
    191                 t._nsplits = o.nsplits
    192         elif on_tile is None:
--> 193             tds[0]._inplace_tile()
    194         else:
    195             tds = on_tile(tileable_data.op.outputs, tds)

~/Workspace/mars/mars/core.py in _inplace_tile(self)
    160 
    161     def _inplace_tile(self):
--> 162         return handler.inplace_tile(self)
    163 
    164     def __getattr__(self, attr):

~/Workspace/mars/mars/tiles.py in inplace_tile(self, to_tile)
    126         if not to_tile.is_coarse():
    127             return to_tile
--> 128         dispatched = self.dispatch(to_tile.op)
    129         self._assign_to([d.data for d in dispatched], to_tile.op.outputs)
    130         return to_tile

~/Workspace/mars/mars/utils.py in _wrapped(*args, **kwargs)
    387                 _kernel_mode.eager = False
    388             _kernel_mode.eager_count = enter_eager_count + 1
--> 389             return func(*args, **kwargs)
    390         finally:
    391             _kernel_mode.eager_count -= 1

~/Workspace/mars/mars/tiles.py in dispatch(self, op)
    113             return self._handlers[op_cls](op)
    114         try:
--> 115             return op_cls.tile(op)
    116         except NotImplementedError as ex:
    117             cause = ex

~/Workspace/mars/mars/tensor/linalg/norm.py in tile(cls, op)
     96             return new_op.new_tensors(op.inputs, op.outputs[0].shape, chunks=out_chunks, nsplits=nsplits)
     97 
---> 98         r = cls._norm(x.astype(op.outputs[0].dtype), ord, axis, keepdims)
     99         recursive_tile(r)
    100         new_op = op.copy()

~/Workspace/mars/mars/tensor/base/astype.py in _astype(tensor, dtype, order, casting, copy)
    154 
    155     if tensor.dtype == dtype and tensor.order == tensor_order:
--> 156         return tensor if not copy else tensor.copy(order=order)
    157     elif not np.can_cast(tensor.dtype, dtype, casting=casting):
    158         raise TypeError('Cannot cast array from {0!r} to {1!r} '

TypeError: copy() got an unexpected keyword argument 'order'
```



Discussion:

Resolving patch:
diff --git a/mars/tensor/linalg/norm.py b/mars/tensor/linalg/norm.py
--- a/mars/tensor/linalg/norm.py
+++ b/mars/tensor/linalg/norm.py
@@ -64,7 +64,7 @@ def __call__(self, x):
 
     @classmethod
     def tile(cls, op):
-        x = op.input
+        x = astensor(op.input)
         axis = op.axis
         ord = op.ord
         keepdims = op.keepdims


Test patch:
diff --git a/mars/tensor/linalg/tests/test_linalg_execute.py b/mars/tensor/linalg/tests/test_linalg_execute.py
--- a/mars/tensor/linalg/tests/test_linalg_execute.py
+++ b/mars/tensor/linalg/tests/test_linalg_execute.py
@@ -811,6 +811,12 @@ def testNormExecution(self):
         res = self.executor.execute_tensor(t)[0]
         self.assertAlmostEqual(res, 3.14, delta=1)
 
+        raw = np.random.RandomState(0).rand(10, 10)
+        d = norm(tensor(raw, chunk_size=5))
+        expected = self.executor.execute_tensor(d, concat=True)[0]
+        result = np.linalg.norm(raw)
+        np.testing.assert_allclose(expected, result)
+
     def testTensordotExecution(self):
         size_executor = ExecutorForTest(sync_provider_type=ExecutorForTest.SyncProviderType.MOCK)