def _scatter_ndarray(ar, axis=-<NUM_LIT:1>, destination=None, blocksize=None):
from .arrays import DistArray, RemoteArray<EOL>shape = ar.shape<EOL>ndim = len(shape)<EOL>if axis is None:<EOL><INDENT>return _directed_scatter([ar], destination=[destination],<EOL>blocksize=blocksize)[<NUM_LIT:0>]<EOL><DEDENT>if axis < -ndim or axis > ndim - <NUM_LIT:1>:<EOL><INDENT>raise DistobValueError('<STR_LIT>')<EOL><DEDENT>if axis < <NUM_LIT:0>:<EOL><INDENT>axis = ndim + axis<EOL><DEDENT>n = shape[axis]<EOL>if n == <NUM_LIT:1>:<EOL><INDENT>return _directed_scatter([ar], destination=[destination])[<NUM_LIT:0>]<EOL><DEDENT>if isinstance(destination, collections.Sequence):<EOL><INDENT>ne = len(destination) <EOL><DEDENT>else:<EOL><INDENT>if distob.engine is None:<EOL><INDENT>setup_engines()<EOL><DEDENT>ne = distob.engine.nengines <EOL><DEDENT>if blocksize is None:<EOL><INDENT>blocksize = ((n - <NUM_LIT:1>) // ne) + <NUM_LIT:1><EOL><DEDENT>if blocksize > n:<EOL><INDENT>blocksize = n<EOL><DEDENT>if isinstance(ar, DistArray):<EOL><INDENT>if axis == ar._distaxis:<EOL><INDENT>return ar<EOL><DEDENT>else:<EOL><INDENT>raise DistobError('<STR_LIT>')<EOL><DEDENT><DEDENT>if isinstance(ar, RemoteArray) and n > blocksize:<EOL><INDENT>ar = ar._ob<EOL><DEDENT>s = slice(None)<EOL>subarrays = []<EOL>low = <NUM_LIT:0><EOL>for i in range(<NUM_LIT:0>, n // blocksize):<EOL><INDENT>high = low + blocksize<EOL>index = (s,)*axis + (slice(low, high),) + (s,)*(ndim - axis - <NUM_LIT:1>)<EOL>subarrays.append(ar[index])<EOL>low += blocksize<EOL><DEDENT>if n % blocksize != <NUM_LIT:0>:<EOL><INDENT>high = low + (n % blocksize)<EOL>index = (s,)*axis + (slice(low, high),) + (s,)*(ndim - axis - <NUM_LIT:1>)<EOL>subarrays.append(ar[index])<EOL><DEDENT>subarrays = _directed_scatter(subarrays, destination=destination)<EOL>return DistArray(subarrays, axis)<EOL>
Turn a numpy ndarray into a DistArray or RemoteArray
    Args:
     ar (array_like)
     axis (int, optional): specifies along which axis to split the array to 
       distribute it. The default is to split along the last axis. `None` means
       do not distribute.
     destination (int or list of int, optional): Optionally force the array to
       go to a specific engine. If an array is to be scattered along an axis, 
       this should be a list of engine ids with the same length as that axis.
     blocksize (int): Optionally control the size of intervals into which the
       distributed axis is split (the default splits the distributed axis
       evenly over all computing engines).