We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
multi_dot


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `ivy/functional/frontends/torch/linalg.py`
Content:
```
1 # local
2 import math
3 import ivy
4 import ivy.functional.frontends.torch as torch_frontend
5 from ivy.functional.frontends.torch.func_wrapper import to_ivy_arrays_and_back
6 from ivy.func_wrapper import with_supported_dtypes, with_unsupported_dtypes
7 
8 
9 @to_ivy_arrays_and_back
10 def vector_norm(input, ord=2, dim=None, keepdim=False, *, dtype=None, out=None):
11     return ivy.vector_norm(
12         input, axis=dim, keepdims=keepdim, ord=ord, out=out, dtype=dtype
13     )
14 
15 
16 @to_ivy_arrays_and_back
17 def diagonal(A, *, offset=0, dim1=-2, dim2=-1):
18     return torch_frontend.diagonal(A, offset=offset, dim1=dim1, dim2=dim2)
19 
20 
21 @to_ivy_arrays_and_back
22 def divide(input, other, *, rounding_mode=None, out=None):
23     return ivy.divide(input, other, out=out)
24 
25 
26 @to_ivy_arrays_and_back
27 def inv(input, *, out=None):
28     return ivy.inv(input, out=out)
29 
30 
31 @to_ivy_arrays_and_back
32 def pinv(input, *, atol=None, rtol=None, hermitian=False, out=None):
33     # TODO: add handling for hermitian once complex numbers are supported
34     if atol is None:
35         return ivy.pinv(input, rtol=rtol, out=out)
36     else:
37         sigma = ivy.svdvals(input)[0]
38         if rtol is None:
39             rtol = atol / sigma
40         else:
41             if atol > rtol * sigma:
42                 rtol = atol / sigma
43 
44     return ivy.pinv(input, rtol=rtol, out=out)
45 
46 
47 @to_ivy_arrays_and_back
48 def det(input, *, out=None):
49     return ivy.det(input, out=out)
50 
51 
52 @to_ivy_arrays_and_back
53 def eigvals(input, *, out=None):
54     # TODO: add handling for out
55     return ivy.eigvals(input)
56 
57 
58 @to_ivy_arrays_and_back
59 def eigvalsh(input, UPLO="L", *, out=None):
60     return ivy.eigvalsh(input, UPLO=UPLO, out=out)
61 
62 
63 @to_ivy_arrays_and_back
64 @with_unsupported_dtypes({"1.11.0 and below": ("bfloat16", "float16")}, "torch")
65 def eigh(a, /, UPLO="L", out=None):
66     return ivy.eigh(a, UPLO=UPLO, out=out)
67 
68 
69 @to_ivy_arrays_and_back
70 def qr(input, mode="reduced", *, out=None):
71     if mode == "reduced":
72         ret = ivy.qr(input, mode="reduced")
73     elif mode == "r":
74         Q, R = ivy.qr(input, mode="r")
75         Q = []
76         ret = Q, R
77     elif mode == "complete":
78         ret = ivy.qr(input, mode="complete")
79     if ivy.exists(out):
80         return ivy.inplace_update(out, ret)
81     return ret
82 
83 
84 @to_ivy_arrays_and_back
85 def slogdet(input, *, out=None):
86     # TODO: add handling for out
87     return ivy.slogdet(input)
88 
89 
90 @to_ivy_arrays_and_back
91 def matrix_power(input, n, *, out=None):
92     return ivy.matrix_power(input, n, out=out)
93 
94 
95 @with_supported_dtypes(
96     {"1.11.0 and below": ("float32", "float64", "complex64", "complex128")}, "torch"
97 )
98 @to_ivy_arrays_and_back
99 def matrix_norm(input, ord="fro", dim=(-2, -1), keepdim=False, *, dtype=None, out=None):
100     if "complex" in ivy.as_ivy_dtype(input.dtype):
101         input = ivy.abs(input)
102     if dtype:
103         input = ivy.astype(input, dtype)
104     return ivy.matrix_norm(input, ord=ord, axis=dim, keepdims=keepdim, out=out)
105 
106 
107 @to_ivy_arrays_and_back
108 @with_unsupported_dtypes({"1.11.0 and below": ("float16",)}, "torch")
109 def cross(input, other, *, dim=None, out=None):
110     return torch_frontend.miscellaneous_ops.cross(input, other, dim=dim, out=out)
111 
112 
113 @to_ivy_arrays_and_back
114 def vecdot(x1, x2, *, dim=-1, out=None):
115     return ivy.vecdot(x1, x2, axis=dim, out=out)
116 
117 
118 @to_ivy_arrays_and_back
119 def matrix_rank(input, *, atol=None, rtol=None, hermitian=False, out=None):
120     # TODO: add handling for hermitian once complex numbers are supported
121     return ivy.astype(ivy.matrix_rank(input, atol=atol, rtol=rtol, out=out), ivy.int64)
122 
123 
124 @to_ivy_arrays_and_back
125 def cholesky(input, *, upper=False, out=None):
126     return ivy.cholesky(input, upper=upper, out=out)
127 
128 
129 @to_ivy_arrays_and_back
130 def svd(A, /, *, full_matrices=True, driver=None, out=None):
131     # TODO: add handling for driver and out
132     return ivy.svd(A, compute_uv=True, full_matrices=full_matrices)
133 
134 
135 @to_ivy_arrays_and_back
136 def svdvals(A, *, driver=None, out=None):
137     # TODO: add handling for driver
138     return ivy.svdvals(A, out=out)
139 
140 
141 @to_ivy_arrays_and_back
142 def inv_ex(input, *, check_errors=False, out=None):
143     try:
144         inputInv = ivy.inv(input, out=out)
145         info = ivy.zeros(input.shape[:-2], dtype=ivy.int32)
146         return inputInv, info
147     except RuntimeError as e:
148         if check_errors:
149             raise RuntimeError(e)
150         else:
151             inputInv = input * math.nan
152             info = ivy.ones(input.shape[:-2], dtype=ivy.int32)
153             return inputInv, info
154 
155 
156 @to_ivy_arrays_and_back
157 @with_unsupported_dtypes({"1.11.0 and below": ("float16", "bfloat16")}, "torch")
158 def tensorinv(input, ind=2, *, out=None):
159     not_invertible = "Reshaped tensor is not invertible"
160     prod_cond = "Tensor shape must satisfy prod(A.shape[:ind]) == prod(A.shape[ind:])"
161     positive_ind_cond = "Expected a strictly positive integer for 'ind'"
162     input_shape = ivy.shape(input)
163     assert ind > 0, f"{positive_ind_cond}"
164     shape_ind_end = input_shape[:ind]
165     shape_ind_start = input_shape[ind:]
166     prod_ind_end = 1
167     prod_ind_start = 1
168     for i in shape_ind_start:
169         prod_ind_start *= i
170     for j in shape_ind_end:
171         prod_ind_end *= j
172     assert prod_ind_end == prod_ind_start, f"{prod_cond}."
173     inverse_shape = shape_ind_start + shape_ind_end
174     input = ivy.reshape(input, shape=(prod_ind_end, -1))
175     inverse_shape_tuple = tuple([*inverse_shape])
176     assert inv_ex(input, check_errors=True), f"{not_invertible}."
177     inverse_tensor = ivy.inv(input)
178     return ivy.reshape(inverse_tensor, shape=inverse_shape_tuple, out=out)
179 
180 
181 @with_unsupported_dtypes({"1.11.0 and below": ("bfloat16", "float16")}, "torch")
182 def eig(input, *, out=None):
183     return ivy.eig(input, out=out)
184 
185 
186 @to_ivy_arrays_and_back
187 @with_unsupported_dtypes({"1.11.0 and below": ("bfloat16", "float16")}, "torch")
188 def solve(input, other, *, out=None):
189     return ivy.solve(input, other, out=out)
190 
191 
192 @to_ivy_arrays_and_back
193 @with_unsupported_dtypes({"1.11.0 and below": ("bfloat16", "float16")}, "torch")
194 def tensorsolve(A, B, dims=None, *, out=None):
195     return ivy.tensorsolve(A, B, axes=dims, out=out)
196 
197 
198 @to_ivy_arrays_and_back
199 @with_unsupported_dtypes({"1.11.0 and below": ("bfloat16", "float16")}, "torch")
200 def lu_factor(A, *, pivot=True, out=None):
201     return ivy.lu_factor(A, pivot=pivot, out=out)
202 
203 
204 @to_ivy_arrays_and_back
205 def matmul(input, other, *, out=None):
206     return ivy.matmul(input, other, out=out)
207 
208 
209 @to_ivy_arrays_and_back
210 @with_unsupported_dtypes({"1.11.0 and below": ("bfloat16", "float16")}, "torch")
211 def vander(x, N=None):
212     if len(x.shape) < 1:
213         raise RuntimeError("Input dim must be greater than or equal to 1.")
214 
215     # pytorch always return int64 for integers
216     if "int" in x.dtype:
217         x = ivy.astype(x, ivy.int64)
218 
219     if len(x.shape) == 1:
220         # torch always returns the powers in ascending order
221         return ivy.vander(x, N=N, increasing=True)
222 
223     # support multi-dimensional array
224     original_shape = x.shape
225     if N is None:
226         N = x.shape[-1]
227 
228     # store the vander output
229     x = ivy.reshape(x, (-1, x.shape[-1]))
230     output = []
231 
232     for i in range(x.shape[0]):
233         output.append(ivy.vander(x[i], N=N, increasing=True))
234 
235     output = ivy.stack(output)
236     output = ivy.reshape(output, (*original_shape, N))
237     output = ivy.astype(output, x.dtype)
238     return output
239
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/ivy/functional/frontends/torch/linalg.py b/ivy/functional/frontends/torch/linalg.py
--- a/ivy/functional/frontends/torch/linalg.py
+++ b/ivy/functional/frontends/torch/linalg.py
@@ -236,3 +236,9 @@
     output = ivy.reshape(output, (*original_shape, N))
     output = ivy.astype(output, x.dtype)
     return output
+
+
+@to_ivy_arrays_and_back
+@with_unsupported_dtypes({"1.11.0 and below": ("bfloat16", "float16")}, "torch")
+def multi_dot(tensors, *, out=None):
+    return ivy.multi_dot(tensors, out=out)

{"golden_diff": "diff --git a/ivy/functional/frontends/torch/linalg.py b/ivy/functional/frontends/torch/linalg.py\n--- a/ivy/functional/frontends/torch/linalg.py\n+++ b/ivy/functional/frontends/torch/linalg.py\n@@ -236,3 +236,9 @@\n     output = ivy.reshape(output, (*original_shape, N))\n     output = ivy.astype(output, x.dtype)\n     return output\n+\n+\n+@to_ivy_arrays_and_back\n+@with_unsupported_dtypes({\"1.11.0 and below\": (\"bfloat16\", \"float16\")}, \"torch\")\n+def multi_dot(tensors, *, out=None):\n+    return ivy.multi_dot(tensors, out=out)\n", "issue": "multi_dot\n\n", "before_files": [{"content": "# local\nimport math\nimport ivy\nimport ivy.functional.frontends.torch as torch_frontend\nfrom ivy.functional.frontends.torch.func_wrapper import to_ivy_arrays_and_back\nfrom ivy.func_wrapper import with_supported_dtypes, with_unsupported_dtypes\n\n\n@to_ivy_arrays_and_back\ndef vector_norm(input, ord=2, dim=None, keepdim=False, *, dtype=None, out=None):\n    return ivy.vector_norm(\n        input, axis=dim, keepdims=keepdim, ord=ord, out=out, dtype=dtype\n    )\n\n\n@to_ivy_arrays_and_back\ndef diagonal(A, *, offset=0, dim1=-2, dim2=-1):\n    return torch_frontend.diagonal(A, offset=offset, dim1=dim1, dim2=dim2)\n\n\n@to_ivy_arrays_and_back\ndef divide(input, other, *, rounding_mode=None, out=None):\n    return ivy.divide(input, other, out=out)\n\n\n@to_ivy_arrays_and_back\ndef inv(input, *, out=None):\n    return ivy.inv(input, out=out)\n\n\n@to_ivy_arrays_and_back\ndef pinv(input, *, atol=None, rtol=None, hermitian=False, out=None):\n    # TODO: add handling for hermitian once complex numbers are supported\n    if atol is None:\n        return ivy.pinv(input, rtol=rtol, out=out)\n    else:\n        sigma = ivy.svdvals(input)[0]\n        if rtol is None:\n            rtol = atol / sigma\n        else:\n            if atol > rtol * sigma:\n                rtol = atol / sigma\n\n    return ivy.pinv(input, rtol=rtol, out=out)\n\n\n@to_ivy_arrays_and_back\ndef det(input, *, out=None):\n    return ivy.det(input, out=out)\n\n\n@to_ivy_arrays_and_back\ndef eigvals(input, *, out=None):\n    # TODO: add handling for out\n    return ivy.eigvals(input)\n\n\n@to_ivy_arrays_and_back\ndef eigvalsh(input, UPLO=\"L\", *, out=None):\n    return ivy.eigvalsh(input, UPLO=UPLO, out=out)\n\n\n@to_ivy_arrays_and_back\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"bfloat16\", \"float16\")}, \"torch\")\ndef eigh(a, /, UPLO=\"L\", out=None):\n    return ivy.eigh(a, UPLO=UPLO, out=out)\n\n\n@to_ivy_arrays_and_back\ndef qr(input, mode=\"reduced\", *, out=None):\n    if mode == \"reduced\":\n        ret = ivy.qr(input, mode=\"reduced\")\n    elif mode == \"r\":\n        Q, R = ivy.qr(input, mode=\"r\")\n        Q = []\n        ret = Q, R\n    elif mode == \"complete\":\n        ret = ivy.qr(input, mode=\"complete\")\n    if ivy.exists(out):\n        return ivy.inplace_update(out, ret)\n    return ret\n\n\n@to_ivy_arrays_and_back\ndef slogdet(input, *, out=None):\n    # TODO: add handling for out\n    return ivy.slogdet(input)\n\n\n@to_ivy_arrays_and_back\ndef matrix_power(input, n, *, out=None):\n    return ivy.matrix_power(input, n, out=out)\n\n\n@with_supported_dtypes(\n    {\"1.11.0 and below\": (\"float32\", \"float64\", \"complex64\", \"complex128\")}, \"torch\"\n)\n@to_ivy_arrays_and_back\ndef matrix_norm(input, ord=\"fro\", dim=(-2, -1), keepdim=False, *, dtype=None, out=None):\n    if \"complex\" in ivy.as_ivy_dtype(input.dtype):\n        input = ivy.abs(input)\n    if dtype:\n        input = ivy.astype(input, dtype)\n    return ivy.matrix_norm(input, ord=ord, axis=dim, keepdims=keepdim, out=out)\n\n\n@to_ivy_arrays_and_back\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"float16\",)}, \"torch\")\ndef cross(input, other, *, dim=None, out=None):\n    return torch_frontend.miscellaneous_ops.cross(input, other, dim=dim, out=out)\n\n\n@to_ivy_arrays_and_back\ndef vecdot(x1, x2, *, dim=-1, out=None):\n    return ivy.vecdot(x1, x2, axis=dim, out=out)\n\n\n@to_ivy_arrays_and_back\ndef matrix_rank(input, *, atol=None, rtol=None, hermitian=False, out=None):\n    # TODO: add handling for hermitian once complex numbers are supported\n    return ivy.astype(ivy.matrix_rank(input, atol=atol, rtol=rtol, out=out), ivy.int64)\n\n\n@to_ivy_arrays_and_back\ndef cholesky(input, *, upper=False, out=None):\n    return ivy.cholesky(input, upper=upper, out=out)\n\n\n@to_ivy_arrays_and_back\ndef svd(A, /, *, full_matrices=True, driver=None, out=None):\n    # TODO: add handling for driver and out\n    return ivy.svd(A, compute_uv=True, full_matrices=full_matrices)\n\n\n@to_ivy_arrays_and_back\ndef svdvals(A, *, driver=None, out=None):\n    # TODO: add handling for driver\n    return ivy.svdvals(A, out=out)\n\n\n@to_ivy_arrays_and_back\ndef inv_ex(input, *, check_errors=False, out=None):\n    try:\n        inputInv = ivy.inv(input, out=out)\n        info = ivy.zeros(input.shape[:-2], dtype=ivy.int32)\n        return inputInv, info\n    except RuntimeError as e:\n        if check_errors:\n            raise RuntimeError(e)\n        else:\n            inputInv = input * math.nan\n            info = ivy.ones(input.shape[:-2], dtype=ivy.int32)\n            return inputInv, info\n\n\n@to_ivy_arrays_and_back\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"float16\", \"bfloat16\")}, \"torch\")\ndef tensorinv(input, ind=2, *, out=None):\n    not_invertible = \"Reshaped tensor is not invertible\"\n    prod_cond = \"Tensor shape must satisfy prod(A.shape[:ind]) == prod(A.shape[ind:])\"\n    positive_ind_cond = \"Expected a strictly positive integer for 'ind'\"\n    input_shape = ivy.shape(input)\n    assert ind > 0, f\"{positive_ind_cond}\"\n    shape_ind_end = input_shape[:ind]\n    shape_ind_start = input_shape[ind:]\n    prod_ind_end = 1\n    prod_ind_start = 1\n    for i in shape_ind_start:\n        prod_ind_start *= i\n    for j in shape_ind_end:\n        prod_ind_end *= j\n    assert prod_ind_end == prod_ind_start, f\"{prod_cond}.\"\n    inverse_shape = shape_ind_start + shape_ind_end\n    input = ivy.reshape(input, shape=(prod_ind_end, -1))\n    inverse_shape_tuple = tuple([*inverse_shape])\n    assert inv_ex(input, check_errors=True), f\"{not_invertible}.\"\n    inverse_tensor = ivy.inv(input)\n    return ivy.reshape(inverse_tensor, shape=inverse_shape_tuple, out=out)\n\n\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"bfloat16\", \"float16\")}, \"torch\")\ndef eig(input, *, out=None):\n    return ivy.eig(input, out=out)\n\n\n@to_ivy_arrays_and_back\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"bfloat16\", \"float16\")}, \"torch\")\ndef solve(input, other, *, out=None):\n    return ivy.solve(input, other, out=out)\n\n\n@to_ivy_arrays_and_back\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"bfloat16\", \"float16\")}, \"torch\")\ndef tensorsolve(A, B, dims=None, *, out=None):\n    return ivy.tensorsolve(A, B, axes=dims, out=out)\n\n\n@to_ivy_arrays_and_back\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"bfloat16\", \"float16\")}, \"torch\")\ndef lu_factor(A, *, pivot=True, out=None):\n    return ivy.lu_factor(A, pivot=pivot, out=out)\n\n\n@to_ivy_arrays_and_back\ndef matmul(input, other, *, out=None):\n    return ivy.matmul(input, other, out=out)\n\n\n@to_ivy_arrays_and_back\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"bfloat16\", \"float16\")}, \"torch\")\ndef vander(x, N=None):\n    if len(x.shape) < 1:\n        raise RuntimeError(\"Input dim must be greater than or equal to 1.\")\n\n    # pytorch always return int64 for integers\n    if \"int\" in x.dtype:\n        x = ivy.astype(x, ivy.int64)\n\n    if len(x.shape) == 1:\n        # torch always returns the powers in ascending order\n        return ivy.vander(x, N=N, increasing=True)\n\n    # support multi-dimensional array\n    original_shape = x.shape\n    if N is None:\n        N = x.shape[-1]\n\n    # store the vander output\n    x = ivy.reshape(x, (-1, x.shape[-1]))\n    output = []\n\n    for i in range(x.shape[0]):\n        output.append(ivy.vander(x[i], N=N, increasing=True))\n\n    output = ivy.stack(output)\n    output = ivy.reshape(output, (*original_shape, N))\n    output = ivy.astype(output, x.dtype)\n    return output\n", "path": "ivy/functional/frontends/torch/linalg.py"}], "after_files": [{"content": "# local\nimport math\nimport ivy\nimport ivy.functional.frontends.torch as torch_frontend\nfrom ivy.functional.frontends.torch.func_wrapper import to_ivy_arrays_and_back\nfrom ivy.func_wrapper import with_supported_dtypes, with_unsupported_dtypes\n\n\n@to_ivy_arrays_and_back\ndef vector_norm(input, ord=2, dim=None, keepdim=False, *, dtype=None, out=None):\n    return ivy.vector_norm(\n        input, axis=dim, keepdims=keepdim, ord=ord, out=out, dtype=dtype\n    )\n\n\n@to_ivy_arrays_and_back\ndef diagonal(A, *, offset=0, dim1=-2, dim2=-1):\n    return torch_frontend.diagonal(A, offset=offset, dim1=dim1, dim2=dim2)\n\n\n@to_ivy_arrays_and_back\ndef divide(input, other, *, rounding_mode=None, out=None):\n    return ivy.divide(input, other, out=out)\n\n\n@to_ivy_arrays_and_back\ndef inv(input, *, out=None):\n    return ivy.inv(input, out=out)\n\n\n@to_ivy_arrays_and_back\ndef pinv(input, *, atol=None, rtol=None, hermitian=False, out=None):\n    # TODO: add handling for hermitian once complex numbers are supported\n    if atol is None:\n        return ivy.pinv(input, rtol=rtol, out=out)\n    else:\n        sigma = ivy.svdvals(input)[0]\n        if rtol is None:\n            rtol = atol / sigma\n        else:\n            if atol > rtol * sigma:\n                rtol = atol / sigma\n\n    return ivy.pinv(input, rtol=rtol, out=out)\n\n\n@to_ivy_arrays_and_back\ndef det(input, *, out=None):\n    return ivy.det(input, out=out)\n\n\n@to_ivy_arrays_and_back\ndef eigvals(input, *, out=None):\n    # TODO: add handling for out\n    return ivy.eigvals(input)\n\n\n@to_ivy_arrays_and_back\ndef eigvalsh(input, UPLO=\"L\", *, out=None):\n    return ivy.eigvalsh(input, UPLO=UPLO, out=out)\n\n\n@to_ivy_arrays_and_back\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"bfloat16\", \"float16\")}, \"torch\")\ndef eigh(a, /, UPLO=\"L\", out=None):\n    return ivy.eigh(a, UPLO=UPLO, out=out)\n\n\n@to_ivy_arrays_and_back\ndef qr(input, mode=\"reduced\", *, out=None):\n    if mode == \"reduced\":\n        ret = ivy.qr(input, mode=\"reduced\")\n    elif mode == \"r\":\n        Q, R = ivy.qr(input, mode=\"r\")\n        Q = []\n        ret = Q, R\n    elif mode == \"complete\":\n        ret = ivy.qr(input, mode=\"complete\")\n    if ivy.exists(out):\n        return ivy.inplace_update(out, ret)\n    return ret\n\n\n@to_ivy_arrays_and_back\ndef slogdet(input, *, out=None):\n    # TODO: add handling for out\n    return ivy.slogdet(input)\n\n\n@to_ivy_arrays_and_back\ndef matrix_power(input, n, *, out=None):\n    return ivy.matrix_power(input, n, out=out)\n\n\n@with_supported_dtypes(\n    {\"1.11.0 and below\": (\"float32\", \"float64\", \"complex64\", \"complex128\")}, \"torch\"\n)\n@to_ivy_arrays_and_back\ndef matrix_norm(input, ord=\"fro\", dim=(-2, -1), keepdim=False, *, dtype=None, out=None):\n    if \"complex\" in ivy.as_ivy_dtype(input.dtype):\n        input = ivy.abs(input)\n    if dtype:\n        input = ivy.astype(input, dtype)\n    return ivy.matrix_norm(input, ord=ord, axis=dim, keepdims=keepdim, out=out)\n\n\n@to_ivy_arrays_and_back\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"float16\",)}, \"torch\")\ndef cross(input, other, *, dim=None, out=None):\n    return torch_frontend.miscellaneous_ops.cross(input, other, dim=dim, out=out)\n\n\n@to_ivy_arrays_and_back\ndef vecdot(x1, x2, *, dim=-1, out=None):\n    return ivy.vecdot(x1, x2, axis=dim, out=out)\n\n\n@to_ivy_arrays_and_back\ndef matrix_rank(input, *, atol=None, rtol=None, hermitian=False, out=None):\n    # TODO: add handling for hermitian once complex numbers are supported\n    return ivy.astype(ivy.matrix_rank(input, atol=atol, rtol=rtol, out=out), ivy.int64)\n\n\n@to_ivy_arrays_and_back\ndef cholesky(input, *, upper=False, out=None):\n    return ivy.cholesky(input, upper=upper, out=out)\n\n\n@to_ivy_arrays_and_back\ndef svd(A, /, *, full_matrices=True, driver=None, out=None):\n    # TODO: add handling for driver and out\n    return ivy.svd(A, compute_uv=True, full_matrices=full_matrices)\n\n\n@to_ivy_arrays_and_back\ndef svdvals(A, *, driver=None, out=None):\n    # TODO: add handling for driver\n    return ivy.svdvals(A, out=out)\n\n\n@to_ivy_arrays_and_back\ndef inv_ex(input, *, check_errors=False, out=None):\n    try:\n        inputInv = ivy.inv(input, out=out)\n        info = ivy.zeros(input.shape[:-2], dtype=ivy.int32)\n        return inputInv, info\n    except RuntimeError as e:\n        if check_errors:\n            raise RuntimeError(e)\n        else:\n            inputInv = input * math.nan\n            info = ivy.ones(input.shape[:-2], dtype=ivy.int32)\n            return inputInv, info\n\n\n@to_ivy_arrays_and_back\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"float16\", \"bfloat16\")}, \"torch\")\ndef tensorinv(input, ind=2, *, out=None):\n    not_invertible = \"Reshaped tensor is not invertible\"\n    prod_cond = \"Tensor shape must satisfy prod(A.shape[:ind]) == prod(A.shape[ind:])\"\n    positive_ind_cond = \"Expected a strictly positive integer for 'ind'\"\n    input_shape = ivy.shape(input)\n    assert ind > 0, f\"{positive_ind_cond}\"\n    shape_ind_end = input_shape[:ind]\n    shape_ind_start = input_shape[ind:]\n    prod_ind_end = 1\n    prod_ind_start = 1\n    for i in shape_ind_start:\n        prod_ind_start *= i\n    for j in shape_ind_end:\n        prod_ind_end *= j\n    assert prod_ind_end == prod_ind_start, f\"{prod_cond}.\"\n    inverse_shape = shape_ind_start + shape_ind_end\n    input = ivy.reshape(input, shape=(prod_ind_end, -1))\n    inverse_shape_tuple = tuple([*inverse_shape])\n    assert inv_ex(input, check_errors=True), f\"{not_invertible}.\"\n    inverse_tensor = ivy.inv(input)\n    return ivy.reshape(inverse_tensor, shape=inverse_shape_tuple, out=out)\n\n\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"bfloat16\", \"float16\")}, \"torch\")\ndef eig(input, *, out=None):\n    return ivy.eig(input, out=out)\n\n\n@to_ivy_arrays_and_back\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"bfloat16\", \"float16\")}, \"torch\")\ndef solve(input, other, *, out=None):\n    return ivy.solve(input, other, out=out)\n\n\n@to_ivy_arrays_and_back\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"bfloat16\", \"float16\")}, \"torch\")\ndef tensorsolve(A, B, dims=None, *, out=None):\n    return ivy.tensorsolve(A, B, axes=dims, out=out)\n\n\n@to_ivy_arrays_and_back\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"bfloat16\", \"float16\")}, \"torch\")\ndef lu_factor(A, *, pivot=True, out=None):\n    return ivy.lu_factor(A, pivot=pivot, out=out)\n\n\n@to_ivy_arrays_and_back\ndef matmul(input, other, *, out=None):\n    return ivy.matmul(input, other, out=out)\n\n\n@to_ivy_arrays_and_back\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"bfloat16\", \"float16\")}, \"torch\")\ndef vander(x, N=None):\n    if len(x.shape) < 1:\n        raise RuntimeError(\"Input dim must be greater than or equal to 1.\")\n\n    # pytorch always return int64 for integers\n    if \"int\" in x.dtype:\n        x = ivy.astype(x, ivy.int64)\n\n    if len(x.shape) == 1:\n        # torch always returns the powers in ascending order\n        return ivy.vander(x, N=N, increasing=True)\n\n    # support multi-dimensional array\n    original_shape = x.shape\n    if N is None:\n        N = x.shape[-1]\n\n    # store the vander output\n    x = ivy.reshape(x, (-1, x.shape[-1]))\n    output = []\n\n    for i in range(x.shape[0]):\n        output.append(ivy.vander(x[i], N=N, increasing=True))\n\n    output = ivy.stack(output)\n    output = ivy.reshape(output, (*original_shape, N))\n    output = ivy.astype(output, x.dtype)\n    return output\n\n\n@to_ivy_arrays_and_back\n@with_unsupported_dtypes({\"1.11.0 and below\": (\"bfloat16\", \"float16\")}, \"torch\")\ndef multi_dot(tensors, *, out=None):\n    return ivy.multi_dot(tensors, out=out)\n", "path": "ivy/functional/frontends/torch/linalg.py"}]}