code: def test_triangular_solve(batch_shape, m, n):
      import torch
  
      b = torch.randn(batch_shape + (n, m))
      L = torch.randn(batch_shape + (n, n)).tril_()
      L.diagonal(dim1=-2, dim2=-1).abs_().add_(0.2)
      U = L.transpose(-1, -2)
  
      actual = ops.triangular_solve(b, L, upper=False)
      expected = torch.linalg.solve_triangular(L, b, upper=False)
      assert_close(actual, expected)
      assert_close(L @ actual, b, atol=1e-4, rtol=1e-3)
  
      actual = ops.triangular_solve(b, U, upper=True)
      expected = torch.linalg.solve_triangular(U, b, upper=True)
      assert_close(actual, expected)
      assert_close(U @ actual, b, atol=1e-4, rtol=1e-3)
  
      actual = ops.triangular_solve(b, L, upper=False, transpose=True)
      expected = torch.linalg.solve_triangular(
          L.transpose(-1, -2), b, upper=True
      )
      assert_close(actual, expected)
      assert_close(
          L.transpose(-1, -2) @ actual, b, atol=1e-4, rtol=1e-3
      )
  
      actual = ops.triangular_solve(b, U, upper=True, transpose=True)
      expected = torch.linalg.solve_triangular(
          U.transpose(-1, -2), b, upper=False
      )
      assert_close(actual, expected)
      assert_close(
          U.transpose(-1, -2) @ actual, b, atol=1e-4, rtol=1e-3
      )
  
imports: import pytest
  import funsor.ops
  from funsor.testing import assert_close, requires_backend
label_desc: Use image node_id 1 for calling a global function with example usage: test_triangular_solve(batch_shape, m, n) without return types