def unravel_index(indices, dims, order='C'): """Converts array of flat indices into a tuple of coordinate arrays. Args: indices (cupy.ndarray): An integer array whose elements are indices into the flattened version of an array of dimensions :obj:`dims`. dims (tuple of ints): The shape of the array to use for unraveling indices. order ('C' or 'F'): Determines whether the indices should be viewed as indexing in row-major (C-style) or column-major (Fortran-style) order. Returns: tuple of ndarrays: Each array in the tuple has the same shape as the indices array. Examples -------- >>> cupy.unravel_index(cupy.array([22, 41, 37]), (7, 6)) (array([3, 6, 6]), array([4, 5, 1])) >>> cupy.unravel_index(cupy.array([31, 41, 13]), (7, 6), order='F') (array([3, 6, 6]), array([4, 5, 1])) .. warning:: This function may synchronize the device. .. seealso:: :func:`numpy.unravel_index`, :func:`ravel_multi_index` """ order = 'C' if order is None else order.upper() if order == 'C': dims = reversed(dims) elif order == 'F': pass else: raise ValueError('order not understood') if not cupy.can_cast(indices, cupy.int64, 'same_kind'): raise TypeError('Iterator operand 0 dtype could not be cast ' 'from dtype(\'{}\') to dtype(\'{}\') ' 'according to the rule \'same_kind\''.format( indices.dtype, cupy.int64().dtype)) if (indices < 0).any(): # synchronize! raise ValueError('invalid entry in index array') unraveled_coords = [] for dim in dims: unraveled_coords.append(indices % dim) indices = indices // dim if (indices > 0).any(): # synchronize! raise ValueError('invalid entry in index array') if order == 'C': unraveled_coords = reversed(unraveled_coords) return tuple(unraveled_coords)
def testBucketIdxNumpyInt64Input(self): c = self._classifier([1], 0.1, 0.1, 0) result = c.compute(0, [1, 5, 9], {'bucketIdx': cupy.int64(4), 'actValue': 34.7}, True, True) self.assertSetEqual(set(result.keys()), set(('actualValues', 1))) self.assertEqual(len(result['actualValues']), 1) self.assertAlmostEqual(result['actualValues'][0], 34.7, places=5)
def cumulative_distribution(data, bins): assert cup.min(data) >= 0.0 and cup.max(data) <= 1.0 hg_av, hg_a = cup.unique(cup.floor(data * (bins - 1)), return_index=True) hg_a = cup.float32(hg_a) hgs = cup.sum(hg_a) hg_a /= hgs res = cup.zeros((bins, )) res[cup.int64(hg_av)] = hg_a return cup.cumsum(res)
def testBucketIdxNumpyInt64Input(self): c = self._classifier([1], 0.1, 0.1, 0) result = c.compute(0, [1, 5, 9], { 'bucketIdx': cupy.int64(4), 'actValue': 34.7 }, True, True) self.assertSetEqual(set(result.keys()), set(('actualValues', 1))) self.assertEqual(len(result['actualValues']), 1) self.assertAlmostEqual(result['actualValues'][0], 34.7, places=5)
def _arg_minor_reduce(self, ufunc, axis): """Reduce nonzeros with a ufunc over the minor axis when non-empty Can be applied to a function of self.data by supplying data parameter. Warning: this does not call sum_duplicates() Args: ufunc (object): Function handle giving the operation to be conducted. axis (int): Maxtrix over which the reduction should be conducted Returns: (cupy.ndarray): Reduce result for nonzeros in each major_index """ # Call to the appropriate kernel function # Create the vector to hold output # Note: it's important to set "int" here, following what SciPy # does, as the outcome dtype is platform dependent out_shape = self.shape[1 - axis] out = cupy.zeros(out_shape, dtype=int) # Perform the calculation ker_name = '_arg_reduction<{}, {}>'.format( _scalar.get_typename(self.data.dtype), _scalar.get_typename(out.dtype)) if ufunc == cupy.argmax: ker = self._max_arg_reduction_mod.get_function('max' + ker_name) elif ufunc == cupy.argmin: ker = self._min_arg_reduction_mod.get_function('min' + ker_name) ker((out_shape,), (1,), (self.data, self.indices, self.indptr[:len(self.indptr) - 1], self.indptr[1:], cupy.int64(self.shape[axis]), out)) return out
def _minor_reduce(self, ufunc, axis, nonzero): """Reduce nonzeros with a ufunc over the minor axis when non-empty Can be applied to a function of self.data by supplying data parameter. Warning: this does not call sum_duplicates() Args: ufunc (object): Function handle giving the operation to be conducted. axis (int): Matrix over which the reduction should be conducted. Returns: (cupy.ndarray): Reduce result for nonzeros in each major_index. """ out_shape = self.shape[1 - axis] # Call to the appropriate kernel function out = cupy.zeros(out_shape).astype(cupy.float64) if nonzero: kerns = { cupy.amax: self._max_nonzero_reduction_kern, cupy.amin: self._min_nonzero_reduction_kern } else: kerns = { cupy.amax: self._max_reduction_kern, cupy.amin: self._min_reduction_kern } kerns[ufunc]((out_shape, ), (1, ), (self.data.astype( cupy.float64), self.indptr[:len(self.indptr) - 1], self.indptr[1:], cupy.int64(self.shape[axis]), out)) return out
def _minor_reduce(self, ufunc, axis, nonzero): """Reduce nonzeros with a ufunc over the minor axis when non-empty Can be applied to a function of self.data by supplying data parameter. Warning: this does not call sum_duplicates() Args: ufunc (object): Function handle giving the operation to be conducted. axis (int): Matrix over which the reduction should be conducted. Returns: (cupy.ndarray): Reduce result for nonzeros in each major_index. """ # Call to the appropriate kernel function if axis == 1: # Create the vector to hold output value = cupy.zeros(self.shape[0]).astype(cupy.float64) if nonzero: # Perform the calculation if ufunc == cupy.amax: self._max_nonzero_reduction_kern( (self.shape[0],), (1,), (self.data.astype(cupy.float64), self.indptr[:len(self.indptr) - 1], self.indptr[1:], cupy.int64(self.shape[1]), value)) if ufunc == cupy.amin: self._min_nonzero_reduction_kern( (self.shape[0],), (1,), (self.data.astype(cupy.float64), self.indptr[:len(self.indptr) - 1], self.indptr[1:], cupy.int64(self.shape[1]), value)) else: # Perform the calculation if ufunc == cupy.amax: self._max_reduction_kern( (self.shape[0],), (1,), (self.data.astype(cupy.float64), self.indptr[:len(self.indptr) - 1], self.indptr[1:], cupy.int64(self.shape[1]), value)) if ufunc == cupy.amin: self._min_reduction_kern( (self.shape[0],), (1,), (self.data.astype(cupy.float64), self.indptr[:len(self.indptr) - 1], self.indptr[1:], cupy.int64(self.shape[1]), value)) if axis == 0: # Create the vector to hold output value = cupy.zeros(self.shape[1]).astype(cupy.float64) if nonzero: # Perform the calculation if ufunc == cupy.amax: self._max_nonzero_reduction_kern( (self.shape[1],), (1,), (self.data.astype(cupy.float64), self.indptr[:len(self.indptr) - 1], self.indptr[1:], cupy.int64(self.shape[0]), value)) if ufunc == cupy.amin: self._min_nonzero_reduction_kern( (self.shape[1],), (1,), (self.data.astype(cupy.float64), self.indptr[:len(self.indptr) - 1], self.indptr[1:], cupy.int64(self.shape[0]), value)) else: # Perform the calculation if ufunc == cupy.amax: self._max_reduction_kern( (self.shape[1],), (1,), (self.data.astype(cupy.float64), self.indptr[:len(self.indptr) - 1], self.indptr[1:], cupy.int64(self.shape[0]), value)) if ufunc == cupy.amin: self._min_reduction_kern( (self.shape[1],), (1,), (self.data.astype(cupy.float64), self.indptr[:len(self.indptr) - 1], self.indptr[1:], cupy.int64(self.shape[0]), value)) return value
def f(): x = jit.grid(2) y = cupy.int64(x) # <- x is a tuple # NOQA
def ravel_multi_index(multi_index, dims, mode='wrap', order='C'): """ Converts a tuple of index arrays into an array of flat indices, applying boundary modes to the multi-index. Args: multi_index (tuple of cupy.ndarray) : A tuple of integer arrays, one array for each dimension. dims (tuple of ints): The shape of array into which the indices from ``multi_index`` apply. mode ('raise', 'wrap' or 'clip'), optional: Specifies how out-of-bounds indices are handled. Can specify either one mode or a tuple of modes, one mode per index: - *'raise'* -- raise an error - *'wrap'* -- wrap around (default) - *'clip'* -- clip to the range In 'clip' mode, a negative index which would normally wrap will clip to 0 instead. order ('C' or 'F'), optional: Determines whether the multi-index should be viewed as indexing in row-major (C-style) or column-major (Fortran-style) order. Returns: raveled_indices (cupy.ndarray): An array of indices into the flattened version of an array of dimensions ``dims``. .. warning:: This function may synchronize the device when ``mode == 'raise'``. Notes ----- Note that the default `mode` (``'wrap'``) is different than in NumPy. This is done to avoid potential device synchronization. Examples -------- >>> cupy.ravel_multi_index(cupy.asarray([[3,6,6],[4,5,1]]), (7,6)) array([22, 41, 37]) >>> cupy.ravel_multi_index(cupy.asarray([[3,6,6],[4,5,1]]), (7,6), ... order='F') array([31, 41, 13]) >>> cupy.ravel_multi_index(cupy.asarray([[3,6,6],[4,5,1]]), (4,6), ... mode='clip') array([22, 23, 19]) >>> cupy.ravel_multi_index(cupy.asarray([[3,6,6],[4,5,1]]), (4,4), ... mode=('clip', 'wrap')) array([12, 13, 13]) >>> cupy.ravel_multi_index(cupy.asarray((3,1,4,1)), (6,7,8,9)) array(1621) .. seealso:: :func:`numpy.ravel_multi_index`, :func:`unravel_index` """ ndim = len(dims) if len(multi_index) != ndim: raise ValueError( "parameter multi_index must be a sequence of " "length {}".format(ndim)) for d in dims: if not isinstance(d, numbers.Integral): raise TypeError( "{} object cannot be interpreted as an integer".format( type(d))) if isinstance(mode, str): mode = (mode, ) * ndim if functools.reduce(operator.mul, dims) > cupy.iinfo(cupy.int64).max: raise ValueError("invalid dims: array size defined by dims is larger " "than the maximum possible size") s = 1 ravel_strides = [1] * ndim if order is None: order = "C" if order == "C": for i in range(ndim - 2, -1, -1): s = s * dims[i + 1] ravel_strides[i] = s elif order == "F": for i in range(1, ndim): s = s * dims[i - 1] ravel_strides[i] = s else: raise TypeError("order not understood") multi_index = cupy.broadcast_arrays(*multi_index) raveled_indices = cupy.zeros(multi_index[0].shape, dtype=cupy.int64) for d, stride, idx, _mode in zip(dims, ravel_strides, multi_index, mode): if not isinstance(idx, cupy.ndarray): raise TypeError("elements of multi_index must be cupy arrays") if not cupy.can_cast(idx, cupy.int64, 'same_kind'): raise TypeError( 'multi_index entries could not be cast from dtype(\'{}\') to ' 'dtype(\'{}\') according to the rule \'same_kind\''.format( idx.dtype, cupy.int64().dtype)) idx = idx.astype(cupy.int64, copy=False) if _mode == "raise": if cupy.any(cupy.logical_or(idx >= d, idx < 0)): raise ValueError("invalid entry in coordinates array") elif _mode == "clip": idx = cupy.clip(idx, 0, d - 1) elif _mode == 'wrap': idx = idx % d else: raise TypeError("Unrecognized mode: {}".format(_mode)) raveled_indices += stride * idx return raveled_indices