python-graphblas 2023.12.0__py3-none-any.whl → 2025.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- graphblas/agg/__init__.py +2 -1
- graphblas/binary/numpy.py +1 -0
- graphblas/core/automethods.py +1 -5
- graphblas/core/base.py +1 -1
- graphblas/core/dtypes.py +16 -6
- graphblas/core/expr.py +4 -4
- graphblas/core/formatting.py +1 -1
- graphblas/core/infix.py +1 -2
- graphblas/core/matrix.py +51 -106
- graphblas/core/operator/base.py +3 -3
- graphblas/core/operator/binary.py +2 -0
- graphblas/core/operator/indexunary.py +2 -0
- graphblas/core/operator/monoid.py +2 -0
- graphblas/core/operator/select.py +2 -0
- graphblas/core/operator/semiring.py +2 -0
- graphblas/core/operator/unary.py +2 -0
- graphblas/core/operator/utils.py +1 -0
- graphblas/core/scalar.py +12 -1
- graphblas/core/ss/__init__.py +3 -1
- graphblas/core/ss/binary.py +1 -0
- graphblas/core/ss/config.py +1 -1
- graphblas/core/ss/descriptor.py +1 -0
- graphblas/core/ss/indexunary.py +1 -0
- graphblas/core/ss/matrix.py +90 -64
- graphblas/core/ss/select.py +1 -0
- graphblas/core/ss/unary.py +1 -0
- graphblas/core/ss/vector.py +61 -30
- graphblas/core/utils.py +18 -6
- graphblas/core/vector.py +31 -72
- graphblas/exceptions.py +11 -3
- graphblas/io/__init__.py +0 -1
- graphblas/io/_awkward.py +1 -0
- graphblas/io/_matrixmarket.py +2 -0
- graphblas/io/_networkx.py +6 -2
- graphblas/io/_scipy.py +1 -0
- graphblas/io/_sparse.py +1 -0
- graphblas/monoid/numpy.py +1 -0
- graphblas/select/__init__.py +4 -11
- graphblas/semiring/numpy.py +1 -0
- graphblas/ss/_core.py +2 -4
- graphblas/tests/conftest.py +18 -6
- graphblas/tests/test_descriptor.py +1 -2
- graphblas/tests/test_dtype.py +9 -1
- graphblas/tests/test_infix.py +1 -1
- graphblas/tests/test_io.py +1 -12
- graphblas/tests/test_matrix.py +13 -21
- graphblas/tests/test_numpyops.py +10 -0
- graphblas/tests/test_op.py +0 -2
- graphblas/tests/test_scalar.py +5 -1
- graphblas/tests/test_ssjit.py +49 -3
- graphblas/tests/test_vector.py +16 -14
- graphblas/unary/numpy.py +1 -0
- graphblas/viz.py +2 -0
- {python_graphblas-2023.12.0.dist-info → python_graphblas-2025.2.0.dist-info}/METADATA +82 -43
- python_graphblas-2025.2.0.dist-info/RECORD +107 -0
- {python_graphblas-2023.12.0.dist-info → python_graphblas-2025.2.0.dist-info}/WHEEL +1 -1
- graphblas/core/agg.py +0 -17
- graphblas/io/_numpy.py +0 -104
- python_graphblas-2023.12.0.dist-info/RECORD +0 -109
- {python_graphblas-2023.12.0.dist-info → python_graphblas-2025.2.0.dist-info}/LICENSE +0 -0
- {python_graphblas-2023.12.0.dist-info → python_graphblas-2025.2.0.dist-info}/top_level.txt +0 -0
graphblas/agg/__init__.py
CHANGED
|
@@ -73,7 +73,8 @@ Custom recipes (specific to SuiteSparse:GraphBLAS):
|
|
|
73
73
|
# - bxnor monoid: even bits
|
|
74
74
|
# - bnor monoid: odd bits
|
|
75
75
|
"""
|
|
76
|
-
|
|
76
|
+
|
|
77
|
+
# All items are dynamically added by classes in core/operator/agg.py
|
|
77
78
|
# This module acts as a container of Aggregator instances
|
|
78
79
|
_deprecated = {}
|
|
79
80
|
|
graphblas/binary/numpy.py
CHANGED
graphblas/core/automethods.py
CHANGED
|
@@ -7,6 +7,7 @@ To automatically create the functions, run:
|
|
|
7
7
|
$ python -m graphblas.core.automethods
|
|
8
8
|
|
|
9
9
|
"""
|
|
10
|
+
|
|
10
11
|
from .. import config
|
|
11
12
|
|
|
12
13
|
|
|
@@ -281,10 +282,6 @@ def to_edgelist(self):
|
|
|
281
282
|
return self._get_value("to_edgelist")
|
|
282
283
|
|
|
283
284
|
|
|
284
|
-
def to_values(self):
|
|
285
|
-
return self._get_value("to_values")
|
|
286
|
-
|
|
287
|
-
|
|
288
285
|
def value(self):
|
|
289
286
|
return self._get_value("value")
|
|
290
287
|
|
|
@@ -398,7 +395,6 @@ def _main():
|
|
|
398
395
|
"ss",
|
|
399
396
|
"to_coo",
|
|
400
397
|
"to_dense",
|
|
401
|
-
"to_values",
|
|
402
398
|
}
|
|
403
399
|
vector = {
|
|
404
400
|
"_as_matrix",
|
graphblas/core/base.py
CHANGED
|
@@ -513,7 +513,7 @@ class BaseType:
|
|
|
513
513
|
_expect_op = _expect_op
|
|
514
514
|
|
|
515
515
|
# Don't let non-scalars be coerced to numpy arrays
|
|
516
|
-
def __array__(self, dtype=None):
|
|
516
|
+
def __array__(self, dtype=None, *, copy=None):
|
|
517
517
|
raise TypeError(
|
|
518
518
|
f"{type(self).__name__} can't be directly converted to a numpy array; "
|
|
519
519
|
f"perhaps use `{self.name}.to_coo()` method instead."
|
graphblas/core/dtypes.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import warnings
|
|
2
|
+
from ast import literal_eval
|
|
2
3
|
|
|
3
4
|
import numpy as np
|
|
4
5
|
from numpy import promote_types, result_type
|
|
@@ -97,7 +98,7 @@ def register_anonymous(dtype, name=None):
|
|
|
97
98
|
# Allow dtypes such as `"INT64[3, 4]"` for convenience
|
|
98
99
|
base_dtype, shape = dtype.split("[", 1)
|
|
99
100
|
base_dtype = lookup_dtype(base_dtype)
|
|
100
|
-
shape =
|
|
101
|
+
shape = literal_eval(f"[{shape}")
|
|
101
102
|
dtype = np.dtype((base_dtype.np_type, shape))
|
|
102
103
|
else:
|
|
103
104
|
raise
|
|
@@ -115,7 +116,17 @@ def register_anonymous(dtype, name=None):
|
|
|
115
116
|
from ..exceptions import check_status_carg
|
|
116
117
|
|
|
117
118
|
gb_obj = ffi.new("GrB_Type*")
|
|
118
|
-
|
|
119
|
+
|
|
120
|
+
if hasattr(lib, "GrB_Type_set_String"):
|
|
121
|
+
# We name this so that we can serialize and deserialize UDTs
|
|
122
|
+
# We don't yet have C definitions
|
|
123
|
+
np_repr = _dtype_to_string(dtype)
|
|
124
|
+
status = lib.GrB_Type_new(gb_obj, dtype.itemsize)
|
|
125
|
+
check_status_carg(status, "Type", gb_obj[0])
|
|
126
|
+
val_obj = ffi.new("char[]", np_repr.encode())
|
|
127
|
+
status = lib.GrB_Type_set_String(gb_obj[0], val_obj, lib.GrB_NAME)
|
|
128
|
+
elif backend == "suitesparse":
|
|
129
|
+
# For SuiteSparse < 9
|
|
119
130
|
# We name this so that we can serialize and deserialize UDTs
|
|
120
131
|
# We don't yet have C definitions
|
|
121
132
|
np_repr = _dtype_to_string(dtype).encode()
|
|
@@ -375,8 +386,7 @@ def lookup_dtype(key, value=None):
|
|
|
375
386
|
|
|
376
387
|
|
|
377
388
|
def unify(type1, type2, *, is_left_scalar=False, is_right_scalar=False):
|
|
378
|
-
"""
|
|
379
|
-
Returns a type that can hold both type1 and type2.
|
|
389
|
+
"""Returns a type that can hold both type1 and type2.
|
|
380
390
|
|
|
381
391
|
For example:
|
|
382
392
|
unify(INT32, INT64) -> INT64
|
|
@@ -430,7 +440,7 @@ def _dtype_to_string(dtype):
|
|
|
430
440
|
np_type = dtype.np_type
|
|
431
441
|
s = str(np_type)
|
|
432
442
|
try:
|
|
433
|
-
if np.dtype(
|
|
443
|
+
if np.dtype(literal_eval(s)) == np_type: # pragma: no branch (safety)
|
|
434
444
|
return s
|
|
435
445
|
except Exception:
|
|
436
446
|
pass
|
|
@@ -449,5 +459,5 @@ def _string_to_dtype(s):
|
|
|
449
459
|
return lookup_dtype(s)
|
|
450
460
|
except Exception:
|
|
451
461
|
pass
|
|
452
|
-
np_type = np.dtype(
|
|
462
|
+
np_type = np.dtype(literal_eval(s))
|
|
453
463
|
return lookup_dtype(np_type)
|
graphblas/core/expr.py
CHANGED
|
@@ -147,13 +147,13 @@ class IndexerResolver:
|
|
|
147
147
|
return self.indices[0]._py_index()
|
|
148
148
|
|
|
149
149
|
def parse_indices(self, indices, shape):
|
|
150
|
-
"""
|
|
151
|
-
Returns
|
|
150
|
+
"""Returns
|
|
152
151
|
-------
|
|
153
152
|
[(rows, rowsize), (cols, colsize)] for Matrix
|
|
154
153
|
[(idx, idx_size)] for Vector
|
|
155
154
|
|
|
156
155
|
Within each tuple, if the index is of type int, the size will be None
|
|
156
|
+
|
|
157
157
|
"""
|
|
158
158
|
if len(shape) == 1:
|
|
159
159
|
if type(indices) is tuple:
|
|
@@ -312,8 +312,8 @@ class AmbiguousAssignOrExtract:
|
|
|
312
312
|
Updater(self.parent, opts=opts)._setitem(self.resolved_indexes, expr, is_submask=False)
|
|
313
313
|
|
|
314
314
|
def new(self, dtype=None, *, mask=None, input_mask=None, name=None, **opts):
|
|
315
|
-
"""
|
|
316
|
-
|
|
315
|
+
"""Force extraction of the indexes into a new object.
|
|
316
|
+
|
|
317
317
|
dtype and mask are the only controllable parameters.
|
|
318
318
|
"""
|
|
319
319
|
if input_mask is not None:
|
graphblas/core/formatting.py
CHANGED
|
@@ -630,7 +630,7 @@ def create_header(type_name, keys, vals, *, lower_border=False, name="", quote=T
|
|
|
630
630
|
name = f'"{name}"'
|
|
631
631
|
key_text = []
|
|
632
632
|
val_text = []
|
|
633
|
-
for key, val in zip(keys, vals):
|
|
633
|
+
for key, val in zip(keys, vals, strict=True):
|
|
634
634
|
width = max(len(key), len(val)) + 2
|
|
635
635
|
key_text.append(key.rjust(width))
|
|
636
636
|
val_text.append(val.rjust(width))
|
graphblas/core/infix.py
CHANGED
|
@@ -236,7 +236,6 @@ class VectorInfixExpr(InfixExprBase):
|
|
|
236
236
|
to_coo = wrapdoc(Vector.to_coo)(property(automethods.to_coo))
|
|
237
237
|
to_dense = wrapdoc(Vector.to_dense)(property(automethods.to_dense))
|
|
238
238
|
to_dict = wrapdoc(Vector.to_dict)(property(automethods.to_dict))
|
|
239
|
-
to_values = wrapdoc(Vector.to_values)(property(automethods.to_values))
|
|
240
239
|
vxm = wrapdoc(Vector.vxm)(property(automethods.vxm))
|
|
241
240
|
wait = wrapdoc(Vector.wait)(property(automethods.wait))
|
|
242
241
|
# These raise exceptions
|
|
@@ -317,6 +316,7 @@ class MatrixInfixExpr(InfixExprBase):
|
|
|
317
316
|
ndim = 2
|
|
318
317
|
output_type = MatrixExpression
|
|
319
318
|
_is_transposed = False
|
|
319
|
+
__networkx_backend__ = "graphblas"
|
|
320
320
|
__networkx_plugin__ = "graphblas"
|
|
321
321
|
|
|
322
322
|
def __init__(self, left, right):
|
|
@@ -396,7 +396,6 @@ class MatrixInfixExpr(InfixExprBase):
|
|
|
396
396
|
to_dense = wrapdoc(Matrix.to_dense)(property(automethods.to_dense))
|
|
397
397
|
to_dicts = wrapdoc(Matrix.to_dicts)(property(automethods.to_dicts))
|
|
398
398
|
to_edgelist = wrapdoc(Matrix.to_edgelist)(property(automethods.to_edgelist))
|
|
399
|
-
to_values = wrapdoc(Matrix.to_values)(property(automethods.to_values))
|
|
400
399
|
wait = wrapdoc(Matrix.wait)(property(automethods.wait))
|
|
401
400
|
# These raise exceptions
|
|
402
401
|
__array__ = Matrix.__array__
|