:mod:`heat.sparse` ================== .. py:module:: heat.sparse .. autoapi-nested-parse:: add sparse heat function to the ht.sparse namespace Submodules ---------- .. toctree:: :titlesonly: :maxdepth: 1 _operations/index.rst arithmetics/index.rst dcsx_matrix/index.rst factories/index.rst manipulations/index.rst Package Contents ---------------- .. function:: add(t1: heat.sparse.dcsx_matrix.DCSR_matrix, t2: heat.sparse.dcsx_matrix.DCSR_matrix, orientation: str = 'row') -> heat.sparse.dcsx_matrix.DCSR_matrix Element-wise addition of values from two operands, commutative. Takes the first and second operand (scalar or :class:`~heat.sparse.DCSR_matrix`) whose elements are to be added as argument and returns a ``DCSR_matrix`` containing the results of element-wise addition of ``t1`` and ``t2``. :param t1: The first operand involved in the addition :type t1: DCSR_matrix :param t2: The second operand involved in the addition :type t2: DCSR_matrix :param orientation: The orientation of the operation. Options: 'row' or 'col' Default: 'row' :type orientation: str, optional .. rubric:: Examples >>> heat_sparse_csr (indptr: tensor([0, 2, 3]), indices: tensor([0, 2, 2]), data: tensor([1., 2., 3.]), dtype=ht.float32, device=cpu:0, split=0) >>> heat_sparse_csr.todense() DNDarray([[1., 0., 2.], [0., 0., 3.]], dtype=ht.float32, device=cpu:0, split=0) >>> sum_sparse = heat_sparse_csr + heat_sparse_csr (or) >>> sum_sparse = ht.sparse.sparse_add(heat_sparse_csr, heat_sparse_csr) >>> sum_sparse (indptr: tensor([0, 2, 3], dtype=torch.int32), indices: tensor([0, 2, 2], dtype=torch.int32), data: tensor([2., 4., 6.]), dtype=ht.float32, device=cpu:0, split=0) >>> sum_sparse.todense() DNDarray([[2., 0., 4.], [0., 0., 6.]], dtype=ht.float32, device=cpu:0, split=0) .. function:: mul(t1: heat.sparse.dcsx_matrix.DCSR_matrix, t2: heat.sparse.dcsx_matrix.DCSR_matrix, orientation: str = 'row') -> heat.sparse.dcsx_matrix.DCSR_matrix Element-wise multiplication (NOT matrix multiplication) of values from two operands, commutative. Takes the first and second operand (scalar or :class:`~heat.sparse.DCSR_matrix`) whose elements are to be multiplied as argument. :param t1: The first operand involved in the multiplication :type t1: DCSR_matrix :param t2: The second operand involved in the multiplication :type t2: DCSR_matrix :param orientation: The orientation of the operation. Options: 'row' or 'col' Default: 'row' :type orientation: str, optional .. rubric:: Examples >>> heat_sparse_csr (indptr: tensor([0, 2, 3]), indices: tensor([0, 2, 2]), data: tensor([1., 2., 3.]), dtype=ht.float32, device=cpu:0, split=0) >>> heat_sparse_csr.todense() DNDarray([[1., 0., 2.], [0., 0., 3.]], dtype=ht.float32, device=cpu:0, split=0) >>> pdt_sparse = heat_sparse_csr * heat_sparse_csr (or) >>> pdt_sparse = ht.sparse.sparse_mul(heat_sparse_csr, heat_sparse_csr) >>> pdt_sparse (indptr: tensor([0, 2, 3]), indices: tensor([0, 2, 2]), data: tensor([1., 4., 9.]), dtype=ht.float32, device=cpu:0, split=0) >>> pdt_sparse.todense() DNDarray([[1., 0., 4.], [0., 0., 9.]], dtype=ht.float32, device=cpu:0, split=0) .. py:class:: DCSR_matrix(array: torch.Tensor, gnnz: int, gshape: Tuple[int, Ellipsis], dtype: heat.core.types.datatype, split: Union[int, None], device: heat.core.devices.Device, comm: Communication, balanced: bool) Bases: :class:`__DCSX_matrix` Distributed Compressed Sparse Row Matrix. It is composed of PyTorch sparse_csr_tensors local to each process. :param array: Local sparse array :type array: torch.Tensor (layout ==> torch.sparse_csr) :param gnnz: Total number of non-zero elements across all processes :type gnnz: int :param gshape: The global shape of the array :type gshape: Tuple[int,...] :param dtype: The datatype of the array :type dtype: datatype :param split: If split is not None, it denotes the axis on which the array is divided between processes. DCSR_matrix only supports distribution along axis 0. :type split: int or None :param device: The device on which the local arrays are using (cpu or gpu) :type device: Device :param comm: The communications object for sending and receiving data :type comm: Communication :param balanced: Describes whether the data are evenly distributed across processes. :type balanced: bool or None .. role:: raw-html(raw) :format: html .. py:class:: DCSC_matrix(array: torch.Tensor, gnnz: int, gshape: Tuple[int, Ellipsis], dtype: heat.core.types.datatype, split: Union[int, None], device: heat.core.devices.Device, comm: Communication, balanced: bool) Bases: :class:`__DCSX_matrix` Distributed Compressed Sparse Column Matrix. It is composed of PyTorch sparse_csc_tensors local to each process. :param array: Local sparse array :type array: torch.Tensor (layout ==> torch.sparse_csc) :param gnnz: Total number of non-zero elements across all processes :type gnnz: int :param gshape: The global shape of the array :type gshape: Tuple[int,...] :param dtype: The datatype of the array :type dtype: datatype :param split: If split is not None, it denotes the axis on which the array is divided between processes. DCSR_matrix only supports distribution along axis 0. :type split: int or None :param device: The device on which the local arrays are using (cpu or gpu) :type device: Device :param comm: The communications object for sending and receiving data :type comm: Communication :param balanced: Describes whether the data are evenly distributed across processes. :type balanced: bool or None .. role:: raw-html(raw) :format: html .. function:: sparse_csr_matrix(obj: Iterable, dtype: Optional[Type[heat.core.types.datatype]] = None, split: Optional[int] = None, is_split: Optional[int] = None, device: Optional[heat.core.devices.Device] = None, comm: Optional[heat.core.communication.Communication] = None) -> heat.sparse.dcsx_matrix.DCSR_matrix Create a :class:`~heat.sparse.DCSR_matrix`. :param obj: A tensor or array, any object exposing the array interface, an object whose ``__array__`` method returns an array, or any (nested) sequence. Sparse tensor that needs to be distributed. :type obj: array_like :param dtype: The desired data-type for the sparse matrix. If not given, then the type will be determined as the minimum type required to hold the objects in the sequence. This argument can only be used to ‘upcast’ the array. For downcasting, use the :func:`~heat.sparse.DCSR_matrix.astype` method. :type dtype: datatype, optional :param split: The axis along which the passed array content ``obj`` is split and distributed in memory. DCSR_matrix only supports distribution along axis 0. Mutually exclusive with ``is_split``. :type split: int or None, optional :param is_split: Specifies the axis along which the local data portions, passed in obj, are split across all machines. DCSR_matrix only supports distribution along axis 0. Useful for interfacing with other distributed-memory code. The shape of the global array is automatically inferred. Mutually exclusive with ``split``. :type is_split: int or None, optional :param device: Specifies the :class:`~heat.core.devices.Device` the array shall be allocated on (i.e. globally set default device). :type device: str or Device, optional :param comm: Handle to the nodes holding distributed array chunks. :type comm: Communication, optional :raises ValueError: If split and is_split parameters are not one of 0 or None. .. rubric:: Examples Create a :class:`~heat.sparse.DCSR_matrix` from :class:`torch.Tensor` (layout ==> torch.sparse_csr) >>> indptr = torch.tensor([0, 2, 3, 6]) >>> indices = torch.tensor([0, 2, 2, 0, 1, 2]) >>> data = torch.tensor([1, 2, 3, 4, 5, 6], dtype=torch.float) >>> torch_sparse_csr = torch.sparse_csr_tensor(indptr, indices, data) >>> heat_sparse_csr = ht.sparse.sparse_csr_matrix(torch_sparse_csr, split=0) >>> heat_sparse_csr (indptr: tensor([0, 2, 3, 6]), indices: tensor([0, 2, 2, 0, 1, 2]), data: tensor([1., 2., 3., 4., 5., 6.]), dtype=ht.float32, device=cpu:0, split=0) Create a :class:`~heat.sparse.DCSR_matrix` from :class:`scipy.sparse.csr_matrix` >>> scipy_sparse_csr = scipy.sparse.csr_matrix((data, indices, indptr)) >>> heat_sparse_csr = ht.sparse.sparse_csr_matrix(scipy_sparse_csr, split=0) >>> heat_sparse_csr (indptr: tensor([0, 2, 3, 6], dtype=torch.int32), indices: tensor([0, 2, 2, 0, 1, 2], dtype=torch.int32), data: tensor([1., 2., 3., 4., 5., 6.]), dtype=ht.float32, device=cpu:0, split=0) Create a :class:`~heat.sparse.DCSR_matrix` using data that is already distributed (with `is_split`) >>> indptrs = [torch.tensor([0, 2, 3]), torch.tensor([0, 3])] >>> indices = [torch.tensor([0, 2, 2]), torch.tensor([0, 1, 2])] >>> data = [torch.tensor([1, 2, 3], dtype=torch.float), torch.tensor([4, 5, 6], dtype=torch.float)] >>> rank = ht.MPI_WORLD.rank >>> local_indptr = indptrs[rank] >>> local_indices = indices[rank] >>> local_data = data[rank] >>> local_torch_sparse_csr = torch.sparse_csr_tensor(local_indptr, local_indices, local_data) >>> heat_sparse_csr = ht.sparse.sparse_csr_matrix(local_torch_sparse_csr, is_split=0) >>> heat_sparse_csr (indptr: tensor([0, 2, 3, 6]), indices: tensor([0, 2, 2, 0, 1, 2]), data: tensor([1., 2., 3., 4., 5., 6.]), dtype=ht.float32, device=cpu:0, split=0) Create a :class:`~heat.sparse.DCSR_matrix` from List >>> ht.sparse.sparse_csr_matrix([[0, 0, 1], [1, 0, 2], [0, 0, 3]]) (indptr: tensor([0, 1, 3, 4]), indices: tensor([2, 0, 2, 2]), data: tensor([1, 1, 2, 3]), dtype=ht.int64, device=cpu:0, split=None) .. function:: sparse_csc_matrix(obj: Iterable, dtype: Optional[Type[heat.core.types.datatype]] = None, split: Optional[int] = None, is_split: Optional[int] = None, device: Optional[heat.core.devices.Device] = None, comm: Optional[heat.core.communication.Communication] = None) -> heat.sparse.dcsx_matrix.DCSC_matrix Create a :class:`~heat.sparse.DCSC_matrix`. :param obj: A tensor or array, any object exposing the array interface, an object whose ``__array__`` method returns an array, or any (nested) sequence. Sparse tensor that needs to be distributed. :type obj: array_like :param dtype: The desired data-type for the sparse matrix. If not given, then the type will be determined as the minimum type required to hold the objects in the sequence. This argument can only be used to ‘upcast’ the array. For downcasting, use the :func:`~heat.sparse.DCSC_matrix.astype` method. :type dtype: datatype, optional :param split: The axis along which the passed array content ``obj`` is split and distributed in memory. DCSC_matrix only supports distribution along axis 1. Mutually exclusive with ``is_split``. :type split: int or None, optional :param is_split: Specifies the axis along which the local data portions, passed in obj, are split across all machines. DCSC_matrix only supports distribution along axis 1. Useful for interfacing with other distributed-memory code. The shape of the global array is automatically inferred. Mutually exclusive with ``split``. :type is_split: int or None, optional :param device: Specifies the :class:`~heat.core.devices.Device` the array shall be allocated on (i.e. globally set default device). :type device: str or Device, optional :param comm: Handle to the nodes holding distributed array chunks. :type comm: Communication, optional :raises ValueError: If split and is_split parameters are not one of 1 or None. .. rubric:: Examples Create a :class:`~heat.sparse.DCSC_matrix` from :class:`torch.Tensor` (layout ==> torch.sparse_csc) >>> indptr = torch.tensor([0, 2, 3, 6]) >>> indices = torch.tensor([0, 2, 2, 0, 1, 2]) >>> data = torch.tensor([1.0, 4.0, 5.0, 2.0, 3.0, 6.0], dtype=torch.float) >>> torch_sparse_csc = torch.sparse_csc_tensor(indptr, indices, data) >>> heat_sparse_csc = ht.sparse.sparse_csc_matrix(torch_sparse_csc, split=1) >>> heat_sparse_csc (indptr: tensor([0, 2, 3, 6]), indices: tensor([0, 2, 2, 0, 1, 2]), data: tensor([1., 4., 5., 2., 3., 6.]), dtype=ht.float32, device=cpu:0, split=1) Create a :class:`~heat.sparse.DCSC_matrix` from :class:`scipy.sparse.csc_matrix` >>> scipy_sparse_csc = scipy.sparse.csc_matrix((data, indices, indptr)) >>> heat_sparse_csc = ht.sparse.sparse_csc_matrix(scipy_sparse_csc, split=1) >>> heat_sparse_csc (indptr: tensor([0, 2, 3, 6], dtype=torch.int32), indices: tensor([0, 2, 2, 0, 1, 2], dtype=torch.int32), data: tensor([1., 4., 5., 2., 3., 6.]), dtype=ht.float32, device=cpu:0, split=1) Create a :class:`~heat.sparse.DCSC_matrix` using data that is already distributed (with `is_split`) >>> indptrs = [torch.tensor([0, 2, 3]), torch.tensor([0, 3])] >>> indices = [torch.tensor([0, 2, 2]), torch.tensor([0, 1, 2])] >>> data = [torch.tensor([1, 2, 3], dtype=torch.float), torch.tensor([4, 5, 6], dtype=torch.float)] >>> rank = ht.MPI_WORLD.rank >>> local_indptr = indptrs[rank] >>> local_indices = indices[rank] >>> local_data = data[rank] >>> local_torch_sparse_csr = torch.sparse_csr_tensor(local_indptr, local_indices, local_data) >>> heat_sparse_csr = ht.sparse.sparse_csr_matrix(local_torch_sparse_csr, is_split=0) >>> heat_sparse_csr (indptr: tensor([0, 2, 3, 6]), indices: tensor([0, 2, 2, 0, 1, 2]), data: tensor([1., 2., 3., 4., 5., 6.]), dtype=ht.float32, device=cpu:0, split=1) Create a :class:`~heat.sparse.DCSC_matrix` from List >>> ht.sparse.sparse_csc_matrix([[0, 0, 1], [1, 0, 2], [0, 0, 3]]) (indptr: tensor([0, 1, 1, 4]), indices: tensor([1, 0, 1, 2]), data: tensor([1, 1, 2, 3]), dtype=ht.int64, device=cpu:0, split=None) .. function:: to_dense(sparse_matrix: heat.sparse.dcsx_matrix.__DCSX_matrix, order='C', out: heat.core.dndarray.DNDarray = None) -> heat.core.dndarray.DNDarray Convert :class:`~heat.sparse.DCSX_matrix` to a dense :class:`~heat.core.DNDarray`. Output follows the same distribution among processes as the input :param sparse_matrix: The sparse csr matrix which is to be converted to a dense array :type sparse_matrix: :class:`~heat.sparse.DCSR_matrix` :param order: Options: ``'C'`` or ``'F'``. Specifies the memory layout of the newly created `DNDarray`. Default is ``order='C'``, meaning the array will be stored in row-major order (C-like). If ``order=‘F’``, the array will be stored in column-major order (Fortran-like). :type order: str, optional :param out: Output buffer in which the values of the dense format is stored. If not specified, a new DNDarray is created. :type out: DNDarray :raises ValueError: If shape of output buffer does not match that of the input. :raises ValueError: If split axis of output buffer does not match that of the input. .. rubric:: Examples >>> indptr = torch.tensor([0, 2, 3, 6]) >>> indices = torch.tensor([0, 2, 2, 0, 1, 2]) >>> data = torch.tensor([1, 2, 3, 4, 5, 6], dtype=torch.float) >>> torch_sparse_csr = torch.sparse_csr_tensor(indptr, indices, data) >>> heat_sparse_csr = ht.sparse.sparse_csr_matrix(torch_sparse_csr, split=0) >>> heat_sparse_csr (indptr: tensor([0, 2, 3, 6]), indices: tensor([0, 2, 2, 0, 1, 2]), data: tensor([1., 2., 3., 4., 5., 6.]), dtype=ht.float32, device=cpu:0, split=0) >>> heat_sparse_csr.todense() DNDarray([[1., 0., 2.], [0., 0., 3.], [4., 5., 6.]], dtype=ht.float32, device=cpu:0, split=0) .. function:: to_sparse_csr(array: heat.core.dndarray.DNDarray) -> heat.sparse.dcsx_matrix.DCSR_matrix Convert the distributed array to a sparse DCSR_matrix representation. :param array: The distributed array to be converted to a sparse DCSR_matrix. :type array: DNDarray :returns: A sparse DCSR_matrix representation of the input DNDarray. :rtype: DCSR_matrix .. rubric:: Examples >>> dense_array = ht.array([[1, 0, 0], [0, 0, 2], [0, 3, 0]]) >>> dense_array.to_sparse_csr() (indptr: tensor([0, 1, 2, 3]), indices: tensor([0, 2, 1]), data: tensor([1, 2, 3]), dtype=ht.int64, device=cpu:0, split=None) .. function:: to_sparse_csc(array: heat.core.dndarray.DNDarray) -> heat.sparse.dcsx_matrix.DCSC_matrix Convert the distributed array to a sparse DCSC_matrix representation. :param array: The distributed array to be converted to a sparse DCSC_matrix. :type array: DNDarray :returns: A sparse DCSC_matrix representation of the input DNDarray. :rtype: DCSC_matrix .. rubric:: Examples >>> dense_array = ht.array([[1, 0, 0], [0, 0, 2], [0, 3, 0]]) >>> dense_array.to_sparse_csc() (indptr: tensor([0, 1, 2, 3]), indices: tensor([0, 2, 1]), data: tensor([1, 3, 2]), dtype=ht.int64, device=cpu:0, split=None)