-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy path_matrixmarket.py
More file actions
191 lines (174 loc) · 7.41 KB
/
Copy path_matrixmarket.py
File metadata and controls
191 lines (174 loc) · 7.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
import warnings
from .. import backend
from ..core.matrix import Matrix
from ._scipy import to_scipy_sparse
def mmread(source, engine="auto", *, dup_op=None, name=None, **kwargs):
"""Create a GraphBLAS Matrix from the contents of a Matrix Market file.
This uses `scipy.io.mmread
<https://docs.scipy.org/doc/scipy/reference/generated/scipy.io.mmread.html>`_
or `fast_matrix_market.mmread
<https://github.com/alugowski/fast_matrix_market/tree/main/python>`_.
By default, ``fast_matrix_market`` will be used if available, because it
is faster. Additional keyword arguments in ``**kwargs`` will be passed
to the engine's ``mmread``. For example, ``parallelism=8`` will set the
number of threads to use to 8 when using ``fast_matrix_market``.
Parameters
----------
source : str or file
Filename (.mtx or .mtz.gz) or file-like object
engine : {"auto", "scipy", "fmm", "fast_matrix_market"}, default "auto"
How to read the matrix market file. "scipy" uses ``scipy.io.mmread``,
"fmm" and "fast_matrix_market" uses ``fast_matrix_market.mmread``,
and "auto" will use "fast_matrix_market" if available.
dup_op : BinaryOp, optional
Aggregation function for duplicate coordinates (if found)
name : str, optional
Name of resulting Matrix
Returns
-------
:class:`~graphblas.Matrix`
"""
try:
# scipy is currently needed for *all* engines
from scipy.io import mmread
except ImportError: # pragma: no cover (import)
raise ImportError("scipy is required to read Matrix Market files") from None
engine = engine.lower()
using_scipy = True
if engine in {"fmm", "fast_matrix_market"}:
warnings.warn(
"fast_matrix_market is no longer maintained and will be removed in a future version. "
'Use engine="scipy" instead.',
DeprecationWarning,
stacklevel=2,
)
if engine in {"auto", "fmm", "fast_matrix_market"}:
try:
from fast_matrix_market import mmread # noqa: F811
if engine == "auto":
warnings.warn(
"fast_matrix_market is installed but is no longer maintained and will be "
"removed in a future version. Uninstall it or use engine='scipy' to "
"silence this warning.",
DeprecationWarning,
stacklevel=2,
)
except ImportError: # pragma: no cover (import)
if engine != "auto":
raise ImportError(
"fast_matrix_market is required to read Matrix Market files "
f'using the "{engine}" engine'
) from None
else:
using_scipy = False
elif engine != "scipy":
raise ValueError(
f'Bad engine value: {engine!r}. Must be "auto", "scipy", "fmm", or "fast_matrix_market"'
)
if using_scipy and "spmatrix" not in kwargs:
# scipy's `mmread` still returns a sparse matrix by default, but 1.18
# deprecated that default and 1.20 flips it to a sparse array. We only
# read `.shape`, `.row`, `.col`, and `.data` below, which both types
# provide, so ask for the future default and skip the warning.
# MAINT: 2026-07-31 once we require scipy >= 1.20 this whole block goes
# away, since False becomes the default.
# Older scipy has no such argument; check rather than pin a version.
import inspect
if "spmatrix" in inspect.signature(mmread).parameters:
kwargs["spmatrix"] = False
array = mmread(source, **kwargs)
if getattr(array, "format", None) == "coo":
nrows, ncols = array.shape
return Matrix.from_coo(
array.row, array.col, array.data, nrows=nrows, ncols=ncols, dup_op=dup_op, name=name
)
return Matrix.from_dense(array, name=name)
def mmwrite(
target,
matrix,
engine="auto",
*,
comment="",
field=None,
precision=None,
symmetry=None,
**kwargs,
):
"""Write a Matrix Market file from the contents of a GraphBLAS Matrix.
This uses `scipy.io.mmwrite
<https://docs.scipy.org/doc/scipy/reference/generated/scipy.io.mmwrite.html>`_.
Parameters
----------
target : str or file target
Filename (.mtx) or file-like object opened for writing
matrix : Matrix
Matrix to be written
engine : {"auto", "scipy", "fmm", "fast_matrix_market"}, default "auto"
How to read the matrix market file. "scipy" uses ``scipy.io.mmwrite``,
"fmm" and "fast_matrix_market" uses ``fast_matrix_market.mmwrite``,
and "auto" will use "fast_matrix_market" if available.
comment : str, optional
Comments to be prepended to the Matrix Market file
field : str
{"real", "complex", "pattern", "integer"}
precision : int, optional
Number of digits to write for real or complex values
symmetry : str, optional
{"general", "symmetric", "skew-symmetric", "hermetian"}
"""
try:
# scipy is currently needed for *all* engines
from scipy.io import mmwrite
except ImportError: # pragma: no cover (import)
raise ImportError("scipy is required to write Matrix Market files") from None
engine = engine.lower()
if engine in {"fmm", "fast_matrix_market"}:
warnings.warn(
"fast_matrix_market is no longer maintained and will be removed in a future version. "
'Use engine="scipy" instead.',
DeprecationWarning,
stacklevel=2,
)
if engine in {"auto", "fmm", "fast_matrix_market"}:
try:
from fast_matrix_market import __version__, mmwrite # noqa: F811
if engine == "auto":
warnings.warn(
"fast_matrix_market is installed but is no longer maintained and will be "
"removed in a future version. Uninstall it or use engine='scipy' to "
"silence this warning.",
DeprecationWarning,
stacklevel=2,
)
except ImportError: # pragma: no cover (import)
if engine != "auto":
raise ImportError(
"fast_matrix_market is required to write Matrix Market files "
f'using the "{engine}" engine'
) from None
else:
import scipy as sp
engine = "fast_matrix_market"
elif engine != "scipy":
raise ValueError(
f'Bad engine value: {engine!r}. Must be "auto", "scipy", "fmm", or "fast_matrix_market"'
)
if backend == "suitesparse" and matrix.ss.format in {"fullr", "fullc"}:
array = matrix.ss.export()["values"]
else:
array = to_scipy_sparse(matrix, format="coo")
if engine == "fast_matrix_market" and __version__ < "1.7." and sp.__version__ > "1.11.":
# 2023-06-25: scipy 1.11.0 added `sparray` and changed e.g. `ss.isspmatrix_coo`.
# fast_matrix_market updated to handle this in version 1.7.0
# Also, it looks like fast_matrix_market has special writers for csr and csc;
# should we see if using those are faster?
array = sp.sparse.coo_matrix(array) # FLAKY COVERAGE
mmwrite(
target,
array,
comment=comment,
field=field,
precision=precision,
symmetry=symmetry,
**kwargs,
)