MLBEDSW-1538: Output diff for elementwise min/max

This commit adds a quantization restriction check
for supported operators, so that operators with
different quantization between its IFM (1/2) and
OFM tensors that do not support it, are correctly
placed on the CPU.

The quantization between two tensors is compared
using a new equality function implemented for
the QuantizationParameters class.

Signed-off-by: Dwight Lidman <dwight.lidman@arm.com>
Change-Id: I70ff36b4ab4955f328d6e6e699f00dbc43c0404a
diff --git a/ethosu/vela/supported_operators.py b/ethosu/vela/supported_operators.py
index 3bf46a9..e8e8d85 100644
--- a/ethosu/vela/supported_operators.py
+++ b/ethosu/vela/supported_operators.py
@@ -100,6 +100,9 @@
         self.supported_operator_restrictions.update(
             {op: self.check_memory_only_restrictions for op in self.memory_only_ops}
         )
+        self.supported_operator_restrictions.update(
+            {op: self.check_quantization_restrictions for op in self.binary_elem_wise_min_max_ops}
+        )
 
     def is_operator_supported(self, op):
         if op.type not in self.supported_operators:
@@ -301,3 +304,12 @@
             if op.attrs["new_axis_mask"] != 0 and op.attrs["shrink_axis_mask"] != 0:
                 return False
         return True
+
+    def check_quantization_restrictions(self, op):
+        # makes sure IFM1, IFM2 and OFM quantization are equal for binary ops
+        if (len(op.inputs) == 2
+            and not op.inputs[0].quantization == op.inputs[1].quantization == op.outputs[0].quantization):
+            print("Warning: Input/output tensors with different quantization is unsupported for the", op.type,
+                  "operator")
+            return False
+        return True
\ No newline at end of file
diff --git a/ethosu/vela/tensor.py b/ethosu/vela/tensor.py
index 5e97cfe..42ba853 100644
--- a/ethosu/vela/tensor.py
+++ b/ethosu/vela/tensor.py
@@ -181,6 +181,19 @@
 
     __repr__ = __str__
 
+    def __eq__(self, other):
+        if other is None:
+            return False
+        if not isinstance(other, QuantizationParameters):
+            return False
+
+        pairs = ((getattr(self, s), getattr(other, s)) for s in QuantizationParameters.__slots__)
+
+        return all(np.array_equal(a, b) for a, b in pairs)
+
+    def __ne__(self, other):
+        return not self == other
+
     def clone(self):
         res = QuantizationParameters()
         res.min = self.min