def _get_dtype(operators, dtypes=None): if dtypes is None: dtypes = [] for obj in operators: if obj is not None and hasattr(obj, 'dtype'): dtypes.append(obj.dtype) return cupy.find_common_type(dtypes, [])
def upcast(*args): """Returns the nearest supported sparse dtype for the combination of one or more types. upcast(t0, t1, ..., tn) -> T where T is a supported dtype Examples: >>> upcast('int32') <type 'numpy.int32'> >>> upcast('int32','float32') <type 'numpy.float64'> >>> upcast('bool',float) <type 'numpy.complex128'> """ t = _upcast_memo.get(args) if t is not None: return t upcast = cupy.find_common_type(args, []) for t in supported_dtypes: if cupy.can_cast(upcast, t): _upcast_memo[args] = t return t raise TypeError('no supported conversion for types: %r' % (args,))
def block_diag(*arrs): """Create a block diagonal matrix from provided arrays. Given the inputs ``A``, ``B``, and ``C``, the output will have these arrays arranged on the diagonal:: [A, 0, 0] [0, B, 0] [0, 0, C] Args: A, B, C, ... (cupy.ndarray): Input arrays. A 1-D array of length ``n`` is treated as a 2-D array with shape ``(1,n)``. Returns: (cupy.ndarray): Array with ``A``, ``B``, ``C``, ... on the diagonal. Output has the same dtype as ``A``. .. seealso:: :func:`scipy.linalg.block_diag` """ if not arrs: return cupy.empty((1, 0)) # Convert to 2D and check if len(arrs) == 1: arrs = (cupy.atleast_2d(*arrs), ) else: arrs = cupy.atleast_2d(*arrs) if any(a.ndim != 2 for a in arrs): bad = [k for k in range(len(arrs)) if arrs[k].ndim != 2] raise ValueError('arguments in the following positions have dimension ' 'greater than 2: {}'.format(bad)) shapes = tuple(a.shape for a in arrs) shape = tuple(sum(x) for x in zip(*shapes)) dtype = cupy.find_common_type([a.dtype for a in arrs], []) out = cupy.zeros(shape, dtype=dtype) r, c = 0, 0 for arr in arrs: rr, cc = arr.shape out[r:r + rr, c:c + cc] = arr r += rr c += cc return out