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.
Files changed (123) hide show
  1. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/LICENSE +1 -1
  2. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/MANIFEST.in +3 -0
  3. {python-graphblas-2023.3.0/python_graphblas.egg-info → python-graphblas-2023.7.0}/PKG-INFO +48 -11
  4. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/README.md +36 -8
  5. python-graphblas-2023.7.0/conftest.py +42 -0
  6. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/__init__.py +15 -1
  7. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/agg/__init__.py +4 -4
  8. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/binary/__init__.py +16 -0
  9. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/binary/numpy.py +14 -2
  10. python-graphblas-2023.7.0/graphblas/binary/ss.py +6 -0
  11. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/__init__.py +9 -0
  12. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/agg.py +3 -3
  13. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/automethods.py +1 -1
  14. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/base.py +3 -3
  15. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/descriptor.py +1 -0
  16. {python-graphblas-2023.3.0/graphblas → python-graphblas-2023.7.0/graphblas/core}/dtypes.py +162 -86
  17. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/expr.py +1 -1
  18. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/formatting.py +1 -0
  19. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/mask.py +5 -5
  20. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/matrix.py +32 -28
  21. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/agg.py +24 -3
  22. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/base.py +78 -93
  23. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/binary.py +150 -36
  24. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/indexunary.py +101 -25
  25. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/monoid.py +38 -11
  26. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/select.py +109 -7
  27. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/semiring.py +41 -21
  28. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/unary.py +77 -14
  29. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/recorder.py +3 -3
  30. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/scalar.py +18 -3
  31. python-graphblas-2023.7.0/graphblas/core/ss/__init__.py +3 -0
  32. python-graphblas-2023.7.0/graphblas/core/ss/binary.py +72 -0
  33. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/ss/config.py +46 -11
  34. python-graphblas-2023.7.0/graphblas/core/ss/context.py +146 -0
  35. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/ss/descriptor.py +21 -9
  36. python-graphblas-2023.7.0/graphblas/core/ss/dtypes.py +88 -0
  37. python-graphblas-2023.7.0/graphblas/core/ss/indexunary.py +77 -0
  38. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/ss/matrix.py +116 -105
  39. python-graphblas-2023.7.0/graphblas/core/ss/select.py +45 -0
  40. python-graphblas-2023.7.0/graphblas/core/ss/unary.py +62 -0
  41. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/ss/vector.py +40 -40
  42. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/utils.py +15 -12
  43. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/vector.py +69 -22
  44. python-graphblas-2023.7.0/graphblas/dtypes/__init__.py +43 -0
  45. python-graphblas-2023.7.0/graphblas/dtypes/ss.py +1 -0
  46. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/indexunary/__init__.py +13 -1
  47. python-graphblas-2023.7.0/graphblas/indexunary/ss.py +6 -0
  48. python-graphblas-2023.7.0/graphblas/io/__init__.py +7 -0
  49. python-graphblas-2023.7.0/graphblas/io/_awkward.py +187 -0
  50. python-graphblas-2023.7.0/graphblas/io/_matrixmarket.py +140 -0
  51. python-graphblas-2023.7.0/graphblas/io/_networkx.py +59 -0
  52. python-graphblas-2023.7.0/graphblas/io/_numpy.py +104 -0
  53. python-graphblas-2023.7.0/graphblas/io/_scipy.py +118 -0
  54. python-graphblas-2023.7.0/graphblas/io/_sparse.py +99 -0
  55. python-graphblas-2023.7.0/graphblas/io/_viz.py +21 -0
  56. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/monoid/__init__.py +13 -1
  57. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/monoid/numpy.py +12 -3
  58. {python-graphblas-2023.3.0/graphblas/binary → python-graphblas-2023.7.0/graphblas/monoid}/ss.py +2 -0
  59. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/op/__init__.py +9 -1
  60. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/op/numpy.py +5 -1
  61. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/op/ss.py +2 -0
  62. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/select/__init__.py +19 -7
  63. python-graphblas-2023.7.0/graphblas/select/ss.py +6 -0
  64. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/semiring/__init__.py +27 -0
  65. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/semiring/numpy.py +12 -1
  66. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/semiring/ss.py +2 -0
  67. python-graphblas-2023.7.0/graphblas/ss/__init__.py +5 -0
  68. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/ss/_core.py +67 -13
  69. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/conftest.py +43 -7
  70. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_core.py +5 -2
  71. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_dtype.py +23 -9
  72. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_formatting.py +70 -3
  73. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_infix.py +7 -0
  74. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_io.py +28 -8
  75. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_matrix.py +100 -47
  76. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_numpyops.py +44 -18
  77. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_op.py +193 -82
  78. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_operator_types.py +6 -0
  79. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_pickle.py +6 -0
  80. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_scalar.py +12 -10
  81. python-graphblas-2023.7.0/graphblas/tests/test_ssjit.py +269 -0
  82. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_vector.py +58 -16
  83. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/unary/numpy.py +12 -1
  84. python-graphblas-2023.7.0/graphblas/unary/ss.py +6 -0
  85. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/viz.py +4 -5
  86. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/pyproject.toml +80 -27
  87. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0/python_graphblas.egg-info}/PKG-INFO +48 -11
  88. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/python_graphblas.egg-info/SOURCES.txt +22 -2
  89. python-graphblas-2023.7.0/python_graphblas.egg-info/requires.txt +64 -0
  90. python-graphblas-2023.3.0/graphblas/io.py +0 -697
  91. python-graphblas-2023.3.0/graphblas/ss/__init__.py +0 -1
  92. python-graphblas-2023.3.0/graphblas/tests/__init__.py +0 -0
  93. python-graphblas-2023.3.0/graphblas/unary/ss.py +0 -3
  94. python-graphblas-2023.3.0/python_graphblas.egg-info/requires.txt +0 -37
  95. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/agg/ss.py +0 -0
  96. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/infix.py +0 -0
  97. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/infixmethods.py +0 -0
  98. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/__init__.py +0 -0
  99. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/operator/utils.py +0 -0
  100. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/slice.py +0 -0
  101. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/core/ss/prefix_scan.py +0 -0
  102. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/exceptions.py +0 -0
  103. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/graphblas.yaml +0 -0
  104. {python-graphblas-2023.3.0/graphblas/core/ss → python-graphblas-2023.7.0/graphblas/tests}/__init__.py +0 -0
  105. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/pickle1-vanilla.pkl +0 -0
  106. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/pickle1.pkl +0 -0
  107. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/pickle2-vanilla.pkl +0 -0
  108. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/pickle2.pkl +0 -0
  109. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/pickle3-vanilla.pkl +0 -0
  110. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/pickle3.pkl +0 -0
  111. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_auto_init.py +0 -0
  112. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_descriptor.py +0 -0
  113. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_external_init.py +0 -0
  114. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_mask.py +0 -0
  115. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_prefix_scan.py +0 -0
  116. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_recorder.py +0 -0
  117. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_resolving.py +0 -0
  118. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/tests/test_ss_utils.py +0 -0
  119. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/graphblas/unary/__init__.py +0 -0
  120. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/python_graphblas.egg-info/dependency_links.txt +0 -0
  121. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/python_graphblas.egg-info/top_level.txt +0 -0
  122. {python-graphblas-2023.3.0 → python-graphblas-2023.7.0}/setup.cfg +0 -0
  123. {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,5 +1,8 @@
1
1
  recursive-include graphblas *.py
2
+ prune docs
3
+ prune scripts
2
4
  include setup.py
5
+ include conftest.py
3
6
  include README.md
4
7
  include LICENSE
5
8
  include MANIFEST.in
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-graphblas
3
- Version: 2023.3.0
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: complete
247
+ Provides-Extra: default
248
+ Provides-Extra: all
240
249
  License-File: LICENSE
241
250
 
242
- # Python-graphblas
251
+ ![Python-graphblas](https://raw.githubusercontent.com/python-graphblas/python-graphblas/main/docs/_static/img/logo-name-medium.svg)
243
252
 
244
253
  [![conda-forge](https://img.shields.io/conda/vn/conda-forge/python-graphblas.svg)](https://anaconda.org/conda-forge/python-graphblas)
245
254
  [![pypi](https://img.shields.io/pypi/v/python-graphblas.svg)](https://pypi.python.org/pypi/python-graphblas/)
246
- ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/python-graphblas)
255
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/python-graphblas)](https://pypi.python.org/pypi/python-graphblas/)
247
256
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/python-graphblas/python-graphblas/blob/main/LICENSE)
257
+ <br>
248
258
  [![Tests](https://github.com/python-graphblas/python-graphblas/workflows/Tests/badge.svg?branch=main)](https://github.com/python-graphblas/python-graphblas/actions)
249
259
  [![Docs](https://readthedocs.org/projects/python-graphblas/badge/?version=latest)](https://python-graphblas.readthedocs.io/en/latest/)
250
260
  [![Coverage](https://coveralls.io/repos/python-graphblas/python-graphblas/badge.svg?branch=main)](https://coveralls.io/r/python-graphblas/python-graphblas)
261
+ <br>
251
262
  [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.7328791.svg)](https://doi.org/10.5281/zenodo.7328791)
252
263
  [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/python-graphblas/python-graphblas/HEAD?filepath=notebooks%2FIntro%20to%20GraphBLAS%20%2B%20SSSP%20example.ipynb)
253
264
  [![Discord](https://img.shields.io/badge/Chat-Discord-blue)](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('suitesparse', blocking=True)
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('force_odd', force_odd_func)
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='csr')
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
- # Python-graphblas
1
+ ![Python-graphblas](https://raw.githubusercontent.com/python-graphblas/python-graphblas/main/docs/_static/img/logo-name-medium.svg)
2
2
 
3
3
  [![conda-forge](https://img.shields.io/conda/vn/conda-forge/python-graphblas.svg)](https://anaconda.org/conda-forge/python-graphblas)
4
4
  [![pypi](https://img.shields.io/pypi/v/python-graphblas.svg)](https://pypi.python.org/pypi/python-graphblas/)
5
- ![PyPI - Python Version](https://img.shields.io/pypi/pyversions/python-graphblas)
5
+ [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/python-graphblas)](https://pypi.python.org/pypi/python-graphblas/)
6
6
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/python-graphblas/python-graphblas/blob/main/LICENSE)
7
+ <br>
7
8
  [![Tests](https://github.com/python-graphblas/python-graphblas/workflows/Tests/badge.svg?branch=main)](https://github.com/python-graphblas/python-graphblas/actions)
8
9
  [![Docs](https://readthedocs.org/projects/python-graphblas/badge/?version=latest)](https://python-graphblas.readthedocs.io/en/latest/)
9
10
  [![Coverage](https://coveralls.io/repos/python-graphblas/python-graphblas/badge.svg?branch=main)](https://coveralls.io/r/python-graphblas/python-graphblas)
11
+ <br>
10
12
  [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.7328791.svg)](https://doi.org/10.5281/zenodo.7328791)
11
13
  [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/python-graphblas/python-graphblas/HEAD?filepath=notebooks%2FIntro%20to%20GraphBLAS%20%2B%20SSSP%20example.ipynb)
12
14
  [![Discord](https://img.shields.io/badge/Chat-Discord-blue)](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('suitesparse', blocking=True)
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('force_odd', force_odd_func)
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='csr')
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
- from suitesparse_graphblas import ffi, initialize, is_initialized, lib
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
- """`graphblas.agg` is an experimental module for exploring Aggregators.
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 `first`, `last`, `first_index`, `last_index`, `argmin`, and `argmax` are
63
- deprecated in the `agg` namespace such as `agg.first`. Use them from `agg.ss` namespace
64
- instead such as `agg.ss.first`. Will be removed in version 2023.9.0 or later.
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
- return globals().keys() | _delayed.keys() | _binary_names
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
 
@@ -0,0 +1,6 @@
1
+ from ..core import operator
2
+ from ..core.ss.binary import register_new # noqa: F401
3
+
4
+ _delayed = {}
5
+
6
+ del operator
@@ -1,3 +1,12 @@
1
+ try:
2
+ import numba
3
+ except ImportError:
4
+ _has_numba = _supports_udfs = False
5
+ else:
6
+ _has_numba = _supports_udfs = True
7
+ del numba
8
+
9
+
1
10
  def __getattr__(name):
2
11
  if name in {"ffi", "lib", "NULL"}:
3
12
  from .. import _autoinit
@@ -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
- `graphblas.core.agg` will be removed in a future release.
5
- Use `graphblas.core.operator.agg` instead.
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 `.new()`.
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
@@ -26,6 +26,7 @@ class Descriptor:
26
26
  self.mask_structure = mask_structure
27
27
  self.transpose_first = transpose_first
28
28
  self.transpose_second = transpose_second
29
+ self._context = None # Used by SuiteSparse:GraphBLAS 8
29
30
 
30
31
  @property
31
32
  def _carg(self):