Repository: ivy-llc/ivy

Issue:
binary_cross_entropy_with_logits



Discussion:

Resolving patch:
diff --git a/ivy/functional/frontends/paddle/nn/functional/loss.py b/ivy/functional/frontends/paddle/nn/functional/loss.py
--- a/ivy/functional/frontends/paddle/nn/functional/loss.py
+++ b/ivy/functional/frontends/paddle/nn/functional/loss.py
@@ -1 +1,45 @@
 # local
+import ivy
+from ivy.func_wrapper import with_supported_dtypes
+import ivy.functional.frontends.paddle as paddle
+from ivy.functional.frontends.paddle.func_wrapper import (
+    inputs_to_ivy_arrays,
+)
+
+
+# helpers
+def _get_reduction_func(reduction):
+    if reduction == "none":
+        ret = lambda x: x
+    elif reduction == "mean":
+        ret = ivy.mean
+    elif reduction == "sum":
+        ret = ivy.sum
+    else:
+        raise ivy.utils.exceptions.IvyException(
+            "{} is not a valid value for reduction".format(reduction)
+        )
+    return ret
+
+
+@with_supported_dtypes(
+    {"2.4.2 and below": ("float32",)},
+    "paddle",
+)
+@inputs_to_ivy_arrays
+def binary_cross_entropy_with_logits(
+    logit,
+    label,
+    weight=None,
+    reduction="mean",
+    pos_weight=None,
+    name=None,
+):
+    ret = ivy.binary_cross_entropy(
+        label, logit, from_logits=True, reduction="none", pos_weight=pos_weight
+    )
+    reduction = _get_reduction_func(reduction)
+    if weight is not None:
+        ret = ivy.multiply(weight, ret)
+    ret = reduction(ret).astype(label.dtype)
+    return paddle.to_tensor(ret.reshape([-1]))


Test patch:
diff --git a/ivy_tests/test_ivy/test_frontends/test_paddle/test_nn/test_functional/test_paddle_loss.py b/ivy_tests/test_ivy/test_frontends/test_paddle/test_nn/test_functional/test_paddle_loss.py
--- a/ivy_tests/test_ivy/test_frontends/test_paddle/test_nn/test_functional/test_paddle_loss.py
+++ b/ivy_tests/test_ivy/test_frontends/test_paddle/test_nn/test_functional/test_paddle_loss.py
@@ -1,3 +1,58 @@
 # global
+from hypothesis import strategies as st
 
 # local
+import ivy_tests.test_ivy.helpers as helpers
+from ivy_tests.test_ivy.helpers import handle_frontend_test
+
+
+@handle_frontend_test(
+    fn_tree="paddle.nn.functional.binary_cross_entropy_with_logits",
+    dtype_and_x=helpers.dtype_and_values(
+        available_dtypes=helpers.get_dtypes("valid"),
+        num_arrays=2,
+        min_value=0,
+        max_value=1,
+        exclude_min=True,
+        exclude_max=True,
+        shared_dtype=True,
+        min_num_dims=1,
+        max_num_dims=1,
+        min_dim_size=2,
+    ),
+    dtype_and_weight=helpers.dtype_and_values(
+        available_dtypes=helpers.get_dtypes("valid"),
+        min_value=1.0013580322265625e-05,
+        max_value=1.0,
+        min_num_dims=1,
+        max_num_dims=1,
+    ),
+    reduction=st.sampled_from(["mean", "none", "sum"]),
+)
+def test_paddle_binary_cross_entropy_with_logits(
+    dtype_and_x,
+    dtype_and_weight,
+    reduction,
+    on_device,
+    fn_tree,
+    frontend,
+    test_flags,
+):
+    # TODO: paddle's implementation of pos_weight is wrong
+    # https://github.com/PaddlePaddle/Paddle/blob/f0422a28d75f9345fa3b801c01cd0284b3b44be3/python/paddle/nn/functional/loss.py#L831
+    x_dtype, x = dtype_and_x
+    weight_dtype, weight = dtype_and_weight
+    helpers.test_frontend_function(
+        input_dtypes=[
+            x_dtype[0],
+            weight_dtype[0],
+        ],
+        frontend=frontend,
+        test_flags=test_flags,
+        fn_tree=fn_tree,
+        on_device=on_device,
+        logit=x[0],
+        label=x[0],
+        weight=weight[0],
+        reduction=reduction,
+    )