'Construct a SmartArray in the memory space defined by \'where\'.
Valid invocations:
* SmartArray(obj=<array-like object>, copy=<optional-true-or-false>):
to create a SmartArray from an existing array-like object.
The \'copy\' argument specifies whether to adopt or to copy it.
* SmartArray(shape=<shape>, dtype=<dtype>, order=<order>)
to create a new SmartArray from scratch, given the typical NumPy array
attributes.
(The optional \'where\' argument specifies where to allocate the array
initially. (Default: \'host\')'

def __init__(self, obj=None, copy=True, shape=None, dtype=None, order=None, where='host'):

    if (where not in self._targets):
        raise ValueError(('"%s"    is    not    a    valid    target' % where))
    assert ((obj is not None) or (shape and dtype))
    self._host = self._gpu = None
    self._host_valid = self._gpu_valid = False
    self._allocate(where, obj, dtype, shape, _o2s(dtype, shape, order), copy)
    if (where == 'host'):
        self._host_valid = True
        t = self._host
    else:
        self._gpu_valid = True
        t = self._gpu
    self._shape = t.shape
    self._strides = t.strides
    self._dtype = t.dtype
    self._ndim = t.ndim
    self._size = t.size
