python-graphblas 2023.3.0__tar.gz → 2023.7.0__tar.gz
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.
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/LICENSE +1 -1
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/MANIFEST.in +3 -0
- {python-graphblas-2023.3.0/python_graphblas.egg-info → python-graphblas-2023.7.0}/PKG-INFO +48 -11
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/README.md +36 -8
- python-graphblas-2023.7.0/conftest.py +42 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/__init__.py +15 -1
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/agg/__init__.py +4 -4
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/binary/__init__.py +16 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/binary/numpy.py +14 -2
- python-graphblas-2023.7.0/graphblas/binary/ss.py +6 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/__init__.py +9 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/agg.py +3 -3
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/automethods.py +1 -1
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/base.py +3 -3
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/descriptor.py +1 -0
- {python-graphblas-2023.3.0/graphblas → python-graphblas-2023.7.0/graphblas/core}/dtypes.py +162 -86
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/expr.py +1 -1
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/formatting.py +1 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/mask.py +5 -5
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/matrix.py +32 -28
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/agg.py +24 -3
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/base.py +78 -93
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/binary.py +150 -36
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/indexunary.py +101 -25
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/monoid.py +38 -11
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/select.py +109 -7
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/semiring.py +41 -21
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/unary.py +77 -14
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/recorder.py +3 -3
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/scalar.py +18 -3
- python-graphblas-2023.7.0/graphblas/core/ss/__init__.py +3 -0
- python-graphblas-2023.7.0/graphblas/core/ss/binary.py +72 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/ss/config.py +46 -11
- python-graphblas-2023.7.0/graphblas/core/ss/context.py +146 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/ss/descriptor.py +21 -9
- python-graphblas-2023.7.0/graphblas/core/ss/dtypes.py +88 -0
- python-graphblas-2023.7.0/graphblas/core/ss/indexunary.py +77 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/ss/matrix.py +116 -105
- python-graphblas-2023.7.0/graphblas/core/ss/select.py +45 -0
- python-graphblas-2023.7.0/graphblas/core/ss/unary.py +62 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/ss/vector.py +40 -40
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/utils.py +15 -12
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/vector.py +69 -22
- python-graphblas-2023.7.0/graphblas/dtypes/__init__.py +43 -0
- python-graphblas-2023.7.0/graphblas/dtypes/ss.py +1 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/indexunary/__init__.py +13 -1
- python-graphblas-2023.7.0/graphblas/indexunary/ss.py +6 -0
- python-graphblas-2023.7.0/graphblas/io/__init__.py +7 -0
- python-graphblas-2023.7.0/graphblas/io/_awkward.py +187 -0
- python-graphblas-2023.7.0/graphblas/io/_matrixmarket.py +140 -0
- python-graphblas-2023.7.0/graphblas/io/_networkx.py +59 -0
- python-graphblas-2023.7.0/graphblas/io/_numpy.py +104 -0
- python-graphblas-2023.7.0/graphblas/io/_scipy.py +118 -0
- python-graphblas-2023.7.0/graphblas/io/_sparse.py +99 -0
- python-graphblas-2023.7.0/graphblas/io/_viz.py +21 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/monoid/__init__.py +13 -1
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/monoid/numpy.py +12 -3
- {python-graphblas-2023.3.0/graphblas/binary → python-graphblas-2023.7.0/graphblas/monoid}/ss.py +2 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/op/__init__.py +9 -1
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/op/numpy.py +5 -1
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/op/ss.py +2 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/select/__init__.py +19 -7
- python-graphblas-2023.7.0/graphblas/select/ss.py +6 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/semiring/__init__.py +27 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/semiring/numpy.py +12 -1
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/semiring/ss.py +2 -0
- python-graphblas-2023.7.0/graphblas/ss/__init__.py +5 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/ss/_core.py +67 -13
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/conftest.py +43 -7
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_core.py +5 -2
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_dtype.py +23 -9
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_formatting.py +70 -3
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_infix.py +7 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_io.py +28 -8
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_matrix.py +100 -47
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_numpyops.py +44 -18
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_op.py +193 -82
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_operator_types.py +6 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_pickle.py +6 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_scalar.py +12 -10
- python-graphblas-2023.7.0/graphblas/tests/test_ssjit.py +269 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_vector.py +58 -16
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/unary/numpy.py +12 -1
- python-graphblas-2023.7.0/graphblas/unary/ss.py +6 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/viz.py +4 -5
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/pyproject.toml +80 -27
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0/python_graphblas.egg-info}/PKG-INFO +48 -11
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/python_graphblas.egg-info/SOURCES.txt +22 -2
- python-graphblas-2023.7.0/python_graphblas.egg-info/requires.txt +64 -0
- python-graphblas-2023.3.0/graphblas/io.py +0 -697
- python-graphblas-2023.3.0/graphblas/ss/__init__.py +0 -1
- python-graphblas-2023.3.0/graphblas/tests/__init__.py +0 -0
- python-graphblas-2023.3.0/graphblas/unary/ss.py +0 -3
- python-graphblas-2023.3.0/python_graphblas.egg-info/requires.txt +0 -37
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/agg/ss.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/infix.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/infixmethods.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/__init__.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/utils.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/slice.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/ss/prefix_scan.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/exceptions.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/graphblas.yaml +0 -0
- {python-graphblas-2023.3.0/graphblas/core/ss → python-graphblas-2023.7.0/graphblas/tests}/__init__.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/pickle1-vanilla.pkl +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/pickle1.pkl +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/pickle2-vanilla.pkl +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/pickle2.pkl +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/pickle3-vanilla.pkl +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/pickle3.pkl +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_auto_init.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_descriptor.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_external_init.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_mask.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_prefix_scan.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_recorder.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_resolving.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_ss_utils.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/unary/__init__.py +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/python_graphblas.egg-info/dependency_links.txt +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/python_graphblas.egg-info/top_level.txt +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/setup.cfg +0 -0
- {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/setup.py +0 -0
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
same "printed page" as the copyright notice for easier
|
|
187
187
|
identification within third-party archives.
|
|
188
188
|
|
|
189
|
-
Copyright 2020 Anaconda, Inc
|
|
189
|
+
Copyright 2020-2023 Anaconda, Inc. and contributors
|
|
190
190
|
|
|
191
191
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
192
|
you may not use this file except in compliance with the License.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-graphblas
|
|
3
|
-
Version: 2023.
|
|
3
|
+
Version: 2023.7.0
|
|
4
4
|
Summary: Python library for GraphBLAS: high-performance sparse linear algebra for scalable graph analytics
|
|
5
5
|
Author: Jim Kitchen, Python-graphblas contributors
|
|
6
6
|
Author-email: Erik Welch <erik.n.welch@gmail.com>
|
|
@@ -193,7 +193,7 @@ License: Apache License
|
|
|
193
193
|
same "printed page" as the copyright notice for easier
|
|
194
194
|
identification within third-party archives.
|
|
195
195
|
|
|
196
|
-
Copyright 2020 Anaconda, Inc
|
|
196
|
+
Copyright 2020-2023 Anaconda, Inc. and contributors
|
|
197
197
|
|
|
198
198
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
199
199
|
you may not use this file except in compliance with the License.
|
|
@@ -222,6 +222,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
222
222
|
Classifier: Programming Language :: Python :: 3.8
|
|
223
223
|
Classifier: Programming Language :: Python :: 3.9
|
|
224
224
|
Classifier: Programming Language :: Python :: 3.10
|
|
225
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
225
226
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
226
227
|
Classifier: Intended Audience :: Developers
|
|
227
228
|
Classifier: Intended Audience :: Other Audience
|
|
@@ -232,29 +233,42 @@ Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
|
232
233
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
233
234
|
Requires-Python: >=3.8
|
|
234
235
|
Description-Content-Type: text/markdown
|
|
236
|
+
Provides-Extra: suitesparse
|
|
237
|
+
Provides-Extra: networkx
|
|
238
|
+
Provides-Extra: numba
|
|
239
|
+
Provides-Extra: pandas
|
|
240
|
+
Provides-Extra: scipy
|
|
241
|
+
Provides-Extra: suitesparse-udf
|
|
235
242
|
Provides-Extra: repr
|
|
236
243
|
Provides-Extra: io
|
|
237
244
|
Provides-Extra: viz
|
|
245
|
+
Provides-Extra: datashade
|
|
238
246
|
Provides-Extra: test
|
|
239
|
-
Provides-Extra:
|
|
247
|
+
Provides-Extra: default
|
|
248
|
+
Provides-Extra: all
|
|
240
249
|
License-File: LICENSE
|
|
241
250
|
|
|
242
|
-
|
|
251
|
+

|
|
243
252
|
|
|
244
253
|
[](https://anaconda.org/conda-forge/python-graphblas)
|
|
245
254
|
[](https://pypi.python.org/pypi/python-graphblas/)
|
|
246
|
-

|
|
255
|
+
[](https://pypi.python.org/pypi/python-graphblas/)
|
|
247
256
|
[](https://github.com/python-graphblas/python-graphblas/blob/main/LICENSE)
|
|
257
|
+
<br>
|
|
248
258
|
[](https://github.com/python-graphblas/python-graphblas/actions)
|
|
249
259
|
[](https://python-graphblas.readthedocs.io/en/latest/)
|
|
250
260
|
[](https://coveralls.io/r/python-graphblas/python-graphblas)
|
|
261
|
+
<br>
|
|
251
262
|
[](https://doi.org/10.5281/zenodo.7328791)
|
|
252
263
|
[](https://mybinder.org/v2/gh/python-graphblas/python-graphblas/HEAD?filepath=notebooks%2FIntro%20to%20GraphBLAS%20%2B%20SSSP%20example.ipynb)
|
|
253
264
|
[](https://discord.com/invite/vur45CbwMz)
|
|
254
265
|
|
|
255
266
|
Python library for GraphBLAS: high-performance sparse linear algebra for scalable graph analytics.
|
|
267
|
+
For algorithms, see
|
|
268
|
+
[`graphblas-algorithms`](https://github.com/python-graphblas/graphblas-algorithms).
|
|
256
269
|
|
|
257
270
|
- **Documentation:** [https://python-graphblas.readthedocs.io/](https://python-graphblas.readthedocs.io/)
|
|
271
|
+
- **FAQ:** [https://python-graphblas.readthedocs.io/en/stable/getting_started/faq.html](https://python-graphblas.readthedocs.io/en/stable/getting_started/faq.html)
|
|
258
272
|
- **GraphBLAS C API:** [https://graphblas.org/docs/GraphBLAS_API_C_v2.0.0.pdf](https://graphblas.org/docs/GraphBLAS_API_C_v2.0.0.pdf)
|
|
259
273
|
- **SuiteSparse:GraphBLAS User Guide:** [https://github.com/DrTimothyAldenDavis/GraphBLAS/raw/stable/Doc/GraphBLAS_UserGuide.pdf](https://github.com/DrTimothyAldenDavis/GraphBLAS/raw/stable/Doc/GraphBLAS_UserGuide.pdf)
|
|
260
274
|
- **Source:** [https://github.com/python-graphblas/python-graphblas](https://github.com/python-graphblas/python-graphblas)
|
|
@@ -263,6 +277,11 @@ Python library for GraphBLAS: high-performance sparse linear algebra for scalabl
|
|
|
263
277
|
- **Weekly community call:** [https://github.com/python-graphblas/python-graphblas/issues/247](https://github.com/python-graphblas/python-graphblas/issues/247)
|
|
264
278
|
- **Chat via Discord:** [https://discord.com/invite/vur45CbwMz](https://discord.com/invite/vur45CbwMz) in the [#graphblas channel](https://discord.com/channels/786703927705862175/1024732940233605190)
|
|
265
279
|
|
|
280
|
+
<p float="left">
|
|
281
|
+
<img src="https://raw.githubusercontent.com/python-graphblas/python-graphblas/main/docs/_static/img/draw-example.png" width="231" align="top" alt="Directed graph", title="Directed graph"/>
|
|
282
|
+
<img src="https://raw.githubusercontent.com/python-graphblas/python-graphblas/main/docs/_static/img/repr-matrix.png" width="231" align="top" alt="Adjacency matrix" title="Adjacency matrix"/>
|
|
283
|
+
</p>
|
|
284
|
+
|
|
266
285
|
## Install
|
|
267
286
|
Install the latest version of Python-graphblas via conda:
|
|
268
287
|
```
|
|
@@ -270,9 +289,10 @@ $ conda install -c conda-forge python-graphblas
|
|
|
270
289
|
```
|
|
271
290
|
or pip:
|
|
272
291
|
```
|
|
273
|
-
$ pip install python-graphblas
|
|
292
|
+
$ pip install python-graphblas[default]
|
|
274
293
|
```
|
|
275
294
|
This will also install the [SuiteSparse:GraphBLAS](https://github.com/DrTimothyAldenDavis/GraphBLAS) compiled C library.
|
|
295
|
+
We currently support the [GraphBLAS C API 2.0 specification](https://graphblas.org/docs/GraphBLAS_API_C_v2.0.0.pdf).
|
|
276
296
|
|
|
277
297
|
### Optional Dependencies
|
|
278
298
|
|
|
@@ -280,14 +300,14 @@ The following are not required by python-graphblas, but may be needed for certai
|
|
|
280
300
|
|
|
281
301
|
- `pandas` – required for nicer `__repr__`;
|
|
282
302
|
- `matplotlib` – required for basic plotting of graphs;
|
|
283
|
-
- `scipy` – used in io module to read/write `scipy.sparse` format;
|
|
303
|
+
- `scipy` – used in `io` module to read/write `scipy.sparse` format;
|
|
284
304
|
- `networkx` – used in `io` module to interface with `networkx` graphs;
|
|
285
305
|
- `fast-matrix-market` - for faster read/write of Matrix Market files with `gb.io.mmread` and `gb.io.mmwrite`.
|
|
286
306
|
|
|
287
307
|
## Description
|
|
288
308
|
Currently works with [SuiteSparse:GraphBLAS](https://github.com/DrTimothyAldenDavis/GraphBLAS), but the goal is to make it work with all implementations of the GraphBLAS spec.
|
|
289
309
|
|
|
290
|
-
The approach taken with this library is to follow the C-API specification as closely as possible while making improvements
|
|
310
|
+
The approach taken with this library is to follow the C-API 2.0 specification as closely as possible while making improvements
|
|
291
311
|
allowed with the Python syntax. Because the spec always passes in the output object to be written to, we follow the same,
|
|
292
312
|
which is very different from the way Python normally operates. In fact, many who are familiar with other Python data
|
|
293
313
|
libraries (numpy, pandas, etc) will find it strange to not create new objects for every call.
|
|
@@ -406,8 +426,9 @@ use as well as the blocking/non-blocking mode. If the context is not initialized
|
|
|
406
426
|
be performed automatically.
|
|
407
427
|
```python
|
|
408
428
|
import graphblas as gb
|
|
429
|
+
|
|
409
430
|
# Context initialization must happen before any other imports
|
|
410
|
-
gb.init(
|
|
431
|
+
gb.init("suitesparse", blocking=True)
|
|
411
432
|
|
|
412
433
|
# Now we can import other items from graphblas
|
|
413
434
|
from graphblas import binary, semiring
|
|
@@ -425,7 +446,7 @@ def force_odd_func(x):
|
|
|
425
446
|
return x + 1
|
|
426
447
|
return x
|
|
427
448
|
|
|
428
|
-
unary.register_new(
|
|
449
|
+
unary.register_new("force_odd", force_odd_func)
|
|
429
450
|
|
|
430
451
|
v = Vector.from_coo([0, 1, 3], [1, 2, 3])
|
|
431
452
|
w = v.apply(unary.force_odd).new()
|
|
@@ -433,6 +454,22 @@ w # indexes=[0, 1, 3], values=[1, 3, 3]
|
|
|
433
454
|
```
|
|
434
455
|
Similar methods exist for BinaryOp, Monoid, and Semiring.
|
|
435
456
|
|
|
457
|
+
## Relation to other network analysis libraries
|
|
458
|
+
Python-graphblas aims to provide an efficient and consistent expression
|
|
459
|
+
of graph operations using linear algebra. This allows the development of
|
|
460
|
+
high-performance implementations of existing and new graph algorithms
|
|
461
|
+
(also see [`graphblas-algorithms`](https://github.com/python-graphblas/graphblas-algorithms)).
|
|
462
|
+
|
|
463
|
+
While end-to-end analysis can be done using `python-graphblas`, users
|
|
464
|
+
might find that other libraries in the Python ecosystem provide a more
|
|
465
|
+
convenient high-level interface for data pre-processing and transformation
|
|
466
|
+
(e.g. `pandas`, `scipy.sparse`), visualization (e.g. `networkx`, `igraph`),
|
|
467
|
+
interactive exploration and analysis (e.g. `networkx`, `igraph`) or for
|
|
468
|
+
algorithms that are not (yet) implemented in `graphblas-algorithms` (e.g.
|
|
469
|
+
`networkx`, `igraph`, `scipy.sparse.csgraph`). To facilitate communication with
|
|
470
|
+
other libraries, `graphblas.io` contains multiple connectors, see the
|
|
471
|
+
following section.
|
|
472
|
+
|
|
436
473
|
## Import/Export connectors to the Python ecosystem
|
|
437
474
|
`graphblas.io` contains functions for converting to and from:
|
|
438
475
|
```python
|
|
@@ -440,7 +477,7 @@ import graphblas as gb
|
|
|
440
477
|
|
|
441
478
|
# scipy.sparse matrices
|
|
442
479
|
A = gb.io.from_scipy_sparse(m)
|
|
443
|
-
m = gb.io.to_scipy_sparse(m, format=
|
|
480
|
+
m = gb.io.to_scipy_sparse(m, format="csr")
|
|
444
481
|
|
|
445
482
|
# networkx graphs
|
|
446
483
|
A = gb.io.from_networkx(g)
|
|
@@ -1,19 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+

|
|
2
2
|
|
|
3
3
|
[](https://anaconda.org/conda-forge/python-graphblas)
|
|
4
4
|
[](https://pypi.python.org/pypi/python-graphblas/)
|
|
5
|
-

|
|
5
|
+
[](https://pypi.python.org/pypi/python-graphblas/)
|
|
6
6
|
[](https://github.com/python-graphblas/python-graphblas/blob/main/LICENSE)
|
|
7
|
+
<br>
|
|
7
8
|
[](https://github.com/python-graphblas/python-graphblas/actions)
|
|
8
9
|
[](https://python-graphblas.readthedocs.io/en/latest/)
|
|
9
10
|
[](https://coveralls.io/r/python-graphblas/python-graphblas)
|
|
11
|
+
<br>
|
|
10
12
|
[](https://doi.org/10.5281/zenodo.7328791)
|
|
11
13
|
[](https://mybinder.org/v2/gh/python-graphblas/python-graphblas/HEAD?filepath=notebooks%2FIntro%20to%20GraphBLAS%20%2B%20SSSP%20example.ipynb)
|
|
12
14
|
[](https://discord.com/invite/vur45CbwMz)
|
|
13
15
|
|
|
14
16
|
Python library for GraphBLAS: high-performance sparse linear algebra for scalable graph analytics.
|
|
17
|
+
For algorithms, see
|
|
18
|
+
[`graphblas-algorithms`](https://github.com/python-graphblas/graphblas-algorithms).
|
|
15
19
|
|
|
16
20
|
- **Documentation:** [https://python-graphblas.readthedocs.io/](https://python-graphblas.readthedocs.io/)
|
|
21
|
+
- **FAQ:** [https://python-graphblas.readthedocs.io/en/stable/getting_started/faq.html](https://python-graphblas.readthedocs.io/en/stable/getting_started/faq.html)
|
|
17
22
|
- **GraphBLAS C API:** [https://graphblas.org/docs/GraphBLAS_API_C_v2.0.0.pdf](https://graphblas.org/docs/GraphBLAS_API_C_v2.0.0.pdf)
|
|
18
23
|
- **SuiteSparse:GraphBLAS User Guide:** [https://github.com/DrTimothyAldenDavis/GraphBLAS/raw/stable/Doc/GraphBLAS_UserGuide.pdf](https://github.com/DrTimothyAldenDavis/GraphBLAS/raw/stable/Doc/GraphBLAS_UserGuide.pdf)
|
|
19
24
|
- **Source:** [https://github.com/python-graphblas/python-graphblas](https://github.com/python-graphblas/python-graphblas)
|
|
@@ -22,6 +27,11 @@ Python library for GraphBLAS: high-performance sparse linear algebra for scalabl
|
|
|
22
27
|
- **Weekly community call:** [https://github.com/python-graphblas/python-graphblas/issues/247](https://github.com/python-graphblas/python-graphblas/issues/247)
|
|
23
28
|
- **Chat via Discord:** [https://discord.com/invite/vur45CbwMz](https://discord.com/invite/vur45CbwMz) in the [#graphblas channel](https://discord.com/channels/786703927705862175/1024732940233605190)
|
|
24
29
|
|
|
30
|
+
<p float="left">
|
|
31
|
+
<img src="https://raw.githubusercontent.com/python-graphblas/python-graphblas/main/docs/_static/img/draw-example.png" width="231" align="top" alt="Directed graph", title="Directed graph"/>
|
|
32
|
+
<img src="https://raw.githubusercontent.com/python-graphblas/python-graphblas/main/docs/_static/img/repr-matrix.png" width="231" align="top" alt="Adjacency matrix" title="Adjacency matrix"/>
|
|
33
|
+
</p>
|
|
34
|
+
|
|
25
35
|
## Install
|
|
26
36
|
Install the latest version of Python-graphblas via conda:
|
|
27
37
|
```
|
|
@@ -29,9 +39,10 @@ $ conda install -c conda-forge python-graphblas
|
|
|
29
39
|
```
|
|
30
40
|
or pip:
|
|
31
41
|
```
|
|
32
|
-
$ pip install python-graphblas
|
|
42
|
+
$ pip install python-graphblas[default]
|
|
33
43
|
```
|
|
34
44
|
This will also install the [SuiteSparse:GraphBLAS](https://github.com/DrTimothyAldenDavis/GraphBLAS) compiled C library.
|
|
45
|
+
We currently support the [GraphBLAS C API 2.0 specification](https://graphblas.org/docs/GraphBLAS_API_C_v2.0.0.pdf).
|
|
35
46
|
|
|
36
47
|
### Optional Dependencies
|
|
37
48
|
|
|
@@ -39,14 +50,14 @@ The following are not required by python-graphblas, but may be needed for certai
|
|
|
39
50
|
|
|
40
51
|
- `pandas` – required for nicer `__repr__`;
|
|
41
52
|
- `matplotlib` – required for basic plotting of graphs;
|
|
42
|
-
- `scipy` – used in io module to read/write `scipy.sparse` format;
|
|
53
|
+
- `scipy` – used in `io` module to read/write `scipy.sparse` format;
|
|
43
54
|
- `networkx` – used in `io` module to interface with `networkx` graphs;
|
|
44
55
|
- `fast-matrix-market` - for faster read/write of Matrix Market files with `gb.io.mmread` and `gb.io.mmwrite`.
|
|
45
56
|
|
|
46
57
|
## Description
|
|
47
58
|
Currently works with [SuiteSparse:GraphBLAS](https://github.com/DrTimothyAldenDavis/GraphBLAS), but the goal is to make it work with all implementations of the GraphBLAS spec.
|
|
48
59
|
|
|
49
|
-
The approach taken with this library is to follow the C-API specification as closely as possible while making improvements
|
|
60
|
+
The approach taken with this library is to follow the C-API 2.0 specification as closely as possible while making improvements
|
|
50
61
|
allowed with the Python syntax. Because the spec always passes in the output object to be written to, we follow the same,
|
|
51
62
|
which is very different from the way Python normally operates. In fact, many who are familiar with other Python data
|
|
52
63
|
libraries (numpy, pandas, etc) will find it strange to not create new objects for every call.
|
|
@@ -165,8 +176,9 @@ use as well as the blocking/non-blocking mode. If the context is not initialized
|
|
|
165
176
|
be performed automatically.
|
|
166
177
|
```python
|
|
167
178
|
import graphblas as gb
|
|
179
|
+
|
|
168
180
|
# Context initialization must happen before any other imports
|
|
169
|
-
gb.init(
|
|
181
|
+
gb.init("suitesparse", blocking=True)
|
|
170
182
|
|
|
171
183
|
# Now we can import other items from graphblas
|
|
172
184
|
from graphblas import binary, semiring
|
|
@@ -184,7 +196,7 @@ def force_odd_func(x):
|
|
|
184
196
|
return x + 1
|
|
185
197
|
return x
|
|
186
198
|
|
|
187
|
-
unary.register_new(
|
|
199
|
+
unary.register_new("force_odd", force_odd_func)
|
|
188
200
|
|
|
189
201
|
v = Vector.from_coo([0, 1, 3], [1, 2, 3])
|
|
190
202
|
w = v.apply(unary.force_odd).new()
|
|
@@ -192,6 +204,22 @@ w # indexes=[0, 1, 3], values=[1, 3, 3]
|
|
|
192
204
|
```
|
|
193
205
|
Similar methods exist for BinaryOp, Monoid, and Semiring.
|
|
194
206
|
|
|
207
|
+
## Relation to other network analysis libraries
|
|
208
|
+
Python-graphblas aims to provide an efficient and consistent expression
|
|
209
|
+
of graph operations using linear algebra. This allows the development of
|
|
210
|
+
high-performance implementations of existing and new graph algorithms
|
|
211
|
+
(also see [`graphblas-algorithms`](https://github.com/python-graphblas/graphblas-algorithms)).
|
|
212
|
+
|
|
213
|
+
While end-to-end analysis can be done using `python-graphblas`, users
|
|
214
|
+
might find that other libraries in the Python ecosystem provide a more
|
|
215
|
+
convenient high-level interface for data pre-processing and transformation
|
|
216
|
+
(e.g. `pandas`, `scipy.sparse`), visualization (e.g. `networkx`, `igraph`),
|
|
217
|
+
interactive exploration and analysis (e.g. `networkx`, `igraph`) or for
|
|
218
|
+
algorithms that are not (yet) implemented in `graphblas-algorithms` (e.g.
|
|
219
|
+
`networkx`, `igraph`, `scipy.sparse.csgraph`). To facilitate communication with
|
|
220
|
+
other libraries, `graphblas.io` contains multiple connectors, see the
|
|
221
|
+
following section.
|
|
222
|
+
|
|
195
223
|
## Import/Export connectors to the Python ecosystem
|
|
196
224
|
`graphblas.io` contains functions for converting to and from:
|
|
197
225
|
```python
|
|
@@ -199,7 +227,7 @@ import graphblas as gb
|
|
|
199
227
|
|
|
200
228
|
# scipy.sparse matrices
|
|
201
229
|
A = gb.io.from_scipy_sparse(m)
|
|
202
|
-
m = gb.io.to_scipy_sparse(m, format=
|
|
230
|
+
m = gb.io.to_scipy_sparse(m, format="csr")
|
|
203
231
|
|
|
204
232
|
# networkx graphs
|
|
205
233
|
A = gb.io.from_networkx(g)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
def pytest_addoption(parser):
|
|
2
|
+
parser.addoption(
|
|
3
|
+
"--backend",
|
|
4
|
+
action="store",
|
|
5
|
+
default=None,
|
|
6
|
+
help="name of a graphblas backend",
|
|
7
|
+
)
|
|
8
|
+
parser.addoption("--runslow", default=None, action="store_true", help="run slow tests")
|
|
9
|
+
parser.addoption(
|
|
10
|
+
"--blocking",
|
|
11
|
+
dest="blocking",
|
|
12
|
+
default=None,
|
|
13
|
+
action="store_true",
|
|
14
|
+
help="run in blocking mode",
|
|
15
|
+
)
|
|
16
|
+
parser.addoption(
|
|
17
|
+
"--nonblocking",
|
|
18
|
+
"--no-blocking",
|
|
19
|
+
"--noblocking",
|
|
20
|
+
"--non-blocking",
|
|
21
|
+
dest="blocking",
|
|
22
|
+
action="store_false",
|
|
23
|
+
help="run in non-blocking mode",
|
|
24
|
+
)
|
|
25
|
+
parser.addoption(
|
|
26
|
+
"--record",
|
|
27
|
+
dest="record",
|
|
28
|
+
default=None,
|
|
29
|
+
action="store_true",
|
|
30
|
+
help="Record GraphBLAS C calls and save to 'record.txt'",
|
|
31
|
+
)
|
|
32
|
+
parser.addoption(
|
|
33
|
+
"--mapnumpy", action="store_true", default=None, help="map numpy ops to GraphBLAS ops"
|
|
34
|
+
)
|
|
35
|
+
parser.addoption(
|
|
36
|
+
"--nomapnumpy",
|
|
37
|
+
"--no-mapnumpy",
|
|
38
|
+
dest="mapnumpy",
|
|
39
|
+
action="store_false",
|
|
40
|
+
help="don't map numpy ops to GraphBLAS ops",
|
|
41
|
+
)
|
|
42
|
+
parser.addoption("--randomly", action="store_true", help="run random test config")
|
|
@@ -137,7 +137,21 @@ def _init(backend_arg, blocking, automatic=False):
|
|
|
137
137
|
|
|
138
138
|
backend = backend_arg
|
|
139
139
|
if backend in {"suitesparse", "suitesparse-vanilla"}:
|
|
140
|
-
|
|
140
|
+
try:
|
|
141
|
+
from suitesparse_graphblas import ffi, initialize, is_initialized, lib
|
|
142
|
+
except ImportError: # pragma: no cover (import)
|
|
143
|
+
raise ImportError(
|
|
144
|
+
f"suitesparse_graphblas is required for {backend!r} backend. "
|
|
145
|
+
"It may be installed with pip or conda:\n\n"
|
|
146
|
+
" $ pip install suitesparse-graphblas\n"
|
|
147
|
+
" $ conda install -c conda-forge python-suitesparse-graphblas\n\n"
|
|
148
|
+
"SuiteSparse:GraphBLAS is the primary C implementation and backend of "
|
|
149
|
+
"python-graphblas and is what we recommend to most users. If you are "
|
|
150
|
+
"installing python-graphblas with pip, we recommend installing with one "
|
|
151
|
+
"of the following to automatically include suitespare-graphblas:\n\n"
|
|
152
|
+
" $ pip install python-graphblas[suitesparse]\n"
|
|
153
|
+
" $ pip install python-graphblas[default]"
|
|
154
|
+
) from None
|
|
141
155
|
|
|
142
156
|
if is_initialized():
|
|
143
157
|
mode = ffi.new("int32_t*")
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""``graphblas.agg`` is an experimental module for exploring Aggregators.
|
|
2
2
|
|
|
3
3
|
Aggregators may be used in reduce methods:
|
|
4
4
|
- Matrix.reduce_rowwise
|
|
@@ -59,9 +59,9 @@ Custom recipes (specific to SuiteSparse:GraphBLAS):
|
|
|
59
59
|
- ss.argmax
|
|
60
60
|
|
|
61
61
|
.. deprecated:: 2023.1.0
|
|
62
|
-
Aggregators
|
|
63
|
-
deprecated in the
|
|
64
|
-
instead such as
|
|
62
|
+
Aggregators ``first``, ``last``, ``first_index``, ``last_index``, ``argmin``, and ``argmax``
|
|
63
|
+
are deprecated in the ``agg`` namespace such as ``agg.first``. Use them from ``agg.ss``
|
|
64
|
+
namespace instead such as ``agg.ss.first``. Will be removed in version 2023.9.0 or later.
|
|
65
65
|
|
|
66
66
|
# Possible aggregators:
|
|
67
67
|
# - absolute_deviation, sum(abs(x - mean(x))), sum_absminus(x, mean(x))
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# All items are dynamically added by classes in operator.py
|
|
2
2
|
# This module acts as a container of BinaryOp instances
|
|
3
|
+
from ..core import _supports_udfs
|
|
4
|
+
|
|
3
5
|
_delayed = {}
|
|
4
6
|
_delayed_commutes_to = {
|
|
5
7
|
"absfirst": "abssecond",
|
|
@@ -9,6 +11,15 @@ _delayed_commutes_to = {
|
|
|
9
11
|
"rpow": "pow",
|
|
10
12
|
}
|
|
11
13
|
_deprecated = {}
|
|
14
|
+
_udfs = {
|
|
15
|
+
"absfirst",
|
|
16
|
+
"abssecond",
|
|
17
|
+
"binom",
|
|
18
|
+
"floordiv",
|
|
19
|
+
"isclose",
|
|
20
|
+
"rfloordiv",
|
|
21
|
+
"rpow",
|
|
22
|
+
}
|
|
12
23
|
|
|
13
24
|
|
|
14
25
|
def __dir__():
|
|
@@ -50,6 +61,11 @@ def __getattr__(key):
|
|
|
50
61
|
ss = import_module(".ss", __name__)
|
|
51
62
|
globals()["ss"] = ss
|
|
52
63
|
return ss
|
|
64
|
+
if not _supports_udfs and key in _udfs:
|
|
65
|
+
raise AttributeError(
|
|
66
|
+
f"module {__name__!r} unable to compile UDF for {key!r}; "
|
|
67
|
+
"install numba for UDF support"
|
|
68
|
+
)
|
|
53
69
|
raise AttributeError(f"module {__name__!r} has no attribute {key!r}")
|
|
54
70
|
|
|
55
71
|
|
|
@@ -10,6 +10,7 @@ import numpy as _np
|
|
|
10
10
|
from .. import _STANDARD_OPERATOR_NAMES
|
|
11
11
|
from .. import binary as _binary
|
|
12
12
|
from .. import config as _config
|
|
13
|
+
from ..core import _supports_udfs
|
|
13
14
|
|
|
14
15
|
_delayed = {}
|
|
15
16
|
_binary_names = {
|
|
@@ -130,7 +131,13 @@ _commutes_to = {
|
|
|
130
131
|
|
|
131
132
|
|
|
132
133
|
def __dir__():
|
|
133
|
-
|
|
134
|
+
if not _supports_udfs and not _config["mapnumpy"]:
|
|
135
|
+
# float_power is special: it's constructed from builtin operators
|
|
136
|
+
return globals().keys() | {"float_power"} # FLAKY COVERAGE
|
|
137
|
+
attrs = _delayed.keys() | _binary_names
|
|
138
|
+
if not _supports_udfs:
|
|
139
|
+
attrs &= _numpy_to_graphblas.keys()
|
|
140
|
+
return attrs | globals().keys()
|
|
134
141
|
|
|
135
142
|
|
|
136
143
|
def __getattr__(name):
|
|
@@ -141,7 +148,7 @@ def __getattr__(name):
|
|
|
141
148
|
return rv
|
|
142
149
|
if name not in _binary_names:
|
|
143
150
|
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
144
|
-
if _config.get("mapnumpy") and name in _numpy_to_graphblas:
|
|
151
|
+
if _config.get("mapnumpy") and name in _numpy_to_graphblas or name == "float_power":
|
|
145
152
|
if name == "float_power":
|
|
146
153
|
from ..core.operator import binary
|
|
147
154
|
from ..dtypes import FP64
|
|
@@ -166,6 +173,11 @@ def __getattr__(name):
|
|
|
166
173
|
globals()[name] = new_op
|
|
167
174
|
else:
|
|
168
175
|
globals()[name] = getattr(_binary, _numpy_to_graphblas[name])
|
|
176
|
+
elif not _supports_udfs:
|
|
177
|
+
raise AttributeError(
|
|
178
|
+
f"module {__name__!r} unable to compile UDF for {name!r}; "
|
|
179
|
+
"install numba for UDF support"
|
|
180
|
+
)
|
|
169
181
|
else:
|
|
170
182
|
numpy_func = getattr(_np, name)
|
|
171
183
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"""graphblas.core.agg namespace is deprecated; please use graphblas.core.operator.agg instead.
|
|
2
2
|
|
|
3
3
|
.. deprecated:: 2023.3.0
|
|
4
|
-
|
|
5
|
-
Use
|
|
4
|
+
``graphblas.core.agg`` will be removed in a future release.
|
|
5
|
+
Use ``graphblas.core.operator.agg`` instead.
|
|
6
6
|
Will be removed in version 2023.11.0 or later.
|
|
7
7
|
|
|
8
8
|
"""
|
|
9
9
|
import warnings
|
|
10
10
|
|
|
11
|
-
from .operator.agg import *
|
|
11
|
+
from .operator.agg import * # pylint: disable=wildcard-import,unused-wildcard-import
|
|
12
12
|
|
|
13
13
|
warnings.warn(
|
|
14
14
|
"graphblas.core.agg namespace is deprecated; please use graphblas.core.operator.agg instead.",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Define functions to use as property methods on expressions.
|
|
2
2
|
|
|
3
|
-
These will automatically compute the value and avoid the need for
|
|
3
|
+
These will automatically compute the value and avoid the need for ``.new()``.
|
|
4
4
|
|
|
5
5
|
To automatically create the functions, run:
|
|
6
6
|
|
|
@@ -348,7 +348,7 @@ class BaseType:
|
|
|
348
348
|
return
|
|
349
349
|
if opts:
|
|
350
350
|
# Ignore opts for now
|
|
351
|
-
descriptor_lookup(**opts)
|
|
351
|
+
desc = descriptor_lookup(**opts)
|
|
352
352
|
self.value = expr
|
|
353
353
|
return
|
|
354
354
|
|
|
@@ -371,7 +371,7 @@ class BaseType:
|
|
|
371
371
|
else:
|
|
372
372
|
if opts:
|
|
373
373
|
# Ignore opts for now
|
|
374
|
-
descriptor_lookup(**opts)
|
|
374
|
+
desc = descriptor_lookup(**opts)
|
|
375
375
|
self.value = expr
|
|
376
376
|
return
|
|
377
377
|
else:
|
|
@@ -571,7 +571,7 @@ class BaseExpression:
|
|
|
571
571
|
):
|
|
572
572
|
if opts:
|
|
573
573
|
# Ignore opts for now
|
|
574
|
-
descriptor_lookup(**opts)
|
|
574
|
+
desc = descriptor_lookup(**opts) # noqa: F841 (keep desc in scope for context)
|
|
575
575
|
if self._is_scalar and self._value._is_cscalar != is_cscalar:
|
|
576
576
|
return self._value.dup(is_cscalar=is_cscalar, name=name)
|
|
577
577
|
rv = self._value
|