MLBEDSW-3350 Put softmax on CPU if beta < 0

Put softmax on CPU if beta < 0

Signed-off-by: Patrik Gustavsson <patrik.gustavsson@arm.com>
Change-Id: I4ec866dd44d14e2737c4cd96474e54bb770bfb3e
diff --git a/ethosu/vela/supported_operators.py b/ethosu/vela/supported_operators.py
index b537b65..46f7a5d 100644
--- a/ethosu/vela/supported_operators.py
+++ b/ethosu/vela/supported_operators.py
@@ -212,6 +212,7 @@
         # Softmax specific checks:
         self.specific_constraints[Op.Softmax].append(SupportedOperators.constraint_matching_shapes)
         self.specific_constraints[Op.Softmax].append(SupportedOperators.constraint_matching_in_out_types)
+        self.specific_constraints[Op.Softmax].append(SupportedOperators.constraint_beta_value_range)
 
         # SplitV specific checks:
         self.specific_constraints[Op.SplitV].append(SupportedOperators.constraint_splitv_inferred)
@@ -560,6 +561,13 @@
         return valid, f"Op has ifm_dtype={ifm_dtype} and ofm_dtype={ofm_dtype}"
 
     @staticmethod
+    def constraint_beta_value_range(op):
+        "Beta value needs to be positive"
+        beta = op.attrs.get("beta", 1.0)
+        valid = beta >= 0
+        return valid, f"Op has beta={beta}"
+
+    @staticmethod
     def constraint_filter_type(op):
         "Kernel filter values for both width and height must be integer types"
         w = op.kernel.width
diff --git a/ethosu/vela/test/test_supported_operators.py b/ethosu/vela/test/test_supported_operators.py
index 7e13f42..62de0d1 100644
--- a/ethosu/vela/test/test_supported_operators.py
+++ b/ethosu/vela/test/test_supported_operators.py
@@ -382,6 +382,15 @@
     assert support.is_operator_supported(op)
 
 
+def test_constraint_beta_value_range():
+    # beta must be positive
+    op = testutil.create_op_with_quant_tensors(Op.Softmax, [1, 1, 1, 8], [1, 1, 1, 8])
+    op.attrs["beta"] = -1.0
+    assert not support.is_operator_supported(op)
+    op.attrs["beta"] = 0.0
+    assert support.is_operator_supported(op)
+
+
 def test_constraint_splitv_inferred():
     # SplitV requires a maximum of one inferred shape (-1)
     qp = testutil.default_quant_params()