# Buggy code
def tile(cls, op):
    x = op.input
    axis = op.axis
    ord = op.ord
    keepdims = op.keepdims

    axis_chunk_shapes = tuple(x.chunk_shape[i] for i in axis)
    can_apply_norm = all(s == 1 for s in axis_chunk_shapes)

    if can_apply_norm:
        axis_set = set(axis)
        get_shape = lambda shape: tuple(
            s if i not in axis_set else 1
            for i, s in enumerate(shape)
            if i not in axis_set or keepdims
        )

        out_chunk_shape = get_shape(x.chunk_shape)
        out_chunks = []
        for idx in itertools.product(*[range(s) for s in out_chunk_shape]):
            idx_iter = iter(idx)
            in_idx = tuple(
                0 if i in axis_set and not keepdims else next(idx_iter)
                for i in range(x.ndim)
            )

            c = x.cix[in_idx]
            chunk_op = op.copy().reset_key()
            out_chunk = chunk_op.new_chunk([c], shape=get_shape(c.shape), index=idx)
            out_chunks.append(out_chunk)

        nsplits = [
            tuple(
                c.shape[i]
                for c in out_chunks
                if all(idx == 0 for j, idx in enumerate(c.index) if j != i)
            )
            for i in range(len(out_chunks[0].shape))
        ]
        new_op = op.copy()
        return new_op.new_tensors(
            op.inputs, op.outputs[0].shape, chunks=out_chunks, nsplits=nsplits
        )

    r = cls._norm(x.astype(op.outputs[0].dtype), ord, axis, keepdims)
    recursive_tile(r)
    new_op = op.copy()
    return new_op.new_tensors(
        op.inputs, op.outputs[0].shape, chunks=r.chunks, nsplits=r.nsplits
    )


# Traceback (TypeError)
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'

# Fixed code
def tile(cls, op):
    x = astensor(op.input)
    axis = op.axis
    ord = op.ord
    keepdims = op.keepdims

    axis_chunk_shapes = tuple(x.chunk_shape[i] for i in axis)
    can_apply_norm = all(s == 1 for s in axis_chunk_shapes)

    if can_apply_norm:
        axis_set = set(axis)
        get_shape = lambda shape: tuple(
            s if i not in axis_set else 1
            for i, s in enumerate(shape)
            if i not in axis_set or keepdims
        )

        out_chunk_shape = get_shape(x.chunk_shape)
        out_chunks = []
        for idx in itertools.product(*[range(s) for s in out_chunk_shape]):
            idx_iter = iter(idx)
            in_idx = tuple(
                0 if i in axis_set and not keepdims else next(idx_iter)
                for i in range(x.ndim)
            )

            c = x.cix[in_idx]
            chunk_op = op.copy().reset_key()
            out_chunk = chunk_op.new_chunk([c], shape=get_shape(c.shape), index=idx)
            out_chunks.append(out_chunk)

        nsplits = [
            tuple(
                c.shape[i]
                for c in out_chunks
                if all(idx == 0 for j, idx in enumerate(c.index) if j != i)
            )
            for i in range(len(out_chunks[0].shape))
        ]
        new_op = op.copy()
        return new_op.new_tensors(
            op.inputs, op.outputs[0].shape, chunks=out_chunks, nsplits=nsplits
        )

    r = cls._norm(x.astype(op.outputs[0].dtype), ord, axis, keepdims)
    recursive_tile(r)
    new_op = op.copy()
    return new_op.new_tensors(
        op.inputs, op.outputs[0].shape, chunks=r.chunks, nsplits=r.nsplits
    )