From f7f499eb173cd9820cf3b054d06d6472ad5e115b Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Thu, 20 Jun 2024 10:47:55 +0800 Subject: [PATCH 01/35] fixed the potentially wrong namedtuple definitions in the svd backend functions, update the docstring of ivy.svd to mention the change of content of return when compute_uv is False, update svd's torch backend to only compute the necessary second component to be more efficient and the relevant docstring in ivy.svd as well --- ivy/functional/backends/jax/linear_algebra.py | 2 +- ivy/functional/backends/numpy/linear_algebra.py | 2 +- ivy/functional/backends/paddle/linear_algebra.py | 2 +- ivy/functional/backends/tensorflow/linear_algebra.py | 3 +-- ivy/functional/backends/torch/linear_algebra.py | 9 +++------ ivy/functional/ivy/linear_algebra.py | 5 +---- 6 files changed, 8 insertions(+), 15 deletions(-) diff --git a/ivy/functional/backends/jax/linear_algebra.py b/ivy/functional/backends/jax/linear_algebra.py index d7b5c55cc9d9a..281ad7eb30315 100644 --- a/ivy/functional/backends/jax/linear_algebra.py +++ b/ivy/functional/backends/jax/linear_algebra.py @@ -361,7 +361,7 @@ def svd( x: JaxArray, /, *, compute_uv: bool = True, full_matrices: bool = True ) -> Union[JaxArray, Tuple[JaxArray, ...]]: if compute_uv: - results = namedtuple("svd", "U S Vh") + results = namedtuple("svd", ['U', 'S', 'Vh']) U, D, VT = jnp.linalg.svd(x, full_matrices=full_matrices, compute_uv=compute_uv) return results(U, D, VT) else: diff --git a/ivy/functional/backends/numpy/linear_algebra.py b/ivy/functional/backends/numpy/linear_algebra.py index 20424a1da7ec5..50691e06cfac4 100644 --- a/ivy/functional/backends/numpy/linear_algebra.py +++ b/ivy/functional/backends/numpy/linear_algebra.py @@ -291,7 +291,7 @@ def svd( x: np.ndarray, /, *, compute_uv: bool = True, full_matrices: bool = True ) -> Union[np.ndarray, Tuple[np.ndarray, ...]]: if compute_uv: - results = namedtuple("svd", "U S Vh") + results = namedtuple("svd", ['U', 'S', 'Vh']) U, D, VT = np.linalg.svd(x, full_matrices=full_matrices, compute_uv=compute_uv) return results(U, D, VT) else: diff --git a/ivy/functional/backends/paddle/linear_algebra.py b/ivy/functional/backends/paddle/linear_algebra.py index 1a037d570f32a..16cdce79c1a0b 100644 --- a/ivy/functional/backends/paddle/linear_algebra.py +++ b/ivy/functional/backends/paddle/linear_algebra.py @@ -521,7 +521,7 @@ def svd( ) -> Union[paddle.Tensor, Tuple[paddle.Tensor, ...]]: ret = paddle.linalg.svd(x, full_matrices=full_matrices) if compute_uv: - results = namedtuple("svd", "U S Vh") + results = namedtuple("svd", ['U', 'S', 'Vh']) return results(*ret) else: results = namedtuple("svd", "S") diff --git a/ivy/functional/backends/tensorflow/linear_algebra.py b/ivy/functional/backends/tensorflow/linear_algebra.py index ca8c412a1149b..39ff8647f1d8f 100644 --- a/ivy/functional/backends/tensorflow/linear_algebra.py +++ b/ivy/functional/backends/tensorflow/linear_algebra.py @@ -545,8 +545,7 @@ def svd( compute_uv: bool = True, ) -> Union[Union[tf.Tensor, tf.Variable], Tuple[Union[tf.Tensor, tf.Variable], ...]]: if compute_uv: - results = namedtuple("svd", "U S Vh") - + results = namedtuple("svd", ['U', 'S', 'Vh']) batch_shape = tf.shape(x)[:-2] num_batch_dims = len(batch_shape) transpose_dims = list(range(num_batch_dims)) + [ diff --git a/ivy/functional/backends/torch/linear_algebra.py b/ivy/functional/backends/torch/linear_algebra.py index e8d960d313b37..752d7b42c0959 100644 --- a/ivy/functional/backends/torch/linear_algebra.py +++ b/ivy/functional/backends/torch/linear_algebra.py @@ -414,16 +414,13 @@ def svd( x: torch.Tensor, /, *, full_matrices: bool = True, compute_uv: bool = True ) -> Union[torch.Tensor, Tuple[torch.Tensor, ...]]: if compute_uv: - results = namedtuple("svd", "U S Vh") - + results = namedtuple("svd", ['U', 'S', 'Vh']) U, D, VT = torch.linalg.svd(x, full_matrices=full_matrices) return results(U, D, VT) else: results = namedtuple("svd", "S") - svd = torch.linalg.svd(x, full_matrices=full_matrices) - # torch.linalg.svd returns a tuple with U, S, and Vh - D = svd[1] - return results(D) + s = torch.linalg.svdvals(x) + return results(s) @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, backend_version) diff --git a/ivy/functional/ivy/linear_algebra.py b/ivy/functional/ivy/linear_algebra.py index 4c61f9fdbbaa0..1c9febe327ad5 100644 --- a/ivy/functional/ivy/linear_algebra.py +++ b/ivy/functional/ivy/linear_algebra.py @@ -2130,15 +2130,12 @@ def svd( If ``True`` then left and right singular vectors will be computed and returned in ``U`` and ``Vh``, respectively. Otherwise, only the singular values will be computed, which can be significantly faster. - .. note:: - with backend set as torch, svd with still compute left and right singular - vectors irrespective of the value of compute_uv, however Ivy will still - only return the singular values. Returns ------- .. note:: once complex numbers are supported, each square matrix must be Hermitian. + In addition, the return will be a namedtuple ``(S)`` when compute_uv is ``False`` ret a namedtuple ``(U, S, Vh)`` whose From 3db7f17dfb0ca3c33bae9b982ee150af56f93bbb Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Thu, 20 Jun 2024 10:53:58 +0800 Subject: [PATCH 02/35] try to fix the blas_and_lapack_ops.py.svd with correct output namedtuple definition and behavior when compute_uv is false --- .../frontends/torch/blas_and_lapack_ops.py | 14 ++++++++++---- ivy/functional/frontends/torch/linalg.py | 7 +++++-- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/ivy/functional/frontends/torch/blas_and_lapack_ops.py b/ivy/functional/frontends/torch/blas_and_lapack_ops.py index a1c8cd9bbe77b..c114b67e293ce 100644 --- a/ivy/functional/frontends/torch/blas_and_lapack_ops.py +++ b/ivy/functional/frontends/torch/blas_and_lapack_ops.py @@ -2,6 +2,7 @@ import ivy from ivy.func_wrapper import with_unsupported_dtypes import ivy.functional.frontends.torch as torch_frontend +from collections import namedtuple from ivy.functional.frontends.torch.func_wrapper import to_ivy_arrays_and_back @@ -191,11 +192,16 @@ def slogdet(A, *, out=None): @to_ivy_arrays_and_back def svd(input, some=True, compute_uv=True, *, out=None): - # TODO: add compute_uv - if some: - ret = ivy.svd(input, full_matrices=False) + # TODO: add handling for driver + ret = ivy.svd(input, full_matrices=not some, compute_uv=compute_uv) + results = namedtuple("svd", ['U', 'S', 'V']) + if compute_uv: + ret = results(ret.U, ret.S, ret.Vh.mH) else: - ret = ivy.svd(input, full_matrices=True) + shape = input.shape + m = shape[-2] + n = shape[-1] + ret = results(ivy.zeros((m,m)), ret.S, ivy.zeros((n,n))) # TODO: keep the zeros on same device as input if ivy.exists(out): return ivy.inplace_update(out, ret) return ret diff --git a/ivy/functional/frontends/torch/linalg.py b/ivy/functional/frontends/torch/linalg.py index 3df44b0ae3fa7..7b6ae985ee102 100644 --- a/ivy/functional/frontends/torch/linalg.py +++ b/ivy/functional/frontends/torch/linalg.py @@ -326,8 +326,11 @@ def solve_ex(A, B, *, left=True, check_errors=False, out=None): {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) def svd(A, /, *, full_matrices=True, driver=None, out=None): - # TODO: add handling for driver and out - return ivy.svd(A, compute_uv=True, full_matrices=full_matrices) + # TODO: add handling for driver + ret = ivy.svd(A, compute_uv=True, full_matrices=full_matrices) + if ivy.exists(out): + return ivy.inplace_update(out, ret) + return ret @to_ivy_arrays_and_back From 46d180a07670a3edc21e280efef55a1e582efcf2 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Thu, 20 Jun 2024 15:09:18 +0800 Subject: [PATCH 03/35] try to fix the blas_and_lapack_ops.py.svd with correct output namedtuple definition and behavior when compute_uv is false --- ivy/functional/frontends/torch/blas_and_lapack_ops.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/functional/frontends/torch/blas_and_lapack_ops.py b/ivy/functional/frontends/torch/blas_and_lapack_ops.py index c114b67e293ce..074a1a62a75a5 100644 --- a/ivy/functional/frontends/torch/blas_and_lapack_ops.py +++ b/ivy/functional/frontends/torch/blas_and_lapack_ops.py @@ -201,7 +201,7 @@ def svd(input, some=True, compute_uv=True, *, out=None): shape = input.shape m = shape[-2] n = shape[-1] - ret = results(ivy.zeros((m,m)), ret.S, ivy.zeros((n,n))) # TODO: keep the zeros on same device as input + ret = results(ivy.zeros((m,m), device=input.device), ret.S, ivy.zeros((n,n), device=input.device)) if ivy.exists(out): return ivy.inplace_update(out, ret) return ret From dce10a65abb1d694fb051d12057af2a3183aff33 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Sun, 30 Jun 2024 18:46:34 +0800 Subject: [PATCH 04/35] replace the unimplemented tensor.mH used to the implemented adjoint, fixed the wrong shape and dtype of return. Now there are somehow numerial difference between return of groundtruth torch.svd and ivy.svd --- .../frontends/torch/blas_and_lapack_ops.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/ivy/functional/frontends/torch/blas_and_lapack_ops.py b/ivy/functional/frontends/torch/blas_and_lapack_ops.py index 074a1a62a75a5..7100d79330090 100644 --- a/ivy/functional/frontends/torch/blas_and_lapack_ops.py +++ b/ivy/functional/frontends/torch/blas_and_lapack_ops.py @@ -193,15 +193,17 @@ def slogdet(A, *, out=None): @to_ivy_arrays_and_back def svd(input, some=True, compute_uv=True, *, out=None): # TODO: add handling for driver - ret = ivy.svd(input, full_matrices=not some, compute_uv=compute_uv) + retu = ivy.svd(input, full_matrices=not some, compute_uv=compute_uv) results = namedtuple("svd", ['U', 'S', 'V']) if compute_uv: - ret = results(ret.U, ret.S, ret.Vh.mH) + ret = results(retu[0], retu[1], ivy.adjoint(retu[2])) else: - shape = input.shape - m = shape[-2] - n = shape[-1] - ret = results(ivy.zeros((m,m), device=input.device), ret.S, ivy.zeros((n,n), device=input.device)) + shape = list(input.shape) + shape1 = shape + shape2 = shape + shape1[-2] = shape[-1] + shape2[-1] = shape[-2] + ret = results(ivy.zeros(shape1, device=input.device, dtype=input.dtype), retu[0], ivy.zeros(shape2, device=input.device, dtype=input.dtype)) if ivy.exists(out): return ivy.inplace_update(out, ret) return ret From 0c13ce6d1d8f1282022c0d777ef59ec486246962 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Wed, 3 Jul 2024 13:49:51 +0800 Subject: [PATCH 05/35] update test of torch.blas_and_lapack_ops.svd to calculate the validity of result instead of matching values --- .../frontends/torch/blas_and_lapack_ops.py | 1 - .../test_torch/test_blas_and_lapack_ops.py | 70 ++++++++++++++----- 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/ivy/functional/frontends/torch/blas_and_lapack_ops.py b/ivy/functional/frontends/torch/blas_and_lapack_ops.py index 7100d79330090..72fc1c415b899 100644 --- a/ivy/functional/frontends/torch/blas_and_lapack_ops.py +++ b/ivy/functional/frontends/torch/blas_and_lapack_ops.py @@ -192,7 +192,6 @@ def slogdet(A, *, out=None): @to_ivy_arrays_and_back def svd(input, some=True, compute_uv=True, *, out=None): - # TODO: add handling for driver retu = ivy.svd(input, full_matrices=not some, compute_uv=compute_uv) results = namedtuple("svd", ['U', 'S', 'V']) if compute_uv: diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py index f66853869c8e4..daa6b8cbbd592 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py @@ -848,11 +848,10 @@ def test_torch_qr( @handle_frontend_test( fn_tree="torch.svd", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float", index=1), - min_num_dims=3, - max_num_dims=5, - min_dim_size=2, - max_dim_size=5, + available_dtypes=helpers.get_dtypes("float"), + min_value=0, + max_value=10, + shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), ), some=st.booleans(), compute=st.booleans(), @@ -860,25 +859,58 @@ def test_torch_qr( def test_torch_svd( dtype_and_x, some, - compute, - on_device, - fn_tree, + compute_uv, frontend, - test_flags, backend_fw, + frontend_method_data, + init_flags, + method_flags, + on_device, ): - dtype, x = dtype_and_x - helpers.test_frontend_function( - input_dtypes=dtype, - backend_to_test=backend_fw, + input_dtype, x = dtype_and_x + x = np.asarray(x[0], dtype=input_dtype[0]) + + ret, frontend_ret = helpers.test_frontend_method( + init_input_dtypes=input_dtype, + init_all_as_kwargs_np={ + "data": x, + }, + method_input_dtypes=input_dtype, + method_all_as_kwargs_np={ + "some": some, + "compute_uv": compute_uv, + }, + frontend_method_data=frontend_method_data, + init_flags=init_flags, + method_flags=method_flags, frontend=frontend, - test_flags=test_flags, - fn_tree=fn_tree, + backend_to_test=backend_fw, on_device=on_device, - input=x[0], - some=some, - compute_uv=compute, - ) + test_values=False, + ) + with helpers.update_backend(backend_fw) as ivy_backend: + ret = [ivy_backend.to_numpy(x) for x in ret] + frontend_ret = [np.asarray(x) for x in frontend_ret] + + u, s, v = ret + frontend_u, frontend_s, frontend_v = frontend_ret + + if compute_uv: + helpers.assert_all_close( + ret_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, + ret_from_gt_np=u @ np.diag(s) @ v.T, + atol=1e-04, + backend=backend_fw, + ground_truth_backend=frontend, + ) + else: + helpers.assert_all_close( + ret_np=frontend_s, + ret_from_gt_np=s, + atol=1e-04, + backend=backend_fw, + ground_truth_backend=frontend, + ) @handle_frontend_test( From 4d0851d1da638ef08db97b52e40ded7795ce31e7 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Wed, 3 Jul 2024 14:08:36 +0800 Subject: [PATCH 06/35] small fix --- .../test_torch/test_blas_and_lapack_ops.py | 35 ++++++++----------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py index daa6b8cbbd592..9baac0f92469d 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py @@ -4,6 +4,7 @@ from hypothesis import strategies as st, assume # local +import ivy import ivy_tests.test_ivy.helpers as helpers from ivy_tests.test_ivy.helpers import handle_frontend_test from ivy_tests.test_ivy.helpers.hypothesis_helpers.general_helpers import ( @@ -854,42 +855,34 @@ def test_torch_qr( shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), ), some=st.booleans(), - compute=st.booleans(), + compute_uv=st.booleans(), ) def test_torch_svd( dtype_and_x, some, compute_uv, frontend, + test_flags, + fn_tree, backend_fw, - frontend_method_data, - init_flags, - method_flags, on_device, ): input_dtype, x = dtype_and_x x = np.asarray(x[0], dtype=input_dtype[0]) - - ret, frontend_ret = helpers.test_frontend_method( - init_input_dtypes=input_dtype, - init_all_as_kwargs_np={ - "data": x, - }, - method_input_dtypes=input_dtype, - method_all_as_kwargs_np={ - "some": some, - "compute_uv": compute_uv, - }, - frontend_method_data=frontend_method_data, - init_flags=init_flags, - method_flags=method_flags, - frontend=frontend, + # make symmetric positive definite beforehand + x = np.matmul(x.T, x) + np.identity(x.shape[0]) * 1e-3 + ret, frontend_ret = helpers.test_frontend_function( + input_dtypes=input_dtype, backend_to_test=backend_fw, + frontend=frontend, + test_flags=test_flags, + fn_tree=fn_tree, on_device=on_device, test_values=False, + some=some, + compute_uv=compute_uv, ) - with helpers.update_backend(backend_fw) as ivy_backend: - ret = [ivy_backend.to_numpy(x) for x in ret] + ret = [ivy.to_numpy(x) for x in ret] frontend_ret = [np.asarray(x) for x in frontend_ret] u, s, v = ret From 3b3670fb14a37d7dc009b05b210213f778726e91 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Wed, 3 Jul 2024 15:31:01 +0800 Subject: [PATCH 07/35] small fix --- .../test_frontends/test_torch/test_blas_and_lapack_ops.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py index 9baac0f92469d..d86a0cc937d64 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py @@ -879,6 +879,7 @@ def test_torch_svd( fn_tree=fn_tree, on_device=on_device, test_values=False, + input = x, some=some, compute_uv=compute_uv, ) From 71fed6bd9ab0c5ef7d8fcc4a193cdc9016e5ff2c Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Wed, 3 Jul 2024 16:27:00 +0800 Subject: [PATCH 08/35] updated the test for torch.linalg.svd --- .../test_frontends/test_torch/test_linalg.py | 37 +++++++++++++------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py index 3fe907273c191..7fae4e9765fda 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py @@ -1247,7 +1247,15 @@ def test_torch_solve_ex( # svd @handle_frontend_test( fn_tree="torch.linalg.svd", - dtype_and_x=_get_dtype_and_matrix(square=True), + dtype_and_x=helpers.dtype_and_values( + available_dtypes=helpers.get_dtypes("float"), + min_value=0, + max_value=10, + min_num_dims=2, + max_num_dims=5, + min_dim_size=1, + max_dim_size=5, + ), full_matrices=st.booleans(), ) def test_torch_svd( @@ -1272,25 +1280,30 @@ def test_torch_svd( fn_tree=fn_tree, on_device=on_device, test_values=False, - atol=1e-03, - rtol=1e-05, A=x, full_matrices=full_matrices, ) ret = [ivy.to_numpy(x) for x in ret] frontend_ret = [np.asarray(x) for x in frontend_ret] - u, s, vh = ret frontend_u, frontend_s, frontend_vh = frontend_ret + if full_matrices: + helpers.assert_all_close( + ret_np=frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_vh.T, + ret_from_gt_np=u[...,:s.shape[0]] @ np.diag(s) @ vh.T, + atol=1e-04, + backend=backend_fw, + ground_truth_backend=frontend, + ) + else: + helpers.assert_all_close( + ret_np=frontend_u @ np.diag(frontend_s) @ frontend_vh.T, + ret_from_gt_np=u @ np.diag(s) @ vh.T, + atol=1e-04, + backend=backend_fw, + ground_truth_backend=frontend, + ) - assert_all_close( - ret_np=u @ np.diag(s) @ vh, - ret_from_gt_np=frontend_u @ np.diag(frontend_s) @ frontend_vh, - rtol=1e-2, - atol=1e-2, - ground_truth_backend=frontend, - backend=backend_fw, - ) # svdvals From 3fdf4dda9886624fd355bd6086adf5b8f29d728a Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Wed, 3 Jul 2024 18:14:34 +0800 Subject: [PATCH 09/35] find that jax.lax.linalg.svd has a argument "subset_by_index" missing --- ivy/functional/frontends/jax/lax/linalg.py | 10 +++++++--- .../test_jax/test_lax/test_linalg.py | 15 ++++++++------- .../test_torch/test_blas_and_lapack_ops.py | 5 +++-- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/ivy/functional/frontends/jax/lax/linalg.py b/ivy/functional/frontends/jax/lax/linalg.py index a48964c859054..d48cac8a85911 100644 --- a/ivy/functional/frontends/jax/lax/linalg.py +++ b/ivy/functional/frontends/jax/lax/linalg.py @@ -44,7 +44,11 @@ def qr(x, /, *, full_matrices=False): @to_ivy_arrays_and_back -def svd(x, /, *, full_matrices=True, compute_uv=True): - if not compute_uv: +@with_unsupported_dtypes({"0.4.14 and below": ("bfloat16",)}, "jax") +def svd(x, /, *, full_matrices=True, compute_uv=True, subset_by_index=None): + #TODO: handle subset_by_index + if compute_uv: + return tuple(ivy.svd(x, full_matrices=full_matrices)) + else: return ivy.svdvals(x) - return ivy.svd(x, full_matrices=full_matrices) + diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py index 789512cb08421..74501eca12a5f 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py @@ -161,19 +161,18 @@ def test_jax_qr( # svd @handle_frontend_test( fn_tree="jax.lax.linalg.svd", - dtype_and_x=helpers.dtype_and_values( + dtype_x=helpers.dtype_and_values( available_dtypes=helpers.get_dtypes("float"), min_value=0, max_value=10, - shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), - ).filter( - lambda x: "float16" not in x[0] - and "bfloat16" not in x[0] - and np.linalg.cond(x[1][0]) < 1 / sys.float_info.epsilon - and np.linalg.det(np.asarray(x[1][0])) != 0 + min_num_dims=2, + max_num_dims=5, ), full_matrices=st.booleans(), compute_uv=st.booleans(), + index=st.one_of( + st.none(), st.tuples(st.integers(min_value=0, max_value=3), st.integers(min_value=3, max_value=5)) + ), test_with_out=st.just(False), ) def test_jax_svd( @@ -181,6 +180,7 @@ def test_jax_svd( dtype_and_x, full_matrices, compute_uv, + index, on_device, fn_tree, frontend, @@ -203,6 +203,7 @@ def test_jax_svd( x=x, full_matrices=full_matrices, compute_uv=compute_uv, + subset_by_index=index, ) if compute_uv: diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py index d86a0cc937d64..68493f0e4e19e 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py @@ -852,7 +852,8 @@ def test_torch_qr( available_dtypes=helpers.get_dtypes("float"), min_value=0, max_value=10, - shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), + min_num_dims = 2, + max_num_dims = 5, ), some=st.booleans(), compute_uv=st.booleans(), @@ -883,7 +884,7 @@ def test_torch_svd( some=some, compute_uv=compute_uv, ) - ret = [ivy.to_numpy(x) for x in ret] + ret = [np.asarray(x) for x in ret] frontend_ret = [np.asarray(x) for x in frontend_ret] u, s, v = ret From c5b59045351f645c1e9d50ed16d2f4564fe8fd28 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Wed, 3 Jul 2024 22:14:48 +0800 Subject: [PATCH 10/35] fixed the skipping torch svd tests according to suggestion, no longer skipping --- .../frontends/torch/blas_and_lapack_ops.py | 2 +- .../test_torch/test_blas_and_lapack_ops.py | 12 ++++++------ .../test_frontends/test_torch/test_linalg.py | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/ivy/functional/frontends/torch/blas_and_lapack_ops.py b/ivy/functional/frontends/torch/blas_and_lapack_ops.py index 72fc1c415b899..47249630a8c58 100644 --- a/ivy/functional/frontends/torch/blas_and_lapack_ops.py +++ b/ivy/functional/frontends/torch/blas_and_lapack_ops.py @@ -202,7 +202,7 @@ def svd(input, some=True, compute_uv=True, *, out=None): shape2 = shape shape1[-2] = shape[-1] shape2[-1] = shape[-2] - ret = results(ivy.zeros(shape1, device=input.device, dtype=input.dtype), retu[0], ivy.zeros(shape2, device=input.device, dtype=input.dtype)) + ret = results(ivy.zeros(shape1, device=input.device, dtype=input.dtype), ivy.astype(retu[0], input.dtype), ivy.zeros(shape2, device=input.device, dtype=input.dtype)) if ivy.exists(out): return ivy.inplace_update(out, ret) return ret diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py index 68493f0e4e19e..fa75313a9d24d 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py @@ -870,7 +870,7 @@ def test_torch_svd( ): input_dtype, x = dtype_and_x x = np.asarray(x[0], dtype=input_dtype[0]) - # make symmetric positive definite beforehand + # make symmetric positive definite x = np.matmul(x.T, x) + np.identity(x.shape[0]) * 1e-3 ret, frontend_ret = helpers.test_frontend_function( input_dtypes=input_dtype, @@ -890,18 +890,18 @@ def test_torch_svd( u, s, v = ret frontend_u, frontend_s, frontend_v = frontend_ret - if compute_uv: + if not some: helpers.assert_all_close( - ret_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, - ret_from_gt_np=u @ np.diag(s) @ v.T, + ret_np=np.asarray(frontend_u @ np.diag(frontend_s) @ frontend_v.T, dtype=np.float32), + ret_from_gt_np=np.asarray(u @ np.diag(s) @ v.T, dtype=np.float32), atol=1e-04, backend=backend_fw, ground_truth_backend=frontend, ) else: helpers.assert_all_close( - ret_np=frontend_s, - ret_from_gt_np=s, + ret_np=np.asarray(frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_v.T, dtype=np.float32), + ret_from_gt_np=np.asarray(u[...,:s.shape[0]] @ np.diag(s) @ v.T, dtype=np.float32), atol=1e-04, backend=backend_fw, ground_truth_backend=frontend, diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py index 7fae4e9765fda..f8310c28c310e 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py @@ -1270,7 +1270,7 @@ def test_torch_svd( ): dtype, x = dtype_and_x x = np.asarray(x[0], dtype=dtype[0]) - # make symmetric positive definite beforehand + # make symmetric positive definite x = np.matmul(x.T, x) + np.identity(x.shape[0]) * 1e-3 ret, frontend_ret = helpers.test_frontend_function( input_dtypes=dtype, @@ -1283,22 +1283,22 @@ def test_torch_svd( A=x, full_matrices=full_matrices, ) - ret = [ivy.to_numpy(x) for x in ret] + ret = [np.asarray(x) for x in ret] frontend_ret = [np.asarray(x) for x in frontend_ret] u, s, vh = ret frontend_u, frontend_s, frontend_vh = frontend_ret if full_matrices: helpers.assert_all_close( - ret_np=frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_vh.T, - ret_from_gt_np=u[...,:s.shape[0]] @ np.diag(s) @ vh.T, + ret_np=np.asarray(frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_vh, dtype=np.float32), + ret_from_gt_np=np.asarray(u[...,:s.shape[0]] @ np.diag(s) @ vh, dtype=np.float32), atol=1e-04, backend=backend_fw, ground_truth_backend=frontend, ) else: helpers.assert_all_close( - ret_np=frontend_u @ np.diag(frontend_s) @ frontend_vh.T, - ret_from_gt_np=u @ np.diag(s) @ vh.T, + ret_np=np.asarray(frontend_u @ np.diag(frontend_s) @ frontend_vh, dtype=np.float32), + ret_from_gt_np=np.asarray(u @ np.diag(s) @ vh, dtype=np.float32), atol=1e-04, backend=backend_fw, ground_truth_backend=frontend, From efe9a5ae405a6b9bd9e494617e78aa07e7099cf7 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Thu, 4 Jul 2024 10:17:00 +0800 Subject: [PATCH 11/35] tests are partially passing, though for torch backend, "RuntimeError: Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead. " happen --- .../test_jax/test_lax/test_linalg.py | 18 ++++++++---------- .../test_jax/test_numpy/test_linalg.py | 3 +-- .../test_linalg/test_decompositions.py | 5 ++--- .../test_tensorflow/test_linalg.py | 3 ++- .../test_tensorflow/test_raw_ops.py | 3 ++- .../test_torch/test_blas_and_lapack_ops.py | 3 +-- .../test_frontends/test_torch/test_linalg.py | 5 +---- .../test_frontends/test_torch/test_tensor.py | 7 ++++--- 8 files changed, 21 insertions(+), 26 deletions(-) diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py index 74501eca12a5f..718ed905105a5 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py @@ -159,6 +159,7 @@ def test_jax_qr( # svd +# TODO: implement proper drawing of index parameter @handle_frontend_test( fn_tree="jax.lax.linalg.svd", dtype_x=helpers.dtype_and_values( @@ -189,7 +190,7 @@ def test_jax_svd( ): dtype, x = dtype_and_x x = np.asarray(x[0], dtype=dtype[0]) - # make symmetric positive-definite beforehand + # make symmetric positive-definite x = np.matmul(x.T, x) + np.identity(x.shape[0]) * 1e-3 ret, frontend_ret = helpers.test_frontend_function( @@ -205,18 +206,15 @@ def test_jax_svd( compute_uv=compute_uv, subset_by_index=index, ) - + ret = [np.asarray(x) for x in ret] + frontend_ret = [np.asarray(x) for x in frontend_ret] if compute_uv: - with BackendHandler.update_backend(backend_fw) as ivy_backend: - ret = [ivy_backend.to_numpy(x) for x in ret] - frontend_ret = [np.asarray(x) for x in frontend_ret] - - u, s, vh = ret - frontend_u, frontend_s, frontend_vh = frontend_ret + u, s, v = ret + frontend_u, frontend_s, frontend_v = frontend_ret assert_all_close( - ret_np=u @ np.diag(s) @ vh, - ret_from_gt_np=frontend_u @ np.diag(frontend_s) @ frontend_vh, + ret_np=u @ np.diag(s) @ v.T, + ret_from_gt_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, rtol=1e-2, atol=1e-2, backend=backend_fw, diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py index fb081e1cd406a..a5510c8ab68d1 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py @@ -881,9 +881,8 @@ def test_jax_svd( ): dtype, x = dtype_and_x x = np.asarray(x[0], dtype=dtype[0]) - # make symmetric positive-definite beforehand + # make symmetric positive-definite x = np.matmul(x.T, x) + np.identity(x.shape[0]) * 1e-3 - ret, frontend_ret = helpers.test_frontend_function( input_dtypes=dtype, frontend=frontend, diff --git a/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py b/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py index f740b7278dacb..bf75c1359b3ae 100644 --- a/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py +++ b/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py @@ -105,9 +105,8 @@ def test_numpy_svd( ): dtype, x = dtype_and_x x = x[0] - x = ( - np.matmul(x.T, x) + np.identity(x.shape[0]) * 1e-3 - ) # make symmetric positive-definite + # make symmetric positive-definite + x = np.matmul(x.T, x) + np.identity(x.shape[0]) * 1e-3 ret, ret_gt = helpers.test_frontend_function( input_dtypes=dtype, backend_to_test=backend_fw, diff --git a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py index 24e4d61344997..882e886e8bf02 100644 --- a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py @@ -1070,6 +1070,7 @@ def test_tensorflow_solve( ) +# svd @handle_frontend_test( fn_tree="tensorflow.linalg.svd", dtype_and_x=helpers.dtype_and_values( @@ -1094,7 +1095,7 @@ def test_tensorflow_svd( ): dtype, x = dtype_and_x x = np.asarray(x[0], dtype=dtype[0]) - # make symmetric positive definite beforehand + # make symmetric positive definite x = np.matmul(x.T, x) + np.identity(x.shape[0]) * 1e-3 ret, frontend_ret = helpers.test_frontend_function( input_dtypes=dtype, diff --git a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py index ad9b5ee4f3114..d82fc291df272 100644 --- a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py @@ -4267,6 +4267,7 @@ def test_tensorflow_Sum( # NOQA ) +# svd @handle_frontend_test( fn_tree="tensorflow.raw_ops.Svd", dtype_and_x=helpers.dtype_and_values( @@ -4291,7 +4292,7 @@ def test_tensorflow_Svd( ): dtype, x = dtype_and_x x = np.asarray(x[0], dtype=dtype[0]) - # make symmetric positive definite beforehand + # make symmetric positive definite x = np.matmul(x.T, x) + np.identity(x.shape[0]) * 1e-3 ret, frontend_ret = helpers.test_frontend_function( input_dtypes=dtype, diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py index fa75313a9d24d..7ec03a6e822b1 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py @@ -852,8 +852,7 @@ def test_torch_qr( available_dtypes=helpers.get_dtypes("float"), min_value=0, max_value=10, - min_num_dims = 2, - max_num_dims = 5, + shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), ), some=st.booleans(), compute_uv=st.booleans(), diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py index f8310c28c310e..2d2cd71104f2e 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py @@ -1251,10 +1251,7 @@ def test_torch_solve_ex( available_dtypes=helpers.get_dtypes("float"), min_value=0, max_value=10, - min_num_dims=2, - max_num_dims=5, - min_dim_size=1, - max_dim_size=5, + shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), ), full_matrices=st.booleans(), ) diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py index 10a8b3385fbf3..0029cfa3ca583 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py @@ -12866,6 +12866,7 @@ def test_torch_sum( ) +# svd @handle_frontend_method( class_tree=CLASS_TREE, init_tree="torch.tensor", @@ -12892,7 +12893,8 @@ def test_torch_svd( ): input_dtype, x = dtype_and_x x = np.asarray(x[0], dtype=input_dtype[0]) - + # make symmetric positive-definite + x = np.matmul(x.T, x) + np.identity(x.shape[0]) * 1e-3 ret, frontend_ret = helpers.test_frontend_method( init_input_dtypes=input_dtype, init_all_as_kwargs_np={ @@ -12911,8 +12913,7 @@ def test_torch_svd( on_device=on_device, test_values=False, ) - with helpers.update_backend(backend_fw) as ivy_backend: - ret = [ivy_backend.to_numpy(x) for x in ret] + ret = [np.asarray(x) for x in ret] frontend_ret = [np.asarray(x) for x in frontend_ret] u, s, vh = ret From 26aeba04824609e91c43d1d7fd4dbf77fd648982 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Sun, 7 Jul 2024 14:37:55 +0800 Subject: [PATCH 12/35] fix test of numpy.linalg.decomposition.svd as it returns a svd object instead of the normal tuple and apply the np.asarray(x) change over ivy.as_numpy in other tests, ensure the different return pattern (s,u,v tha u,s,v)from tensorflow and when comput_uv is false get handled in the tests. Now only dtype mismatches happens --- .../frontends/numpy/linalg/decompositions.py | 2 +- .../test_jax/test_lax/test_linalg.py | 8 ++-- .../test_jax/test_numpy/test_linalg.py | 7 +--- .../test_linalg/test_decompositions.py | 39 ++++++++++++------- .../test_tensorflow/test_linalg.py | 35 +++++++++++------ .../test_tensorflow/test_raw_ops.py | 36 ++++++++++------- 6 files changed, 78 insertions(+), 49 deletions(-) diff --git a/ivy/functional/frontends/numpy/linalg/decompositions.py b/ivy/functional/frontends/numpy/linalg/decompositions.py index 0452e9c19a271..24bf8dda890d5 100644 --- a/ivy/functional/frontends/numpy/linalg/decompositions.py +++ b/ivy/functional/frontends/numpy/linalg/decompositions.py @@ -15,5 +15,5 @@ def qr(a, mode="reduced"): @to_ivy_arrays_and_back def svd(a, full_matrices=True, compute_uv=True, hermitian=False): - # Todo: conpute_uv and hermitian handling + # Todo: hermitian handling return ivy.svd(a, full_matrices=full_matrices, compute_uv=compute_uv) diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py index 718ed905105a5..27d4f7f738b09 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py @@ -206,9 +206,9 @@ def test_jax_svd( compute_uv=compute_uv, subset_by_index=index, ) - ret = [np.asarray(x) for x in ret] - frontend_ret = [np.asarray(x) for x in frontend_ret] if compute_uv: + ret = [np.asarray(x) for x in ret] + frontend_ret = [np.asarray(x) for x in frontend_ret] u, s, v = ret frontend_u, frontend_s, frontend_v = frontend_ret @@ -221,11 +221,9 @@ def test_jax_svd( ground_truth_backend=frontend, ) else: - with BackendHandler.update_backend(backend_fw) as ivy_backend: - ret = ivy_backend.to_numpy(ret) assert_all_close( ret_np=ret, - ret_from_gt_np=np.asarray(frontend_ret[0]), + ret_from_gt_np=frontend_ret, rtol=1e-2, atol=1e-2, backend=backend_fw, diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py index a5510c8ab68d1..79ca88fc0456d 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py @@ -897,8 +897,7 @@ def test_jax_svd( ) if compute_uv: - with BackendHandler.update_backend(backend_fw) as ivy_backend: - ret = [ivy_backend.to_numpy(x) for x in ret] + ret = [np.asarray(x) for x in ret] frontend_ret = [np.asarray(x) for x in frontend_ret] u, s, vh = ret @@ -913,11 +912,9 @@ def test_jax_svd( ground_truth_backend=frontend, ) else: - with BackendHandler.update_backend(backend_fw) as ivy_backend: - ret = ivy_backend.to_numpy(ret) assert_all_close( ret_np=ret, - ret_from_gt_np=np.asarray(frontend_ret[0]), + ret_from_gt_np=frontend_ret, rtol=1e-2, atol=1e-2, backend=backend_fw, diff --git a/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py b/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py index bf75c1359b3ae..44a67f6dd00ff 100644 --- a/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py +++ b/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py @@ -4,6 +4,7 @@ from hypothesis import strategies as st # local +import ivy import ivy_tests.test_ivy.helpers as helpers from ivy_tests.test_ivy.helpers import handle_frontend_test, BackendHandler from ivy_tests.test_ivy.test_functional.test_core.test_linalg import ( @@ -81,6 +82,7 @@ def test_numpy_qr( # svd +# Todo: hermitian handling @handle_frontend_test( fn_tree="numpy.linalg.svd", dtype_and_x=helpers.dtype_and_values( @@ -107,7 +109,7 @@ def test_numpy_svd( x = x[0] # make symmetric positive-definite x = np.matmul(x.T, x) + np.identity(x.shape[0]) * 1e-3 - ret, ret_gt = helpers.test_frontend_function( + ret, frontend_ret = helpers.test_frontend_function( input_dtypes=dtype, backend_to_test=backend_fw, frontend=frontend, @@ -119,15 +121,26 @@ def test_numpy_svd( full_matrices=full_matrices, compute_uv=compute_uv, ) - with BackendHandler.update_backend(backend_fw) as ivy_backend: - for u, v in zip(ret, ret_gt): - u = ivy_backend.to_numpy(ivy_backend.abs(u)) - v = ivy_backend.to_numpy(ivy_backend.abs(v)) - helpers.value_test( - ret_np_flat=u, - ret_np_from_gt_flat=v, - rtol=1e-04, - atol=1e-04, - backend=backend_fw, - ground_truth_backend=frontend, - ) + if compute_uv: + ret = [np.asarray(x) for x in ret] + frontend_ret = [np.asarray(x) for x in frontend_ret] + u, s, v = ret + frontend_u, frontend_s, frontend_v = frontend_ret + + helpers.assert_all_close( + ret_np=u @ np.diag(s) @ v.T, + ret_from_gt_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, + rtol=1e-2, + atol=1e-2, + backend=backend_fw, + ground_truth_backend=frontend, + ) + else: + helpers.assert_all_close( + ret_np=ret.S, + ret_from_gt_np=frontend_ret, + rtol=1e-2, + atol=1e-2, + backend=backend_fw, + ground_truth_backend=frontend, + ) diff --git a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py index 882e886e8bf02..3eca73117d088 100644 --- a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py @@ -1111,20 +1111,31 @@ def test_tensorflow_svd( full_matrices=full_matrices, compute_uv=compute_uv, ) - ret = [ivy.to_numpy(x) for x in ret] - frontend_ret = [np.asarray(x) for x in frontend_ret] - u, s, vh = ret - frontend_s, frontend_u, frontend_vh = frontend_ret + if compute_uv: + ret = [np.asarray(x) for x in ret] + frontend_ret = [np.asarray(x) for x in frontend_ret] - assert_all_close( - ret_np=u @ np.diag(s) @ vh, - ret_from_gt_np=frontend_u @ np.diag(frontend_s) @ frontend_vh.T, - rtol=1e-2, - atol=1e-2, - ground_truth_backend=frontend, - backend=backend_fw, - ) + s, u, v = ret + frontend_s, frontend_u, frontend_v = frontend_ret + + assert_all_close( + ret_np=u @ np.diag(s) @ v.T, + ret_from_gt_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, + rtol=1e-2, + atol=1e-2, + backend=backend_fw, + ground_truth_backend=frontend, + ) + else: + assert_all_close( + ret_np=ret, + ret_from_gt_np=frontend_ret, + rtol=1e-2, + atol=1e-2, + backend=backend_fw, + ground_truth_backend=frontend, + ) # tensor_diag diff --git a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py index d82fc291df272..1c634f57fcb9e 100644 --- a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py @@ -4306,20 +4306,30 @@ def test_tensorflow_Svd( full_matrices=full_matrices, compute_uv=compute_uv, ) - ret = [ivy.to_numpy(x) for x in ret] - frontend_ret = [np.asarray(x) for x in frontend_ret] - u, s, vh = ret - frontend_s, frontend_u, frontend_vh = frontend_ret - - assert_all_close( - ret_np=u @ np.diag(s) @ vh, - ret_from_gt_np=frontend_u @ np.diag(frontend_s) @ frontend_vh.T, - rtol=1e-2, - atol=1e-2, - ground_truth_backend=frontend, - backend=backend_fw, - ) + if compute_uv: + ret = [np.asarray(x) for x in ret] + frontend_ret = [np.asarray(x) for x in frontend_ret] + + s, u, v = ret + frontend_s, frontend_u, frontend_v = frontend_ret + assert_all_close( + ret_np=u @ np.diag(s) @ v.T, + ret_from_gt_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, + rtol=1e-2, + atol=1e-2, + backend=backend_fw, + ground_truth_backend=frontend, + ) + else: + assert_all_close( + ret_np=s, + ret_from_gt_np=frontend_s, + rtol=1e-2, + atol=1e-2, + backend=backend_fw, + ground_truth_backend=frontend, + ) # Tan From 3bb5b667b123e8252d21870c06e5dc471edc26ad Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Mon, 15 Jul 2024 09:41:58 +0800 Subject: [PATCH 13/35] now only torch backend of jax.numpy.linalg.svd is failing due to "RuntimeError: Can't call numpy() on Tensor that requires grad. Use tensor.detach().numpy() instead." when the test function calls np.asarray to the returned value --- ivy/functional/frontends/jax/numpy/linalg.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ivy/functional/frontends/jax/numpy/linalg.py b/ivy/functional/frontends/jax/numpy/linalg.py index 57c69ee5b1596..1b978f64f5574 100644 --- a/ivy/functional/frontends/jax/numpy/linalg.py +++ b/ivy/functional/frontends/jax/numpy/linalg.py @@ -121,9 +121,11 @@ def solve(a, b): @to_ivy_arrays_and_back def svd(a, /, *, full_matrices=True, compute_uv=True, hermitian=None): + # TODO: handle hermitian if not compute_uv: - return ivy.svdvals(a) - return ivy.svd(a, full_matrices=full_matrices) + return ivy.svdvals(a).astype(ivy.float64) + ret = ivy.svd(a, full_matrices=full_matrices) + return tuple([ x.astype(ivy.float64) for x in ret]) @to_ivy_arrays_and_back From 8b29eb74597db0b363eef24fccdc89a0c224ae90 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Mon, 15 Jul 2024 13:19:45 +0800 Subject: [PATCH 14/35] all tests for tesnorflow.linalg.svd are passing --- ivy/functional/frontends/jax/numpy/linalg.py | 4 +--- ivy/functional/frontends/tensorflow/linalg.py | 7 ++++++- .../test_frontends/test_tensorflow/test_linalg.py | 8 +++----- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ivy/functional/frontends/jax/numpy/linalg.py b/ivy/functional/frontends/jax/numpy/linalg.py index 1b978f64f5574..79821e417d990 100644 --- a/ivy/functional/frontends/jax/numpy/linalg.py +++ b/ivy/functional/frontends/jax/numpy/linalg.py @@ -122,9 +122,7 @@ def solve(a, b): @to_ivy_arrays_and_back def svd(a, /, *, full_matrices=True, compute_uv=True, hermitian=None): # TODO: handle hermitian - if not compute_uv: - return ivy.svdvals(a).astype(ivy.float64) - ret = ivy.svd(a, full_matrices=full_matrices) + ret = ivy.svd(a, full_matrices=full_matrices, compute_uv=compute_uv) return tuple([ x.astype(ivy.float64) for x in ret]) diff --git a/ivy/functional/frontends/tensorflow/linalg.py b/ivy/functional/frontends/tensorflow/linalg.py index 01a8f293f4497..fe797894f4aef 100644 --- a/ivy/functional/frontends/tensorflow/linalg.py +++ b/ivy/functional/frontends/tensorflow/linalg.py @@ -358,7 +358,12 @@ def solve(matrix, rhs, /, *, adjoint=False, name=None): @to_ivy_arrays_and_back def svd(a, /, *, full_matrices=False, compute_uv=True, name=None): - return ivy.svd(a, compute_uv=compute_uv, full_matrices=full_matrices) + if compute_uv: + svd = ivy.svd(a, compute_uv=compute_uv, full_matrices=full_matrices) + return tuple([ivy.astype(svd.S, ivy.float64), ivy.astype(svd.U, ivy.float64), ivy.astype(svd.Vh.T, ivy.float64)]) + else: + svd = ivy.svd(a, compute_uv=compute_uv, full_matrices=full_matrices) + return ivy.astype(svd.S, ivy.float64) @to_ivy_arrays_and_back diff --git a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py index 3eca73117d088..c6a62f6598367 100644 --- a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py @@ -1080,7 +1080,7 @@ def test_tensorflow_solve( shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), ), full_matrices=st.booleans(), - compute_uv=st.just(True), + compute_uv=st.booleans(), ) def test_tensorflow_svd( *, @@ -1105,8 +1105,6 @@ def test_tensorflow_svd( fn_tree=fn_tree, on_device=on_device, test_values=False, - atol=1e-03, - rtol=1e-05, a=x, full_matrices=full_matrices, compute_uv=compute_uv, @@ -1129,8 +1127,8 @@ def test_tensorflow_svd( ) else: assert_all_close( - ret_np=ret, - ret_from_gt_np=frontend_ret, + ret_np=np.asarray(ret), + ret_from_gt_np=np.asarray(frontend_ret), rtol=1e-2, atol=1e-2, backend=backend_fw, From bc30d7d54ff8601784800c369d637e1752f49f70 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Tue, 16 Jul 2024 08:31:07 +0800 Subject: [PATCH 15/35] try to fix the two svd function in torch frontend, now the only problem is that the ground truth returns a ivy array with dtype the same as input, while the function returns a torch tensor with the torch version of that dtype. --- .../test_torch/test_blas_and_lapack_ops.py | 22 +++++++++++-------- .../test_frontends/test_torch/test_linalg.py | 10 ++++----- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py index 7ec03a6e822b1..1ff94bb431034 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py @@ -883,24 +883,28 @@ def test_torch_svd( some=some, compute_uv=compute_uv, ) - ret = [np.asarray(x) for x in ret] - frontend_ret = [np.asarray(x) for x in frontend_ret] - u, s, v = ret frontend_u, frontend_s, frontend_v = frontend_ret - - if not some: + if not compute_uv: + helpers.assert_all_close( + ret_np=frontend_s.numpy(), + ret_from_gt_np=s, + atol=1e-04, + backend=backend_fw, + ground_truth_backend=frontend, + ) + elif not some: helpers.assert_all_close( - ret_np=np.asarray(frontend_u @ np.diag(frontend_s) @ frontend_v.T, dtype=np.float32), - ret_from_gt_np=np.asarray(u @ np.diag(s) @ v.T, dtype=np.float32), + ret_np=np.asarray(frontend_u @ np.diag(frontend_s) @ frontend_v.T, dtype=np.float64), + ret_from_gt_np=np.asarray(u @ np.diag(s) @ v.T, dtype=np.float64), atol=1e-04, backend=backend_fw, ground_truth_backend=frontend, ) else: helpers.assert_all_close( - ret_np=np.asarray(frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_v.T, dtype=np.float32), - ret_from_gt_np=np.asarray(u[...,:s.shape[0]] @ np.diag(s) @ v.T, dtype=np.float32), + ret_np=np.asarray(frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_v.T, dtype=np.float64), + ret_from_gt_np=np.asarray(u[...,:s.shape[0]] @ np.diag(s) @ v.T, dtype=np.float64), atol=1e-04, backend=backend_fw, ground_truth_backend=frontend, diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py index ffd8d4f44af7e..d7efd0ef9bbc2 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py @@ -1281,22 +1281,20 @@ def test_torch_svd( A=x, full_matrices=full_matrices, ) - ret = [np.asarray(x) for x in ret] - frontend_ret = [np.asarray(x) for x in frontend_ret] u, s, vh = ret frontend_u, frontend_s, frontend_vh = frontend_ret if full_matrices: helpers.assert_all_close( - ret_np=np.asarray(frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_vh, dtype=np.float32), - ret_from_gt_np=np.asarray(u[...,:s.shape[0]] @ np.diag(s) @ vh, dtype=np.float32), + ret_np=frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_vh, + ret_from_gt_np=u[...,:s.shape[0]] @ np.diag(s) @ vh, atol=1e-04, backend=backend_fw, ground_truth_backend=frontend, ) else: helpers.assert_all_close( - ret_np=np.asarray(frontend_u @ np.diag(frontend_s) @ frontend_vh, dtype=np.float32), - ret_from_gt_np=np.asarray(u @ np.diag(s) @ vh, dtype=np.float32), + ret_np=frontend_u @ np.diag(frontend_s) @ frontend_vh, + ret_from_gt_np=u @ np.diag(s) @ vh, atol=1e-04, backend=backend_fw, ground_truth_backend=frontend, From bed8f77ea865d10b3039b0305813e2254b80bd7b Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Tue, 16 Jul 2024 08:57:07 +0800 Subject: [PATCH 16/35] applied the suggested fix to torch svd tests, they are all passing now --- .../test_torch/test_blas_and_lapack_ops.py | 17 ++++++++++++----- .../test_frontends/test_torch/test_linalg.py | 7 +++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py index 1ff94bb431034..206313798ff54 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py @@ -883,11 +883,18 @@ def test_torch_svd( some=some, compute_uv=compute_uv, ) + if backend_fw == "torch": + frontend_ret = [x.detach() for x in frontend_ret] + ret = [x.detach() for x in frontend_ret] + ret = [np.asarray(x, dtype=np.dtype(getattr(np, input_dtype[0]))) for x in ret] + else: + ret = [np.asarray(x) for x in ret] + frontend_ret = [np.asarray(x, dtype=np.dtype(getattr(np, input_dtype[0]))) for x in frontend_ret] u, s, v = ret frontend_u, frontend_s, frontend_v = frontend_ret if not compute_uv: helpers.assert_all_close( - ret_np=frontend_s.numpy(), + ret_np=frontend_s, ret_from_gt_np=s, atol=1e-04, backend=backend_fw, @@ -895,16 +902,16 @@ def test_torch_svd( ) elif not some: helpers.assert_all_close( - ret_np=np.asarray(frontend_u @ np.diag(frontend_s) @ frontend_v.T, dtype=np.float64), - ret_from_gt_np=np.asarray(u @ np.diag(s) @ v.T, dtype=np.float64), + ret_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, + ret_from_gt_np=u @ np.diag(s) @ v.T, atol=1e-04, backend=backend_fw, ground_truth_backend=frontend, ) else: helpers.assert_all_close( - ret_np=np.asarray(frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_v.T, dtype=np.float64), - ret_from_gt_np=np.asarray(u[...,:s.shape[0]] @ np.diag(s) @ v.T, dtype=np.float64), + ret_np=frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_v.T, + ret_from_gt_np=u[...,:s.shape[0]] @ np.diag(s) @ v.T, atol=1e-04, backend=backend_fw, ground_truth_backend=frontend, diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py index d7efd0ef9bbc2..b6d3b64f08af1 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py @@ -1281,6 +1281,13 @@ def test_torch_svd( A=x, full_matrices=full_matrices, ) + if backend_fw == "torch": + frontend_ret = [x.detach() for x in frontend_ret] + ret = [x.detach() for x in frontend_ret] + ret = [np.asarray(x, dtype=np.dtype(getattr(np, dtype[0]))) for x in ret] + else: + ret = [np.asarray(x) for x in ret] + frontend_ret = [np.asarray(x, dtype=np.dtype(getattr(np, dtype[0]))) for x in frontend_ret] u, s, vh = ret frontend_u, frontend_s, frontend_vh = frontend_ret if full_matrices: From 316986ededa8c9923dc7995ca933bcdb57e83f38 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Tue, 16 Jul 2024 09:03:47 +0800 Subject: [PATCH 17/35] make namedtuple definition more simple as suggested --- ivy/functional/backends/jax/linear_algebra.py | 2 +- ivy/functional/backends/numpy/linear_algebra.py | 2 +- ivy/functional/backends/paddle/linear_algebra.py | 2 +- ivy/functional/backends/tensorflow/linear_algebra.py | 2 +- ivy/functional/backends/torch/linear_algebra.py | 2 +- ivy/functional/frontends/torch/blas_and_lapack_ops.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ivy/functional/backends/jax/linear_algebra.py b/ivy/functional/backends/jax/linear_algebra.py index 281ad7eb30315..3d032fffb9f98 100644 --- a/ivy/functional/backends/jax/linear_algebra.py +++ b/ivy/functional/backends/jax/linear_algebra.py @@ -361,7 +361,7 @@ def svd( x: JaxArray, /, *, compute_uv: bool = True, full_matrices: bool = True ) -> Union[JaxArray, Tuple[JaxArray, ...]]: if compute_uv: - results = namedtuple("svd", ['U', 'S', 'Vh']) + results = namedtuple("svd", 'U S Vh') U, D, VT = jnp.linalg.svd(x, full_matrices=full_matrices, compute_uv=compute_uv) return results(U, D, VT) else: diff --git a/ivy/functional/backends/numpy/linear_algebra.py b/ivy/functional/backends/numpy/linear_algebra.py index 50691e06cfac4..d580a469f4f66 100644 --- a/ivy/functional/backends/numpy/linear_algebra.py +++ b/ivy/functional/backends/numpy/linear_algebra.py @@ -291,7 +291,7 @@ def svd( x: np.ndarray, /, *, compute_uv: bool = True, full_matrices: bool = True ) -> Union[np.ndarray, Tuple[np.ndarray, ...]]: if compute_uv: - results = namedtuple("svd", ['U', 'S', 'Vh']) + results = namedtuple("svd", 'U S Vh') U, D, VT = np.linalg.svd(x, full_matrices=full_matrices, compute_uv=compute_uv) return results(U, D, VT) else: diff --git a/ivy/functional/backends/paddle/linear_algebra.py b/ivy/functional/backends/paddle/linear_algebra.py index 16cdce79c1a0b..5bbefe31838a9 100644 --- a/ivy/functional/backends/paddle/linear_algebra.py +++ b/ivy/functional/backends/paddle/linear_algebra.py @@ -521,7 +521,7 @@ def svd( ) -> Union[paddle.Tensor, Tuple[paddle.Tensor, ...]]: ret = paddle.linalg.svd(x, full_matrices=full_matrices) if compute_uv: - results = namedtuple("svd", ['U', 'S', 'Vh']) + results = namedtuple("svd", 'U S Vh') return results(*ret) else: results = namedtuple("svd", "S") diff --git a/ivy/functional/backends/tensorflow/linear_algebra.py b/ivy/functional/backends/tensorflow/linear_algebra.py index 39ff8647f1d8f..976c2fb132b05 100644 --- a/ivy/functional/backends/tensorflow/linear_algebra.py +++ b/ivy/functional/backends/tensorflow/linear_algebra.py @@ -545,7 +545,7 @@ def svd( compute_uv: bool = True, ) -> Union[Union[tf.Tensor, tf.Variable], Tuple[Union[tf.Tensor, tf.Variable], ...]]: if compute_uv: - results = namedtuple("svd", ['U', 'S', 'Vh']) + results = namedtuple("svd", 'U S Vh') batch_shape = tf.shape(x)[:-2] num_batch_dims = len(batch_shape) transpose_dims = list(range(num_batch_dims)) + [ diff --git a/ivy/functional/backends/torch/linear_algebra.py b/ivy/functional/backends/torch/linear_algebra.py index 752d7b42c0959..26deaf8d25f66 100644 --- a/ivy/functional/backends/torch/linear_algebra.py +++ b/ivy/functional/backends/torch/linear_algebra.py @@ -414,7 +414,7 @@ def svd( x: torch.Tensor, /, *, full_matrices: bool = True, compute_uv: bool = True ) -> Union[torch.Tensor, Tuple[torch.Tensor, ...]]: if compute_uv: - results = namedtuple("svd", ['U', 'S', 'Vh']) + results = namedtuple("svd", 'U S Vh') U, D, VT = torch.linalg.svd(x, full_matrices=full_matrices) return results(U, D, VT) else: diff --git a/ivy/functional/frontends/torch/blas_and_lapack_ops.py b/ivy/functional/frontends/torch/blas_and_lapack_ops.py index 47249630a8c58..4ced2b61b24e8 100644 --- a/ivy/functional/frontends/torch/blas_and_lapack_ops.py +++ b/ivy/functional/frontends/torch/blas_and_lapack_ops.py @@ -193,7 +193,7 @@ def slogdet(A, *, out=None): @to_ivy_arrays_and_back def svd(input, some=True, compute_uv=True, *, out=None): retu = ivy.svd(input, full_matrices=not some, compute_uv=compute_uv) - results = namedtuple("svd", ['U', 'S', 'V']) + results = namedtuple("svd", 'U S V') if compute_uv: ret = results(retu[0], retu[1], ivy.adjoint(retu[2])) else: From e0268c6709d2331ae1ac290e1a419eb2a8f20d2f Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Tue, 16 Jul 2024 12:55:30 +0800 Subject: [PATCH 18/35] tried to fix jax.lac.linalg.svd. p.s. there is no implementation of subset_by_index parameter. tensorflow,torch and paddle backends are all failing due to significant value differences in only part of the reconstructed matrixes. --- .../test_jax/test_lax/test_linalg.py | 57 +++++++++++-------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py index 27d4f7f738b09..d44cd78bf60b3 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py @@ -159,26 +159,25 @@ def test_jax_qr( # svd -# TODO: implement proper drawing of index parameter +# TODO: implement proper drawing of index parameter and implement subset_by_index @handle_frontend_test( fn_tree="jax.lax.linalg.svd", dtype_x=helpers.dtype_and_values( available_dtypes=helpers.get_dtypes("float"), min_value=0, max_value=10, - min_num_dims=2, - max_num_dims=5, + shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), ), full_matrices=st.booleans(), compute_uv=st.booleans(), index=st.one_of( - st.none(), st.tuples(st.integers(min_value=0, max_value=3), st.integers(min_value=3, max_value=5)) + st.none() #, st.tuples(st.integers(min_value=0, max_value=3), st.integers(min_value=3, max_value=5)) ), test_with_out=st.just(False), ) def test_jax_svd( *, - dtype_and_x, + dtype_x, full_matrices, compute_uv, index, @@ -188,11 +187,10 @@ def test_jax_svd( test_flags, backend_fw, ): - dtype, x = dtype_and_x + dtype, x = dtype_x x = np.asarray(x[0], dtype=dtype[0]) # make symmetric positive-definite x = np.matmul(x.T, x) + np.identity(x.shape[0]) * 1e-3 - ret, frontend_ret = helpers.test_frontend_function( input_dtypes=dtype, backend_to_test=backend_fw, @@ -206,26 +204,35 @@ def test_jax_svd( compute_uv=compute_uv, subset_by_index=index, ) - if compute_uv: - ret = [np.asarray(x) for x in ret] - frontend_ret = [np.asarray(x) for x in frontend_ret] - u, s, v = ret - frontend_u, frontend_s, frontend_v = frontend_ret - + if not compute_uv: + if backend_fw == "torch": + frontend_ret = frontend_ret.detach() + ret = ret.detach() assert_all_close( - ret_np=u @ np.diag(s) @ v.T, - ret_from_gt_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, - rtol=1e-2, - atol=1e-2, + ret_np=np.asarray(frontend_ret, dtype=np.dtype(getattr(np, dtype[0]))), + ret_from_gt_np=np.asarray(ret), + atol=1e-03, backend=backend_fw, ground_truth_backend=frontend, ) else: - assert_all_close( - ret_np=ret, - ret_from_gt_np=frontend_ret, - rtol=1e-2, - atol=1e-2, - backend=backend_fw, - ground_truth_backend=frontend, - ) + ret = [np.asarray(x) for x in ret] + frontend_ret = [np.asarray(x, dtype=np.dtype(getattr(np, dtype[0]))) for x in frontend_ret] + u, s, v = ret + frontend_u, frontend_s, frontend_v = frontend_ret + if full_matrices: + helpers.assert_all_close( + ret_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, + ret_from_gt_np=u @ np.diag(s) @ v.T, + atol=1e-03, + backend=backend_fw, + ground_truth_backend=frontend, + ) + else: + helpers.assert_all_close( + ret_np=frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_v.T, + ret_from_gt_np=u[...,:s.shape[0]] @ np.diag(s) @ v.T, + atol=1e-03, + backend=backend_fw, + ground_truth_backend=frontend, + ) \ No newline at end of file From dcab2c1864f411e58bef5e6496d4943dff6d4205 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Tue, 16 Jul 2024 16:00:47 +0800 Subject: [PATCH 19/35] fixed jax.numpy.linalg.svd, all tests are passing, but jax.lax.linalg.svd produces significant difference with compute_uv=True (like flipped signs) in the reconstructed matrixes for all backends. I suspect that the decomposition of jax.lax.linalg.svd is different from other similiar functions --- ivy/functional/frontends/jax/numpy/linalg.py | 6 ++- .../test_jax/test_lax/test_linalg.py | 7 ++-- .../test_jax/test_numpy/test_linalg.py | 38 +++++++++++-------- 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/ivy/functional/frontends/jax/numpy/linalg.py b/ivy/functional/frontends/jax/numpy/linalg.py index 79821e417d990..16bbaecfc8f39 100644 --- a/ivy/functional/frontends/jax/numpy/linalg.py +++ b/ivy/functional/frontends/jax/numpy/linalg.py @@ -123,7 +123,11 @@ def solve(a, b): def svd(a, /, *, full_matrices=True, compute_uv=True, hermitian=None): # TODO: handle hermitian ret = ivy.svd(a, full_matrices=full_matrices, compute_uv=compute_uv) - return tuple([ x.astype(ivy.float64) for x in ret]) + if compute_uv: + return tuple(ret) + else: + return ivy.svdvals(a) + @to_ivy_arrays_and_back diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py index d44cd78bf60b3..35e7496e03aeb 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py @@ -206,7 +206,6 @@ def test_jax_svd( ) if not compute_uv: if backend_fw == "torch": - frontend_ret = frontend_ret.detach() ret = ret.detach() assert_all_close( ret_np=np.asarray(frontend_ret, dtype=np.dtype(getattr(np, dtype[0]))), @@ -216,6 +215,8 @@ def test_jax_svd( ground_truth_backend=frontend, ) else: + if backend_fw == "torch": + ret = [x.detach() for x in ret] ret = [np.asarray(x) for x in ret] frontend_ret = [np.asarray(x, dtype=np.dtype(getattr(np, dtype[0]))) for x in frontend_ret] u, s, v = ret @@ -224,7 +225,7 @@ def test_jax_svd( helpers.assert_all_close( ret_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, ret_from_gt_np=u @ np.diag(s) @ v.T, - atol=1e-03, + atol=1e-3, backend=backend_fw, ground_truth_backend=frontend, ) @@ -232,7 +233,7 @@ def test_jax_svd( helpers.assert_all_close( ret_np=frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_v.T, ret_from_gt_np=u[...,:s.shape[0]] @ np.diag(s) @ v.T, - atol=1e-03, + atol=1e-3, backend=backend_fw, ground_truth_backend=frontend, ) \ No newline at end of file diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py index 79ca88fc0456d..331891d684a8b 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py @@ -895,28 +895,34 @@ def test_jax_svd( full_matrices=full_matrices, compute_uv=compute_uv, ) - if compute_uv: ret = [np.asarray(x) for x in ret] - frontend_ret = [np.asarray(x) for x in frontend_ret] - + frontend_ret = [np.asarray(x, dtype=np.dtype(getattr(np, dtype[0]))) for x in frontend_ret] u, s, vh = ret frontend_u, frontend_s, frontend_vh = frontend_ret - - assert_all_close( - ret_np=u @ np.diag(s) @ vh, - ret_from_gt_np=frontend_u @ np.diag(frontend_s) @ frontend_vh, - rtol=1e-2, - atol=1e-2, - backend=backend_fw, - ground_truth_backend=frontend, - ) + if full_matrices: + helpers.assert_all_close( + ret_np=frontend_u @ np.diag(frontend_s) @ frontend_vh, + ret_from_gt_np=u @ np.diag(s) @ vh, + atol=1e-3, + backend=backend_fw, + ground_truth_backend=frontend, + ) + else: + helpers.assert_all_close( + ret_np=frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_vh, + ret_from_gt_np=u[...,:s.shape[0]] @ np.diag(s) @ vh, + atol=1e-3, + backend=backend_fw, + ground_truth_backend=frontend, + ) else: + if backend_fw == "torch": + ret = ret.detach() assert_all_close( - ret_np=ret, - ret_from_gt_np=frontend_ret, - rtol=1e-2, - atol=1e-2, + ret_np=np.asarray(frontend_ret, dtype=np.dtype(getattr(np, dtype[0]))), + ret_from_gt_np=np.asarray(ret), + atol=1e-3, backend=backend_fw, ground_truth_backend=frontend, ) From ac7a60afd6590036bafb3d039e3d69fe0062ec4d Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Thu, 18 Jul 2024 21:39:58 +0800 Subject: [PATCH 20/35] fixing numpy.linalg.decompositions.svd --- .../frontends/numpy/linalg/decompositions.py | 5 ++- .../test_jax/test_lax/test_linalg.py | 2 +- .../test_jax/test_numpy/test_linalg.py | 2 +- .../test_linalg/test_decompositions.py | 36 +++++++++++-------- 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/ivy/functional/frontends/numpy/linalg/decompositions.py b/ivy/functional/frontends/numpy/linalg/decompositions.py index 24bf8dda890d5..0e6dae20461c2 100644 --- a/ivy/functional/frontends/numpy/linalg/decompositions.py +++ b/ivy/functional/frontends/numpy/linalg/decompositions.py @@ -16,4 +16,7 @@ def qr(a, mode="reduced"): @to_ivy_arrays_and_back def svd(a, full_matrices=True, compute_uv=True, hermitian=False): # Todo: hermitian handling - return ivy.svd(a, full_matrices=full_matrices, compute_uv=compute_uv) + if compute_uv: + return ivy.svd(a, full_matrices=full_matrices, compute_uv=compute_uv) + else: + return ivy.astype(ivy.svdvals(a), a.dtype) diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py index 35e7496e03aeb..7cf8d69e6c6a0 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py @@ -221,7 +221,7 @@ def test_jax_svd( frontend_ret = [np.asarray(x, dtype=np.dtype(getattr(np, dtype[0]))) for x in frontend_ret] u, s, v = ret frontend_u, frontend_s, frontend_v = frontend_ret - if full_matrices: + if not full_matrices: helpers.assert_all_close( ret_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, ret_from_gt_np=u @ np.diag(s) @ v.T, diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py index 331891d684a8b..92c0e6148f831 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py @@ -900,7 +900,7 @@ def test_jax_svd( frontend_ret = [np.asarray(x, dtype=np.dtype(getattr(np, dtype[0]))) for x in frontend_ret] u, s, vh = ret frontend_u, frontend_s, frontend_vh = frontend_ret - if full_matrices: + if not full_matrices: helpers.assert_all_close( ret_np=frontend_u @ np.diag(frontend_s) @ frontend_vh, ret_from_gt_np=u @ np.diag(s) @ vh, diff --git a/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py b/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py index 44a67f6dd00ff..f806acc743a47 100644 --- a/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py +++ b/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py @@ -124,23 +124,29 @@ def test_numpy_svd( if compute_uv: ret = [np.asarray(x) for x in ret] frontend_ret = [np.asarray(x) for x in frontend_ret] - u, s, v = ret - frontend_u, frontend_s, frontend_v = frontend_ret - - helpers.assert_all_close( - ret_np=u @ np.diag(s) @ v.T, - ret_from_gt_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, - rtol=1e-2, - atol=1e-2, - backend=backend_fw, - ground_truth_backend=frontend, - ) + u, s, vh = ret + frontend_u, frontend_s, frontend_vh = frontend_ret + if not full_matrices: + helpers.assert_all_close( + ret_np=frontend_u @ np.diag(frontend_s) @ frontend_vh, + ret_from_gt_np=u @ np.diag(s) @ vh, + atol=1e-3, + backend=backend_fw, + ground_truth_backend=frontend, + ) + else: + helpers.assert_all_close( + ret_np=frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_vh, + ret_from_gt_np=u[...,:s.shape[0]] @ np.diag(s) @ vh, + atol=1e-3, + backend=backend_fw, + ground_truth_backend=frontend, + ) else: helpers.assert_all_close( - ret_np=ret.S, - ret_from_gt_np=frontend_ret, - rtol=1e-2, - atol=1e-2, + ret_np=frontend_ret, + ret_from_gt_np=ret, + atol=1e-3, backend=backend_fw, ground_truth_backend=frontend, ) From 8e927a41dde4ddf442ca1e10706c9da87f8637ed Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Fri, 16 Aug 2024 06:08:54 +0000 Subject: [PATCH 21/35] fixed ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py::test_torch_svd, all tests passed --- .../test_frontends/test_torch/test_tensor.py | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py index 8c690b5aac4c0..c9c63f85686c3 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py @@ -13146,24 +13146,31 @@ def test_torch_svd( ret = [np.asarray(x) for x in ret] frontend_ret = [np.asarray(x) for x in frontend_ret] - u, s, vh = ret - frontend_u, frontend_s, frontend_vh = frontend_ret - - if compute_uv: + u, s, v = ret + frontend_u, frontend_s, frontend_v = frontend_ret + if not compute_uv: helpers.assert_all_close( - ret_np=frontend_u @ np.diag(frontend_s) @ frontend_vh.T, - ret_from_gt_np=u @ np.diag(s) @ vh, - rtol=1e-2, - atol=1e-2, + ret_np=frontend_s, + ret_from_gt_np=s, + atol=1e-04, + backend=backend_fw, + ground_truth_backend=frontend, + ) + elif not some: + helpers.assert_all_close( + ret_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, + ret_from_gt_np=u @ np.diag(s) @ v.T, + atol=1e-04, backend=backend_fw, ground_truth_backend=frontend, ) else: helpers.assert_all_close( - ret_np=frontend_s, - ret_from_gt_np=s, - rtol=1e-2, - atol=1e-2, + ret_np=frontend_u[..., : frontend_s.shape[0]] + @ np.diag(frontend_s) + @ frontend_v.T, + ret_from_gt_np=u[..., : s.shape[0]] @ np.diag(s) @ v.T, + atol=1e-04, backend=backend_fw, ground_truth_backend=frontend, ) From 37272a888cc861e6301bef05ef454d1317e504c3 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Fri, 16 Aug 2024 12:21:41 +0000 Subject: [PATCH 22/35] fixed ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py::test_numpy_svd, though seems like using ivy.astype to convert type does not work at all --- .../frontends/numpy/linalg/decompositions.py | 2 +- .../test_numpy/test_linalg/test_decompositions.py | 13 +++++++------ .../test_torch/test_blas_and_lapack_ops.py | 13 +++++++------ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/ivy/functional/frontends/numpy/linalg/decompositions.py b/ivy/functional/frontends/numpy/linalg/decompositions.py index 0e6dae20461c2..927096f08476a 100644 --- a/ivy/functional/frontends/numpy/linalg/decompositions.py +++ b/ivy/functional/frontends/numpy/linalg/decompositions.py @@ -15,7 +15,7 @@ def qr(a, mode="reduced"): @to_ivy_arrays_and_back def svd(a, full_matrices=True, compute_uv=True, hermitian=False): - # Todo: hermitian handling + # Todo: hermitian handling, ivy.astype does not work for some reason if compute_uv: return ivy.svd(a, full_matrices=full_matrices, compute_uv=compute_uv) else: diff --git a/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py b/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py index f806acc743a47..d7909c88d9fa2 100644 --- a/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py +++ b/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py @@ -4,9 +4,8 @@ from hypothesis import strategies as st # local -import ivy import ivy_tests.test_ivy.helpers as helpers -from ivy_tests.test_ivy.helpers import handle_frontend_test, BackendHandler +from ivy_tests.test_ivy.helpers import handle_frontend_test from ivy_tests.test_ivy.test_functional.test_core.test_linalg import ( _get_dtype_and_matrix, ) @@ -123,7 +122,7 @@ def test_numpy_svd( ) if compute_uv: ret = [np.asarray(x) for x in ret] - frontend_ret = [np.asarray(x) for x in frontend_ret] + frontend_ret = [np.asarray(x).astype(dtype[0]) for x in frontend_ret] u, s, vh = ret frontend_u, frontend_s, frontend_vh = frontend_ret if not full_matrices: @@ -136,15 +135,17 @@ def test_numpy_svd( ) else: helpers.assert_all_close( - ret_np=frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_vh, - ret_from_gt_np=u[...,:s.shape[0]] @ np.diag(s) @ vh, + ret_np=frontend_u[..., : frontend_s.shape[0]] + @ np.diag(frontend_s) + @ frontend_vh, + ret_from_gt_np=u[..., : s.shape[0]] @ np.diag(s) @ vh, atol=1e-3, backend=backend_fw, ground_truth_backend=frontend, ) else: helpers.assert_all_close( - ret_np=frontend_ret, + ret_np=frontend_ret.astype(dtype[0]), ret_from_gt_np=ret, atol=1e-3, backend=backend_fw, diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py index 206313798ff54..1f86b0a825963 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py @@ -4,7 +4,6 @@ from hypothesis import strategies as st, assume # local -import ivy import ivy_tests.test_ivy.helpers as helpers from ivy_tests.test_ivy.helpers import handle_frontend_test from ivy_tests.test_ivy.helpers.hypothesis_helpers.general_helpers import ( @@ -879,17 +878,17 @@ def test_torch_svd( fn_tree=fn_tree, on_device=on_device, test_values=False, - input = x, + input=x, some=some, compute_uv=compute_uv, ) if backend_fw == "torch": frontend_ret = [x.detach() for x in frontend_ret] ret = [x.detach() for x in frontend_ret] - ret = [np.asarray(x, dtype=np.dtype(getattr(np, input_dtype[0]))) for x in ret] + ret = [np.asarray(x) for x in ret] else: ret = [np.asarray(x) for x in ret] - frontend_ret = [np.asarray(x, dtype=np.dtype(getattr(np, input_dtype[0]))) for x in frontend_ret] + frontend_ret = [np.asarray(x).astype(input_dtype[0]) for x in frontend_ret] u, s, v = ret frontend_u, frontend_s, frontend_v = frontend_ret if not compute_uv: @@ -910,8 +909,10 @@ def test_torch_svd( ) else: helpers.assert_all_close( - ret_np=frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_v.T, - ret_from_gt_np=u[...,:s.shape[0]] @ np.diag(s) @ v.T, + ret_np=frontend_u[..., : frontend_s.shape[0]] + @ np.diag(frontend_s) + @ frontend_v.T, + ret_from_gt_np=u[..., : s.shape[0]] @ np.diag(s) @ v.T, atol=1e-04, backend=backend_fw, ground_truth_backend=frontend, From dc90073b324bbd1959a217c8987f07b0f00adf57 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Sun, 18 Aug 2024 07:04:47 +0000 Subject: [PATCH 23/35] Fixing ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py::test_tensorflow_Svd, now the frontend somehow always return float64 nomatter input dtype --- .../frontends/tensorflow/raw_ops.py | 9 ++-- .../test_linalg/test_decompositions.py | 4 +- .../test_tensorflow/test_raw_ops.py | 42 +++++++++++-------- .../test_torch/test_blas_and_lapack_ops.py | 2 +- .../test_frontends/test_torch/test_tensor.py | 2 +- 5 files changed, 35 insertions(+), 24 deletions(-) diff --git a/ivy/functional/frontends/tensorflow/raw_ops.py b/ivy/functional/frontends/tensorflow/raw_ops.py index 61c87dcb5c76b..0128e89695fca 100644 --- a/ivy/functional/frontends/tensorflow/raw_ops.py +++ b/ivy/functional/frontends/tensorflow/raw_ops.py @@ -832,12 +832,15 @@ def Sum(*, input, axis, keep_dims=False, name="Sum"): @with_supported_dtypes( - {"2.15.0 and below": ("float64", "float128", "halfcomplex64", "complex128")}, + {"2.15.0 and below": ("float64", "float32", "half", "complex64", "complex128")}, "tensorflow", ) @to_ivy_arrays_and_back -def Svd(*, input, full_matrices=False, compute_uv=True, name=None): - return ivy.svd(input, compute_uv=compute_uv, full_matrices=full_matrices) +def Svd(*, input, full_matrices=False, compute_uv=True, name="Svd"): + ret = ivy.svd(input, compute_uv=compute_uv, full_matrices=full_matrices) + if not compute_uv: + return (ret.S, None, None) + return (ret.S, ret.U, ivy.adjoint(ret.Vh)) @to_ivy_arrays_and_back diff --git a/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py b/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py index d7909c88d9fa2..1e43a8a4e866c 100644 --- a/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py +++ b/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py @@ -85,7 +85,7 @@ def test_numpy_qr( @handle_frontend_test( fn_tree="numpy.linalg.svd", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float"), + available_dtypes=helpers.get_dtypes("valid"), min_value=0.1, max_value=10, shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), @@ -105,7 +105,7 @@ def test_numpy_svd( on_device, ): dtype, x = dtype_and_x - x = x[0] + x = np.asarray(x[0], dtype=dtype[0]) # make symmetric positive-definite x = np.matmul(x.T, x) + np.identity(x.shape[0]) * 1e-3 ret, frontend_ret = helpers.test_frontend_function( diff --git a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py index 1c634f57fcb9e..b0f40ec0b440e 100644 --- a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py @@ -4277,7 +4277,7 @@ def test_tensorflow_Sum( # NOQA shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), ), full_matrices=st.booleans(), - compute_uv=st.just(True), + compute_uv=st.booleans(), ) def test_tensorflow_Svd( *, @@ -4306,25 +4306,33 @@ def test_tensorflow_Svd( full_matrices=full_matrices, compute_uv=compute_uv, ) - + ret = [np.asarray(x) for x in ret] + frontend_ret = [np.asarray(x) for x in frontend_ret] + s, u, v = ret + frontend_s, frontend_u, frontend_v = frontend_ret if compute_uv: - ret = [np.asarray(x) for x in ret] - frontend_ret = [np.asarray(x) for x in frontend_ret] - - s, u, v = ret - frontend_s, frontend_u, frontend_v = frontend_ret - assert_all_close( - ret_np=u @ np.diag(s) @ v.T, - ret_from_gt_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, - rtol=1e-2, - atol=1e-2, - backend=backend_fw, - ground_truth_backend=frontend, - ) + if not full_matrices: + helpers.assert_all_close( + ret_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, + ret_from_gt_np=u @ np.diag(s) @ v.T, + atol=1e-04, + backend=backend_fw, + ground_truth_backend=frontend, + ) + else: + helpers.assert_all_close( + ret_np=frontend_u[..., : frontend_s.shape[0]] + @ np.diag(frontend_s) + @ frontend_v.T, + ret_from_gt_np=u[..., : s.shape[0]] @ np.diag(s) @ v.T, + atol=1e-04, + backend=backend_fw, + ground_truth_backend=frontend, + ) else: assert_all_close( - ret_np=s, - ret_from_gt_np=frontend_s, + ret_np=frontend_s, + ret_from_gt_np=s, rtol=1e-2, atol=1e-2, backend=backend_fw, diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py index 1f86b0a825963..250874089d456 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py @@ -848,7 +848,7 @@ def test_torch_qr( @handle_frontend_test( fn_tree="torch.svd", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float"), + available_dtypes=helpers.get_dtypes("valid"), min_value=0, max_value=10, shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py index c9c63f85686c3..0640f82060abc 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py @@ -13102,7 +13102,7 @@ def test_torch_sum( init_tree="torch.tensor", method_name="svd", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float"), + available_dtypes=helpers.get_dtypes("valid"), min_value=0, max_value=10, shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), From 65c902fc059833bf78698e96514272f971c778a4 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Tue, 20 Aug 2024 07:04:22 +0000 Subject: [PATCH 24/35] fixed ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py::test_jax_svd --- ivy/functional/frontends/jax/numpy/linalg.py | 2 +- .../test_jax/test_numpy/test_linalg.py | 23 +++++++++++-------- .../test_torch/test_blas_and_lapack_ops.py | 4 +--- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/ivy/functional/frontends/jax/numpy/linalg.py b/ivy/functional/frontends/jax/numpy/linalg.py index 16bbaecfc8f39..993d8a8328cee 100644 --- a/ivy/functional/frontends/jax/numpy/linalg.py +++ b/ivy/functional/frontends/jax/numpy/linalg.py @@ -120,6 +120,7 @@ def solve(a, b): @to_ivy_arrays_and_back +@with_unsupported_dtypes({"0.4.24 and below": ("float16", "bfloat16")}, "jax") def svd(a, /, *, full_matrices=True, compute_uv=True, hermitian=None): # TODO: handle hermitian ret = ivy.svd(a, full_matrices=full_matrices, compute_uv=compute_uv) @@ -129,7 +130,6 @@ def svd(a, /, *, full_matrices=True, compute_uv=True, hermitian=None): return ivy.svdvals(a) - @to_ivy_arrays_and_back @with_unsupported_dtypes({"0.4.24 and below": ("float16", "bfloat16")}, "jax") def tensorinv(a, ind=2): diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py index 92c0e6148f831..ea390e6526aed 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py @@ -858,12 +858,7 @@ def test_jax_solve( min_value=0, max_value=10, shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), - ).filter( - lambda x: "float16" not in x[0] - and "bfloat16" not in x[0] - and np.linalg.cond(x[1][0]) < 1 / sys.float_info.epsilon - and np.linalg.det(np.asarray(x[1][0])) != 0 - ), + ).filter(lambda x: "float16" not in x[0] and "bfloat16" not in x[0]), full_matrices=st.booleans(), compute_uv=st.booleans(), test_with_out=st.just(False), @@ -896,8 +891,14 @@ def test_jax_svd( compute_uv=compute_uv, ) if compute_uv: - ret = [np.asarray(x) for x in ret] - frontend_ret = [np.asarray(x, dtype=np.dtype(getattr(np, dtype[0]))) for x in frontend_ret] + if backend_fw == "torch": + frontend_ret = [ + x for x in frontend_ret + ] # unpack jaxlib.xla_extension.ArrayImpl as it is no .detach() + ret = [x for x in frontend_ret] + detyp = np.dtype(getattr(np, dtype[0])) + ret = [np.asarray(x).astype(detyp) for x in ret] + frontend_ret = [np.asarray(x, dtype=detyp) for x in frontend_ret] u, s, vh = ret frontend_u, frontend_s, frontend_vh = frontend_ret if not full_matrices: @@ -910,8 +911,10 @@ def test_jax_svd( ) else: helpers.assert_all_close( - ret_np=frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_vh, - ret_from_gt_np=u[...,:s.shape[0]] @ np.diag(s) @ vh, + ret_np=frontend_u[..., : frontend_s.shape[0]] + @ np.diag(frontend_s) + @ frontend_vh, + ret_from_gt_np=u[..., : s.shape[0]] @ np.diag(s) @ vh, atol=1e-3, backend=backend_fw, ground_truth_backend=frontend, diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py index 250874089d456..b84819a5de224 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py @@ -885,9 +885,7 @@ def test_torch_svd( if backend_fw == "torch": frontend_ret = [x.detach() for x in frontend_ret] ret = [x.detach() for x in frontend_ret] - ret = [np.asarray(x) for x in ret] - else: - ret = [np.asarray(x) for x in ret] + ret = [np.asarray(x) for x in ret] frontend_ret = [np.asarray(x).astype(input_dtype[0]) for x in frontend_ret] u, s, v = ret frontend_u, frontend_s, frontend_v = frontend_ret From c92b6be00433b1432adec350fb6dc4c5e3d156a0 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Tue, 20 Aug 2024 11:00:17 +0000 Subject: [PATCH 25/35] fixing ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py::test_tensorflow_Svd, though if input is complex number the results show large difference --- .../test_jax/test_lax/test_linalg.py | 23 ++++++++++++------- .../test_tensorflow/test_raw_ops.py | 22 ++++++++++++------ .../test_torch/test_blas_and_lapack_ops.py | 2 +- .../test_frontends/test_torch/test_linalg.py | 13 +++++++---- 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py index 7cf8d69e6c6a0..d25a5ec3858f2 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py @@ -160,6 +160,7 @@ def test_jax_qr( # svd # TODO: implement proper drawing of index parameter and implement subset_by_index +# and to resolve groundtruth's significant inaccuracy @handle_frontend_test( fn_tree="jax.lax.linalg.svd", dtype_x=helpers.dtype_and_values( @@ -171,7 +172,9 @@ def test_jax_qr( full_matrices=st.booleans(), compute_uv=st.booleans(), index=st.one_of( - st.none() #, st.tuples(st.integers(min_value=0, max_value=3), st.integers(min_value=3, max_value=5)) + st.none() + # , st.tuples(st.integers(min_value=0, max_value=3), + # st.integers(min_value=3, max_value=5)) ), test_with_out=st.just(False), ) @@ -210,7 +213,7 @@ def test_jax_svd( assert_all_close( ret_np=np.asarray(frontend_ret, dtype=np.dtype(getattr(np, dtype[0]))), ret_from_gt_np=np.asarray(ret), - atol=1e-03, + rtol=1e-3, backend=backend_fw, ground_truth_backend=frontend, ) @@ -218,22 +221,26 @@ def test_jax_svd( if backend_fw == "torch": ret = [x.detach() for x in ret] ret = [np.asarray(x) for x in ret] - frontend_ret = [np.asarray(x, dtype=np.dtype(getattr(np, dtype[0]))) for x in frontend_ret] + frontend_ret = [ + np.asarray(x, dtype=np.dtype(getattr(np, dtype[0]))) for x in frontend_ret + ] u, s, v = ret frontend_u, frontend_s, frontend_v = frontend_ret if not full_matrices: helpers.assert_all_close( ret_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, ret_from_gt_np=u @ np.diag(s) @ v.T, - atol=1e-3, + rtol=1e-3, backend=backend_fw, ground_truth_backend=frontend, ) else: helpers.assert_all_close( - ret_np=frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_v.T, - ret_from_gt_np=u[...,:s.shape[0]] @ np.diag(s) @ v.T, - atol=1e-3, + ret_np=frontend_u[..., : frontend_s.shape[0]] + @ np.diag(frontend_s) + @ frontend_v.T, + ret_from_gt_np=u[..., : s.shape[0]] @ np.diag(s) @ v.T, + rtol=1e-3, backend=backend_fw, ground_truth_backend=frontend, - ) \ No newline at end of file + ) diff --git a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py index b0f40ec0b440e..b312ac1bc7b6e 100644 --- a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_raw_ops.py @@ -4272,7 +4272,7 @@ def test_tensorflow_Sum( # NOQA fn_tree="tensorflow.raw_ops.Svd", dtype_and_x=helpers.dtype_and_values( available_dtypes=helpers.get_dtypes("valid"), - min_value=0, + min_value=0.1, max_value=10, shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), ), @@ -4294,6 +4294,7 @@ def test_tensorflow_Svd( x = np.asarray(x[0], dtype=dtype[0]) # make symmetric positive definite x = np.matmul(x.T, x) + np.identity(x.shape[0]) * 1e-3 + x = x.astype(dtype[0]) ret, frontend_ret = helpers.test_frontend_function( input_dtypes=dtype, backend_to_test=backend_fw, @@ -4306,8 +4307,13 @@ def test_tensorflow_Svd( full_matrices=full_matrices, compute_uv=compute_uv, ) + if backend_fw == "torch": + if not compute_uv: + ret = [ret[0].detach(), None, None] + else: + ret = [x.detach() for x in ret] ret = [np.asarray(x) for x in ret] - frontend_ret = [np.asarray(x) for x in frontend_ret] + frontend_ret = [np.asarray(x).astype(dtype[0]) for x in frontend_ret] s, u, v = ret frontend_s, frontend_u, frontend_v = frontend_ret if compute_uv: @@ -4315,7 +4321,8 @@ def test_tensorflow_Svd( helpers.assert_all_close( ret_np=frontend_u @ np.diag(frontend_s) @ frontend_v.T, ret_from_gt_np=u @ np.diag(s) @ v.T, - atol=1e-04, + rtol=1e-3, + atol=1e-3, backend=backend_fw, ground_truth_backend=frontend, ) @@ -4325,16 +4332,17 @@ def test_tensorflow_Svd( @ np.diag(frontend_s) @ frontend_v.T, ret_from_gt_np=u[..., : s.shape[0]] @ np.diag(s) @ v.T, - atol=1e-04, + rtol=1e-3, + atol=1e-3, backend=backend_fw, ground_truth_backend=frontend, ) else: assert_all_close( ret_np=frontend_s, - ret_from_gt_np=s, - rtol=1e-2, - atol=1e-2, + ret_from_gt_np=s.astype(dtype[0]), + rtol=1e-3, + atol=1e-3, backend=backend_fw, ground_truth_backend=frontend, ) diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py index b84819a5de224..a9580069cb512 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py @@ -884,7 +884,7 @@ def test_torch_svd( ) if backend_fw == "torch": frontend_ret = [x.detach() for x in frontend_ret] - ret = [x.detach() for x in frontend_ret] + ret = [x.detach() for x in ret] ret = [np.asarray(x) for x in ret] frontend_ret = [np.asarray(x).astype(input_dtype[0]) for x in frontend_ret] u, s, v = ret diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py index b6d3b64f08af1..6884f2864148a 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py @@ -1283,17 +1283,21 @@ def test_torch_svd( ) if backend_fw == "torch": frontend_ret = [x.detach() for x in frontend_ret] - ret = [x.detach() for x in frontend_ret] + ret = [x.detach() for x in ret] ret = [np.asarray(x, dtype=np.dtype(getattr(np, dtype[0]))) for x in ret] else: ret = [np.asarray(x) for x in ret] - frontend_ret = [np.asarray(x, dtype=np.dtype(getattr(np, dtype[0]))) for x in frontend_ret] + frontend_ret = [ + np.asarray(x, dtype=np.dtype(getattr(np, dtype[0]))) for x in frontend_ret + ] u, s, vh = ret frontend_u, frontend_s, frontend_vh = frontend_ret if full_matrices: helpers.assert_all_close( - ret_np=frontend_u[...,:frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_vh, - ret_from_gt_np=u[...,:s.shape[0]] @ np.diag(s) @ vh, + ret_np=frontend_u[..., : frontend_s.shape[0]] + @ np.diag(frontend_s) + @ frontend_vh, + ret_from_gt_np=u[..., : s.shape[0]] @ np.diag(s) @ vh, atol=1e-04, backend=backend_fw, ground_truth_backend=frontend, @@ -1308,7 +1312,6 @@ def test_torch_svd( ) - # svdvals @handle_frontend_test( fn_tree="torch.linalg.svdvals", From c1a6632bfd62c3c8f1b88cf306ade754082b1a1d Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Thu, 22 Aug 2024 03:43:22 +0000 Subject: [PATCH 26/35] changed ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py::test_torch_svd so that complex number inputs are also tested, they are passing --- .../frontends/torch/blas_and_lapack_ops.py | 14 +++++++++++--- .../test_torch/test_blas_and_lapack_ops.py | 4 +++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/ivy/functional/frontends/torch/blas_and_lapack_ops.py b/ivy/functional/frontends/torch/blas_and_lapack_ops.py index 4ced2b61b24e8..f5f33ec714b74 100644 --- a/ivy/functional/frontends/torch/blas_and_lapack_ops.py +++ b/ivy/functional/frontends/torch/blas_and_lapack_ops.py @@ -1,6 +1,6 @@ # global import ivy -from ivy.func_wrapper import with_unsupported_dtypes +from ivy.func_wrapper import with_unsupported_dtypes, with_supported_dtypes import ivy.functional.frontends.torch as torch_frontend from collections import namedtuple from ivy.functional.frontends.torch.func_wrapper import to_ivy_arrays_and_back @@ -190,10 +190,14 @@ def slogdet(A, *, out=None): return torch_frontend.linalg.slogdet(A, out=out) +@with_supported_dtypes( + {"2.15.0 and below": ("float64", "float32", "half", "complex64", "complex128")}, + "torch", +) @to_ivy_arrays_and_back def svd(input, some=True, compute_uv=True, *, out=None): retu = ivy.svd(input, full_matrices=not some, compute_uv=compute_uv) - results = namedtuple("svd", 'U S V') + results = namedtuple("svd", "U S V") if compute_uv: ret = results(retu[0], retu[1], ivy.adjoint(retu[2])) else: @@ -202,7 +206,11 @@ def svd(input, some=True, compute_uv=True, *, out=None): shape2 = shape shape1[-2] = shape[-1] shape2[-1] = shape[-2] - ret = results(ivy.zeros(shape1, device=input.device, dtype=input.dtype), ivy.astype(retu[0], input.dtype), ivy.zeros(shape2, device=input.device, dtype=input.dtype)) + ret = results( + ivy.zeros(shape1, device=input.device, dtype=input.dtype), + ivy.astype(retu[0], input.dtype), + ivy.zeros(shape2, device=input.device, dtype=input.dtype), + ) if ivy.exists(out): return ivy.inplace_update(out, ret) return ret diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py index a9580069cb512..31bfd26582d55 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py @@ -886,7 +886,9 @@ def test_torch_svd( frontend_ret = [x.detach() for x in frontend_ret] ret = [x.detach() for x in ret] ret = [np.asarray(x) for x in ret] - frontend_ret = [np.asarray(x).astype(input_dtype[0]) for x in frontend_ret] + frontend_ret = [ + np.asarray(x.resolve_conj()).astype(input_dtype[0]) for x in frontend_ret + ] u, s, v = ret frontend_u, frontend_s, frontend_v = frontend_ret if not compute_uv: From 9b75cd11f201836111bfa08f3ee67d4488fb575e Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Thu, 22 Aug 2024 05:54:41 +0000 Subject: [PATCH 27/35] changed all the torch's test_torch_svd so that complex number inputs are also tested, they are all passing --- ivy/functional/frontends/torch/blas_and_lapack_ops.py | 3 +-- ivy/functional/frontends/torch/tensor.py | 4 +++- ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py | 2 +- ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py | 6 ++++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/ivy/functional/frontends/torch/blas_and_lapack_ops.py b/ivy/functional/frontends/torch/blas_and_lapack_ops.py index f5f33ec714b74..403175a8253a6 100644 --- a/ivy/functional/frontends/torch/blas_and_lapack_ops.py +++ b/ivy/functional/frontends/torch/blas_and_lapack_ops.py @@ -191,8 +191,7 @@ def slogdet(A, *, out=None): @with_supported_dtypes( - {"2.15.0 and below": ("float64", "float32", "half", "complex64", "complex128")}, - "torch", + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" ) @to_ivy_arrays_and_back def svd(input, some=True, compute_uv=True, *, out=None): diff --git a/ivy/functional/frontends/torch/tensor.py b/ivy/functional/frontends/torch/tensor.py index d27360e361468..6cdca52182b4c 100644 --- a/ivy/functional/frontends/torch/tensor.py +++ b/ivy/functional/frontends/torch/tensor.py @@ -2009,7 +2009,9 @@ def adjoint(self): def conj(self): return torch_frontend.conj(self) - @with_unsupported_dtypes({"2.2 and below": ("float16", "bfloat16")}, "torch") + @with_supported_dtypes( + {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + ) def svd(self, some=True, compute_uv=True, *, out=None): return torch_frontend.svd(self, some=some, compute_uv=compute_uv, out=out) diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py index 6884f2864148a..0c908db303618 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py @@ -1249,7 +1249,7 @@ def test_torch_solve_ex( @handle_frontend_test( fn_tree="torch.linalg.svd", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float"), + available_dtypes=helpers.get_dtypes("valid"), min_value=0, max_value=10, shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py index 0640f82060abc..2d6c53b093212 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py @@ -13144,13 +13144,15 @@ def test_torch_svd( test_values=False, ) ret = [np.asarray(x) for x in ret] - frontend_ret = [np.asarray(x) for x in frontend_ret] + frontend_ret = [np.asarray(x.resolve_conj()) for x in frontend_ret] u, s, v = ret frontend_u, frontend_s, frontend_v = frontend_ret if not compute_uv: helpers.assert_all_close( - ret_np=frontend_s, + ret_np=frontend_s.astype( + input_dtype[0] + ), # it somehow always return float32 ret_from_gt_np=s, atol=1e-04, backend=backend_fw, From 5c9de15b384b68a4208e28f749c08e03ea6b24b2 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Thu, 22 Aug 2024 07:00:24 +0000 Subject: [PATCH 28/35] try to update torch and tensorflow's svd functions as they somehow return fixed dtypes depending on if input is complex, --- ivy/functional/frontends/tensorflow/linalg.py | 14 +++++++++-- ivy/functional/frontends/torch/linalg.py | 8 ++++++- .../test_tensorflow/test_linalg.py | 2 +- .../test_frontends/test_torch/test_linalg.py | 24 +++++++++++-------- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/ivy/functional/frontends/tensorflow/linalg.py b/ivy/functional/frontends/tensorflow/linalg.py index fe797894f4aef..7b2197111f3f6 100644 --- a/ivy/functional/frontends/tensorflow/linalg.py +++ b/ivy/functional/frontends/tensorflow/linalg.py @@ -357,13 +357,23 @@ def solve(matrix, rhs, /, *, adjoint=False, name=None): @to_ivy_arrays_and_back +@with_supported_dtypes( + {"2.15.0 and below": ("float32", "float64", "half", "complex32", "complex64")}, + "tensorflow", +) def svd(a, /, *, full_matrices=False, compute_uv=True, name=None): + if ivy.is_complex_dtype(a.dtype): + d = ivy.complex128 + else: + d = ivy.float64 if compute_uv: svd = ivy.svd(a, compute_uv=compute_uv, full_matrices=full_matrices) - return tuple([ivy.astype(svd.S, ivy.float64), ivy.astype(svd.U, ivy.float64), ivy.astype(svd.Vh.T, ivy.float64)]) + return tuple( + [ivy.astype(svd.S, d), ivy.astype(svd.U, d), ivy.astype(svd.Vh.T, d)] + ) else: svd = ivy.svd(a, compute_uv=compute_uv, full_matrices=full_matrices) - return ivy.astype(svd.S, ivy.float64) + return ivy.astype(svd.S, d) @to_ivy_arrays_and_back diff --git a/ivy/functional/frontends/torch/linalg.py b/ivy/functional/frontends/torch/linalg.py index e52d69a0de8c8..39a58e868b16e 100644 --- a/ivy/functional/frontends/torch/linalg.py +++ b/ivy/functional/frontends/torch/linalg.py @@ -333,7 +333,13 @@ def solve_ex(A, B, *, left=True, check_errors=False, out=None): ) def svd(A, /, *, full_matrices=True, driver=None, out=None): # TODO: add handling for driver - ret = ivy.svd(A, compute_uv=True, full_matrices=full_matrices) + USVh = ivy.svd(A, compute_uv=True, full_matrices=full_matrices) + if ivy.is_complex_dtype(A.dtype): + d = ivy.complex64 + else: + d = ivy.float32 + nt = namedtuple("svd", "U S Vh") + ret = nt(ivy.astype(USVh.U, d), ivy.astype(USVh.S, d), ivy.astype(USVh.Vh, d)) if ivy.exists(out): return ivy.inplace_update(out, ret) return ret diff --git a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py index c6a62f6598367..1f33ca53cc80f 100644 --- a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_linalg.py @@ -1074,7 +1074,7 @@ def test_tensorflow_solve( @handle_frontend_test( fn_tree="tensorflow.linalg.svd", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float"), + available_dtypes=helpers.get_dtypes("valid"), min_value=0, max_value=10, shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py index 0c908db303618..51a73184aee96 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py @@ -1284,19 +1284,23 @@ def test_torch_svd( if backend_fw == "torch": frontend_ret = [x.detach() for x in frontend_ret] ret = [x.detach() for x in ret] - ret = [np.asarray(x, dtype=np.dtype(getattr(np, dtype[0]))) for x in ret] - else: - ret = [np.asarray(x) for x in ret] - frontend_ret = [ - np.asarray(x, dtype=np.dtype(getattr(np, dtype[0]))) for x in frontend_ret - ] + ret = [np.asarray(x) for x in ret] + frontend_ret = [np.asarray(x) for x in frontend_ret] u, s, vh = ret frontend_u, frontend_s, frontend_vh = frontend_ret + if ivy.is_complex_dtype(x.dtype): + d = ivy.complex64 + else: + d = ivy.float32 + # the dtypes somehow become wrong after matrix calculation + # though the return values should have correct dtypes if full_matrices: helpers.assert_all_close( - ret_np=frontend_u[..., : frontend_s.shape[0]] - @ np.diag(frontend_s) - @ frontend_vh, + ret_np=( + frontend_u[..., : frontend_s.shape[0]] + @ np.diag(frontend_s) + @ frontend_vh + ).astype(d), ret_from_gt_np=u[..., : s.shape[0]] @ np.diag(s) @ vh, atol=1e-04, backend=backend_fw, @@ -1304,7 +1308,7 @@ def test_torch_svd( ) else: helpers.assert_all_close( - ret_np=frontend_u @ np.diag(frontend_s) @ frontend_vh, + ret_np=(frontend_u @ np.diag(frontend_s) @ frontend_vh).astype(d), ret_from_gt_np=u @ np.diag(s) @ vh, atol=1e-04, backend=backend_fw, From 2f76f664e300625f8d822164eecdc61f657953b7 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Thu, 22 Aug 2024 09:51:42 +0000 Subject: [PATCH 29/35] seems like should not use svdvals as it always return a not complex value instead as the same as the input, but the documents shows that the S component will always be real, which is different from the groundtruth behavior shown in the, updated the jax svd tests to check for complex inputs --- ivy/functional/frontends/jax/lax/linalg.py | 6 +++--- ivy/functional/frontends/numpy/linalg/decompositions.py | 7 ++++++- .../test_frontends/test_jax/test_lax/test_linalg.py | 2 +- .../test_frontends/test_jax/test_numpy/test_linalg.py | 4 ++-- .../test_numpy/test_linalg/test_decompositions.py | 4 ++-- 5 files changed, 14 insertions(+), 9 deletions(-) diff --git a/ivy/functional/frontends/jax/lax/linalg.py b/ivy/functional/frontends/jax/lax/linalg.py index d48cac8a85911..7180ae2d1a988 100644 --- a/ivy/functional/frontends/jax/lax/linalg.py +++ b/ivy/functional/frontends/jax/lax/linalg.py @@ -46,9 +46,9 @@ def qr(x, /, *, full_matrices=False): @to_ivy_arrays_and_back @with_unsupported_dtypes({"0.4.14 and below": ("bfloat16",)}, "jax") def svd(x, /, *, full_matrices=True, compute_uv=True, subset_by_index=None): - #TODO: handle subset_by_index + # TODO: handle subset_by_index + ret = ivy.svd(x, full_matrices=full_matrices) if compute_uv: - return tuple(ivy.svd(x, full_matrices=full_matrices)) + return tuple(ret) else: return ivy.svdvals(x) - diff --git a/ivy/functional/frontends/numpy/linalg/decompositions.py b/ivy/functional/frontends/numpy/linalg/decompositions.py index 927096f08476a..5fe8c364e0f27 100644 --- a/ivy/functional/frontends/numpy/linalg/decompositions.py +++ b/ivy/functional/frontends/numpy/linalg/decompositions.py @@ -1,6 +1,7 @@ # local import ivy from ivy.functional.frontends.numpy.func_wrapper import to_ivy_arrays_and_back +from ivy.func_wrapper import with_supported_dtypes @to_ivy_arrays_and_back @@ -14,8 +15,12 @@ def qr(a, mode="reduced"): @to_ivy_arrays_and_back +@with_supported_dtypes( + {"1.26.3 and below": ("float64", "float32", "half", "complex64", "complex128")}, + "numpy", +) def svd(a, full_matrices=True, compute_uv=True, hermitian=False): - # Todo: hermitian handling, ivy.astype does not work for some reason + # Todo: hermitian handling if compute_uv: return ivy.svd(a, full_matrices=full_matrices, compute_uv=compute_uv) else: diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py index d25a5ec3858f2..0698b1ff9cdbe 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py @@ -164,7 +164,7 @@ def test_jax_qr( @handle_frontend_test( fn_tree="jax.lax.linalg.svd", dtype_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float"), + available_dtypes=helpers.get_dtypes("valid"), min_value=0, max_value=10, shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py index ea390e6526aed..6cf1376c6bccf 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py @@ -854,11 +854,11 @@ def test_jax_solve( @handle_frontend_test( fn_tree="jax.numpy.linalg.svd", dtype_and_x=helpers.dtype_and_values( - available_dtypes=helpers.get_dtypes("float"), + available_dtypes=helpers.get_dtypes("valid"), min_value=0, max_value=10, shape=helpers.ints(min_value=2, max_value=5).map(lambda x: (x, x)), - ).filter(lambda x: "float16" not in x[0] and "bfloat16" not in x[0]), + ), full_matrices=st.booleans(), compute_uv=st.booleans(), test_with_out=st.just(False), diff --git a/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py b/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py index 1e43a8a4e866c..a8d57e1100b1b 100644 --- a/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py +++ b/ivy_tests/test_ivy/test_frontends/test_numpy/test_linalg/test_decompositions.py @@ -122,7 +122,7 @@ def test_numpy_svd( ) if compute_uv: ret = [np.asarray(x) for x in ret] - frontend_ret = [np.asarray(x).astype(dtype[0]) for x in frontend_ret] + frontend_ret = [np.asarray(x) for x in frontend_ret] u, s, vh = ret frontend_u, frontend_s, frontend_vh = frontend_ret if not full_matrices: @@ -145,7 +145,7 @@ def test_numpy_svd( ) else: helpers.assert_all_close( - ret_np=frontend_ret.astype(dtype[0]), + ret_np=frontend_ret, ret_from_gt_np=ret, atol=1e-3, backend=backend_fw, From 412e60c8b75348fec397867e5abef0598b5e7f57 Mon Sep 17 00:00:00 2001 From: Jin Wang Date: Fri, 23 Aug 2024 08:08:14 +0000 Subject: [PATCH 30/35] fixed jax's svd to teat for complex input. though only jax.lax.linalg.svd fail for tensorflow backend due to significant and updated all relavent svd with more complex supported dtype --- ivy/functional/frontends/jax/lax/linalg.py | 28 +++++++++++++++---- ivy/functional/frontends/jax/numpy/linalg.py | 26 ++++++++++++++--- .../frontends/numpy/linalg/decompositions.py | 11 +++++++- ivy/functional/frontends/tensorflow/linalg.py | 11 +++++++- .../frontends/tensorflow/raw_ops.py | 11 +++++++- .../frontends/torch/blas_and_lapack_ops.py | 12 +++++++- ivy/functional/frontends/torch/linalg.py | 12 +++++++- ivy/functional/frontends/torch/tensor.py | 12 +++++++- .../test_jax/test_lax/test_linalg.py | 6 ++-- .../test_jax/test_numpy/test_linalg.py | 7 ++--- 10 files changed, 113 insertions(+), 23 deletions(-) diff --git a/ivy/functional/frontends/jax/lax/linalg.py b/ivy/functional/frontends/jax/lax/linalg.py index 7180ae2d1a988..c9568fbfdf214 100644 --- a/ivy/functional/frontends/jax/lax/linalg.py +++ b/ivy/functional/frontends/jax/lax/linalg.py @@ -1,6 +1,6 @@ import ivy from ivy.functional.frontends.jax.func_wrapper import to_ivy_arrays_and_back -from ivy.func_wrapper import with_unsupported_dtypes +from ivy.func_wrapper import with_unsupported_dtypes, with_supported_dtypes @to_ivy_arrays_and_back @@ -44,11 +44,29 @@ def qr(x, /, *, full_matrices=False): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"0.4.14 and below": ("bfloat16",)}, "jax") +@with_supported_dtypes( + { + "0.4.14 and below": ( + "float64", + "float32", + "half", + "complex32", + "complex64", + "complex128", + ) + }, + "jax", +) def svd(x, /, *, full_matrices=True, compute_uv=True, subset_by_index=None): # TODO: handle subset_by_index - ret = ivy.svd(x, full_matrices=full_matrices) + if ivy.is_complex_dtype(x.dtype): + d = ivy.complex128 + else: + d = ivy.float64 if compute_uv: - return tuple(ret) + svd = ivy.svd(x, compute_uv=compute_uv, full_matrices=full_matrices) + return tuple( + [ivy.astype(svd.U, d), ivy.astype(svd.S, d), ivy.astype(svd.Vh, d)] + ) else: - return ivy.svdvals(x) + return ivy.astype(ivy.svdvals(x), ivy.float64) diff --git a/ivy/functional/frontends/jax/numpy/linalg.py b/ivy/functional/frontends/jax/numpy/linalg.py index 993d8a8328cee..1265b6648246c 100644 --- a/ivy/functional/frontends/jax/numpy/linalg.py +++ b/ivy/functional/frontends/jax/numpy/linalg.py @@ -120,14 +120,32 @@ def solve(a, b): @to_ivy_arrays_and_back -@with_unsupported_dtypes({"0.4.24 and below": ("float16", "bfloat16")}, "jax") +@with_supported_dtypes( + { + "0.4.24 and below": ( + "float64", + "float32", + "half", + "complex32", + "complex64", + "complex128", + ) + }, + "jax", +) def svd(a, /, *, full_matrices=True, compute_uv=True, hermitian=None): # TODO: handle hermitian - ret = ivy.svd(a, full_matrices=full_matrices, compute_uv=compute_uv) + if ivy.is_complex_dtype(a.dtype): + d = ivy.complex128 + else: + d = ivy.float64 if compute_uv: - return tuple(ret) + svd = ivy.svd(a, compute_uv=compute_uv, full_matrices=full_matrices) + return tuple( + [ivy.astype(svd.U, d), ivy.astype(svd.S, d), ivy.astype(svd.Vh, d)] + ) else: - return ivy.svdvals(a) + return ivy.astype(ivy.svdvals(a), ivy.float64) @to_ivy_arrays_and_back diff --git a/ivy/functional/frontends/numpy/linalg/decompositions.py b/ivy/functional/frontends/numpy/linalg/decompositions.py index 5fe8c364e0f27..7147c7d1e6679 100644 --- a/ivy/functional/frontends/numpy/linalg/decompositions.py +++ b/ivy/functional/frontends/numpy/linalg/decompositions.py @@ -16,7 +16,16 @@ def qr(a, mode="reduced"): @to_ivy_arrays_and_back @with_supported_dtypes( - {"1.26.3 and below": ("float64", "float32", "half", "complex64", "complex128")}, + { + "1.26.3 and below": ( + "float64", + "float32", + "half", + "complex32", + "complex64", + "complex128", + ) + }, "numpy", ) def svd(a, full_matrices=True, compute_uv=True, hermitian=False): diff --git a/ivy/functional/frontends/tensorflow/linalg.py b/ivy/functional/frontends/tensorflow/linalg.py index 7b2197111f3f6..7d80146b349b3 100644 --- a/ivy/functional/frontends/tensorflow/linalg.py +++ b/ivy/functional/frontends/tensorflow/linalg.py @@ -358,7 +358,16 @@ def solve(matrix, rhs, /, *, adjoint=False, name=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.15.0 and below": ("float32", "float64", "half", "complex32", "complex64")}, + { + "2.15.0 and below": ( + "float32", + "float64", + "half", + "complex32", + "complex64", + "complex128", + ) + }, "tensorflow", ) def svd(a, /, *, full_matrices=False, compute_uv=True, name=None): diff --git a/ivy/functional/frontends/tensorflow/raw_ops.py b/ivy/functional/frontends/tensorflow/raw_ops.py index 0128e89695fca..38ffbcd15b160 100644 --- a/ivy/functional/frontends/tensorflow/raw_ops.py +++ b/ivy/functional/frontends/tensorflow/raw_ops.py @@ -832,7 +832,16 @@ def Sum(*, input, axis, keep_dims=False, name="Sum"): @with_supported_dtypes( - {"2.15.0 and below": ("float64", "float32", "half", "complex64", "complex128")}, + { + "2.15.0 and below": ( + "float64", + "float32", + "half", + "complex32", + "complex64", + "complex128", + ) + }, "tensorflow", ) @to_ivy_arrays_and_back diff --git a/ivy/functional/frontends/torch/blas_and_lapack_ops.py b/ivy/functional/frontends/torch/blas_and_lapack_ops.py index 403175a8253a6..c0f6f27bd584b 100644 --- a/ivy/functional/frontends/torch/blas_and_lapack_ops.py +++ b/ivy/functional/frontends/torch/blas_and_lapack_ops.py @@ -191,7 +191,17 @@ def slogdet(A, *, out=None): @with_supported_dtypes( - {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + { + "2.2 and below": ( + "float64", + "float32", + "half", + "complex32", + "complex64", + "complex128", + ) + }, + "torch", ) @to_ivy_arrays_and_back def svd(input, some=True, compute_uv=True, *, out=None): diff --git a/ivy/functional/frontends/torch/linalg.py b/ivy/functional/frontends/torch/linalg.py index 39a58e868b16e..79ac5f318f20c 100644 --- a/ivy/functional/frontends/torch/linalg.py +++ b/ivy/functional/frontends/torch/linalg.py @@ -329,7 +329,17 @@ def solve_ex(A, B, *, left=True, check_errors=False, out=None): @to_ivy_arrays_and_back @with_supported_dtypes( - {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + { + "2.2 and below": ( + "float64", + "float32", + "half", + "complex32", + "complex64", + "complex128", + ) + }, + "torch", ) def svd(A, /, *, full_matrices=True, driver=None, out=None): # TODO: add handling for driver diff --git a/ivy/functional/frontends/torch/tensor.py b/ivy/functional/frontends/torch/tensor.py index 6cdca52182b4c..ea51c564388e9 100644 --- a/ivy/functional/frontends/torch/tensor.py +++ b/ivy/functional/frontends/torch/tensor.py @@ -2010,7 +2010,17 @@ def conj(self): return torch_frontend.conj(self) @with_supported_dtypes( - {"2.2 and below": ("float32", "float64", "complex32", "complex64")}, "torch" + { + "2.2 and below": ( + "float64", + "float32", + "half", + "complex32", + "complex64", + "complex128", + ) + }, + "torch", ) def svd(self, some=True, compute_uv=True, *, out=None): return torch_frontend.svd(self, some=some, compute_uv=compute_uv, out=out) diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py index 0698b1ff9cdbe..dae44990b5a34 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_lax/test_linalg.py @@ -211,7 +211,7 @@ def test_jax_svd( if backend_fw == "torch": ret = ret.detach() assert_all_close( - ret_np=np.asarray(frontend_ret, dtype=np.dtype(getattr(np, dtype[0]))), + ret_np=np.asarray(frontend_ret), ret_from_gt_np=np.asarray(ret), rtol=1e-3, backend=backend_fw, @@ -221,9 +221,7 @@ def test_jax_svd( if backend_fw == "torch": ret = [x.detach() for x in ret] ret = [np.asarray(x) for x in ret] - frontend_ret = [ - np.asarray(x, dtype=np.dtype(getattr(np, dtype[0]))) for x in frontend_ret - ] + frontend_ret = [np.asarray(x) for x in frontend_ret] u, s, v = ret frontend_u, frontend_s, frontend_v = frontend_ret if not full_matrices: diff --git a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py index 6cf1376c6bccf..aee40b5b147fa 100644 --- a/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_jax/test_numpy/test_linalg.py @@ -896,9 +896,8 @@ def test_jax_svd( x for x in frontend_ret ] # unpack jaxlib.xla_extension.ArrayImpl as it is no .detach() ret = [x for x in frontend_ret] - detyp = np.dtype(getattr(np, dtype[0])) - ret = [np.asarray(x).astype(detyp) for x in ret] - frontend_ret = [np.asarray(x, dtype=detyp) for x in frontend_ret] + ret = [np.asarray(x) for x in ret] + frontend_ret = [np.asarray(x) for x in frontend_ret] u, s, vh = ret frontend_u, frontend_s, frontend_vh = frontend_ret if not full_matrices: @@ -923,7 +922,7 @@ def test_jax_svd( if backend_fw == "torch": ret = ret.detach() assert_all_close( - ret_np=np.asarray(frontend_ret, dtype=np.dtype(getattr(np, dtype[0]))), + ret_np=np.asarray(frontend_ret), ret_from_gt_np=np.asarray(ret), atol=1e-3, backend=backend_fw, From 99b7266f884277d0c4b641bcf095be51eff82518 Mon Sep 17 00:00:00 2001 From: Daniel4078 <45633544+Daniel4078@users.noreply.github.com> Date: Sat, 28 Sep 2024 20:40:29 +0100 Subject: [PATCH 31/35] small update on test_torch.test_tensor.test_torch_svd --- ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py index 2d6c53b093212..887f2cbfdab4d 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py @@ -13145,14 +13145,11 @@ def test_torch_svd( ) ret = [np.asarray(x) for x in ret] frontend_ret = [np.asarray(x.resolve_conj()) for x in frontend_ret] - u, s, v = ret frontend_u, frontend_s, frontend_v = frontend_ret if not compute_uv: helpers.assert_all_close( - ret_np=frontend_s.astype( - input_dtype[0] - ), # it somehow always return float32 + ret_np=frontend_s ret_from_gt_np=s, atol=1e-04, backend=backend_fw, From 00f7754a90007dcf86997b2c55f5bb49158c1bb7 Mon Sep 17 00:00:00 2001 From: Daniel4078 <45633544+Daniel4078@users.noreply.github.com> Date: Sat, 28 Sep 2024 20:42:54 +0100 Subject: [PATCH 32/35] Update test_blas_and_lapack_ops.py --- .../test_frontends/test_torch/test_blas_and_lapack_ops.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py index 31bfd26582d55..8cd18e858f16e 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_blas_and_lapack_ops.py @@ -886,9 +886,7 @@ def test_torch_svd( frontend_ret = [x.detach() for x in frontend_ret] ret = [x.detach() for x in ret] ret = [np.asarray(x) for x in ret] - frontend_ret = [ - np.asarray(x.resolve_conj()).astype(input_dtype[0]) for x in frontend_ret - ] + frontend_ret = [np.asarray(x.resolve_conj()) for x in frontend_ret] u, s, v = ret frontend_u, frontend_s, frontend_v = frontend_ret if not compute_uv: From 49db616fa28068b9387e2012e65c8b9262d94ed2 Mon Sep 17 00:00:00 2001 From: Daniel4078 <45633544+Daniel4078@users.noreply.github.com> Date: Sat, 28 Sep 2024 20:45:02 +0100 Subject: [PATCH 33/35] Update test_linalg.py --- .../test_ivy/test_frontends/test_torch/test_linalg.py | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py index ee79e451aefe5..0739426396286 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py @@ -1282,19 +1282,13 @@ def test_torch_svd( frontend_ret = [np.asarray(x) for x in frontend_ret] u, s, vh = ret frontend_u, frontend_s, frontend_vh = frontend_ret - if ivy.is_complex_dtype(x.dtype): - d = ivy.complex64 - else: - d = ivy.float32 - # the dtypes somehow become wrong after matrix calculation - # though the return values should have correct dtypes if full_matrices: helpers.assert_all_close( ret_np=( frontend_u[..., : frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_vh - ).astype(d), + ) ret_from_gt_np=u[..., : s.shape[0]] @ np.diag(s) @ vh, atol=1e-04, backend=backend_fw, @@ -1302,7 +1296,7 @@ def test_torch_svd( ) else: helpers.assert_all_close( - ret_np=(frontend_u @ np.diag(frontend_s) @ frontend_vh).astype(d), + ret_np=(frontend_u @ np.diag(frontend_s) @ frontend_vh), ret_from_gt_np=u @ np.diag(s) @ vh, atol=1e-04, backend=backend_fw, From 637652ef54cca5f38a5508e94195e4b570551693 Mon Sep 17 00:00:00 2001 From: Daniel4078 <45633544+Daniel4078@users.noreply.github.com> Date: Mon, 30 Sep 2024 10:43:44 +0100 Subject: [PATCH 34/35] Update test_linalg.py --- ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py index 0739426396286..6710067a2678e 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_linalg.py @@ -1288,7 +1288,7 @@ def test_torch_svd( frontend_u[..., : frontend_s.shape[0]] @ np.diag(frontend_s) @ frontend_vh - ) + ), ret_from_gt_np=u[..., : s.shape[0]] @ np.diag(s) @ vh, atol=1e-04, backend=backend_fw, From 390b00bb5c403ce4fa2d16ebc3fd09e01f2fb7b8 Mon Sep 17 00:00:00 2001 From: Daniel4078 <45633544+Daniel4078@users.noreply.github.com> Date: Mon, 30 Sep 2024 10:45:11 +0100 Subject: [PATCH 35/35] Update test_tensor.py --- ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py index 887f2cbfdab4d..eaad5586b17fd 100644 --- a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py +++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py @@ -13149,7 +13149,7 @@ def test_torch_svd( frontend_u, frontend_s, frontend_v = frontend_ret if not compute_uv: helpers.assert_all_close( - ret_np=frontend_s + ret_np=frontend_s, ret_from_gt_np=s, atol=1e-04, backend=backend_fw,