From 0213c4b957ddb89ed06a8a9d605093fc1b9b0c47 Mon Sep 17 00:00:00 2001 From: Erik Welch Date: Tue, 21 Feb 2023 14:59:02 +0100 Subject: [PATCH 1/3] Remove expired deprecation of using scipy matrix --- graphblas/io.py | 40 -------------------------------------- graphblas/tests/test_io.py | 5 ----- 2 files changed, 45 deletions(-) diff --git a/graphblas/io.py b/graphblas/io.py index 32a5f3f0d..125e69d25 100644 --- a/graphblas/io.py +++ b/graphblas/io.py @@ -111,20 +111,6 @@ def from_numpy(m): # pragma: no cover (deprecated) return from_scipy_sparse(A) -def from_scipy_sparse_matrix(m, *, dup_op=None, name=None): - """Matrix dtype is inferred from m.dtype.""" - _warn( - "`from_scipy_sparse_matrix` is deprecated; please use `from_scipy_sparse` instead.", - DeprecationWarning, - ) - A = m.tocoo() - nrows, ncols = A.shape - dtype = _lookup_dtype(m.dtype) - return _Matrix.from_coo( - A.row, A.col, A.data, nrows=nrows, ncols=ncols, dtype=dtype, dup_op=dup_op, name=name - ) - - def from_scipy_sparse(A, *, dup_op=None, name=None): """Create a Matrix from a scipy.sparse array or matrix. @@ -361,32 +347,6 @@ def to_numpy(m): # pragma: no cover (deprecated) return sparse.toarray() -def to_scipy_sparse_matrix(m, format="csr"): # pragma: no cover (deprecated) - """format: str in {'bsr', 'csr', 'csc', 'coo', 'lil', 'dia', 'dok'}.""" - import scipy.sparse as ss - - _warn( - "`to_scipy_sparse_matrix` is deprecated; please use `to_scipy_sparse` instead.", - DeprecationWarning, - ) - format = format.lower() - if _output_type(m) is _Vector: - indices, data = m.to_coo() - if format == "csc": - return ss.csc_matrix((data, indices, [0, len(data)]), shape=(m._size, 1)) - rv = ss.csr_matrix((data, indices, [0, len(data)]), shape=(1, m._size)) - if format == "csr": - return rv - else: - rows, cols, data = m.to_coo() - rv = ss.coo_matrix((data, (rows, cols)), shape=m.shape) - if format == "coo": - return rv - if format not in {"bsr", "csr", "csc", "coo", "lil", "dia", "dok"}: - raise _GraphblasException(f"Invalid format: {format}") - return rv.asformat(format) - - def to_scipy_sparse(A, format="csr"): """Create a scipy.sparse array from a GraphBLAS Matrix or Vector. diff --git a/graphblas/tests/test_io.py b/graphblas/tests/test_io.py index 0f78430c1..f5bd4736f 100644 --- a/graphblas/tests/test_io.py +++ b/graphblas/tests/test_io.py @@ -43,8 +43,6 @@ def test_deprecated(): with pytest.warns(DeprecationWarning): a2 = gb.io.to_numpy(v) np.testing.assert_array_equal(a, a2) - with pytest.warns(DeprecationWarning): - gb.io.to_scipy_sparse_matrix(v, "coo") @pytest.mark.skipif("not ss") @@ -298,9 +296,6 @@ def test_from_scipy_sparse_duplicates(): a2 = gb.io.from_scipy_sparse(a, dup_op=gb.binary.plus) expected = gb.Matrix.from_coo([0, 1, 2], [2, 1, 0], [1, 2, 7]) assert a2.isequal(expected) - with pytest.warns(DeprecationWarning): - a3 = gb.io.from_scipy_sparse_matrix(a, dup_op=gb.binary.plus) - assert a3.isequal(expected) @pytest.mark.skipif("not ss") From 6e4bd6ebe5ad287be54b53a0b9e760d5f6109827 Mon Sep 17 00:00:00 2001 From: Erik Welch Date: Tue, 21 Feb 2023 17:14:17 +0100 Subject: [PATCH 2/3] Maybe fix complex tests on Windows --- graphblas/tests/test_numpyops.py | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/graphblas/tests/test_numpyops.py b/graphblas/tests/test_numpyops.py index bc2e018d3..13e004a2c 100644 --- a/graphblas/tests/test_numpyops.py +++ b/graphblas/tests/test_numpyops.py @@ -1,6 +1,7 @@ # These tests are very slow, since they force creation of all # numpy unary, binary, monoid, and semiring objects. import itertools +import sys import numpy as np import pytest @@ -10,11 +11,14 @@ import graphblas.monoid.numpy as npmonoid import graphblas.semiring.numpy as npsemiring import graphblas.unary.numpy as npunary -from graphblas import Vector +from graphblas import Vector, backend from graphblas.dtypes import _supports_complex from .conftest import compute +is_win = sys.platform.startswith("win") +suitesparse = backend == "suitesparse" + def test_numpyops_dir(): assert "exp2" in dir(npunary) @@ -61,6 +65,10 @@ def test_npunary(): "INT64": {"reciprocal"}, "FC64": {"ceil", "floor", "trunc"}, } + if suitesparse and is_win: + # asin is known to be wrong in SuiteSparse:GraphBLAS due to limitation of MSVC with complex + blocklist["FC64"].add("asin") + blocklist["FC32"] = {"asin"} isclose = gb.binary.isclose(1e-6, 0) for gb_input, np_input in data: for unary_name in sorted(npunary._unary_names): @@ -148,18 +156,22 @@ def test_npbinary(): gb_left.dtype.name, () ): continue - if not _supports_complex and binary_name == "ldexp": + if is_win and binary_name == "ldexp": # On Windows, the second argument must be int32 or less (I'm not sure why) np_right = np_right.astype(np.int32) with np.errstate(divide="ignore", over="ignore", under="ignore", invalid="ignore"): gb_result = gb_left.ewise_mult(gb_right, op).new() - if gb_left.dtype == "BOOL" and gb_result.dtype == "FP32": - np_result = getattr(np, binary_name)(np_left, np_right, dtype="float32") - compare_op = isclose - else: - np_result = getattr(np, binary_name)(np_left, np_right) - compare_op = npbinary.equal - + try: + if gb_left.dtype == "BOOL" and gb_result.dtype == "FP32": + np_result = getattr(np, binary_name)(np_left, np_right, dtype="float32") + compare_op = isclose + else: + np_result = getattr(np, binary_name)(np_left, np_right) + compare_op = npbinary.equal + except Exception: # pragma: no cover (debug) + print(f"Error computing numpy result for {binary_name}") + print(f"dtypes: ({gb_left.dtype}, {gb_right.dtype}) -> {gb_result.dtype}") + raise np_result = Vector.from_coo(np.arange(np_left.size), np_result, dtype=gb_result.dtype) assert gb_result.nvals == np_result.size From 9c9df0610625886eed4e2217e03d19cab9f8adda Mon Sep 17 00:00:00 2001 From: Erik Welch Date: Tue, 21 Feb 2023 17:22:47 +0100 Subject: [PATCH 3/3] Also asinh --- graphblas/tests/test_numpyops.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/graphblas/tests/test_numpyops.py b/graphblas/tests/test_numpyops.py index 13e004a2c..fc24762bc 100644 --- a/graphblas/tests/test_numpyops.py +++ b/graphblas/tests/test_numpyops.py @@ -66,9 +66,10 @@ def test_npunary(): "FC64": {"ceil", "floor", "trunc"}, } if suitesparse and is_win: - # asin is known to be wrong in SuiteSparse:GraphBLAS due to limitation of MSVC with complex - blocklist["FC64"].add("asin") - blocklist["FC32"] = {"asin"} + # asin and asinh are known to be wrong in SuiteSparse:GraphBLAS + # due to limitation of MSVC with complex + blocklist["FC64"].update({"asin", "asinh"}) + blocklist["FC32"] = {"asin", "asinh"} isclose = gb.binary.isclose(1e-6, 0) for gb_input, np_input in data: for unary_name in sorted(npunary._unary_names):