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


--- 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/indexing_slicing_joining_mutating_ops.py`
Content:
```
1 # local
2 import ivy
3 from ivy.functional.frontends.torch.func_wrapper import to_ivy_arrays_and_back
4 
5 
6 @to_ivy_arrays_and_back
7 def adjoint(input):
8     return ivy.adjoint(input)
9 
10 
11 @to_ivy_arrays_and_back
12 def cat(tensors, dim=0, *, out=None):
13     return ivy.concat(tensors, axis=dim, out=out)
14 
15 
16 @to_ivy_arrays_and_back
17 def chunk(input, chunks, dim=0):
18     if ivy.shape(input) == ():
19         return [input]
20     else:
21         dim_size = ivy.shape(input)[dim]
22         chunk_size = dim_size // chunks
23         if chunk_size == 0:
24             return ivy.split(input, num_or_size_splits=dim_size, axis=dim)
25         else:
26             remainder = dim_size % chunks
27             if remainder == 0:
28                 return ivy.split(input, num_or_size_splits=chunks, axis=dim)
29             else:
30                 return ivy.split(
31                     input,
32                     num_or_size_splits=tuple(
33                         [chunk_size + remainder] + [chunk_size] * (chunks - 1)
34                     ),
35                     axis=dim,
36                 )
37 
38 
39 @to_ivy_arrays_and_back
40 def concat(tensors, dim=0, *, out=None):
41     return ivy.concat(tensors, axis=dim, out=out)
42 
43 
44 @to_ivy_arrays_and_back
45 def gather(input, dim, index, *, sparse_grad=False, out=None):
46     if sparse_grad:
47         raise ivy.utils.exceptions.IvyException(
48             "Gather does not yet support the sparse grad functionality"
49         )
50 
51     dim = dim % len(input.shape)
52     all_indices = ivy.argwhere(ivy.full(index.shape, True))
53     gather_locations = ivy.reshape(index, [ivy.prod(ivy.array(index.shape))])
54 
55     gather_indices = []
56     for axis in range(len(index.shape)):
57         if axis == dim:
58             gather_indices.append(ivy.array(gather_locations, dtype=index.dtype))
59         else:
60             gather_indices.append(ivy.array(all_indices[:, axis], dtype=index.dtype))
61 
62     gather_indices = ivy.stack(gather_indices, axis=-1)
63     gathered = ivy.gather_nd(input, gather_indices)
64     reshaped = ivy.reshape(gathered, index.shape)
65     return reshaped
66 
67 
68 @to_ivy_arrays_and_back
69 def nonzero(input, *, out=None, as_tuple=False):
70     ret = ivy.nonzero(input)
71     if as_tuple is False:
72         ret = ivy.matrix_transpose(ivy.stack(ret))
73 
74     if ivy.exists(out):
75         return ivy.inplace_update(out, ret)
76     return ret
77 
78 
79 @to_ivy_arrays_and_back
80 def permute(input, dims):
81     return ivy.permute_dims(input, axes=dims)
82 
83 
84 @to_ivy_arrays_and_back
85 def reshape(input, shape):
86     return ivy.reshape(input, shape)
87 
88 
89 @to_ivy_arrays_and_back
90 def squeeze(input, dim):
91     if isinstance(dim, int) and input.ndim > 0:
92         if input.shape[dim] > 1:
93             return input
94     return ivy.squeeze(input, dim)
95 
96 
97 @to_ivy_arrays_and_back
98 def stack(tensors, dim=0, *, out=None):
99     return ivy.stack(tensors, axis=dim, out=out)
100 
101 
102 @to_ivy_arrays_and_back
103 def swapaxes(input, axis0, axis1):
104     return ivy.swapaxes(input, axis0, axis1)
105 
106 
107 @to_ivy_arrays_and_back
108 def swapdims(input, dim0, dim1):
109     return ivy.swapaxes(input, dim0, dim1)
110 
111 
112 @to_ivy_arrays_and_back
113 def transpose(input, dim0, dim1):
114     return ivy.swapaxes(input, dim0, dim1)
115 
116 
117 @to_ivy_arrays_and_back
118 def t(input):
119     if input.ndim > 2:
120         raise ivy.utils.exceptions.IvyException(
121             "t(input) expects a tensor with <= 2 dimensions, but self is %dD"
122             % input.ndim
123         )
124     if input.ndim == 2:
125         return ivy.swapaxes(input, 0, 1)
126     else:
127         return input
128 
129 
130 @to_ivy_arrays_and_back
131 def tile(input, dims):
132     try:
133         tup = tuple(dims)
134     except TypeError:
135         tup = (dims,)
136     d = len(tup)
137     res = 0
138     if len(input.shape) > len([dims]) - 1:
139         res = input
140     if d < input.ndim:
141         tup = (1,) * (input.ndim - d) + tup
142         res = ivy.tile(input, tup)
143 
144     else:
145         res = ivy.tile(input, repeats=dims, out=None)
146     return res
147 
148 
149 @to_ivy_arrays_and_back
150 def unsqueeze(input, dim=0):
151     return ivy.expand_dims(input, axis=dim)
152 
153 
154 @to_ivy_arrays_and_back
155 def argwhere(input):
156     return ivy.argwhere(input)
157 
158 
159 @to_ivy_arrays_and_back
160 def movedim(input, source, destination):
161     return ivy.moveaxis(input, source, destination)
162 
163 
164 @to_ivy_arrays_and_back
165 def moveaxis(input, source, destination):
166     return ivy.moveaxis(input, source, destination)
167 
168 
169 @to_ivy_arrays_and_back
170 def hstack(tensors, *, out=None):
171     return ivy.hstack(tensors, out=out)
172 
173 
174 @to_ivy_arrays_and_back
175 def index_select(input, dim, index, *, out=None):
176     return ivy.gather(input, index, axis=dim, out=out)
177 
178 
179 @to_ivy_arrays_and_back
180 def dstack(tensors, *, out=None):
181     return ivy.dstack(tensors, out=out)
182 
183 
184 @to_ivy_arrays_and_back
185 def take_along_dim(input, indices, dim, *, out=None):
186     return ivy.take_along_axis(input, indices, dim, out=out)
187 
188 
189 @to_ivy_arrays_and_back
190 def vstack(tensors, *, out=None):
191     return ivy.vstack(tensors, out=out)
192 
193 
194 @to_ivy_arrays_and_back
195 def split(tensor, split_size_or_sections, dim=0):
196     if isinstance(split_size_or_sections, int):
197         split_size = split_size_or_sections
198         split_size_or_sections = [split_size] * (tensor.shape[dim] // split_size)
199         if tensor.shape[dim] % split_size:
200             split_size_or_sections.append(tensor.shape[dim] % split_size)
201     return tuple(
202         ivy.split(
203             tensor,
204             num_or_size_splits=split_size_or_sections,
205             axis=dim,
206             with_remainder=True,
207         )
208     )
209 
210 
211 @to_ivy_arrays_and_back
212 def tensor_split(input, indices_or_sections, dim=0):
213     if isinstance(indices_or_sections, (list, tuple)):
214         indices_or_sections = (
215             ivy.diff(indices_or_sections, prepend=[0], append=[input.shape[dim]])
216             .astype(ivy.int8)
217             .to_list()
218         )
219     return ivy.split(
220         input, num_or_size_splits=indices_or_sections, axis=dim, with_remainder=False
221     )
222 
223 
224 @to_ivy_arrays_and_back
225 def unbind(input, dim=0):
226     shape = list(input.shape)
227     shape.pop(dim)
228     return tuple([x.reshape(tuple(shape)) for x in split(input, 1, dim=dim)])
229 
230 
231 def _get_indices_or_sections(indices_or_sections, indices, sections):
232     if not ivy.exists(indices_or_sections):
233         if ivy.exists(indices) and not ivy.exists(sections):
234             indices_or_sections = indices
235         elif ivy.exists(sections) and not ivy.exists(indices):
236             indices_or_sections = sections
237         else:
238             raise ivy.utils.exception.IvyError(
239                 "got invalid argument for indices_or_sections"
240             )
241     return indices_or_sections
242 
243 
244 @to_ivy_arrays_and_back
245 def dsplit(input, indices_or_sections=None, /, *, indices=None, sections=None):
246     indices_or_sections = _get_indices_or_sections(
247         indices_or_sections, indices, sections
248     )
249     return tuple(ivy.dsplit(input, indices_or_sections))
250 
251 
252 @to_ivy_arrays_and_back
253 def hsplit(input, indices_or_sections=None, /, *, indices=None, sections=None):
254     indices_or_sections = _get_indices_or_sections(
255         indices_or_sections, indices, sections
256     )
257     return tuple(ivy.hsplit(input, indices_or_sections))
258 
259 
260 @to_ivy_arrays_and_back
261 def vsplit(input, indices_or_sections=None, /, *, indices=None, sections=None):
262     indices_or_sections = _get_indices_or_sections(
263         indices_or_sections, indices, sections
264     )
265     return tuple(ivy.vsplit(input, indices_or_sections))
266 
267 
268 @to_ivy_arrays_and_back
269 def row_stack(tensors, *, out=None):
270     return ivy.vstack(tensors, out=out)
271 
272 
273 @to_ivy_arrays_and_back
274 def where(condition, input=None, other=None):
275     if not ivy.exists(input) and not ivy.exists(other):
276         return nonzero(condition, as_tuple=True)
277     return ivy.where(condition, input, other)
278 
279 
280 @to_ivy_arrays_and_back
281 def conj(input):
282     return ivy.conj(input)
283
```
--- 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/indexing_slicing_joining_mutating_ops.py b/ivy/functional/frontends/torch/indexing_slicing_joining_mutating_ops.py
--- a/ivy/functional/frontends/torch/indexing_slicing_joining_mutating_ops.py
+++ b/ivy/functional/frontends/torch/indexing_slicing_joining_mutating_ops.py
@@ -280,3 +280,45 @@
 @to_ivy_arrays_and_back
 def conj(input):
     return ivy.conj(input)
+
+
+@to_ivy_arrays_and_back
+def index_add(input, dim, index, source, *, alpha=1, out=None):
+    # Potential Bug:
+    #   There is an issue with the torch backend (not caused by ivy)
+    #   where half precision (float16) values get ignored in summation:
+    #
+    #   >>> a = torch.tensor(-14., dtype=torch.float16)
+    #   >>> b = torch.tensor(1.014, dtype=torch.float16)
+    #   >>> a+b
+    #   tensor(-12.9844, dtype=torch.float16)
+    #   >>> a = torch.tensor(-24., dtype=torch.float16)
+    #   >>> a+b
+    #   tensor(-22.9844, dtype=torch.float16)
+    #   >>> a = torch.tensor(-34., dtype=torch.float16)
+    #   >>> a+b
+    #   tensor(-33., dtype=torch.float16)
+    #   >>>
+    input = ivy.swapaxes(input, dim, 0)
+    source = ivy.swapaxes(source, dim, 0)
+    _to_adds = []
+    index = sorted(zip(ivy.to_list(index), range(len(index))), key=(lambda x: x[0]))
+    while index:
+        _curr_idx = index[0][0]
+        while len(_to_adds) < _curr_idx:
+            _to_adds.append(ivy.zeros_like(source[0]))
+        _to_add_cum = ivy.get_item(source, index[0][1])
+        while (1 < len(index)) and (index[0][0] == index[1][0]):
+            _to_add_cum = ivy.add(_to_add_cum, ivy.get_item(source, index.pop(1)[1]))
+        index.pop(0)
+        _to_adds.append(_to_add_cum)
+    while len(_to_adds) < input.shape[0]:
+        _to_adds.append(ivy.zeros_like(source[0]))
+    _to_adds = ivy.stack(_to_adds)
+    if len(input.shape) < 2:
+        # Added this line due to the paddle backend treating scalars as 1-d arrays
+        _to_adds = ivy.flatten(_to_adds)
+
+    ret = ivy.add(input, _to_adds, alpha=alpha)
+    ret = ivy.swapaxes(ret, 0, dim, out=out)
+    return ret

{"golden_diff": "diff --git a/ivy/functional/frontends/torch/indexing_slicing_joining_mutating_ops.py b/ivy/functional/frontends/torch/indexing_slicing_joining_mutating_ops.py\n--- a/ivy/functional/frontends/torch/indexing_slicing_joining_mutating_ops.py\n+++ b/ivy/functional/frontends/torch/indexing_slicing_joining_mutating_ops.py\n@@ -280,3 +280,45 @@\n @to_ivy_arrays_and_back\r\n def conj(input):\r\n     return ivy.conj(input)\r\n+\r\n+\r\n+@to_ivy_arrays_and_back\r\n+def index_add(input, dim, index, source, *, alpha=1, out=None):\r\n+    # Potential Bug:\r\n+    #   There is an issue with the torch backend (not caused by ivy)\r\n+    #   where half precision (float16) values get ignored in summation:\r\n+    #\r\n+    #   >>> a = torch.tensor(-14., dtype=torch.float16)\r\n+    #   >>> b = torch.tensor(1.014, dtype=torch.float16)\r\n+    #   >>> a+b\r\n+    #   tensor(-12.9844, dtype=torch.float16)\r\n+    #   >>> a = torch.tensor(-24., dtype=torch.float16)\r\n+    #   >>> a+b\r\n+    #   tensor(-22.9844, dtype=torch.float16)\r\n+    #   >>> a = torch.tensor(-34., dtype=torch.float16)\r\n+    #   >>> a+b\r\n+    #   tensor(-33., dtype=torch.float16)\r\n+    #   >>>\r\n+    input = ivy.swapaxes(input, dim, 0)\r\n+    source = ivy.swapaxes(source, dim, 0)\r\n+    _to_adds = []\r\n+    index = sorted(zip(ivy.to_list(index), range(len(index))), key=(lambda x: x[0]))\r\n+    while index:\r\n+        _curr_idx = index[0][0]\r\n+        while len(_to_adds) < _curr_idx:\r\n+            _to_adds.append(ivy.zeros_like(source[0]))\r\n+        _to_add_cum = ivy.get_item(source, index[0][1])\r\n+        while (1 < len(index)) and (index[0][0] == index[1][0]):\r\n+            _to_add_cum = ivy.add(_to_add_cum, ivy.get_item(source, index.pop(1)[1]))\r\n+        index.pop(0)\r\n+        _to_adds.append(_to_add_cum)\r\n+    while len(_to_adds) < input.shape[0]:\r\n+        _to_adds.append(ivy.zeros_like(source[0]))\r\n+    _to_adds = ivy.stack(_to_adds)\r\n+    if len(input.shape) < 2:\r\n+        # Added this line due to the paddle backend treating scalars as 1-d arrays\r\n+        _to_adds = ivy.flatten(_to_adds)\r\n+\r\n+    ret = ivy.add(input, _to_adds, alpha=alpha)\r\n+    ret = ivy.swapaxes(ret, 0, dim, out=out)\r\n+    return ret\n", "issue": "index_add\n\n", "before_files": [{"content": "# local\r\nimport ivy\r\nfrom ivy.functional.frontends.torch.func_wrapper import to_ivy_arrays_and_back\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef adjoint(input):\r\n    return ivy.adjoint(input)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef cat(tensors, dim=0, *, out=None):\r\n    return ivy.concat(tensors, axis=dim, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef chunk(input, chunks, dim=0):\r\n    if ivy.shape(input) == ():\r\n        return [input]\r\n    else:\r\n        dim_size = ivy.shape(input)[dim]\r\n        chunk_size = dim_size // chunks\r\n        if chunk_size == 0:\r\n            return ivy.split(input, num_or_size_splits=dim_size, axis=dim)\r\n        else:\r\n            remainder = dim_size % chunks\r\n            if remainder == 0:\r\n                return ivy.split(input, num_or_size_splits=chunks, axis=dim)\r\n            else:\r\n                return ivy.split(\r\n                    input,\r\n                    num_or_size_splits=tuple(\r\n                        [chunk_size + remainder] + [chunk_size] * (chunks - 1)\r\n                    ),\r\n                    axis=dim,\r\n                )\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef concat(tensors, dim=0, *, out=None):\r\n    return ivy.concat(tensors, axis=dim, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef gather(input, dim, index, *, sparse_grad=False, out=None):\r\n    if sparse_grad:\r\n        raise ivy.utils.exceptions.IvyException(\r\n            \"Gather does not yet support the sparse grad functionality\"\r\n        )\r\n\r\n    dim = dim % len(input.shape)\r\n    all_indices = ivy.argwhere(ivy.full(index.shape, True))\r\n    gather_locations = ivy.reshape(index, [ivy.prod(ivy.array(index.shape))])\r\n\r\n    gather_indices = []\r\n    for axis in range(len(index.shape)):\r\n        if axis == dim:\r\n            gather_indices.append(ivy.array(gather_locations, dtype=index.dtype))\r\n        else:\r\n            gather_indices.append(ivy.array(all_indices[:, axis], dtype=index.dtype))\r\n\r\n    gather_indices = ivy.stack(gather_indices, axis=-1)\r\n    gathered = ivy.gather_nd(input, gather_indices)\r\n    reshaped = ivy.reshape(gathered, index.shape)\r\n    return reshaped\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef nonzero(input, *, out=None, as_tuple=False):\r\n    ret = ivy.nonzero(input)\r\n    if as_tuple is False:\r\n        ret = ivy.matrix_transpose(ivy.stack(ret))\r\n\r\n    if ivy.exists(out):\r\n        return ivy.inplace_update(out, ret)\r\n    return ret\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef permute(input, dims):\r\n    return ivy.permute_dims(input, axes=dims)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef reshape(input, shape):\r\n    return ivy.reshape(input, shape)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef squeeze(input, dim):\r\n    if isinstance(dim, int) and input.ndim > 0:\r\n        if input.shape[dim] > 1:\r\n            return input\r\n    return ivy.squeeze(input, dim)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef stack(tensors, dim=0, *, out=None):\r\n    return ivy.stack(tensors, axis=dim, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef swapaxes(input, axis0, axis1):\r\n    return ivy.swapaxes(input, axis0, axis1)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef swapdims(input, dim0, dim1):\r\n    return ivy.swapaxes(input, dim0, dim1)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef transpose(input, dim0, dim1):\r\n    return ivy.swapaxes(input, dim0, dim1)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef t(input):\r\n    if input.ndim > 2:\r\n        raise ivy.utils.exceptions.IvyException(\r\n            \"t(input) expects a tensor with <= 2 dimensions, but self is %dD\"\r\n            % input.ndim\r\n        )\r\n    if input.ndim == 2:\r\n        return ivy.swapaxes(input, 0, 1)\r\n    else:\r\n        return input\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef tile(input, dims):\r\n    try:\r\n        tup = tuple(dims)\r\n    except TypeError:\r\n        tup = (dims,)\r\n    d = len(tup)\r\n    res = 0\r\n    if len(input.shape) > len([dims]) - 1:\r\n        res = input\r\n    if d < input.ndim:\r\n        tup = (1,) * (input.ndim - d) + tup\r\n        res = ivy.tile(input, tup)\r\n\r\n    else:\r\n        res = ivy.tile(input, repeats=dims, out=None)\r\n    return res\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef unsqueeze(input, dim=0):\r\n    return ivy.expand_dims(input, axis=dim)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef argwhere(input):\r\n    return ivy.argwhere(input)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef movedim(input, source, destination):\r\n    return ivy.moveaxis(input, source, destination)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef moveaxis(input, source, destination):\r\n    return ivy.moveaxis(input, source, destination)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef hstack(tensors, *, out=None):\r\n    return ivy.hstack(tensors, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef index_select(input, dim, index, *, out=None):\r\n    return ivy.gather(input, index, axis=dim, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef dstack(tensors, *, out=None):\r\n    return ivy.dstack(tensors, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef take_along_dim(input, indices, dim, *, out=None):\r\n    return ivy.take_along_axis(input, indices, dim, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef vstack(tensors, *, out=None):\r\n    return ivy.vstack(tensors, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef split(tensor, split_size_or_sections, dim=0):\r\n    if isinstance(split_size_or_sections, int):\r\n        split_size = split_size_or_sections\r\n        split_size_or_sections = [split_size] * (tensor.shape[dim] // split_size)\r\n        if tensor.shape[dim] % split_size:\r\n            split_size_or_sections.append(tensor.shape[dim] % split_size)\r\n    return tuple(\r\n        ivy.split(\r\n            tensor,\r\n            num_or_size_splits=split_size_or_sections,\r\n            axis=dim,\r\n            with_remainder=True,\r\n        )\r\n    )\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef tensor_split(input, indices_or_sections, dim=0):\r\n    if isinstance(indices_or_sections, (list, tuple)):\r\n        indices_or_sections = (\r\n            ivy.diff(indices_or_sections, prepend=[0], append=[input.shape[dim]])\r\n            .astype(ivy.int8)\r\n            .to_list()\r\n        )\r\n    return ivy.split(\r\n        input, num_or_size_splits=indices_or_sections, axis=dim, with_remainder=False\r\n    )\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef unbind(input, dim=0):\r\n    shape = list(input.shape)\r\n    shape.pop(dim)\r\n    return tuple([x.reshape(tuple(shape)) for x in split(input, 1, dim=dim)])\r\n\r\n\r\ndef _get_indices_or_sections(indices_or_sections, indices, sections):\r\n    if not ivy.exists(indices_or_sections):\r\n        if ivy.exists(indices) and not ivy.exists(sections):\r\n            indices_or_sections = indices\r\n        elif ivy.exists(sections) and not ivy.exists(indices):\r\n            indices_or_sections = sections\r\n        else:\r\n            raise ivy.utils.exception.IvyError(\r\n                \"got invalid argument for indices_or_sections\"\r\n            )\r\n    return indices_or_sections\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef dsplit(input, indices_or_sections=None, /, *, indices=None, sections=None):\r\n    indices_or_sections = _get_indices_or_sections(\r\n        indices_or_sections, indices, sections\r\n    )\r\n    return tuple(ivy.dsplit(input, indices_or_sections))\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef hsplit(input, indices_or_sections=None, /, *, indices=None, sections=None):\r\n    indices_or_sections = _get_indices_or_sections(\r\n        indices_or_sections, indices, sections\r\n    )\r\n    return tuple(ivy.hsplit(input, indices_or_sections))\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef vsplit(input, indices_or_sections=None, /, *, indices=None, sections=None):\r\n    indices_or_sections = _get_indices_or_sections(\r\n        indices_or_sections, indices, sections\r\n    )\r\n    return tuple(ivy.vsplit(input, indices_or_sections))\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef row_stack(tensors, *, out=None):\r\n    return ivy.vstack(tensors, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef where(condition, input=None, other=None):\r\n    if not ivy.exists(input) and not ivy.exists(other):\r\n        return nonzero(condition, as_tuple=True)\r\n    return ivy.where(condition, input, other)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef conj(input):\r\n    return ivy.conj(input)\r\n", "path": "ivy/functional/frontends/torch/indexing_slicing_joining_mutating_ops.py"}], "after_files": [{"content": "# local\r\nimport ivy\r\nfrom ivy.functional.frontends.torch.func_wrapper import to_ivy_arrays_and_back\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef adjoint(input):\r\n    return ivy.adjoint(input)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef cat(tensors, dim=0, *, out=None):\r\n    return ivy.concat(tensors, axis=dim, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef chunk(input, chunks, dim=0):\r\n    if ivy.shape(input) == ():\r\n        return [input]\r\n    else:\r\n        dim_size = ivy.shape(input)[dim]\r\n        chunk_size = dim_size // chunks\r\n        if chunk_size == 0:\r\n            return ivy.split(input, num_or_size_splits=dim_size, axis=dim)\r\n        else:\r\n            remainder = dim_size % chunks\r\n            if remainder == 0:\r\n                return ivy.split(input, num_or_size_splits=chunks, axis=dim)\r\n            else:\r\n                return ivy.split(\r\n                    input,\r\n                    num_or_size_splits=tuple(\r\n                        [chunk_size + remainder] + [chunk_size] * (chunks - 1)\r\n                    ),\r\n                    axis=dim,\r\n                )\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef concat(tensors, dim=0, *, out=None):\r\n    return ivy.concat(tensors, axis=dim, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef gather(input, dim, index, *, sparse_grad=False, out=None):\r\n    if sparse_grad:\r\n        raise ivy.utils.exceptions.IvyException(\r\n            \"Gather does not yet support the sparse grad functionality\"\r\n        )\r\n\r\n    dim = dim % len(input.shape)\r\n    all_indices = ivy.argwhere(ivy.full(index.shape, True))\r\n    gather_locations = ivy.reshape(index, [ivy.prod(ivy.array(index.shape))])\r\n\r\n    gather_indices = []\r\n    for axis in range(len(index.shape)):\r\n        if axis == dim:\r\n            gather_indices.append(ivy.array(gather_locations, dtype=index.dtype))\r\n        else:\r\n            gather_indices.append(ivy.array(all_indices[:, axis], dtype=index.dtype))\r\n\r\n    gather_indices = ivy.stack(gather_indices, axis=-1)\r\n    gathered = ivy.gather_nd(input, gather_indices)\r\n    reshaped = ivy.reshape(gathered, index.shape)\r\n    return reshaped\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef nonzero(input, *, out=None, as_tuple=False):\r\n    ret = ivy.nonzero(input)\r\n    if as_tuple is False:\r\n        ret = ivy.matrix_transpose(ivy.stack(ret))\r\n\r\n    if ivy.exists(out):\r\n        return ivy.inplace_update(out, ret)\r\n    return ret\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef permute(input, dims):\r\n    return ivy.permute_dims(input, axes=dims)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef reshape(input, shape):\r\n    return ivy.reshape(input, shape)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef squeeze(input, dim):\r\n    if isinstance(dim, int) and input.ndim > 0:\r\n        if input.shape[dim] > 1:\r\n            return input\r\n    return ivy.squeeze(input, dim)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef stack(tensors, dim=0, *, out=None):\r\n    return ivy.stack(tensors, axis=dim, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef swapaxes(input, axis0, axis1):\r\n    return ivy.swapaxes(input, axis0, axis1)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef swapdims(input, dim0, dim1):\r\n    return ivy.swapaxes(input, dim0, dim1)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef transpose(input, dim0, dim1):\r\n    return ivy.swapaxes(input, dim0, dim1)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef t(input):\r\n    if input.ndim > 2:\r\n        raise ivy.utils.exceptions.IvyException(\r\n            \"t(input) expects a tensor with <= 2 dimensions, but self is %dD\"\r\n            % input.ndim\r\n        )\r\n    if input.ndim == 2:\r\n        return ivy.swapaxes(input, 0, 1)\r\n    else:\r\n        return input\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef tile(input, dims):\r\n    try:\r\n        tup = tuple(dims)\r\n    except TypeError:\r\n        tup = (dims,)\r\n    d = len(tup)\r\n    res = 0\r\n    if len(input.shape) > len([dims]) - 1:\r\n        res = input\r\n    if d < input.ndim:\r\n        tup = (1,) * (input.ndim - d) + tup\r\n        res = ivy.tile(input, tup)\r\n\r\n    else:\r\n        res = ivy.tile(input, repeats=dims, out=None)\r\n    return res\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef unsqueeze(input, dim=0):\r\n    return ivy.expand_dims(input, axis=dim)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef argwhere(input):\r\n    return ivy.argwhere(input)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef movedim(input, source, destination):\r\n    return ivy.moveaxis(input, source, destination)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef moveaxis(input, source, destination):\r\n    return ivy.moveaxis(input, source, destination)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef hstack(tensors, *, out=None):\r\n    return ivy.hstack(tensors, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef index_select(input, dim, index, *, out=None):\r\n    return ivy.gather(input, index, axis=dim, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef dstack(tensors, *, out=None):\r\n    return ivy.dstack(tensors, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef take_along_dim(input, indices, dim, *, out=None):\r\n    return ivy.take_along_axis(input, indices, dim, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef vstack(tensors, *, out=None):\r\n    return ivy.vstack(tensors, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef split(tensor, split_size_or_sections, dim=0):\r\n    if isinstance(split_size_or_sections, int):\r\n        split_size = split_size_or_sections\r\n        split_size_or_sections = [split_size] * (tensor.shape[dim] // split_size)\r\n        if tensor.shape[dim] % split_size:\r\n            split_size_or_sections.append(tensor.shape[dim] % split_size)\r\n    return tuple(\r\n        ivy.split(\r\n            tensor,\r\n            num_or_size_splits=split_size_or_sections,\r\n            axis=dim,\r\n            with_remainder=True,\r\n        )\r\n    )\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef tensor_split(input, indices_or_sections, dim=0):\r\n    if isinstance(indices_or_sections, (list, tuple)):\r\n        indices_or_sections = (\r\n            ivy.diff(indices_or_sections, prepend=[0], append=[input.shape[dim]])\r\n            .astype(ivy.int8)\r\n            .to_list()\r\n        )\r\n    return ivy.split(\r\n        input, num_or_size_splits=indices_or_sections, axis=dim, with_remainder=False\r\n    )\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef unbind(input, dim=0):\r\n    shape = list(input.shape)\r\n    shape.pop(dim)\r\n    return tuple([x.reshape(tuple(shape)) for x in split(input, 1, dim=dim)])\r\n\r\n\r\ndef _get_indices_or_sections(indices_or_sections, indices, sections):\r\n    if not ivy.exists(indices_or_sections):\r\n        if ivy.exists(indices) and not ivy.exists(sections):\r\n            indices_or_sections = indices\r\n        elif ivy.exists(sections) and not ivy.exists(indices):\r\n            indices_or_sections = sections\r\n        else:\r\n            raise ivy.utils.exception.IvyError(\r\n                \"got invalid argument for indices_or_sections\"\r\n            )\r\n    return indices_or_sections\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef dsplit(input, indices_or_sections=None, /, *, indices=None, sections=None):\r\n    indices_or_sections = _get_indices_or_sections(\r\n        indices_or_sections, indices, sections\r\n    )\r\n    return tuple(ivy.dsplit(input, indices_or_sections))\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef hsplit(input, indices_or_sections=None, /, *, indices=None, sections=None):\r\n    indices_or_sections = _get_indices_or_sections(\r\n        indices_or_sections, indices, sections\r\n    )\r\n    return tuple(ivy.hsplit(input, indices_or_sections))\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef vsplit(input, indices_or_sections=None, /, *, indices=None, sections=None):\r\n    indices_or_sections = _get_indices_or_sections(\r\n        indices_or_sections, indices, sections\r\n    )\r\n    return tuple(ivy.vsplit(input, indices_or_sections))\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef row_stack(tensors, *, out=None):\r\n    return ivy.vstack(tensors, out=out)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef where(condition, input=None, other=None):\r\n    if not ivy.exists(input) and not ivy.exists(other):\r\n        return nonzero(condition, as_tuple=True)\r\n    return ivy.where(condition, input, other)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef conj(input):\r\n    return ivy.conj(input)\r\n\r\n\r\n@to_ivy_arrays_and_back\r\ndef index_add(input, dim, index, source, *, alpha=1, out=None):\r\n    # Potential Bug:\r\n    #   There is an issue with the torch backend (not caused by ivy)\r\n    #   where half precision (float16) values get ignored in summation:\r\n    #\r\n    #   >>> a = torch.tensor(-14., dtype=torch.float16)\r\n    #   >>> b = torch.tensor(1.014, dtype=torch.float16)\r\n    #   >>> a+b\r\n    #   tensor(-12.9844, dtype=torch.float16)\r\n    #   >>> a = torch.tensor(-24., dtype=torch.float16)\r\n    #   >>> a+b\r\n    #   tensor(-22.9844, dtype=torch.float16)\r\n    #   >>> a = torch.tensor(-34., dtype=torch.float16)\r\n    #   >>> a+b\r\n    #   tensor(-33., dtype=torch.float16)\r\n    #   >>>\r\n    input = ivy.swapaxes(input, dim, 0)\r\n    source = ivy.swapaxes(source, dim, 0)\r\n    _to_adds = []\r\n    index = sorted(zip(ivy.to_list(index), range(len(index))), key=(lambda x: x[0]))\r\n    while index:\r\n        _curr_idx = index[0][0]\r\n        while len(_to_adds) < _curr_idx:\r\n            _to_adds.append(ivy.zeros_like(source[0]))\r\n        _to_add_cum = ivy.get_item(source, index[0][1])\r\n        while (1 < len(index)) and (index[0][0] == index[1][0]):\r\n            _to_add_cum = ivy.add(_to_add_cum, ivy.get_item(source, index.pop(1)[1]))\r\n        index.pop(0)\r\n        _to_adds.append(_to_add_cum)\r\n    while len(_to_adds) < input.shape[0]:\r\n        _to_adds.append(ivy.zeros_like(source[0]))\r\n    _to_adds = ivy.stack(_to_adds)\r\n    if len(input.shape) < 2:\r\n        # Added this line due to the paddle backend treating scalars as 1-d arrays\r\n        _to_adds = ivy.flatten(_to_adds)\r\n\r\n    ret = ivy.add(input, _to_adds, alpha=alpha)\r\n    ret = ivy.swapaxes(ret, 0, dim, out=out)\r\n    return ret\r\n", "path": "ivy/functional/frontends/torch/indexing_slicing_joining_mutating_ops.py"}]}