abracudabra =========== .. py:module:: abracudabra .. autoapi-nested-parse:: Convert dataframes, arrays, and tensors to CPU/CUDA. Submodules ---------- .. toctree:: :maxdepth: 1 /autoapi/abracudabra/conversion/index /autoapi/abracudabra/device/index /autoapi/abracudabra/testing/index Classes ------- .. autoapisummary:: abracudabra.Device Functions --------- .. autoapisummary:: abracudabra.to_array abracudabra.to_dataframe abracudabra.to_series abracudabra.to_tensor abracudabra.to_device abracudabra.get_np_or_cp abracudabra.get_pd_or_cudf abracudabra.get_device Package Contents ---------------- .. py:function:: to_array(sequence, /, device = None, *, strict = False) Convert an array, series, or dataframe to a NumPy or CuPy array. :param sequence: The sequence to convert. :param device: The device to convert the sequence to. If None, the sequence stays on the same device. :param strict: Whether to raise an error if the sequence is not a valid type. A NumPy/CuPy array, Pandas/cuDF series or dataframe, or Torch tensor are valid types. If False, the sequence is converted to a NumPy/CuPy array if possible, but it might raise an error if the conversion is not possible. :returns: A NumPy/CuPy array. :raises TypeError: If the sequence is not a valid type and ``strict`` is True. .. rubric:: Examples Build a CuPy array from a sequence >>> import cupy as cp >>> cupy_array = to_array([1, 2, 3], "cuda:0") >>> print(type(cupy_array)) Build a NumPy array from a cuDF series >>> import cudf >>> cudf_series = cudf.Series([1, 2, 3]) >>> numpy_array = to_array(cudf_series) >>> print(type(numpy_array)) .. py:function:: to_dataframe(data, /, index = None, device = None, *, strict = False, **kwargs) Convert to a Pandas/cuDF dataframe. :param data: The data to convert. If a mapping, the keys will be used as column names. :param index: The optional index for the dataframe. :param device: The device to use for the dataframe. If not provided, the type is guessed from the data. :param strict: Whether to raise an error if the provided data does not consist of NumPy/CuPy arrays or Torch tensors. :param \*\*kwargs: Additional keyword arguments for the dataframe. :returns: The converted dataframe. .. rubric:: Examples Build a dataframe from mixed data types >>> import cupy as cp >>> import numpy as np >>> import torch >>> numpy_array = np.full((5,), 1, dtype=np.float32) >>> cupy_array = cp.full((5,), 2, dtype=cp.int8) >>> torch_tensor = torch.full((5,), 3, dtype=torch.float32, device="cuda:0") >>> dataframe = to_dataframe( ... {"numpy": numpy_array, "cupy": cupy_array, "torch": torch_tensor}, ... device="cuda:0", ... ) >>> print(dataframe) numpy cupy torch 0 1.0 2 3.0 1 1.0 2 3.0 2 1.0 2 3.0 3 1.0 2 3.0 4 1.0 2 3.0 >>> print(type(dataframe)) .. py:function:: to_series(sequence, /, index = None, device = None, *, strict = False, **kwargs) Convert an array or tensor to a Pandas/cuDF series. :param sequence: The array or tensor to convert. :param index: The optional index for the series. :param device: The device to use for the series. If not provided, the array stays on the same device. :param strict: Whether to raise an error if the sequence is not a NumPy/CuPy array or Torch tensor. :param \*\*kwargs: Additional keyword arguments for the series. :returns: The converted series. .. rubric:: Examples Convert a list to a CuPy series >>> series = to_series([10, 20, 30], device="cuda") >>> print(type(series)) Convert a CuPy array to a cuDF series >>> import cupy as cp >>> cupy_array = cp.array([40, 50, 60]) >>> series = to_series(cupy_array) >>> print(type(series)) .. py:function:: to_tensor(sequence, /, device = None, *, strict = False) Convert an array, series, or dataframe to a Torch tensor. :param sequence: The sequence to convert. :param device: The device to convert the sequence to. If None, the sequence stays on the same device. :param strict: Whether to raise an error if the sequence is not a valid type. A NumPy/CuPy array, Pandas/cuDF series or dataframe, or Torch tensor are valid types. If False, the sequence is converted to a Torch tensor if possible, but it might raise an error if the conversion is not possible. :returns: A Torch tensor. :raises TypeError: If the sequence is not a valid type and ``strict`` is True. .. rubric:: Examples Build a Torch tensor from a sequence >>> import torch >>> to_tensor([1, 2, 3]) tensor([1, 2, 3]) Build a Torch tensor from a CuPy array >>> import cupy as cp >>> cupy_array = cp.array([4, 5, 6]) >>> torch_tensor = to_tensor(cupy_array) >>> print(torch_tensor.device) tensor([4, 5, 6], device='cuda:0') .. py:class:: Device Bases: :py:obj:`NamedTuple` A device with a name and index. .. py:attribute:: type :type: DeviceType The device type, e.g., ``"cpu"`` or ``"cuda"``. .. py:attribute:: idx :type: int | None :value: None The device index, e.g., ``0`` or ``None``. .. py:method:: __str__() Return the device name. .. py:method:: validate(device, idx = None) :classmethod: Return a device, validating the device type and index. :param device: The device type. :param idx: The optional device index. :returns: The device. .. py:method:: from_str(device, /) :classmethod: Return a device from a string. The string should be in the format ``"device[:idx]"``. .. rubric:: Examples >>> Device.from_str("cpu") Device(type="cpu", idx=None) >>> Device.from_str("cuda:1") Device(type="cuda", idx=1) .. py:method:: parse(device, /) :classmethod: Return a device from a string or device. If the input is already a device, it is returned as is. Otherwise, the input is parsed as a string. :param device: The device or device string (e.g., ``"cpu"`` or ``"cuda:1"``). :returns: The device. .. py:method:: to_torch() Return a torch device. .. rubric:: Examples >>> Device("cpu", None).to_torch() device(type='cpu') >>> Device("cuda", 1).to_torch() device(type='cuda', index=1) .. py:function:: to_device(sequence: abracudabra._annotations.Series, /, device: abracudabra.device.base.Device | str) -> abracudabra._annotations.Series to_device(sequence: torch.Tensor, /, device: abracudabra.device.base.Device | str) -> torch.Tensor to_device(sequence: abracudabra._annotations.DataFrame, /, device: abracudabra.device.base.Device | str) -> abracudabra._annotations.DataFrame to_device(sequence: abracudabra._annotations.Index, /, device: abracudabra.device.base.Device | str) -> abracudabra._annotations.Index to_device(sequence: abracudabra._annotations.Array, /, device: abracudabra.device.base.Device | str) -> abracudabra._annotations.Array to_device(sequence: abracudabra._annotations.Array | abracudabra._annotations.Series | torch.Tensor, /, device: abracudabra.device.base.Device | str) -> abracudabra._annotations.Index | abracudabra._annotations.Series | abracudabra._annotations.DataFrame | abracudabra._annotations.Array | torch.Tensor Move an array, series, or tensor to a device. Call the appropriate function to move the element to the device: * :py:func:`abracudabra.device.conversion.array_to_device` for NumPy/CuPy arrays. * :py:func:`abracudabra.device.conversion.frame_to_device` for Pandas/cuDF index/series/dataframes. * :py:func:`abracudabra.device.conversion.tensor_to_device` for Torch tensors. :param sequence: The sequence to move to the device. :param device: The device to move the sequence to. :returns: The sequence on the specified device. :raises TypeError: If the sequence is not a NumPy/CuPy array, Pandas/cuDF index/series/dataframe or Torch tensor. .. rubric:: Examples Move a Pandas dataframe to the GPU (cuDF dataframe): >>> import pandas as pd >>> from abracudabra import to_device >>> df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}) >>> df_gpu = to_device(df, "cuda") >>> print(type(df_gpu)) Move a cuDF dataframe to the CPU (Pandas dataframe): >>> df_cpu = to_device(df_gpu, "cpu") >>> print(type(df_cpu)) >> import numpy as np >>> arr = np.array([1, 2, 3]) >>> arr_gpu = to_device(arr, "cuda") >>> print(type(arr_gpu)) .. py:function:: get_np_or_cp(device_type = None) Get the numpy or cupy library based on the device type. * if ``device_type`` is ``"cpu"``, return the numpy library * if ``device_type`` is ``"cuda"``, return the cupy library If ``device_type`` is not specified, return the numpy library (default). .. rubric:: Examples >>> device_type = "cuda" # in some configuration for example >>> np_or_cp = get_np_or_cp(device_type) >>> np_or_cp.random.choice([1, 2, 3], size=1) # returns a cupy array array([3]) .. py:function:: get_pd_or_cudf(device_type = None) Get the pandas or cudf library based on the device type. * if ``device_type`` is ``"cpu"``, return the pandas library * if ``device_type`` is ``"cuda"``, return the cudf library If ``device_type`` is not specified, return the pandas library (default). .. rubric:: Examples >>> pd_or_cudf = get_pd_or_cudf("cpu") >>> pd_or_cudf.Series([1, 2, 3]) # returns a pandas series 0 1 1 2 2 3 dtype: int64 .. py:function:: get_device(element: abracudabra._annotations.Array | torch.Tensor, /, *, raise_if_unknown: Literal[True] = ...) -> abracudabra.device.base.Device get_device(element: abracudabra._annotations.Array | torch.Tensor, /, *, raise_if_unknown: bool = ...) -> abracudabra.device.base.Device | None Get the device of a NumPy/CuPy array or series. :param element: The element to check. :param raise_if_unknown: Whether to raise an error if the element is not a known array or tensor. :returns: The device of the element. .. rubric:: Examples >>> import numpy as np >>> array = np.random.rand(3) >>> get_device(array) Device(type="cpu", idx=None) >>> import torch >>> tensor = torch.rand(3, device="cuda") >>> get_device(tensor) Device(type="cuda", idx=0)