Skip to content

Commit 18c1596

Browse files
authored
Merge pull request #652 from pydata/finch-benchmark-test
Finch+PyData benchmarks
2 parents 9a8b31a + 525149d commit 18c1596

File tree

8 files changed

+230
-4
lines changed

8 files changed

+230
-4
lines changed

asv.conf.json

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,54 @@
33
"HEAD"
44
],
55
"build_command": [],
6-
"environment_type": "conda",
6+
"environment_type": "virtualenv",
7+
"exclude": [
8+
{
9+
"env": {
10+
"SPARSE_BACKEND": "Finch"
11+
},
12+
"req": {
13+
"finch-tensor": null
14+
}
15+
},
16+
{
17+
"env": {
18+
"SPARSE_BACKEND": "PyData"
19+
},
20+
"req": {
21+
"finch-tensor": ""
22+
}
23+
}
24+
],
725
"install_command": [
826
"pip install --no-deps ."
927
],
1028
"matrix": {
11-
"env": {},
29+
"env": {
30+
"SPARSE_BACKEND": [
31+
"Finch",
32+
"PyData"
33+
]
34+
},
1235
"env_nobuild": {},
1336
"req": {
14-
"numba": [],
15-
"numpy": []
37+
"finch-tensor": [
38+
"",
39+
null
40+
],
41+
"numba": [
42+
""
43+
],
44+
"numpy": [
45+
""
46+
]
1647
}
1748
},
1849
"project": "sparse",
1950
"project_url": "https://sparse.pydata.org/",
51+
"pythons": [
52+
"3.10"
53+
],
2054
"repo": ".",
2155
"uninstall_command": [
2256
"pip uninstall sparse --yes"

benchmarks/benchmark_backends.py

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
import sparse
2+
3+
import numpy as np
4+
5+
from .utils import SkipNotImplemented
6+
7+
TIMEOUT: float = 200.0
8+
BACKEND: sparse.BackendType = sparse.backend_var.get()
9+
10+
11+
class Tensordot:
12+
timeout = TIMEOUT
13+
14+
def setup(self):
15+
rng = np.random.default_rng(0)
16+
17+
random_kwargs = {"density": 0.01, "random_state": rng}
18+
if sparse.BackendType.PyData == BACKEND:
19+
random_kwargs["format"] = "gcxs"
20+
21+
self.s1 = sparse.random((100, 10), **random_kwargs)
22+
self.s2 = sparse.random((100, 100, 10), **random_kwargs)
23+
24+
if sparse.BackendType.Finch == BACKEND:
25+
import finch
26+
27+
self.s1 = self.s1.to_device(
28+
finch.Storage(finch.Dense(finch.SparseList(finch.Element(0.0))), order=self.s1.get_order())
29+
)
30+
self.s2 = self.s2.to_device(
31+
finch.Storage(
32+
finch.Dense(finch.SparseList(finch.SparseList(finch.Element(0.0)))),
33+
order=self.s2.get_order(),
34+
)
35+
)
36+
37+
sparse.tensordot(self.s1, self.s2, axes=([0, 1], [0, 2])) # compilation
38+
39+
def time_tensordot(self):
40+
sparse.tensordot(self.s1, self.s2, axes=([0, 1], [0, 2]))
41+
42+
43+
class SpMv:
44+
timeout = TIMEOUT
45+
# NOTE: https://github.com/willow-ahrens/Finch.jl/issues/488
46+
params = [[True, False], [(10, 0.01)]] # (1000, 0.01), (1_000_000, 1e-05)
47+
param_names = ["lazy_mode", "size_and_density"]
48+
49+
def setup(self, lazy_mode, size_and_density):
50+
rng = np.random.default_rng(0)
51+
size, density = size_and_density
52+
53+
random_kwargs = {"density": density, "random_state": rng}
54+
if sparse.BackendType.PyData == BACKEND:
55+
random_kwargs["format"] = "gcxs"
56+
57+
self.M = sparse.random((size, size), **random_kwargs)
58+
# NOTE: Once https://github.com/willow-ahrens/Finch.jl/issues/487 is fixed change to (size, 1).
59+
self.v1 = rng.normal(size=(size, 2))
60+
self.v2 = rng.normal(size=(size, 2))
61+
62+
if sparse.BackendType.Finch == BACKEND:
63+
import finch
64+
65+
self.M = self.M.to_device(
66+
finch.Storage(finch.Dense(finch.SparseList(finch.Element(0.0))), order=self.M.get_order())
67+
)
68+
self.v1 = finch.Tensor(self.v1)
69+
self.v2 = finch.Tensor(self.v2)
70+
if lazy_mode:
71+
72+
@sparse.compiled
73+
def fn(tns1, tns2, tns3):
74+
return tns1 @ tns2 + tns3
75+
else:
76+
77+
def fn(tns1, tns2, tns3):
78+
return tns1 @ tns2 + tns3
79+
80+
elif sparse.BackendType.PyData == BACKEND:
81+
if lazy_mode:
82+
raise SkipNotImplemented("PyData doesn't have lazy mode")
83+
84+
def fn(tns1, tns2, tns3):
85+
return tns1 @ tns2 + tns3
86+
87+
else:
88+
raise Exception(f"Invalid backend: {BACKEND}")
89+
90+
self.fn = fn
91+
self.fn(self.M, self.v1, self.v2)
92+
93+
def time_spmv(self, lazy_mode, size_and_density):
94+
self.fn(self.M, self.v1, self.v2)
95+
96+
97+
class Elemwise:
98+
timeout = TIMEOUT
99+
100+
def setup(self):
101+
rng = np.random.default_rng(0)
102+
103+
random_kwargs = {"density": 0.01, "random_state": rng}
104+
if sparse.BackendType.PyData == BACKEND:
105+
random_kwargs["format"] = "gcxs"
106+
107+
self.s1 = sparse.random((100, 10), **random_kwargs)
108+
self.s2 = sparse.random((100, 100, 10), **random_kwargs)
109+
110+
if sparse.BackendType.Finch == BACKEND:
111+
import finch
112+
113+
self.s1 = self.s1.to_device(
114+
finch.Storage(finch.Dense(finch.SparseList(finch.Element(0.0))), order=self.s1.get_order())
115+
)
116+
self.s2 = self.s2.to_device(
117+
finch.Storage(
118+
finch.Dense(finch.SparseList(finch.SparseList(finch.Element(0.0)))), order=self.s2.get_order()
119+
)
120+
)
121+
122+
self.s1 + self.s2
123+
self.s1 * self.s2
124+
125+
def time_add(self):
126+
self.s1 + self.s2
127+
128+
def time_mul(self):
129+
self.s1 * self.s2
130+
131+
132+
# class SDDMM:
133+
# timeout = TIMEOUT
134+
135+
# def setup():
136+
# pass
137+
138+
# class Reductions:
139+
# timeout = TIMEOUT
140+
141+
# def setup():
142+
# pass

benchmarks/benchmark_coo.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22

33
import numpy as np
44

5+
from .utils import skip_if_finch
6+
57

68
class MatrixMultiplySuite:
79
def setup(self):
10+
skip_if_finch()
11+
812
rng = np.random.default_rng(0)
913
self.x = sparse.random((100, 100), density=0.01, random_state=rng)
1014
self.y = sparse.random((100, 100), density=0.01, random_state=rng)
@@ -17,11 +21,14 @@ def time_matmul(self):
1721

1822
class ElemwiseSuite:
1923
def setup(self):
24+
skip_if_finch()
25+
2026
rng = np.random.default_rng(0)
2127
self.x = sparse.random((100, 100, 100), density=0.01, random_state=rng)
2228
self.y = sparse.random((100, 100, 100), density=0.01, random_state=rng)
2329

2430
self.x + self.y # Numba compilation
31+
self.x * self.y # Numba compilation
2532

2633
def time_add(self):
2734
self.x + self.y
@@ -32,10 +39,15 @@ def time_mul(self):
3239

3340
class ElemwiseBroadcastingSuite:
3441
def setup(self):
42+
skip_if_finch()
43+
3544
rng = np.random.default_rng(0)
3645
self.x = sparse.random((100, 1, 100), density=0.01, random_state=rng)
3746
self.y = sparse.random((100, 100), density=0.01, random_state=rng)
3847

48+
self.x + self.y # Numba compilation
49+
self.x * self.y # Numba compilation
50+
3951
def time_add(self):
4052
self.x + self.y
4153

@@ -45,6 +57,8 @@ def time_mul(self):
4557

4658
class IndexingSuite:
4759
def setup(self):
60+
skip_if_finch()
61+
4862
rng = np.random.default_rng(0)
4963
self.index = rng.integers(0, 100, 50)
5064
self.x = sparse.random((100, 100, 100), density=0.01, random_state=rng)

benchmarks/benchmark_gcxs.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22

33
import numpy as np
44

5+
from .utils import skip_if_finch
6+
57

68
class MatrixMultiplySuite:
79
def setup(self):
10+
skip_if_finch()
11+
812
rng = np.random.default_rng(0)
913
self.x = sparse.random((100, 100), density=0.01, format="gcxs", random_state=rng)
1014
self.y = sparse.random((100, 100), density=0.01, format="gcxs", random_state=rng)
@@ -17,6 +21,8 @@ def time_matmul(self):
1721

1822
class ElemwiseSuite:
1923
def setup(self):
24+
skip_if_finch()
25+
2026
rng = np.random.default_rng(0)
2127
self.x = sparse.random((100, 100, 100), density=0.01, format="gcxs", random_state=rng)
2228
self.y = sparse.random((100, 100, 100), density=0.01, format="gcxs", random_state=rng)
@@ -32,6 +38,8 @@ def time_mul(self):
3238

3339
class ElemwiseBroadcastingSuite:
3440
def setup(self):
41+
skip_if_finch()
42+
3543
rng = np.random.default_rng(0)
3644
self.x = sparse.random((100, 1, 100), density=0.01, format="gcxs", random_state=rng)
3745
self.y = sparse.random((100, 100), density=0.01, format="gcxs", random_state=rng)
@@ -45,6 +53,8 @@ def time_mul(self):
4553

4654
class IndexingSuite:
4755
def setup(self):
56+
skip_if_finch()
57+
4858
rng = np.random.default_rng(0)
4959
self.index = rng.integers(0, 100, 50)
5060
self.x = sparse.random((100, 100, 100), density=0.01, format="gcxs", random_state=rng)
@@ -74,6 +84,8 @@ class DenseMultiplySuite:
7484
param_names = ["compressed axis", "n_vectors"]
7585

7686
def setup(self, compressed_axis, n_vecs):
87+
skip_if_finch()
88+
7789
rng = np.random.default_rng(1337)
7890
n = 10000
7991
x = sparse.random((n, n), density=0.001, format="gcxs", random_state=rng).change_compressed_axes(

benchmarks/benchmark_matmul.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
import numpy as np
44

5+
from .utils import skip_if_finch
6+
57

68
class Matmul_Sparse:
79
params = (["coo", "gcxs"], [0, 1, None])
810

911
def setup(self, p, dens_arg):
12+
skip_if_finch()
13+
1014
rng = np.random.default_rng(0)
1115
self.x = sparse.random((100, 100), density=0.01, format=p, random_state=rng)
1216
self.y = sparse.random((100, 100), density=0.01, format=p, random_state=rng)

benchmarks/benchmark_tensordot.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import numpy as np
44

5+
from .utils import skip_if_finch
6+
57

68
class TensordotSuiteDenseSparse:
79
"""
@@ -10,6 +12,8 @@ class TensordotSuiteDenseSparse:
1012
"""
1113

1214
def setup(self):
15+
skip_if_finch()
16+
1317
rng = np.random.default_rng(0)
1418
self.n = rng.random((100, 100))
1519
self.s = sparse.random((100, 100, 100, 100), density=0.01, random_state=rng)
@@ -28,6 +32,8 @@ class TensordotSuiteSparseSparse:
2832
"""
2933

3034
def setup(self):
35+
skip_if_finch()
36+
3137
rng = np.random.default_rng(0)
3238
self.s1 = sparse.random((100, 100), density=0.01, random_state=rng)
3339
self.s2 = sparse.random((100, 100, 100, 100), density=0.01, random_state=rng)
@@ -46,6 +52,8 @@ class TensordotSuiteSparseDense:
4652
"""
4753

4854
def setup(self):
55+
skip_if_finch()
56+
4957
rng = np.random.default_rng(0)
5058
self.s = sparse.random((100, 100, 100, 100), density=0.01, random_state=rng)
5159
self.n = rng.random((100, 100))

benchmarks/utils.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import sparse
2+
3+
from asv_runner.benchmarks.mark import SkipNotImplemented
4+
5+
6+
def skip_if_finch():
7+
if sparse.backend_var.get() == sparse.BackendType.Finch:
8+
raise SkipNotImplemented("Finch backend is skipped.")

sparse/finch_backend/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
int64,
2323
int_,
2424
lazy,
25+
matmul,
2526
multiply,
2627
negative,
2728
permute_dims,
@@ -30,6 +31,7 @@
3031
random,
3132
subtract,
3233
sum,
34+
tensordot,
3335
uint,
3436
uint8,
3537
uint16,
@@ -56,6 +58,7 @@
5658
"int64",
5759
"int_",
5860
"lazy",
61+
"matmul",
5962
"multiply",
6063
"negative",
6164
"permute_dims",
@@ -64,6 +67,7 @@
6467
"random",
6568
"subtract",
6669
"sum",
70+
"tensordot",
6771
"uint",
6872
"uint8",
6973
"uint16",

0 commit comments

Comments
 (0)