Repository: ivy-llc/ivy

Issue:
index_add



Discussion:

Resolving patch:
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
@@ -284,21 +284,6 @@ def 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 = []
@@ -309,7 +294,7 @@ def index_add(input, dim, index, source, *, alpha=1, out=None):
             _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]))
+            _to_add_cum = _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]:
diff --git a/ivy/functional/frontends/torch/tensor.py b/ivy/functional/frontends/torch/tensor.py
--- a/ivy/functional/frontends/torch/tensor.py
+++ b/ivy/functional/frontends/torch/tensor.py
@@ -757,6 +757,12 @@ def index_add_(self, dim, index, source, *, alpha=1):
         ).ivy_array
         return self
 
+    @with_unsupported_dtypes({"1.11.0 and below": ("float16", "bfloat16")}, "torch")
+    def index_add(self, dim, index, source, *, alpha=1):
+        return torch_frontend.index_add(
+            self._ivy_array, dim, index, source, alpha=alpha
+        )
+
     @with_unsupported_dtypes({"1.11.0 and below": ("float16",)}, "torch")
     def acosh_(self):
         self.ivy_array = self.acosh().ivy_array


Test patch:
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
--- a/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py
+++ b/ivy_tests/test_ivy/test_frontends/test_torch/test_tensor.py
@@ -5759,6 +5759,49 @@ def test_torch_instance_index_add_(
     )
 
 
+@handle_frontend_method(
+    class_tree=CLASS_TREE,
+    init_tree="torch.tensor",
+    method_name="index_add",
+    xs_dtypes_dim_idx=_arrays_dim_idx_n_dtypes(),
+    alpha=st.integers(min_value=1, max_value=2),
+)
+def test_torch_instance_index_add(
+    *,
+    xs_dtypes_dim_idx,
+    alpha,
+    frontend_method_data,
+    init_flags,
+    method_flags,
+    on_device,
+    frontend,
+):
+    xs, input_dtypes, axis, indices = xs_dtypes_dim_idx
+    if xs[0].shape[axis] < xs[1].shape[axis]:
+        source, input = xs
+    else:
+        input, source = xs
+    helpers.test_frontend_method(
+        init_input_dtypes=[input_dtypes[0]],
+        init_all_as_kwargs_np={
+            "data": input,
+        },
+        method_input_dtypes=["int64", input_dtypes[1]],
+        method_all_as_kwargs_np={
+            "dim": axis,
+            "index": indices,
+            "source": source,
+            "alpha": alpha,
+        },
+        frontend=frontend,
+        frontend_method_data=frontend_method_data,
+        init_flags=init_flags,
+        method_flags=method_flags,
+        on_device=on_device,
+        rtol_=1e-03,
+    )
+
+
 @st.composite
 def _get_clamp_inputs(draw):
     shape = draw(