diff --git a/.github/workflows/codspeed.yml b/.github/workflows/codspeed.yml index fed68f03..4f0aee45 100644 --- a/.github/workflows/codspeed.yml +++ b/.github/workflows/codspeed.yml @@ -25,4 +25,9 @@ jobs: - name: Run benchmarks uses: CodSpeedHQ/action@v3 with: - run: pytest benchmarks/ --codspeed + run: SPARSE_BACKEND=Numba pytest benchmarks/ --codspeed + + - name: Run benchmarks + uses: CodSpeedHQ/action@v3 + with: + run: SPARSE_BACKEND=Finch pytest benchmarks/ --codspeed diff --git a/benchmarks/conftest.py b/benchmarks/conftest.py index b80d9b88..bf5e12a8 100644 --- a/benchmarks/conftest.py +++ b/benchmarks/conftest.py @@ -1,3 +1,5 @@ +import sparse + import pytest @@ -6,6 +8,21 @@ def seed(scope="session"): return 42 +def get_backend_id(param): + backend = param + return f"{backend=}" + + +@pytest.fixture(params=[sparse._BACKEND.value], autouse=True, ids=get_backend_id) +def backend(request): + return request.param + + +@pytest.fixture +def min_size(scope="session"): + return 50 + + @pytest.fixture def max_size(scope="session"): return 2**26 diff --git a/benchmarks/test_benchmark_coo.py b/benchmarks/test_benchmark_coo.py index 108ac075..7bc33a63 100644 --- a/benchmarks/test_benchmark_coo.py +++ b/benchmarks/test_benchmark_coo.py @@ -15,16 +15,19 @@ def format_id(format): @pytest.mark.parametrize("format", ["coo", "gcxs"]) -def test_matmul(benchmark, sides, format, seed, max_size, ids=format_id): +def test_matmul(benchmark, sides, seed, format, backend, min_size, max_size, ids=format_id): m, n, p = sides - if m * n >= max_size or n * p >= max_size: + if m * n >= max_size or n * p >= max_size or m * n <= min_size or n * p <= min_size: pytest.skip() rng = np.random.default_rng(seed=seed) x = sparse.random((m, n), density=DENSITY, format=format, random_state=rng) y = sparse.random((n, p), density=DENSITY, format=format, random_state=rng) + if hasattr(sparse, "compiled"): + operator.matmul = sparse.compiled(operator.matmul) + x @ y # Numba compilation @benchmark @@ -50,8 +53,12 @@ def elemwise_args(request, seed, max_size): @pytest.mark.parametrize("f", [operator.add, operator.mul]) -def test_elemwise(benchmark, f, elemwise_args): +def test_elemwise(benchmark, f, elemwise_args, backend): x, y = elemwise_args + + if hasattr(sparse, "compiled"): + f = sparse.compiled(f) + f(x, y) @benchmark @@ -78,6 +85,10 @@ def elemwise_broadcast_args(request, seed, max_size): @pytest.mark.parametrize("f", [operator.add, operator.mul]) def test_elemwise_broadcast(benchmark, f, elemwise_broadcast_args): x, y = elemwise_broadcast_args + + if hasattr(sparse, "compiled"): + f = sparse.compiled(f) + f(x, y) @benchmark @@ -101,6 +112,9 @@ def test_index_scalar(benchmark, indexing_args): side = x.shape[0] rank = x.ndim + if hasattr(sparse, "compiled"): + operator.getitem = sparse.compiled(operator.getitem) + x[(side // 2,) * rank] # Numba compilation @benchmark @@ -113,6 +127,9 @@ def test_index_slice(benchmark, indexing_args): side = x.shape[0] rank = x.ndim + if hasattr(sparse, "compiled"): + operator.getitem = sparse.compiled(operator.getitem) + x[(slice(side // 2),) * rank] # Numba compilation @benchmark @@ -126,6 +143,9 @@ def test_index_fancy(benchmark, indexing_args, seed): rng = np.random.default_rng(seed=seed) index = rng.integers(0, side, size=(side // 2,)) + if hasattr(sparse, "compiled"): + operator.getitem = sparse.compiled(operator.getitem) + x[index] # Numba compilation @benchmark @@ -165,6 +185,9 @@ def densemul_args(request, sides, seed, max_size): def test_gcxs_dot_ndarray(benchmark, densemul_args): x, t = densemul_args + if hasattr(sparse, "compiled"): + operator.matmul = sparse.compiled(operator.matmul) + # Numba compilation x @ t