//  [python]
def test_solve_errors_and_warnings(self, device, dtype):
        # solve expects batches of square matrices as input
        with self.assertRaisesRegex(RuntimeError, "must be batches of square matrices"):
            a = torch.randn(2, 3, 4, 3, dtype=dtype, device=device)
            b = torch.randn(2, 3, 4, 1, dtype=dtype, device=device)
            torch.linalg.solve(a, b)

        # solve expects compatible shapes for A x = b
        with self.assertRaisesRegex(RuntimeError, "Incompatible matrix sizes"):
            a = torch.randn(2, 3, 3, 3, dtype=dtype, device=device)
            b = torch.randn(2, 3, 2, 1, dtype=dtype, device=device)
            torch.linalg.solve(a, b)

        # if input is not solvable, RuntimeError is raised mentioning the first non-solvable batch
        def run_test_singular_input(batch_dim, n):
            a = torch.eye(3, 3, dtype=dtype, device=device).reshape((1, 3, 3)).repeat(batch_dim, 1, 1)
            a[n, -1, -1] = 0
            b = torch.randn(batch_dim, 3, 1, dtype=dtype, device=device)
            with self.assertRaisesRegex(RuntimeError, rf'For batch {n}: U\(3,3\) is zero'):
                torch.linalg.solve(a, b)

        for params in [(1, 0), (2, 0), (2, 1), (4, 0), (4, 2), (10, 2)]:
            run_test_singular_input(*params)

        # if out tensor with wrong shape is passed a warning is given
        # matrix 'b' case
        with warnings.catch_warnings(record=True) as w:
            A = torch.eye(2, dtype=dtype, device=device).reshape((1, 2, 2)).repeat(2, 1, 1)
            b = torch.randn(2, 2, 2, dtype=dtype, device=device)
            out = torch.zeros(1, dtype=dtype, device=device)
            # Trigger warning
            torch.linalg.solve(A, b, out=out)
            # Check warning occurs
            self.assertEqual(len(w), 1)
            self.assertTrue("An output with one or more elements was resized" in str(w[-1].message))

        # if out tensor with wrong shape is passed a warning is given
        # vector 'b' case
        with warnings.catch_warnings(record=True) as w:
            A = torch.eye(2, dtype=dtype, device=device)
            b = torch.randn(2, dtype=dtype, device=device)
            out = torch.zeros(1, dtype=dtype, device=device)
            # Trigger warning
            torch.linalg.solve(A, b, out=out)
            # Check warning occurs
            self.assertEqual(len(w), 1)
            self.assertTrue("An output with one or more elements was resized" in str(w[-1].message))

        # dtypes should be safely castable
        a = torch.eye(2, dtype=dtype, device=device)
        b = torch.randn(2, 1, dtype=dtype, device=device)
        out = torch.empty(0, dtype=torch.int, device=device)
        with self.assertRaisesRegex(RuntimeError, "but got result with dtype Int"):
            torch.linalg.solve(a, b, out=out)

        # device should match
        if torch.cuda.is_available():
            wrong_device = 'cpu' if self.device_type != 'cpu' else 'cuda'
            out = torch.empty(0, dtype=dtype, device=wrong_device)
            clone_a = torch.empty_like(a)
            with self.assertRaisesRegex(RuntimeError, "tensors to be on the same device"):
                torch.linalg.solve(a, b, out=out)