code: def test_bspmm(create_func, shape, nnz):
      dev = F.ctx()
      A = create_func(shape, nnz, dev, 2)
      X = torch.randn(shape[1], 10, 2, requires_grad=True, device=dev)
      X = rand_stride(X)
  
      sparse_result = matmul(A, X)
      grad = torch.randn_like(sparse_result)
      sparse_result.backward(grad)
  
      XX = clone_detach_and_grad(X)
      torch_A = A.to_dense().clone().detach().requires_grad_()
      torch_result = torch_A.permute(2, 0, 1) @ XX.permute(2, 0, 1)
  
      torch_result.backward(grad.permute(2, 0, 1))
      assert torch.allclose(
          sparse_result.permute(2, 0, 1), torch_result, atol=1e-05
      )
      assert torch.allclose(X.grad, XX.grad, atol=1e-05)
      assert torch.allclose(
          dense_mask(torch_A.grad, A),
          sparse_matrix_to_dense(val_like(A, A.val.grad)),
          atol=1e-05,
      )
  
file_path: dgl/tests/python/pytorch/sparse/test_matmul.py
imports: import warnings
  import backend
  import pytest
  import torch
  from dgl.sparse import bspmm, diag, from_coo, val_like
  from dgl.sparse.matmul import matmul
  from .utils import clone_detach_and_grad, dense_mask, rand_coo, rand_csc, rand_csr, rand_stride, sparse_matrix_to_dense, sparse_matrix_to_torch_sparse
label_desc: Use image node_id 3 for calling a global function with example usage: test_bspmm(create_func, shape, nnz) without return types