Repository: ivy-llc/ivy

Issue:
clib_by_global_norm



Discussion:

Resolving patch:
diff --git a/ivy/functional/frontends/tensorflow/general_functions.py b/ivy/functional/frontends/tensorflow/general_functions.py
--- a/ivy/functional/frontends/tensorflow/general_functions.py
+++ b/ivy/functional/frontends/tensorflow/general_functions.py
@@ -3,7 +3,7 @@
 
 # local
 import ivy
-from ivy.func_wrapper import with_unsupported_dtypes
+from ivy.func_wrapper import with_unsupported_dtypes, with_supported_dtypes
 from ivy.functional.frontends.tensorflow.func_wrapper import (
     to_ivy_arrays_and_back,
     handle_tf_dtype,
@@ -37,6 +37,20 @@ def clip_by_value(t, clip_value_min, clip_value_max):
     return ivy.clip(t, clip_value_min, clip_value_max)
 
 
+@with_supported_dtypes({"2.9.1 and below": ("float32",)}, "tensorflow")
+@to_ivy_arrays_and_back
+def clip_by_global_norm(t_list, clip_norm, use_norm=None):
+    if use_norm is not None:
+        global_norm = use_norm
+    else:
+        global_norm = ivy.sqrt(ivy.sum([ivy.vector_norm(t) ** 2 for t in t_list]))
+
+    max_clip_ratio = ivy.maximum(clip_norm, global_norm)
+    return [
+        ivy.multiply(t, ivy.divide(clip_norm, max_clip_ratio)) for t in t_list
+    ], global_norm
+
+
 @to_ivy_arrays_and_back
 def clip_by_norm(t, clip_norm, axes=None):
     t = ivy.array(t)


Test patch:
diff --git a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_general_functions.py b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_general_functions.py
--- a/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_general_functions.py
+++ b/ivy_tests/test_ivy/test_frontends/test_tensorflow/test_general_functions.py
@@ -2,7 +2,6 @@
 from hypothesis import strategies as st, assume
 import numpy as np
 
-
 # local
 import ivy_tests.test_ivy.helpers as helpers
 from ivy.functional.frontends.tensorflow.general_functions import _num_to_bit_list
@@ -99,6 +98,88 @@ def test_tensorflow_clip_by_value(
     )
 
 
+@st.composite
+def _get_global_norm_clip_inputs(draw):
+
+    t_list_dtype, t_list = draw(
+        helpers.dtype_and_values(
+            num_arrays=2,
+            min_num_dims=1,
+            shared_dtype=True,
+            min_value=-100,
+            max_value=100,
+            dtype=["float32"] * 2,
+        )
+    )
+
+    norm_dtype, norm = draw(
+        helpers.dtype_and_values(
+            shape=(1,),
+            shared_dtype=True,
+            min_value=0,
+            exclude_min=True,
+            max_value=100,
+            dtype=["float32"],
+        )
+    )
+
+    global_norm_dtype, global_norm = draw(
+        helpers.dtype_and_values(
+            shape=(1,),
+            shared_dtype=True,
+            min_value=0,
+            exclude_min=True,
+            max_value=100,
+            dtype=["float32"],
+        )
+    )
+    include_global = draw(st.booleans())
+    if not include_global:
+        global_norm_dtype, global_norm = None, None
+    return t_list_dtype, t_list, norm_dtype, norm, global_norm_dtype, global_norm
+
+
+# clip_by_global_norm
+@handle_frontend_test(
+    fn_tree="tensorflow.clip_by_global_norm",
+    input_and_norm=_get_global_norm_clip_inputs(),
+    test_with_out=st.just(False),
+)
+def test_tensorflow_clip_by_global_norm(
+    *,
+    input_and_norm,
+    frontend,
+    test_flags,
+    fn_tree,
+    on_device,
+):
+    (
+        t_list_dtype,
+        t_list,
+        norm_dtype,
+        norm,
+        global_norm_dtype,
+        global_norm,
+    ) = input_and_norm
+
+    input_dtypes = [t_list_dtype[0], norm_dtype[0]]
+    use_norm = None
+    if global_norm_dtype:
+        input_dtypes.append(global_norm_dtype[0])
+        use_norm = global_norm[0]
+
+    helpers.test_frontend_function(
+        input_dtypes=input_dtypes,
+        frontend=frontend,
+        test_flags=test_flags,
+        fn_tree=fn_tree,
+        on_device=on_device,
+        t_list=t_list,
+        clip_norm=norm[0],
+        use_norm=use_norm,
+    )
+
+
 @st.composite
 def _get_norm_clip_inputs(draw):
     x_dtype, x = draw(