def execute(self, interp): w_lhs = self.lhs.execute(interp) if isinstance(self.rhs, SliceConstant): w_rhs = self.rhs.wrap(interp.space) else: w_rhs = self.rhs.execute(interp) if not isinstance(w_lhs, W_NDimArray): # scalar dtype = get_dtype_cache(interp.space).w_float64dtype w_lhs = W_NDimArray.new_scalar(interp.space, dtype, w_lhs) assert isinstance(w_lhs, W_NDimArray) if self.name == '+': w_res = w_lhs.descr_add(interp.space, w_rhs) elif self.name == '*': w_res = w_lhs.descr_mul(interp.space, w_rhs) elif self.name == '-': w_res = w_lhs.descr_sub(interp.space, w_rhs) elif self.name == '->': if isinstance(w_rhs, FloatObject): w_rhs = IntObject(int(w_rhs.floatval)) assert isinstance(w_lhs, W_NDimArray) w_res = w_lhs.descr_getitem(interp.space, w_rhs) else: raise NotImplementedError if (not isinstance(w_res, W_NDimArray) and not isinstance(w_res, interp_boxes.W_GenericBox)): dtype = get_dtype_cache(interp.space).w_float64dtype w_res = W_NDimArray.new_scalar(interp.space, dtype, w_res) return w_res
def frombuffer(space, w_buffer, w_dtype=None, count=-1, offset=0): dtype = space.interp_w(descriptor.W_Dtype, space.call_function(space.gettypefor(descriptor.W_Dtype), w_dtype)) if dtype.elsize == 0: raise oefmt(space.w_ValueError, "itemsize cannot be zero in type") try: buf = _getbuffer(space, w_buffer) except OperationError as e: if not e.match(space, space.w_TypeError): raise w_buffer = space.call_method(w_buffer, '__buffer__', space.newint(space.BUF_FULL_RO)) buf = _getbuffer(space, w_buffer) ts = buf.getlength() if offset < 0 or offset > ts: raise oefmt(space.w_ValueError, "offset must be non-negative and no greater than " "buffer length (%d)", ts) s = ts - offset if offset: buf = SubBuffer(buf, offset, s) n = count itemsize = dtype.elsize assert itemsize > 0 if n < 0: if s % itemsize != 0: raise oefmt(space.w_ValueError, "buffer size must be a multiple of element size") n = s / itemsize else: if s < n * itemsize: raise oefmt(space.w_ValueError, "buffer is smaller than requested size") try: storage = buf.get_raw_address() except ValueError: a = W_NDimArray.from_shape(space, [n], dtype=dtype) loop.fromstring_loop(space, a, dtype, itemsize, buf.as_str()) return a else: writable = not buf.readonly return W_NDimArray.from_shape_and_storage(space, [n], storage, storage_bytes=s, dtype=dtype, w_base=w_buffer, writable=writable)
def apply(self, space, orig_arr): arr = orig_arr.implementation ofs, subdtype = arr.dtype.fields[self.name] # strides backstrides are identical, ofs only changes start return W_NDimArray.new_slice(space, arr.start + ofs, arr.get_strides(), arr.get_backstrides(), arr.shape, arr, orig_arr, subdtype)
def numpify(space, w_object): """Convert the object to a W_NumpyObject""" # XXX: code duplication with _array() from pypy.module.micronumpy import strides if isinstance(w_object, W_NumpyObject): return w_object # for anything that isn't already an array, try __array__ method first w_array = try_array_method(space, w_object) if w_array is not None: return w_array shape, elems_w = strides.find_shape_and_elems(space, w_object, None) dtype = find_dtype_for_seq(space, elems_w, None) if dtype is None: dtype = descriptor.get_dtype_cache(space).w_float64dtype elif dtype.is_str_or_unicode() and dtype.elsize < 1: # promote S0 -> S1, U0 -> U1 dtype = descriptor.variable_dtype(space, dtype.char + '1') if len(elems_w) == 1: return dtype.coerce(space, elems_w[0]) else: w_arr = W_NDimArray.from_shape(space, shape, dtype) loop.assign(space, w_arr, elems_w) return w_arr
def new_view(space, w_arr, chunks): arr = w_arr.implementation r = calculate_slice_strides(space, arr.shape, arr.start, arr.get_strides(), arr.get_backstrides(), chunks) shape, start, strides, backstrides = r return W_NDimArray.new_slice(space, start, strides[:], backstrides[:], shape[:], arr, w_arr)
def accumulate(space, func, w_arr, axis, calc_dtype, w_out, identity): out_iter, out_state = w_out.create_iter() arr_shape = w_arr.get_shape() temp_shape = arr_shape[:axis] + arr_shape[axis + 1:] temp = W_NDimArray.from_shape(space, temp_shape, calc_dtype, w_instance=w_arr) temp_iter = AxisIter(temp.implementation, w_arr.get_shape(), axis) temp_state = temp_iter.reset() arr_iter, arr_state = w_arr.create_iter() arr_iter.track_index = False if identity is not None: identity = identity.convert_to(space, calc_dtype) shapelen = len(arr_shape) while not out_iter.done(out_state): accumulate_driver.jit_merge_point(shapelen=shapelen, func=func, calc_dtype=calc_dtype) w_item = arr_iter.getitem(arr_state).convert_to(space, calc_dtype) arr_state = arr_iter.next(arr_state) out_indices = out_iter.indices(out_state) if out_indices[axis] == 0: if identity is not None: w_item = func(calc_dtype, identity, w_item) else: cur_value = temp_iter.getitem(temp_state) w_item = func(calc_dtype, cur_value, w_item) out_iter.setitem(out_state, w_item) out_state = out_iter.next(out_state) temp_iter.setitem(temp_state, w_item) temp_state = temp_iter.next(temp_state) return w_out
def zeros(space, w_shape, w_dtype=None, w_order=None): dtype = space.interp_w(descriptor.W_Dtype, space.call_function(space.gettypefor(descriptor.W_Dtype), w_dtype)) if dtype.is_str_or_unicode() and dtype.elsize < 1: dtype = descriptor.variable_dtype(space, dtype.char + '1') shape = shape_converter(space, w_shape, dtype) return W_NDimArray.from_shape(space, shape, dtype=dtype)
def call2(space, shape, func, calc_dtype, res_dtype, w_lhs, w_rhs, out): # handle array_priority # w_lhs and w_rhs could be of different ndarray subtypes. Numpy does: # 1. if __array_priorities__ are equal and one is an ndarray and the # other is a subtype, flip the order # 2. elif rhs.__array_priority__ is higher, flip the order # Now return the subtype of the first one w_ndarray = space.gettypefor(W_NDimArray) lhs_type = space.type(w_lhs) rhs_type = space.type(w_rhs) lhs_for_subtype = w_lhs rhs_for_subtype = w_rhs #it may be something like a FlatIter, which is not an ndarray if not space.is_true(space.issubtype(lhs_type, w_ndarray)): lhs_type = space.type(w_lhs.base) lhs_for_subtype = w_lhs.base if not space.is_true(space.issubtype(rhs_type, w_ndarray)): rhs_type = space.type(w_rhs.base) rhs_for_subtype = w_rhs.base if space.is_w(lhs_type, w_ndarray) and not space.is_w(rhs_type, w_ndarray): lhs_for_subtype = rhs_for_subtype # TODO handle __array_priorities__ and maybe flip the order if w_lhs.get_size() == 1: w_left = w_lhs.get_scalar_value().convert_to(space, calc_dtype) left_iter = left_state = None else: w_left = None left_iter, left_state = w_lhs.create_iter(shape) left_iter.track_index = False if w_rhs.get_size() == 1: w_right = w_rhs.get_scalar_value().convert_to(space, calc_dtype) right_iter = right_state = None else: w_right = None right_iter, right_state = w_rhs.create_iter(shape) right_iter.track_index = False if out is None: out = W_NDimArray.from_shape(space, shape, res_dtype, w_instance=lhs_for_subtype) out_iter, out_state = out.create_iter(shape) shapelen = len(shape) while not out_iter.done(out_state): call2_driver.jit_merge_point(shapelen=shapelen, func=func, calc_dtype=calc_dtype, res_dtype=res_dtype) if left_iter: w_left = left_iter.getitem(left_state).convert_to(space, calc_dtype) left_state = left_iter.next(left_state) if right_iter: w_right = right_iter.getitem(right_state).convert_to(space, calc_dtype) right_state = right_iter.next(right_state) out_iter.setitem(out_state, func(calc_dtype, w_left, w_right).convert_to( space, res_dtype)) out_state = out_iter.next(out_state) return out
def apply(self, space, orig_arr): arr = orig_arr.implementation shape = self.extend_shape(arr.shape) r = calculate_slice_strides(arr.shape, arr.start, arr.get_strides(), arr.get_backstrides(), self.l) _, start, strides, backstrides = r return W_NDimArray.new_slice(space, start, strides[:], backstrides[:], shape[:], arr, orig_arr)
def set_shape(self, space, orig_array, new_shape): if not new_shape: return self if support.product(new_shape) == 1: arr = W_NDimArray.from_shape(space, new_shape, self.dtype) arr_iter = arr.create_iter(new_shape) arr_iter.setitem(self.value) return arr.implementation raise OperationError(space.w_ValueError, space.wrap("total size of the array must be unchanged"))
def swapaxes(self, space, orig_arr, axis1, axis2): shape = self.get_shape()[:] strides = self.get_strides()[:] backstrides = self.get_backstrides()[:] shape[axis1], shape[axis2] = shape[axis2], shape[axis1] strides[axis1], strides[axis2] = strides[axis2], strides[axis1] backstrides[axis1], backstrides[axis2] = backstrides[axis2], backstrides[axis1] return W_NDimArray.new_slice(space, self.start, strides, backstrides, shape, self, orig_arr)
def nonzero(self, space, index_type): s = loop.count_all_true_concrete(self) box = index_type.itemtype.box nd = len(self.get_shape()) or 1 w_res = W_NDimArray.from_shape(space, [s, nd], index_type) loop.nonzero(w_res, self, box) w_res = w_res.implementation.swapaxes(space, w_res, 0, 1) l_w = [w_res.descr_getitem(space, space.wrap(d)) for d in range(nd)] return space.newtuple(l_w)
def concatenate(space, w_args, w_axis=None): args_w = space.listview(w_args) if len(args_w) == 0: raise oefmt(space.w_ValueError, "need at least one array to concatenate") args_w = [convert_to_array(space, w_arg) for w_arg in args_w] if w_axis is None: w_axis = space.wrap(0) if space.is_none(w_axis): args_w = [w_arg.reshape(space, space.newlist([w_arg.descr_get_size(space)]), w_arg.get_order()) for w_arg in args_w] w_axis = space.wrap(0) dtype = args_w[0].get_dtype() shape = args_w[0].get_shape()[:] ndim = len(shape) if ndim == 0: raise oefmt(space.w_ValueError, "zero-dimensional arrays cannot be concatenated") axis = space.int_w(w_axis) orig_axis = axis if axis < 0: axis = ndim + axis if ndim == 1 and axis != 0: axis = 0 if axis < 0 or axis >= ndim: raise oefmt(space.w_IndexError, "axis %d out of bounds [0, %d)", orig_axis, ndim) for arr in args_w[1:]: if len(arr.get_shape()) != ndim: raise oefmt(space.w_ValueError, "all the input arrays must have same number of " "dimensions") for i, axis_size in enumerate(arr.get_shape()): if i == axis: shape[i] += axis_size elif axis_size != shape[i]: raise oefmt(space.w_ValueError, "all the input array dimensions except for the " "concatenation axis must match exactly") dtype = find_result_type(space, args_w, []) # concatenate does not handle ndarray subtypes, it always returns a ndarray res = W_NDimArray.from_shape(space, shape, dtype, NPY.CORDER) chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 for arr in args_w: if arr.get_shape()[axis] == 0: continue chunks[axis] = Chunk(axis_start, axis_start + arr.get_shape()[axis], 1, arr.get_shape()[axis]) view = new_view(space, res, chunks) view.implementation.setslice(space, arr) axis_start += arr.get_shape()[axis] return res
def concatenate(space, w_args, w_axis=None): args_w = space.listview(w_args) if len(args_w) == 0: raise oefmt(space.w_ValueError, "need at least one array to concatenate") args_w = [convert_to_array(space, w_arg) for w_arg in args_w] if w_axis is None: w_axis = space.wrap(0) if space.is_none(w_axis): args_w = [w_arg.reshape(space, space.newlist([w_arg.descr_get_size(space)]), w_arg.get_order()) for w_arg in args_w] w_axis = space.wrap(0) dtype = args_w[0].get_dtype() shape = args_w[0].get_shape()[:] ndim = len(shape) if ndim == 0: raise oefmt(space.w_ValueError, "zero-dimensional arrays cannot be concatenated") axis = space.int_w(w_axis) orig_axis = axis if axis < 0: axis = ndim + axis if ndim == 1 and axis != 0: axis = 0 if axis < 0 or axis >= ndim: raise oefmt(space.w_IndexError, "axis %d out of bounds [0, %d)", orig_axis, ndim) for arr in args_w[1:]: if len(arr.get_shape()) != ndim: raise OperationError(space.w_ValueError, space.wrap( "all the input arrays must have same number of dimensions")) for i, axis_size in enumerate(arr.get_shape()): if i == axis: shape[i] += axis_size elif axis_size != shape[i]: raise OperationError(space.w_ValueError, space.wrap( "all the input array dimensions except for the " "concatenation axis must match exactly")) dtype = find_result_type(space, args_w, []) # concatenate does not handle ndarray subtypes, it always returns a ndarray res = W_NDimArray.from_shape(space, shape, dtype, NPY.CORDER) chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 for arr in args_w: if arr.get_shape()[axis] == 0: continue chunks[axis] = Chunk(axis_start, axis_start + arr.get_shape()[axis], 1, arr.get_shape()[axis]) view = new_view(space, res, chunks) view.implementation.setslice(space, arr) axis_start += arr.get_shape()[axis] return res
def empty_like(space, w_a, w_dtype=None, w_order=None, subok=True): w_a = convert_to_array(space, w_a) if space.is_none(w_dtype): dtype = w_a.get_dtype() else: dtype = space.interp_w(descriptor.W_Dtype, space.call_function(space.gettypefor(descriptor.W_Dtype), w_dtype)) if dtype.is_str_or_unicode() and dtype.elsize < 1: dtype = descriptor.variable_dtype(space, dtype.char + '1') return W_NDimArray.from_shape(space, w_a.get_shape(), dtype=dtype, w_instance=w_a if subok else None)
def empty_like(space, w_a, w_dtype=None, w_order=None, subok=True): w_a = convert_to_array(space, w_a) if space.is_none(w_dtype): dtype = w_a.get_dtype() else: dtype = space.interp_w(descriptor.W_Dtype, space.call_function(space.gettypefor(descriptor.W_Dtype), w_dtype)) if dtype.is_str_or_unicode() and dtype.elsize < 1: dtype = descriptor.variable_dtype(space, dtype.char + '1') return W_NDimArray.from_shape(space, w_a.get_shape(), dtype=dtype, w_instance=w_a if subok else None, zero=False)
def concatenate(space, w_args, axis=0): args_w = space.listview(w_args) if len(args_w) == 0: raise OperationError( space.w_ValueError, space.wrap("need at least one array to concatenate")) args_w = [convert_to_array(space, w_arg) for w_arg in args_w] dtype = args_w[0].get_dtype() shape = args_w[0].get_shape()[:] _axis = axis if axis < 0: _axis = len(shape) + axis for arr in args_w[1:]: for i, axis_size in enumerate(arr.get_shape()): if len(arr.get_shape()) != len(shape) or (i != _axis and axis_size != shape[i]): raise OperationError( space.w_ValueError, space.wrap( "all the input arrays must have same number of dimensions" )) elif i == _axis: shape[i] += axis_size a_dt = arr.get_dtype() if dtype.is_record_type() and a_dt.is_record_type(): # Record types must match for f in dtype.fields: if f not in a_dt.fields or \ dtype.fields[f] != a_dt.fields[f]: raise OperationError(space.w_TypeError, space.wrap("invalid type promotion")) elif dtype.is_record_type() or a_dt.is_record_type(): raise OperationError(space.w_TypeError, space.wrap("invalid type promotion")) dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, arr.get_dtype()) if _axis < 0 or len(arr.get_shape()) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) # concatenate does not handle ndarray subtypes, it always returns a ndarray res = W_NDimArray.from_shape(space, shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 for arr in args_w: if arr.get_shape()[_axis] == 0: continue chunks[_axis] = Chunk(axis_start, axis_start + arr.get_shape()[_axis], 1, arr.get_shape()[_axis]) Chunks(chunks).apply(space, res).implementation.setslice(space, arr) axis_start += arr.get_shape()[_axis] return res
def array(space, w_object, w_dtype=None, copy=True, w_order=None, subok=False, ndmin=0): w_res = _array(space, w_object, w_dtype, copy, w_order, subok) shape = w_res.get_shape() if len(shape) < ndmin: shape = [1] * (ndmin - len(shape)) + shape impl = w_res.implementation.set_shape(space, w_res, shape) if w_res is w_object: return W_NDimArray(impl) else: w_res.implementation = impl return w_res
def tostring(space, arr): builder = StringBuilder() iter = arr.create_iter() w_res_str = W_NDimArray.from_shape(space, [1], arr.get_dtype(), order='C') itemsize = arr.get_dtype().itemtype.get_element_size() res_str_casted = rffi.cast(rffi.CArrayPtr(lltype.Char), w_res_str.implementation.get_storage_as_int(space)) while not iter.done(): w_res_str.implementation.setitem(0, iter.getitem()) for i in range(itemsize): builder.append(res_str_casted[i]) iter.next() return builder.build()
def repeat(space, w_arr, repeats, w_axis): arr = convert_to_array(space, w_arr) if space.is_none(w_axis): arr = arr.descr_flatten(space) orig_size = arr.get_shape()[0] shape = [arr.get_shape()[0] * repeats] w_res = W_NDimArray.from_shape(space, shape, arr.get_dtype(), w_instance=arr) for i in range(repeats): Chunks([Chunk(i, shape[0] - repeats + i, repeats, orig_size)]).apply(space, w_res).implementation.setslice( space, arr ) else: axis = space.int_w(w_axis) shape = arr.get_shape()[:] chunks = [Chunk(0, i, 1, i) for i in shape] orig_size = shape[axis] shape[axis] *= repeats w_res = W_NDimArray.from_shape(space, shape, arr.get_dtype(), w_instance=arr) for i in range(repeats): chunks[axis] = Chunk(i, shape[axis] - repeats + i, repeats, orig_size) Chunks(chunks).apply(space, w_res).implementation.setslice(space, arr) return w_res
def tostring(space, arr): builder = StringBuilder() iter, state = arr.create_iter() w_res_str = W_NDimArray.from_shape(space, [1], arr.get_dtype(), order="C") itemsize = arr.get_dtype().elsize with w_res_str.implementation as storage: res_str_casted = rffi.cast(rffi.CArrayPtr(lltype.Char), support.get_storage_as_int(storage)) while not iter.done(state): w_res_str.implementation.setitem(0, iter.getitem(state)) for i in range(itemsize): builder.append(res_str_casted[i]) state = iter.next(state) return builder.build()
def tostring(space, arr): builder = StringBuilder() iter, state = arr.create_iter() w_res_str = W_NDimArray.from_shape(space, [1], arr.get_dtype(), order='C') itemsize = arr.get_dtype().elsize res_str_casted = rffi.cast(rffi.CArrayPtr(lltype.Char), w_res_str.implementation.get_storage_as_int(space)) while not iter.done(state): w_res_str.implementation.setitem(0, iter.getitem(state)) for i in range(itemsize): builder.append(res_str_casted[i]) state = iter.next(state) return builder.build()
def call1(space, shape, func, calc_dtype, res_dtype, w_obj, out): if out is None: out = W_NDimArray.from_shape(space, shape, res_dtype, w_instance=w_obj) obj_iter, obj_state = w_obj.create_iter(shape) out_iter, out_state = out.create_iter(shape) shapelen = len(shape) while not out_iter.done(out_state): call1_driver.jit_merge_point(shapelen=shapelen, func=func, calc_dtype=calc_dtype, res_dtype=res_dtype) elem = obj_iter.getitem(obj_state).convert_to(space, calc_dtype) out_iter.setitem(out_state, func(calc_dtype, elem).convert_to(space, res_dtype)) out_state = out_iter.next(out_state) obj_state = obj_iter.next(obj_state) return out
def descr_getitem(self, space, w_idx): if not (space.isinstance_w(w_idx, space.w_int) or space.isinstance_w(w_idx, space.w_slice)): raise oefmt(space.w_IndexError, 'unsupported iterator index') self.reset() base = self.base start, stop, step, length = space.decode_index4(w_idx, base.get_size()) base_iter, base_state = base.create_iter() base_state = base_iter.next_skip_x(base_state, start) if length == 1: return base_iter.getitem(base_state) res = W_NDimArray.from_shape(space, [length], base.get_dtype(), base.get_order(), w_instance=base) return loop.flatiter_getitem(res, base_iter, base_state, step)
def _fromstring_text(space, s, count, sep, length, dtype): sep_stripped = strip_spaces(sep) skip_bad_vals = len(sep_stripped) == 0 items = [] num_items = 0 idx = 0 while (num_items < count or count == -1) and idx < len(s): nextidx = s.find(sep, idx) if nextidx < 0: nextidx = length piece = strip_spaces(s[idx:nextidx]) if len(piece) > 0 or not skip_bad_vals: if len(piece) == 0 and not skip_bad_vals: val = dtype.itemtype.default_fromstring(space) else: try: val = dtype.coerce(space, space.newtext(piece)) except OperationError as e: if not e.match(space, space.w_ValueError): raise gotit = False while not gotit and len(piece) > 0: piece = piece[:-1] try: val = dtype.coerce(space, space.newtext(piece)) gotit = True except OperationError as e: if not e.match(space, space.w_ValueError): raise if not gotit: val = dtype.itemtype.default_fromstring(space) nextidx = length items.append(val) num_items += 1 idx = nextidx + 1 if count > num_items: raise oefmt(space.w_ValueError, "string is smaller than requested size") a = W_NDimArray.from_shape(space, [num_items], dtype=dtype) ai, state = a.create_iter() for val in items: ai.setitem(state, val) state = ai.next(state) return a
def _fromstring_text(space, s, count, sep, length, dtype): sep_stripped = strip_spaces(sep) skip_bad_vals = len(sep_stripped) == 0 items = [] num_items = 0 idx = 0 while (num_items < count or count == -1) and idx < len(s): nextidx = s.find(sep, idx) if nextidx < 0: nextidx = length piece = strip_spaces(s[idx:nextidx]) if len(piece) > 0 or not skip_bad_vals: if len(piece) == 0 and not skip_bad_vals: val = dtype.itemtype.default_fromstring(space) else: try: val = dtype.coerce(space, space.wrap(piece)) except OperationError as e: if not e.match(space, space.w_ValueError): raise gotit = False while not gotit and len(piece) > 0: piece = piece[:-1] try: val = dtype.coerce(space, space.wrap(piece)) gotit = True except OperationError as e: if not e.match(space, space.w_ValueError): raise if not gotit: val = dtype.itemtype.default_fromstring(space) nextidx = length items.append(val) num_items += 1 idx = nextidx + 1 if count > num_items: raise oefmt(space.w_ValueError, "string is smaller than requested size") a = W_NDimArray.from_shape(space, [num_items], dtype=dtype) ai, state = a.create_iter() for val in items: ai.setitem(state, val) state = ai.next(state) return space.wrap(a)
def repeat(space, w_arr, repeats, w_axis): arr = convert_to_array(space, w_arr) if space.is_none(w_axis): arr = arr.descr_flatten(space) orig_size = arr.get_shape()[0] shape = [arr.get_shape()[0] * repeats] w_res = W_NDimArray.from_shape(space, shape, arr.get_dtype(), w_instance=arr) for i in range(repeats): chunks = [Chunk(i, shape[0] - repeats + i, repeats, orig_size)] view = new_view(space, w_res, chunks) view.implementation.setslice(space, arr) else: axis = space.int_w(w_axis) shape = arr.get_shape()[:] chunks = [Chunk(0, i, 1, i) for i in shape] orig_size = shape[axis] shape[axis] *= repeats w_res = W_NDimArray.from_shape(space, shape, arr.get_dtype(), w_instance=arr) for i in range(repeats): chunks[axis] = Chunk(i, shape[axis] - repeats + i, repeats, orig_size) view = new_view(space, w_res, chunks) view.implementation.setslice(space, arr) return w_res
def _zeros_or_empty(space, w_shape, w_dtype, w_order, zero): dtype = space.interp_w(descriptor.W_Dtype, space.call_function(space.gettypefor(descriptor.W_Dtype), w_dtype)) if dtype.is_str_or_unicode() and dtype.elsize < 1: dtype = descriptor.variable_dtype(space, dtype.char + '1') shape = shape_converter(space, w_shape, dtype) for dim in shape: if dim < 0: raise OperationError(space.w_ValueError, space.wrap( "negative dimensions are not allowed")) try: support.product_check(shape) except OverflowError: raise oefmt(space.w_ValueError, "array is too big.") return W_NDimArray.from_shape(space, shape, dtype=dtype, zero=zero)
def descr_getitem(self, space, w_idx): if not (space.isinstance_w(w_idx, space.w_int) or space.isinstance_w(w_idx, space.w_slice)): raise OperationError(space.w_IndexError, space.wrap('unsupported iterator index')) self.reset() base = self.base start, stop, step, length = space.decode_index4(w_idx, base.get_size()) base_iter = base.create_iter() base_iter.next_skip_x(start) if length == 1: return base_iter.getitem() res = W_NDimArray.from_shape(space, [length], base.get_dtype(), base.get_order(), w_instance=base) return loop.flatiter_getitem(res, base_iter, step)
def call1(space, shape, func, calc_dtype, res_dtype, w_obj, out): obj_iter, obj_state = w_obj.create_iter(shape) obj_iter.track_index = False if out is None: out = W_NDimArray.from_shape(space, shape, res_dtype, w_instance=w_obj) out_iter, out_state = out.create_iter(shape) shapelen = len(shape) while not out_iter.done(out_state): call1_driver.jit_merge_point(shapelen=shapelen, func=func, calc_dtype=calc_dtype, res_dtype=res_dtype) elem = obj_iter.getitem(obj_state).convert_to(space, calc_dtype) out_iter.setitem(out_state, func(calc_dtype, elem).convert_to(space, res_dtype)) out_state = out_iter.next(out_state) obj_state = obj_iter.next(obj_state) return out
def _zeros_or_empty(space, w_shape, w_dtype, w_order, zero): dtype = space.interp_w(descriptor.W_Dtype, space.call_function(space.gettypefor(descriptor.W_Dtype), w_dtype)) if dtype.is_str_or_unicode() and dtype.elsize < 1: dtype = descriptor.variable_dtype(space, dtype.char + '1') shape = shape_converter(space, w_shape, dtype) for dim in shape: if dim < 0: raise OperationError(space.w_ValueError, space.wrap( "negative dimensions are not allowed")) try: support.product(shape) except OverflowError: raise OperationError(space.w_ValueError, space.wrap( "array is too big.")) return W_NDimArray.from_shape(space, shape, dtype=dtype, zero=zero)
def _fromstring_bin(space, s, count, length, dtype): itemsize = dtype.elsize assert itemsize >= 0 if count == -1: count = length / itemsize if length % itemsize != 0: raise oefmt(space.w_ValueError, "string length %d not divisable by item size %d", length, itemsize) if count * itemsize > length: raise OperationError(space.w_ValueError, space.wrap( "string is smaller than requested size")) a = W_NDimArray.from_shape(space, [count], dtype=dtype) loop.fromstring_loop(space, a, dtype, itemsize, s) return space.wrap(a)
def _fromstring_bin(space, s, count, length, dtype): itemsize = dtype.elsize assert itemsize >= 0 if count == -1: count = length / itemsize if length % itemsize != 0: raise oefmt(space.w_ValueError, "string length %d not divisable by item size %d", length, itemsize) if count * itemsize > length: raise oefmt(space.w_ValueError, "string is smaller than requested size") a = W_NDimArray.from_shape(space, [count], dtype=dtype) loop.fromstring_loop(space, a, dtype, itemsize, s) return a
def argsort(arr, space, w_axis): if w_axis is space.w_None: # note that it's fine ot pass None here as we're not going # to pass the result around (None is the link to base in slices) if arr.get_size() > 0: arr = arr.reshape(None, [arr.get_size()]) axis = 0 elif w_axis is None: axis = -1 else: axis = space.int_w(w_axis) # create array of indexes dtype = descriptor.get_dtype_cache(space).w_longdtype index_arr = W_NDimArray.from_shape(space, arr.get_shape(), dtype) with index_arr.implementation as storage, arr as arr_storage: if len(arr.get_shape()) == 1: for i in range(arr.get_size()): raw_storage_setitem(storage, i * INT_SIZE, i) r = Repr(INT_SIZE, arr.strides[0], arr.get_size(), arr_storage, storage, 0, arr.start) ArgSort(r).sort() else: shape = arr.get_shape() if axis < 0: axis = len(shape) + axis if axis < 0 or axis >= len(shape): raise oefmt(space.w_IndexError, "Wrong axis %d", axis) arr_iter = AllButAxisIter(arr, axis) arr_state = arr_iter.reset() index_impl = index_arr.implementation index_iter = AllButAxisIter(index_impl, axis) index_state = index_iter.reset() stride_size = arr.strides[axis] index_stride_size = index_impl.strides[axis] axis_size = arr.shape[axis] while not arr_iter.done(arr_state): for i in range(axis_size): raw_storage_setitem( storage, i * index_stride_size + index_state.offset, i) r = Repr(index_stride_size, stride_size, axis_size, arr_storage, storage, index_state.offset, arr_state.offset) ArgSort(r).sort() arr_state = arr_iter.next(arr_state) index_state = index_iter.next(index_state) return index_arr
def apply(self, space, orig_arr): arr = orig_arr.implementation ofs, subdtype = arr.dtype.fields[self.name] # ofs only changes start # create a view of the original array by extending # the shape, strides, backstrides of the array strides, backstrides = calc_strides(subdtype.shape, subdtype.subdtype, arr.order) final_shape = arr.shape + subdtype.shape final_strides = arr.get_strides() + strides final_backstrides = arr.get_backstrides() + backstrides final_dtype = subdtype if subdtype.subdtype: final_dtype = subdtype.subdtype return W_NDimArray.new_slice(space, arr.start + ofs, final_strides, final_backstrides, final_shape, arr, orig_arr, final_dtype)
def _fromstring_bin(space, s, count, length, dtype): itemsize = dtype.itemtype.get_element_size() assert itemsize >= 0 if count == -1: count = length / itemsize if length % itemsize != 0: raise operationerrfmt( space.w_ValueError, "string length %d not divisable by item size %d", length, itemsize) if count * itemsize > length: raise OperationError( space.w_ValueError, space.wrap("string is smaller than requested size")) a = W_NDimArray.from_shape(space, [count], dtype=dtype) loop.fromstring_loop(a, dtype, itemsize, s) return space.wrap(a)
def argsort(arr, space, w_axis, itemsize): if w_axis is space.w_None: # note that it's fine ot pass None here as we're not going # to pass the result around (None is the link to base in slices) arr = arr.reshape(space, None, [arr.get_size()]) axis = 0 elif w_axis is None: axis = -1 else: axis = space.int_w(w_axis) # create array of indexes dtype = interp_dtype.get_dtype_cache(space).w_longdtype index_arr = W_NDimArray.from_shape(space, arr.get_shape(), dtype) storage = index_arr.implementation.get_storage() if len(arr.get_shape()) == 1: for i in range(arr.get_size()): raw_storage_setitem(storage, i * INT_SIZE, i) r = Repr(INT_SIZE, itemsize, arr.get_size(), arr.get_storage(), storage, 0, arr.start) ArgSort(r).sort() else: shape = arr.get_shape() if axis < 0: axis = len(shape) + axis if axis < 0 or axis >= len(shape): raise OperationError(space.w_IndexError, space.wrap("Wrong axis %d" % axis)) iterable_shape = shape[:axis] + [0] + shape[axis + 1:] iter = AxisIterator(arr, iterable_shape, axis, False) index_impl = index_arr.implementation index_iter = AxisIterator(index_impl, iterable_shape, axis, False) stride_size = arr.strides[axis] index_stride_size = index_impl.strides[axis] axis_size = arr.shape[axis] while not iter.done(): for i in range(axis_size): raw_storage_setitem( storage, i * index_stride_size + index_iter.offset, i) r = Repr(index_stride_size, stride_size, axis_size, arr.get_storage(), storage, index_iter.offset, iter.offset) ArgSort(r).sort() iter.next() index_iter.next() return index_arr
def argsort(arr, space, w_axis): if w_axis is space.w_None: # note that it's fine ot pass None here as we're not going # to pass the result around (None is the link to base in slices) if arr.get_size() > 0: arr = arr.reshape(None, [arr.get_size()]) axis = 0 elif w_axis is None: axis = -1 else: axis = space.int_w(w_axis) # create array of indexes dtype = descriptor.get_dtype_cache(space).w_longdtype index_arr = W_NDimArray.from_shape(space, arr.get_shape(), dtype) with index_arr.implementation as storage, arr as arr_storage: if len(arr.get_shape()) == 1: for i in range(arr.get_size()): raw_storage_setitem(storage, i * INT_SIZE, i) r = Repr(INT_SIZE, arr.strides[0], arr.get_size(), arr_storage, storage, 0, arr.start) ArgSort(r).sort() else: shape = arr.get_shape() if axis < 0: axis = len(shape) + axis if axis < 0 or axis >= len(shape): raise oefmt(space.w_IndexError, "Wrong axis %d", axis) arr_iter = AllButAxisIter(arr, axis) arr_state = arr_iter.reset() index_impl = index_arr.implementation index_iter = AllButAxisIter(index_impl, axis) index_state = index_iter.reset() stride_size = arr.strides[axis] index_stride_size = index_impl.strides[axis] axis_size = arr.shape[axis] while not arr_iter.done(arr_state): for i in range(axis_size): raw_storage_setitem(storage, i * index_stride_size + index_state.offset, i) r = Repr(index_stride_size, stride_size, axis_size, arr_storage, storage, index_state.offset, arr_state.offset) ArgSort(r).sort() arr_state = arr_iter.next(arr_state) index_state = index_iter.next(index_state) return index_arr
def _zeros_or_empty(space, w_shape, w_dtype, w_order, zero): # w_order can be None, str, or boolean order = order_converter(space, w_order, NPY.CORDER) dtype = space.interp_w( descriptor.W_Dtype, space.call_function(space.gettypefor(descriptor.W_Dtype), w_dtype)) if dtype.is_str_or_unicode() and dtype.elsize < 1: dtype = descriptor.variable_dtype(space, dtype.char + '1') shape = shape_converter(space, w_shape, dtype) for dim in shape: if dim < 0: raise oefmt(space.w_ValueError, "negative dimensions are not allowed") try: support.product_check(shape) except OverflowError: raise oefmt(space.w_ValueError, "array is too big.") return W_NDimArray.from_shape(space, shape, dtype, order, zero=zero)
def argsort(arr, space, w_axis, itemsize): if w_axis is space.w_None: # note that it's fine ot pass None here as we're not going # to pass the result around (None is the link to base in slices) arr = arr.reshape(space, None, [arr.get_size()]) axis = 0 elif w_axis is None: axis = -1 else: axis = space.int_w(w_axis) # create array of indexes dtype = interp_dtype.get_dtype_cache(space).w_longdtype index_arr = W_NDimArray.from_shape(space, arr.get_shape(), dtype) storage = index_arr.implementation.get_storage() if len(arr.get_shape()) == 1: for i in range(arr.get_size()): raw_storage_setitem(storage, i * INT_SIZE, i) r = Repr(INT_SIZE, itemsize, arr.get_size(), arr.get_storage(), storage, 0, arr.start) ArgSort(r).sort() else: shape = arr.get_shape() if axis < 0: axis = len(shape) + axis - 1 if axis < 0 or axis > len(shape): raise OperationError(space.w_IndexError, space.wrap( "Wrong axis %d" % axis)) iterable_shape = shape[:axis] + [0] + shape[axis + 1:] iter = AxisIterator(arr, iterable_shape, axis, False) index_impl = index_arr.implementation index_iter = AxisIterator(index_impl, iterable_shape, axis, False) stride_size = arr.strides[axis] index_stride_size = index_impl.strides[axis] axis_size = arr.shape[axis] while not iter.done(): for i in range(axis_size): raw_storage_setitem(storage, i * index_stride_size + index_iter.offset, i) r = Repr(index_stride_size, stride_size, axis_size, arr.get_storage(), storage, index_iter.offset, iter.offset) ArgSort(r).sort() iter.next() index_iter.next() return index_arr
def concatenate(space, w_args, axis=0): args_w = space.listview(w_args) if len(args_w) == 0: raise OperationError(space.w_ValueError, space.wrap("need at least one array to concatenate")) args_w = [convert_to_array(space, w_arg) for w_arg in args_w] dtype = args_w[0].get_dtype() shape = args_w[0].get_shape()[:] _axis = axis if axis < 0: _axis = len(shape) + axis for arr in args_w[1:]: for i, axis_size in enumerate(arr.get_shape()): if len(arr.get_shape()) != len(shape) or (i != _axis and axis_size != shape[i]): raise OperationError(space.w_ValueError, space.wrap( "all the input arrays must have same number of dimensions")) elif i == _axis: shape[i] += axis_size a_dt = arr.get_dtype() if dtype.is_record_type() and a_dt.is_record_type(): #Record types must match for f in dtype.fields: if f not in a_dt.fields or \ dtype.fields[f] != a_dt.fields[f]: raise OperationError(space.w_TypeError, space.wrap("record type mismatch")) elif dtype.is_record_type() or a_dt.is_record_type(): raise OperationError(space.w_TypeError, space.wrap("invalid type promotion")) dtype = interp_ufuncs.find_binop_result_dtype(space, dtype, arr.get_dtype()) if _axis < 0 or len(arr.get_shape()) <= _axis: raise operationerrfmt(space.w_IndexError, "axis %d out of bounds [0, %d)", axis, len(shape)) # concatenate does not handle ndarray subtypes, it always returns a ndarray res = W_NDimArray.from_shape(space, shape, dtype, 'C') chunks = [Chunk(0, i, 1, i) for i in shape] axis_start = 0 for arr in args_w: if arr.get_shape()[_axis] == 0: continue chunks[_axis] = Chunk(axis_start, axis_start + arr.get_shape()[_axis], 1, arr.get_shape()[_axis]) Chunks(chunks).apply(space, res).implementation.setslice(space, arr) axis_start += arr.get_shape()[_axis] return res
def can_cast(space, w_from, w_totype, casting='safe'): try: target = as_dtype(space, w_totype, allow_None=False) except TypeError: raise oefmt(space.w_TypeError, "did not understand one of the types; 'None' not accepted") if isinstance(w_from, W_NDimArray): return space.wrap(can_cast_array(space, w_from, target, casting)) elif is_scalar_w(space, w_from): w_scalar = as_scalar(space, w_from) w_arr = W_NDimArray.from_scalar(space, w_scalar) return space.wrap(can_cast_array(space, w_arr, target, casting)) try: origin = as_dtype(space, w_from, allow_None=False) except TypeError: raise oefmt(space.w_TypeError, "did not understand one of the types; 'None' not accepted") return space.wrap(can_cast_type(space, origin, target, casting))
def can_cast(space, w_from, w_totype, casting='safe'): try: target = as_dtype(space, w_totype, allow_None=False) except TypeError: raise oefmt( space.w_TypeError, "did not understand one of the types; 'None' not accepted") if isinstance(w_from, W_NDimArray): return space.wrap(can_cast_array(space, w_from, target, casting)) elif is_scalar_w(space, w_from): w_scalar = as_scalar(space, w_from) w_arr = W_NDimArray.from_scalar(space, w_scalar) return space.wrap(can_cast_array(space, w_arr, target, casting)) try: origin = as_dtype(space, w_from, allow_None=False) except TypeError: raise oefmt( space.w_TypeError, "did not understand one of the types; 'None' not accepted") return space.wrap(can_cast_type(space, origin, target, casting))
def result_type(space, __args__): args_w, kw_w = __args__.unpack() if kw_w: raise oefmt(space.w_TypeError, "result_type() takes no keyword arguments") if not args_w: raise oefmt(space.w_ValueError, "at least one array or dtype is required") arrays_w = [] dtypes_w = [] for w_arg in args_w: if isinstance(w_arg, W_NDimArray): arrays_w.append(w_arg) elif is_scalar_w(space, w_arg): w_scalar = as_scalar(space, w_arg) w_arr = W_NDimArray.from_scalar(space, w_scalar) arrays_w.append(w_arr) else: dtype = as_dtype(space, w_arg) dtypes_w.append(dtype) return find_result_type(space, arrays_w, dtypes_w)
def diagonal(space, arr, offset, axis1, axis2): shape = arr.get_shape() shapelen = len(shape) if offset < 0: offset = -offset axis1, axis2 = axis2, axis1 size = min(shape[axis1], shape[axis2] - offset) dtype = arr.dtype if axis1 < axis2: shape = shape[:axis1] + shape[axis1 + 1 : axis2] + shape[axis2 + 1 :] + [size] else: shape = shape[:axis2] + shape[axis2 + 1 : axis1] + shape[axis1 + 1 :] + [size] out = W_NDimArray.from_shape(space, shape, dtype) if size == 0: return out if shapelen == 2: # simple case loop.diagonal_simple(space, arr, out, offset, axis1, axis2, size) else: loop.diagonal_array(space, arr, out, offset, axis1, axis2, shape) return out
def empty_like(space, w_a, w_dtype=None, w_order=None, subok=True): w_a = convert_to_array(space, w_a) npy_order = order_converter(space, w_order, w_a.get_order()) if space.is_none(w_dtype): dtype = w_a.get_dtype() else: dtype = space.interp_w(descriptor.W_Dtype, space.call_function(space.gettypefor(descriptor.W_Dtype), w_dtype)) if dtype.is_str_or_unicode() and dtype.elsize < 1: dtype = descriptor.variable_dtype(space, dtype.char + '1') if npy_order in (NPY.KEEPORDER, NPY.ANYORDER): # Try to copy the stride pattern impl = w_a.implementation.astype(space, dtype, NPY.KEEPORDER) if subok: w_type = space.type(w_a) else: w_type = None return wrap_impl(space, w_type, w_a, impl) return W_NDimArray.from_shape(space, w_a.get_shape(), dtype=dtype, order=npy_order, w_instance=w_a if subok else None, zero=False)
def numpify(space, w_object): """Convert the object to a W_NumpyObject""" # XXX: code duplication with _array() if isinstance(w_object, W_NumpyObject): return w_object # for anything that isn't already an array, try __array__ method first w_array = try_array_method(space, w_object) if w_array is not None: return w_array if is_scalar_like(space, w_object, dtype=None): dtype = scalar2dtype(space, w_object) if dtype.is_str_or_unicode() and dtype.elsize < 1: # promote S0 -> S1, U0 -> U1 dtype = descriptor.variable_dtype(space, dtype.char + '1') return dtype.coerce(space, w_object) shape, elems_w = _find_shape_and_elems(space, w_object) dtype = find_dtype_for_seq(space, elems_w, None) w_arr = W_NDimArray.from_shape(space, shape, dtype) loop.assign(space, w_arr, elems_w) return w_arr
def diagonal(space, arr, offset, axis1, axis2): shape = arr.get_shape() shapelen = len(shape) if offset < 0: offset = -offset axis1, axis2 = axis2, axis1 size = min(shape[axis1], shape[axis2] - offset) dtype = arr.dtype if axis1 < axis2: shape = (shape[:axis1] + shape[axis1 + 1:axis2] + shape[axis2 + 1:] + [size]) else: shape = (shape[:axis2] + shape[axis2 + 1:axis1] + shape[axis1 + 1:] + [size]) out = W_NDimArray.from_shape(space, shape, dtype) if size == 0: return out if shapelen == 2: # simple case loop.diagonal_simple(space, arr, out, offset, axis1, axis2, size) else: loop.diagonal_array(space, arr, out, offset, axis1, axis2, shape) return out
def new_view(space, w_arr, chunks): arr = w_arr.implementation dim = -1 for i, c in enumerate(chunks): if isinstance(c, BooleanChunk): dim = i break if dim >= 0: # filter by axis dim filtr = chunks[dim] assert isinstance(filtr, BooleanChunk) # XXX this creates a new array, and fails in setitem w_arr = w_arr.getitem_filter(space, filtr.w_idx, axis=dim) arr = w_arr.implementation chunks[dim] = SliceChunk(space.newslice(space.newint(0), space.w_None, space.w_None)) r = calculate_slice_strides(space, arr.shape, arr.start, arr.get_strides(), arr.get_backstrides(), chunks) else: r = calculate_slice_strides(space, arr.shape, arr.start, arr.get_strides(), arr.get_backstrides(), chunks) shape, start, strides, backstrides = r return W_NDimArray.new_slice(space, start, strides[:], backstrides[:], shape[:], arr, w_arr)
def where(space, w_arr, w_x=None, w_y=None): """where(condition, [x, y]) Return elements, either from `x` or `y`, depending on `condition`. If only `condition` is given, return ``condition.nonzero()``. Parameters ---------- condition : array_like, bool When True, yield `x`, otherwise yield `y`. x, y : array_like, optional Values from which to choose. `x` and `y` need to have the same shape as `condition`. Returns ------- out : ndarray or tuple of ndarrays If both `x` and `y` are specified, the output array contains elements of `x` where `condition` is True, and elements from `y` elsewhere. If only `condition` is given, return the tuple ``condition.nonzero()``, the indices where `condition` is True. See Also -------- nonzero, choose Notes ----- If `x` and `y` are given and input arrays are 1-D, `where` is equivalent to:: [xv if c else yv for (c,xv,yv) in zip(condition,x,y)] Examples -------- >>> np.where([[True, False], [True, True]], ... [[1, 2], [3, 4]], ... [[9, 8], [7, 6]]) array([[1, 8], [3, 4]]) >>> np.where([[0, 1], [1, 0]]) (array([0, 1]), array([1, 0])) >>> x = np.arange(9.).reshape(3, 3) >>> np.where( x > 5 ) (array([2, 2, 2]), array([0, 1, 2])) >>> x[np.where( x > 3.0 )] # Note: result is 1D. array([ 4., 5., 6., 7., 8.]) >>> np.where(x < 5, x, -1) # Note: broadcasting. array([[ 0., 1., 2.], [ 3., 4., -1.], [-1., -1., -1.]]) NOTE: support for not passing x and y is unsupported """ if space.is_none(w_y): if space.is_none(w_x): raise OperationError( space.w_NotImplementedError, space.wrap("1-arg where unsupported right now")) raise OperationError( space.w_ValueError, space.wrap("Where should be called with either 1 or 3 arguments")) if space.is_none(w_x): raise OperationError( space.w_ValueError, space.wrap("Where should be called with either 1 or 3 arguments")) arr = convert_to_array(space, w_arr) x = convert_to_array(space, w_x) y = convert_to_array(space, w_y) if x.is_scalar() and y.is_scalar() and arr.is_scalar(): if arr.get_dtype().itemtype.bool(arr.get_scalar_value()): return x return y dtype = ufuncs.find_binop_result_dtype(space, x.get_dtype(), y.get_dtype()) shape = shape_agreement(space, arr.get_shape(), x) shape = shape_agreement(space, shape, y) out = W_NDimArray.from_shape(space, shape, dtype) return loop.where(space, out, shape, arr, x, y, dtype)
def _get_item(self, it, st): return W_NDimArray(it.getoperand(st))
def call2(space, shape, func, calc_dtype, res_dtype, w_lhs, w_rhs, out): # handle array_priority # w_lhs and w_rhs could be of different ndarray subtypes. Numpy does: # 1. if __array_priorities__ are equal and one is an ndarray and the # other is a subtype, flip the order # 2. elif rhs.__array_priority__ is higher, flip the order # Now return the subtype of the first one w_ndarray = space.gettypefor(W_NDimArray) lhs_type = space.type(w_lhs) rhs_type = space.type(w_rhs) lhs_for_subtype = w_lhs rhs_for_subtype = w_rhs #it may be something like a FlatIter, which is not an ndarray if not space.is_true(space.issubtype(lhs_type, w_ndarray)): lhs_type = space.type(w_lhs.base) lhs_for_subtype = w_lhs.base if not space.is_true(space.issubtype(rhs_type, w_ndarray)): rhs_type = space.type(w_rhs.base) rhs_for_subtype = w_rhs.base if space.is_w(lhs_type, w_ndarray) and not space.is_w(rhs_type, w_ndarray): lhs_for_subtype = rhs_for_subtype # TODO handle __array_priorities__ and maybe flip the order if w_lhs.get_size() == 1: w_left = w_lhs.get_scalar_value().convert_to(space, calc_dtype) left_iter = left_state = None else: w_left = None left_iter, left_state = w_lhs.create_iter(shape) left_iter.track_index = False if w_rhs.get_size() == 1: w_right = w_rhs.get_scalar_value().convert_to(space, calc_dtype) right_iter = right_state = None else: w_right = None right_iter, right_state = w_rhs.create_iter(shape) right_iter.track_index = False if out is None: out = W_NDimArray.from_shape(space, shape, res_dtype, w_instance=lhs_for_subtype) out_iter, out_state = out.create_iter(shape) shapelen = len(shape) while not out_iter.done(out_state): call2_driver.jit_merge_point(shapelen=shapelen, func=func, calc_dtype=calc_dtype, res_dtype=res_dtype) if left_iter: w_left = left_iter.getitem(left_state).convert_to( space, calc_dtype) left_state = left_iter.next(left_state) if right_iter: w_right = right_iter.getitem(right_state).convert_to( space, calc_dtype) right_state = right_iter.next(right_state) out_iter.setitem( out_state, func(calc_dtype, w_left, w_right).convert_to(space, res_dtype)) out_state = out_iter.next(out_state) return out
def getitem(self, it, st): res = it.getoperand(st) return W_NDimArray(res)
def __init__(self, space, w_seq, w_flags, w_op_flags, w_op_dtypes, w_casting, w_op_axes, w_itershape, buffersize=0, order=NPY.KEEPORDER, allow_backward=True): self.external_loop = False self.buffered = False self.tracked_index = '' self.common_dtype = False self.delay_bufalloc = False self.grow_inner = False self.ranged = False self.refs_ok = False self.reduce_ok = False self.zerosize_ok = False self.index_iter = None self.done = False self.first_next = True self.op_axes = [] self.allow_backward = allow_backward if not space.is_w(w_casting, space.w_None): self.casting = space.str_w(w_casting) else: self.casting = 'safe' # convert w_seq operands to a list of W_NDimArray if space.isinstance_w(w_seq, space.w_tuple) or \ space.isinstance_w(w_seq, space.w_list): w_seq_as_list = space.listview(w_seq) self.seq = [ convert_to_array(space, w_elem) if not space.is_none(w_elem) else None for w_elem in w_seq_as_list ] else: self.seq = [convert_to_array(space, w_seq)] if order == NPY.ANYORDER: # 'A' means "'F' order if all the arrays are Fortran contiguous, # 'C' order otherwise" order = NPY.CORDER for s in self.seq: if s and not (s.get_flags() & NPY.ARRAY_F_CONTIGUOUS): break else: order = NPY.FORTRANORDER elif order == NPY.KEEPORDER: # 'K' means "as close to the order the array elements appear in # memory as possible", so match self.order to seq.order order = NPY.CORDER for s in self.seq: if s and not (s.get_order() == NPY.FORTRANORDER): break else: order = NPY.FORTRANORDER self.order = order parse_func_flags(space, self, w_flags) self.op_flags = parse_op_arg(space, 'op_flags', w_op_flags, len(self.seq), parse_op_flag) # handle w_op_axes oa_ndim = -1 if not space.is_none(w_op_axes): oa_ndim = self.set_op_axes(space, w_op_axes) self.ndim = calculate_ndim(self.seq, oa_ndim) # handle w_op_dtypes part 1: creating self.dtypes list from input if not space.is_none(w_op_dtypes): w_seq_as_list = space.listview(w_op_dtypes) self.dtypes = [ decode_w_dtype(space, w_elem) for w_elem in w_seq_as_list ] if len(self.dtypes) != len(self.seq): raise oefmt( space.w_ValueError, "op_dtypes must be a tuple/list matching the number of ops" ) else: self.dtypes = [] # handle None or writable operands, calculate my shape outargs = [ i for i in range(len(self.seq)) if self.seq[i] is None or self.op_flags[i].rw == 'w' ] if len(outargs) > 0: out_shape = shape_agreement_multiple( space, [self.seq[i] for i in outargs]) else: out_shape = None if space.isinstance_w(w_itershape, space.w_tuple) or \ space.isinstance_w(w_itershape, space.w_list): self.shape = [space.int_w(i) for i in space.listview(w_itershape)] else: self.shape = shape_agreement_multiple(space, self.seq, shape=out_shape) if len(outargs) > 0: # Make None operands writeonly and flagged for allocation if len(self.dtypes) > 0: out_dtype = self.dtypes[outargs[0]] else: out_dtype = None for i in range(len(self.seq)): if self.seq[i] is None: self.op_flags[i].allocate = True continue if self.op_flags[i].rw == 'w': continue out_dtype = find_binop_result_dtype( space, self.seq[i].get_dtype(), out_dtype) for i in outargs: if self.seq[i] is None: # XXX can we postpone allocation to later? self.seq[i] = W_NDimArray.from_shape( space, self.shape, out_dtype) else: if not self.op_flags[i].broadcast: # Raises if output cannot be broadcast try: shape_agreement(space, self.shape, self.seq[i], False) except OperationError as e: raise oefmt( space.w_ValueError, "non-broadcastable" " output operand with shape %s doesn't match " "the broadcast shape %s", str(self.seq[i].get_shape()), str(self.shape)) if self.tracked_index != "": order = self.order if order == NPY.KEEPORDER: order = self.seq[0].implementation.order if self.tracked_index == "multi": backward = False else: backward = ((order == NPY.CORDER and self.tracked_index != 'C') or (order == NPY.FORTRANORDER and self.tracked_index != 'F')) self.index_iter = IndexIterator(self.shape, backward=backward) # handle w_op_dtypes part 2: copy where needed if possible if len(self.dtypes) > 0: for i in range(len(self.seq)): self_d = self.dtypes[i] seq_d = self.seq[i].get_dtype() if not self_d: self.dtypes[i] = seq_d elif self_d != seq_d: impl = self.seq[i].implementation if self.buffered or 'r' in self.op_flags[i].tmp_copy: if not can_cast_array(space, self.seq[i], self_d, self.casting): raise oefmt( space.w_TypeError, "Iterator operand %d" " dtype could not be cast from %s to %s" " according to the rule '%s'", i, space.str_w(seq_d.descr_repr(space)), space.str_w(self_d.descr_repr(space)), self.casting) order = support.get_order_as_CF(impl.order, self.order) new_impl = impl.astype(space, self_d, order).copy(space) self.seq[i] = W_NDimArray(new_impl) else: raise oefmt( space.w_TypeError, "Iterator " "operand required copying or buffering, " "but neither copying nor buffering was " "enabled") if 'w' in self.op_flags[i].rw: if not can_cast_type(space, self_d, seq_d, self.casting): raise oefmt( space.w_TypeError, "Iterator" " requested dtype could not be cast from " " %s to %s, the operand %d dtype, accord" "ing to the rule '%s'", space.str_w(self_d.descr_repr(space)), space.str_w(seq_d.descr_repr(space)), i, self.casting) elif self.buffered and not (self.external_loop and len(self.seq) < 2): for i in range(len(self.seq)): if i not in outargs: self.seq[i] = self.seq[i].descr_copy(space, w_order=space.wrap( self.order)) self.dtypes = [s.get_dtype() for s in self.seq] else: #copy them from seq self.dtypes = [s.get_dtype() for s in self.seq] # create an iterator for each operand self.iters = [] for i in range(len(self.seq)): it = self.get_iter(space, i) it.contiguous = False self.iters.append((it, it.reset())) if self.external_loop: coalesce_axes(self, space)
except OperationError, e: if not e.match(space, space.w_ValueError): raise if not gotit: val = dtype.itemtype.default_fromstring(space) nextidx = length items.append(val) num_items += 1 idx = nextidx + 1 if count > num_items: raise OperationError( space.w_ValueError, space.wrap("string is smaller than requested size")) a = W_NDimArray.from_shape(space, [num_items], dtype=dtype) ai, state = a.create_iter() for val in items: ai.setitem(state, val) state = ai.next(state) return space.wrap(a) def _fromstring_bin(space, s, count, length, dtype): itemsize = dtype.elsize assert itemsize >= 0 if count == -1: count = length / itemsize if length % itemsize != 0: raise oefmt(space.w_ValueError,
def _array(space, w_object, w_dtype=None, copy=True, w_order=None, subok=False): from pypy.module.micronumpy import strides # for anything that isn't already an array, try __array__ method first if not isinstance(w_object, W_NDimArray): w_array = try_array_method(space, w_object, w_dtype) if w_array is not None: # continue with w_array, but do further operations in place w_object = w_array copy = False if not isinstance(w_object, W_NDimArray): w_array = try_interface_method(space, w_object) if w_array is not None: w_object = w_array copy = False dtype = descriptor.decode_w_dtype(space, w_dtype) if space.is_none(w_order): order = 'C' else: order = space.str_w(w_order) if order == 'K': order = 'C' if order != 'C': # or order != 'F': raise oefmt(space.w_ValueError, "Unknown order: %s", order) if isinstance(w_object, W_NDimArray): if (dtype is None or w_object.get_dtype() is dtype): if copy and (subok or type(w_object) is W_NDimArray): return w_object.descr_copy(space, w_order) elif not copy and (subok or type(w_object) is W_NDimArray): return w_object if subok and not type(w_object) is W_NDimArray: raise oefmt(space.w_NotImplementedError, "array(..., subok=True) only partially implemented") # we have a ndarray, but need to copy or change dtype if dtype is None: dtype = w_object.get_dtype() if dtype != w_object.get_dtype(): # silently reject the copy value copy = True if copy: shape = w_object.get_shape() elems_w = [None] * w_object.get_size() elsize = w_object.get_dtype().elsize # TODO - use w_object.implementation without copying to a list # unfortunately that causes a union error in translation for i in range(w_object.get_size()): elems_w[i] = w_object.implementation.getitem(i * elsize) else: imp = w_object.implementation with imp as storage: sz = support.product(w_object.get_shape()) * dtype.elsize return W_NDimArray.from_shape_and_storage(space, w_object.get_shape(), storage, dtype, storage_bytes=sz, w_base=w_object, start=imp.start) else: # not an array shape, elems_w = strides.find_shape_and_elems(space, w_object, dtype) if dtype is None or (dtype.is_str_or_unicode() and dtype.elsize < 1): dtype = strides.find_dtype_for_seq(space, elems_w, dtype) if dtype is None: dtype = descriptor.get_dtype_cache(space).w_float64dtype elif dtype.is_str_or_unicode() and dtype.elsize < 1: # promote S0 -> S1, U0 -> U1 dtype = descriptor.variable_dtype(space, dtype.char + '1') w_arr = W_NDimArray.from_shape(space, shape, dtype, order=order) if support.product(shape) == 1: w_arr.set_scalar_value(dtype.coerce(space, elems_w[0])) else: loop.assign(space, w_arr, elems_w) return w_arr
def getitem(self, it, st): w_res = W_NDimArray(it.getoperand(st)) return w_res