//  [python]
def test_norm_dtype(self, device):
        def run_test_case(input_size, ord, keepdim, from_dtype, to_dtype):
            # Determine the best dtype to use for comparisons between tensors
            # of two different types
            def get_compare_dtype(type0, type1):
                types_32bit_based = [torch.float, torch.cfloat]
                is_complex = type0.is_complex or type1.is_complex

                if type0 in types_32bit_based or type1 in types_32bit_based:
                    return torch.cfloat if is_complex else torch.float
                else:
                    return torch.cdouble if is_complex else torch.double

            compare_dtype = get_compare_dtype(from_dtype, to_dtype)

            def get_value_type(dtype):
                if dtype == torch.cfloat:
                    return torch.float
                elif dtype == torch.cdouble:
                    return torch.double
                else:
                    return dtype

            msg = (
                f'input_size={input_size}, ord={ord}, keepdim={keepdim}, '
                f'from_dtype={from_dtype}, to_dtype={to_dtype}')
            input = torch.randn(*input_size, dtype=from_dtype, device=device)
            result = torch.linalg.norm(input, ord, keepdim=keepdim)
            if from_dtype.is_complex:
                # By default, norm downgrades a complex input to the corresponding real number type
                self.assertEqual(result.dtype, get_value_type(from_dtype), msg=msg)
            else:
                self.assertEqual(result.dtype, from_dtype, msg=msg)

            result_out = torch.empty((0), dtype=to_dtype, device=device)
            torch.linalg.norm(input, ord, keepdim=keepdim, out=result_out)
            self.assertEqual(result_out.dtype, to_dtype, msg=msg)
            self.assertEqual(result.to(compare_dtype), result_out.to(compare_dtype), msg=msg)

            result_with_dtype = torch.linalg.norm(input, ord, keepdim=keepdim, dtype=to_dtype)
            self.assertEqual(result_with_dtype.dtype, to_dtype, msg=msg)

            if from_dtype.is_complex:
                result_convert_first = torch.linalg.norm(input.to(to_dtype), ord, keepdim=keepdim)
                self.assertEqual(result_with_dtype.to(compare_dtype), result_convert_first.to(compare_dtype), msg=msg)
            else:
                self.assertEqual(result.to(compare_dtype), result_with_dtype.to(compare_dtype), msg=msg)

            result_out_with_dtype = torch.empty_like(result_with_dtype)
            torch.linalg.norm(input, ord, keepdim=keepdim, dtype=to_dtype, out=result_out_with_dtype)
            self.assertEqual(result_out_with_dtype.dtype, to_dtype, msg=msg)
            self.assertEqual(result_with_dtype, result_out_with_dtype, msg=msg)

        ord_vector = [0, 0.1, -0.1, 1, -1, 2, -2, 3, -3, 4.5, -4.5, inf, -inf, None]
        ord_matrix = ['fro', 'nuc', 1, -1, 2, -2, inf, -inf, None]
        S = 10
        test_cases = [
            ((S, ), ord_vector),
            ((S, S), ord_matrix),
        ]
        for keepdim in [True, False]:
            for input_size, ord_settings in test_cases:
                for ord in ord_settings:
                    if self.device_type == 'cpu' and not torch._C.has_lapack and ord in [2, -2, 'nuc']:
                        continue

                    dtypes = [torch.float, torch.double, torch.cfloat, torch.cdouble]
                    for from_dtype, to_dtype in itertools.product(dtypes, dtypes):
                        if from_dtype.is_complex and not to_dtype.is_complex:
                            continue
                        run_test_case(input_size, ord, keepdim, from_dtype, to_dtype)

        # Make sure that setting dtype != out.dtype raises an error
        dtype_pairs = [
            (torch.float, torch.double),
            (torch.double, torch.float),
            (torch.cfloat, torch.cdouble),
            (torch.cdouble, torch.cfloat),
        ]
        for keepdim in [True, False]:
            for input_size, ord_settings in test_cases:
                for ord in ord_settings:
                    for dtype, out_dtype in dtype_pairs:
                        input = torch.rand(*input_size)
                        result = torch.tensor([]).to(out_dtype)
                        with self.assertRaisesRegex(RuntimeError, r'provided dtype must match dtype of result'):
                            torch.linalg.norm(input, ord=ord, keepdim=keepdim, dtype=dtype, out=result)