code: def test_sddmm_sputnik_backward(device):
      contiguous = True
  
      B, L, M, K = 8, 10, 16, 32
      prob = 0.5
      a = torch.rand(B, L, K, device=device, requires_grad=True)
      b = (
          torch.rand(B, M, K, device=device)
          .transpose(-2, -1)
          .requires_grad_(True)
      )
      if not contiguous:
          a = (
              a.detach()
              .transpose(-2, -1)
              .contiguous()
              .transpose(-2, -1)
              .requires_grad_()
          )
          b = (
              b.detach()
              .transpose(-2, -1)
              .contiguous()
              .transpose(-2, -1)
              .requires_grad_()
          )
      mask = _create_random_sparsity(
          torch.ones(B, L, M, dtype=torch.bool, device=device), prob
      )
  
      mask_csr = xformers.components.attention.core.SparseCS(
          mask, device
      )
  
      fn = xformers.components.attention.core._matmul_with_mask
  
      mask = mask.to_sparse()
  
      out_csr = fn(a, b, mask_csr)
      out_csr.values.sum().backward()
      grad_a = a.grad.clone()
      grad_b = b.grad.clone()
      a.grad = None
      b.grad = None
      # fn(a[None], b[None], mask).coalesce().values().sum().backward()  # TODO check why this fails
      fn(a, b, mask).to_dense().sum().backward()
      assert torch.allclose(grad_a, a.grad, atol=1e-7)
      assert torch.allclose(grad_b, b.grad, atol=1e-7)
  
imports: import pytest
  import torch
  import xformers
  import xformers.components.attention.core
  from xformers.components.attention._sputnik_sparse import _csr_to_coo
  from xformers.components.attention.core import _broadcast_batch, _create_random_sparsity, _sparse_bmm
label_desc: Use image node_id 10 for calling a global function with example usage: test_sddmm_sputnik_backward(device) without return types