Skip to content

Commit

Permalink
Expose GxB_pack_HyperHash and GxB_unpack_HyperHash (python-graphb…
Browse files Browse the repository at this point in the history
…las#305)

* Expose `GxB_pack_HyperHash` and `GxB_unpack_HyperHash`

* add test

* oops
  • Loading branch information
eriknw authored Oct 27, 2022
1 parent 14d24e3 commit 7661442
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 7 deletions.
6 changes: 3 additions & 3 deletions graphblas/core/matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from .. import backend, binary, monoid, select, semiring
from ..dtypes import _INDEX, FP64, lookup_dtype, unify
from ..exceptions import DimensionMismatch, NoValue, check_status
from . import NULL, automethods, ffi, lib, utils
from . import automethods, ffi, lib, utils
from .base import BaseExpression, BaseType, _check_mask, call
from .expr import AmbiguousAssignOrExtract, IndexerResolver, Updater
from .mask import Mask, StructuralMask, ValueMask
Expand Down Expand Up @@ -2248,7 +2248,7 @@ def to_pygraphblas(self): # pragma: no cover
import pygraphblas as pg

matrix = pg.Matrix(self.gb_obj, pg.types._gb_type_to_type(self.dtype.gb_obj))
self.gb_obj = NULL
self.gb_obj = ffi_new("GrB_Matrix*")
return matrix

@classmethod
Expand All @@ -2274,7 +2274,7 @@ def from_pygraphblas(cls, matrix): # pragma: no cover
rv = cls(matrix._matrix, dtype)
rv._nrows = matrix.nrows
rv._ncols = matrix.ncols
matrix._matrix = NULL
matrix._matrix = ffi_new("GrB_Matrix*")
return rv


Expand Down
33 changes: 33 additions & 0 deletions graphblas/core/ss/matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -3545,6 +3545,39 @@ def _import_any(
else:
raise ValueError(f"Invalid format: {format}")

def unpack_hyperhash(self, *, compute=False, name=None):
"""Unpacks the hyper_hash of a hypersparse matrix if possible.
Will return None if the matrix is not hypersparse or if the hash is not computed.
Use ``compute=True`` to compute the hyper_hash if the input is hypersparse.
Use ``pack_hyperhash`` to move a hyper_hash matrix that was previously unpacked
back into a matrix.
This may be used before unpacking a HyperCSR or HyperCSC matrix to preserve the
full underlying data structure that can be packed back into an empty matrix.
"""
from ..matrix import Matrix

if compute and self.format.startswith("hypercs"):
self._parent.wait()
rv = Matrix._from_obj(ffi_new("GrB_Matrix*"), INT64, 0, 0, name=name)
call("GxB_unpack_HyperHash", [self._parent, _Pointer(rv), None])
if rv.gb_obj[0] == NULL:
return
rv._nrows = rv.nrows
rv._ncols = rv.ncols
return rv

def pack_hyperhash(self, Y):
"""Pack a hyper_hash matrix Y into the current hypersparse matrix.
The hyper_hash matrix Y should be from ``unpack_hyperhash`` and unmodified.
This uses move semantics. Y will become an invalid matrix.
"""
call("GxB_pack_HyperHash", [self._parent, _Pointer(Y), None])

@wrapdoc(head)
def head(self, n=10, dtype=None, *, sort=False):
return head(self._parent, n, dtype, sort=sort)
Expand Down
6 changes: 3 additions & 3 deletions graphblas/core/vector.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from .. import backend, binary, monoid, select, semiring
from ..dtypes import _INDEX, FP64, INT64, lookup_dtype, unify
from ..exceptions import DimensionMismatch, NoValue, check_status
from . import NULL, automethods, ffi, lib, utils
from . import automethods, ffi, lib, utils
from .base import BaseExpression, BaseType, _check_mask, call
from .expr import AmbiguousAssignOrExtract, IndexerResolver, Updater
from .mask import Mask, StructuralMask, ValueMask
Expand Down Expand Up @@ -1582,7 +1582,7 @@ def to_pygraphblas(self): # pragma: no cover
import pygraphblas as pg

vector = pg.Vector(self.gb_obj, pg.types._gb_type_to_type(self.dtype.gb_obj))
self.gb_obj = NULL
self.gb_obj = ffi_new("GrB_Vector*")
return vector

@classmethod
Expand All @@ -1607,7 +1607,7 @@ def from_pygraphblas(cls, vector): # pragma: no cover
dtype = lookup_dtype(vector.gb_type)
rv = cls(vector._vector, dtype)
rv._size = vector.size
vector._vector = NULL
vector._vector = ffi_new("GrB_Vector*")
return rv


Expand Down
17 changes: 17 additions & 0 deletions graphblas/tests/test_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -3746,3 +3746,20 @@ def test_to_csr_from_csc(A):
assert expected.isequal(B, check_dtype=True)
assert Matrix.from_csr(*B.to_csr(), ncols=2).isequal(B)
assert Matrix.from_csr(*B.to_csr()).isequal(B[:, 0:0].new())


def test_ss_pack_hyperhash(A):
A.ss.config["sparsity_control"] = "sparse"
assert A.ss.unpack_hyperhash() is None

C = Matrix(int, 20000, 200000)
C.ss.config["sparsity_control"] = "hypersparse"
C[100, 2000] = 2
C[10, 20] = 1
Y = C.ss.unpack_hyperhash()
Y = C.ss.unpack_hyperhash(compute=True)
assert C.ss.unpack_hyperhash() is None
assert Y.nrows == C.nrows
C.ss.pack_hyperhash(Y)
assert Y.gb_obj[0] == graphblas.core.NULL
assert C.ss.unpack_hyperhash() is not None
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
url="https://github.com/python-graphblas/python-graphblas",
packages=find_packages(),
python_requires=">=3.8",
install_requires=["suitesparse-graphblas >=7.2.0.0, <7.4", "numba", "donfig", "pyyaml"],
install_requires=["suitesparse-graphblas >=7.3.0.0, <7.4", "numba", "donfig", "pyyaml"],
extras_require=extras_require,
include_package_data=True,
license="Apache License 2.0",
Expand Down

0 comments on commit 7661442

Please sign in to comment.