def METHOD_NAME(self, kernel, args, kwargs):
    distributed_arrays = []
    regular_arrays = []
    for i, arg in enumerate(args):
        if isinstance(arg, _DistributedArray):
            distributed_arrays.append((i, arg))
        elif isinstance(arg, cupy.ndarray):
            regular_arrays.append((i, arg))
    # Do it for kwargs too
    for k, arg in kwargs.items():
        if isinstance(arg, _DistributedArray):
            distributed_arrays.append((k, arg))
        elif isinstance(arg, cupy.ndarray):
            regular_arrays.append((k, arg))
    args = list(args)
    devices = self._get_execution_devices(distributed_arrays)
    dev_outs = {}
    dtype = None
    for dev in devices:
        array_args = self._prepare_args(
            distributed_arrays, regular_arrays, dev)
        for (i, arg) in array_args:
            if isinstance(i, int):
                args[i] = arg
            else:
                kwargs[i] = arg
        with cupy.cuda.Device(dev):
            out = kernel(*args, **kwargs)
            dtype = out.dtype
            dev_outs[dev] = out
    for out in dev_outs.values():
        if not isinstance(out, cupy.ndarray):
            raise RuntimeError(
                'kernels returning other than single array not supported')
    return _DistributedArray(
        self.shape, dtype, dev_outs,
        self._axis, self._tile_size, devices)