Skip to content

Commit

Permalink
Complex monoid UDFs are finally working!
Browse files Browse the repository at this point in the history
Update to latest python-suitesparse-graphblas to avoid segfaults.
Also, let's see if using `pytest-randomly` works now.
  • Loading branch information
eriknw committed Apr 14, 2022
1 parent 784f0fd commit 3bd9b1b
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 22 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/test_and_build.yml
Expand Up @@ -54,7 +54,7 @@ jobs:
activate-environment: graphblas
- name: Update env
run: |
conda install -c conda-forge pytest-runner coverage 'black>=20.8b1' flake8 coveralls
conda install -c conda-forge pytest coverage 'black>=20.8b1' flake8 coveralls pytest-randomly
- name: Style Checks
run: |
flake8
Expand Down Expand Up @@ -98,14 +98,14 @@ jobs:
- name: Unit tests
# if: (! contains(matrix.cfg.testopts, 'pygraphblas')) || (matrix.cfg.pyver != 3.9)
run: |
coverage run --branch -m pytest ${{ matrix.cfg.testopts }}
coverage run --branch -m pytest ${{ matrix.cfg.testopts }} -v
# Run tests again with Scalars being C scalars by default
find graphblas -type f -name "*.py" -print0 | xargs -0 sed -i -s \
-e '/# pragma: is_grbscalar/! s/is_cscalar=False/is_cscalar=True/g' \
-e '/# pragma: is_grbscalar/! s/is_cscalar = False/is_cscalar = True/g' \
-e '/# pragma: to_grb/ s/is_cscalar=True/is_cscalar=False/g' \
-e '/# pragma: to_grb/ s/is_cscalar = True/is_cscalar = False/g'
coverage run -a --branch -m pytest ${{ matrix.cfg.testopts }}
coverage run -a --branch -m pytest ${{ matrix.cfg.testopts }} -v
git checkout . # Undo changes to scalar default
# Test (and cover) automatic initialization
Expand Down
3 changes: 1 addition & 2 deletions graphblas/operator.py
Expand Up @@ -1772,8 +1772,7 @@ def _build(cls, name, binaryop, identity, *, anonymous=False):
ret_type = binaryop[type_].return_type
# If there is a domain mismatch, then DomainMismatch will be raised
# below if identities were explicitly given.
# Skip complex dtypes for now, because they segfault!
if type_ != ret_type and not explicit_identities or "FC" in type_.name:
if type_ != ret_type and not explicit_identities:
continue
new_monoid = ffi_new("GrB_Monoid*")
func = libget(f"GrB_Monoid_new_{type_.name}")
Expand Down
26 changes: 13 additions & 13 deletions graphblas/tests/test_numpyops.py
Expand Up @@ -200,19 +200,19 @@ def test_npmonoid():
],
]
# Complex monoids not working yet (they segfault upon creation in graphblas.operators)
# if _supports_complex: # pragma: no branch
# data.append(
# [
# [
# Vector.from_values(index, values1, dtype="FC64"),
# Vector.from_values(index, values2, dtype="FC64"),
# ],
# [
# np.array(values1, dtype=np.complex128),
# np.array(values2, dtype=np.complex128),
# ],
# ]
# )
if _supports_complex: # pragma: no branch
data.append(
[
[
Vector.from_values(index, values1, dtype="FC64"),
Vector.from_values(index, values2, dtype="FC64"),
],
[
np.array(values1, dtype=np.complex128),
np.array(values2, dtype=np.complex128),
],
]
)
blocklist = {}
reduction_blocklist = {
"BOOL": {"add"},
Expand Down
5 changes: 4 additions & 1 deletion graphblas/tests/test_op.py
Expand Up @@ -527,7 +527,7 @@ def plus_plus_one(x, y):
BinaryOp.register_new("plus_plus_one", plus_plus_one)
Monoid.register_new("plus_plus_one", binary.plus_plus_one, -1)
assert hasattr(monoid, "plus_plus_one")
assert set(monoid.plus_plus_one.types) == {
comp_set = {
INT8,
INT16,
INT32,
Expand All @@ -539,6 +539,9 @@ def plus_plus_one(x, y):
FP32,
FP64,
}
if dtypes._supports_complex:
comp_set.update({FC32, FC64})
assert set(monoid.plus_plus_one.types) == comp_set
v1 = Vector.from_values([0, 1, 3], [1, 2, -4], dtype=dtypes.INT32)
v2 = Vector.from_values([0, 2, 3], [2, 3, 7], dtype=dtypes.INT32)
w = v1.ewise_add(v2, monoid.plus_plus_one).new()
Expand Down
3 changes: 2 additions & 1 deletion graphblas/tests/test_scalar.py
@@ -1,5 +1,6 @@
import inspect
import pickle
import random
import sys
import weakref

Expand Down Expand Up @@ -266,7 +267,7 @@ def test_neg():
for dtype in sorted(
(dtype for dtype in vars(dtypes).values() if isinstance(dtype, dtypes.DataType)),
key=lambda x: x.name,
reverse=True, # XXX: segfault when False!!!
reverse=random.choice([False, True]), # used to segfault when False
):
s = Scalar.from_value(1, dtype=dtype)
empty = Scalar(dtype)
Expand Down
2 changes: 1 addition & 1 deletion recipe/meta.yaml
Expand Up @@ -21,7 +21,7 @@ requirements:
run:
- python
- numba
- python-suitesparse-graphblas >=7.0.2,<7.1
- python-suitesparse-graphblas >=7.0.3.1,<7.1
- pytest-runner

about:
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -25,7 +25,7 @@
url="https://github.com/metagraph-dev/python-graphblas",
packages=find_packages(),
python_requires=">=3.8",
install_requires=["suitesparse-graphblas >=7.0.2, <7.1", "numba", "donfig", "pyyaml"],
install_requires=["suitesparse-graphblas >=7.0.3.1, <7.1", "numba", "donfig", "pyyaml"],
extras_require=extras_require,
include_package_data=True,
license="Apache License 2.0",
Expand Down

0 comments on commit 3bd9b1b

Please sign in to comment.