Validate that a model input or output is only so designated once.

Also tweak some log text.

Test: NeuralNetworksTest_static
Test: VtsHalNeuralnetworksV1_1TargetTest [email protected]::IDevice/sample-all
Test: VtsHalNeuralnetworksV1_0TargetTest [email protected]::IDevice/sample-all

Bug: 67828197

Merged-In: I8426a7363253c1ccbaf90c9a64a2890f62cf0158
Change-Id: I8426a7363253c1ccbaf90c9a64a2890f62cf0158
(cherry picked from commit 6df88e757be293e0010d304ef303164de2e0ff30)
diff --git a/common/ValidateHal.cpp b/common/ValidateHal.cpp
index 1e830e6..9d6d3e8 100644
--- a/common/ValidateHal.cpp
+++ b/common/ValidateHal.cpp
@@ -104,7 +104,7 @@
                 if (operand.scale != 0.f) {
                     LOG(ERROR) << "Operand " << index << ": Operand of type "
                                << getOperandTypeName(operand.type) << " with a non-zero scale ("
-                               << operand.scale;
+                               << operand.scale << ")";
                     return false;
                 }
                 break;
@@ -287,7 +287,7 @@
     const size_t operandCount = operands.size();
     for (uint32_t i : indexes) {
         if (i >= operandCount) {
-            LOG(ERROR) << "Model input or output index out of range " << i << "/" << operandCount;
+            LOG(ERROR) << "Model input or output index out of range: " << i << "/" << operandCount;
             return false;
         }
         const Operand& operand = operands[i];
@@ -297,6 +297,14 @@
             return false;
         }
     }
+
+    std::vector<uint32_t> sortedIndexes = indexes;
+    std::sort(sortedIndexes.begin(), sortedIndexes.end());
+    auto adjacentI = std::adjacent_find(sortedIndexes.begin(), sortedIndexes.end());
+    if (adjacentI != sortedIndexes.end()) {
+        LOG(ERROR) << "Model input or output occurs multiple times: " << *adjacentI;
+        return false;
+    }
     return true;
 }