Exemple #1
0
    def __init__(self, id_or_device):
        _type, id = None, None
        if isinstance(id_or_device, int):
            id = id_or_device
        elif id_or_device == "cpu":
            _type, id = id_or_device, -1
        elif isinstance(id_or_device, Device):
            _type, id = id_or_device.type, id_or_device.id
        elif env.cupy_available() and isinstance(id_or_device, cp.cuda.Device):
            _type, id = "cuda", id_or_device.id
        elif env.sigpy_available() and isinstance(id_or_device, sp.Device):
            id = id_or_device.id
        elif env.torch_available() and isinstance(id_or_device, torch.device):
            _type, id = id_or_device.type, id_or_device.index
            if id is None:
                if _type == "cuda":
                    id = torch.cuda.current_device()
                elif _type == "cpu":
                    id = -1
                else:
                    raise ValueError(f"Unsupported device type: {_type}")
        else:
            raise ValueError(
                f"Accepts int, Device, cupy.cuda.Device, or torch.device"
                f"got {id_or_device}")

        assert id >= -1
        if _type is None:
            _type = "cpu" if id == -1 else "cuda"

        cpdevice = None
        if id != -1:
            if env.cupy_available():
                cpdevice = cp.cuda.Device(id)
            else:
                raise ValueError(
                    "cupy not installed, but set device {}.".format(id))

        self._type = _type
        self._id = id
        self._cpdevice = cpdevice
Exemple #2
0
    def _process_mask(self, mask, y: MedicalVolume):
        """Process mask into appropriate shape."""
        arr_types = (np.ndarray,
                     cp.ndarray) if env.cupy_available() else (np.ndarray, )
        if isinstance(mask, arr_types):
            mask = y._partial_clone(volume=mask, headers=None)
        elif not isinstance(mask, MedicalVolume):
            raise TypeError("`mask` must be a MedicalVolume or ndarray")

        mask = mask.reformat_as(y)
        if not mask.is_same_dimensions(y, defaults.AFFINE_DECIMAL_PRECISION):
            raise RuntimeError("`mask` and `y` dimension mismatch")

        return mask > 0
Exemple #3
0
 def __eq__(self, other):
     if other == -1:
         # other integers are not compared as self.type may be subject to change
         return self.id == other
     elif isinstance(other, Device):
         return self.type == other.type and self.id == other.id
     elif env.cupy_available() and isinstance(other, cp.cuda.Device):
         return self.type == "cuda" and self.id == other.id
     elif env.sigpy_available() and isinstance(other, sp.Device):
         try:
             return self.spdevice == other
         except RuntimeError:
             return False
     elif env.torch_available() and isinstance(other, torch.device):
         return self.ptdevice == other
     else:
         return False
Exemple #4
0
def get_array_module(array):
    """Gets an appropriate module from :mod:`numpy` or :mod:`cupy`.

    This is almost equivalent to :func:`cupy.get_array_module`. The differences
    are that this function can be used even if cupy is not available.

    Adapted from :mod:`sigpy`.

    Args:
        array: Input array.

    Returns:
        module: :mod:`cupy` or :mod:`numpy` is returned based on input.
    """
    if env.cupy_available():
        return cp.get_array_module(array)
    else:
        return np
Exemple #5
0
 def _extract_input_array_ufunc(self, input, device=None):
     if device is None:
         device = self.device
     device_err = "Expected device {} but got device ".format(device) + "{}"
     if isinstance(input, Number):
         return input
     elif isinstance(input, np.ndarray):
         if device != cpu_device:
             raise RuntimeError(device_err.format(cpu_device))
         return input
     elif env.cupy_available() and isinstance(input, cp.ndarray):
         if device != input.device:
             raise RuntimeError(device_err.format(Device(input.device)))
         return input
     elif isinstance(input, MedicalVolume):
         if device != input.device:
             raise RuntimeError(device_err.format(Device(input.device)))
         assert self.is_same_dimensions(input, err=True)
         return input._volume
     else:
         return NotImplemented
Exemple #6
0
"""Functions and classes for getting and setting computing devices.

"""
import numpy as np

from dosma.utils import env

if env.cupy_available():
    import cupy as cp
if env.sigpy_available():
    import sigpy as sp
if env.torch_available():
    import torch

__all__ = ["Device", "get_device", "to_device"]


class Device(object):
    """Device class.

    This class extends ``cupy.Device`` and can also be used to interface with
    ``torch.Device`` and ``sigpy.Device``. This class contains a device type
    ('cpu' or 'cuda') and optional device ordinal (i.e. the id) for the device type.
    This class can also be constructed using only the ordinal id, where id >= 0
    representing the id-th GPU, and id = -1 representing CPU. cupy must be installed to use GPUs.

    The array module for the corresponding device can be obtained via ``device.xp``.
    Similar to cupy.Device, the Device object can be used as a context:

        >>> device = Device(1)  # gpu 1
        >>> xp = device.xp  # xp is cupy.