summaryrefslogtreecommitdiff
path: root/nn
diff options
context:
space:
mode:
authorPrzemyslaw Szczepaniak <pszczepaniak@google.com>2020-05-01 09:36:33 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2020-05-01 09:36:33 +0000
commit3484c5284b7b6b49471c56737637215c2a7d700d (patch)
treee67a3165e537909e0ae2f16cd2baa00a2e7dd94e /nn
parent7ef73c26b5af4f563be3926c0c2070e0871e67da (diff)
parent7264d519af881284e23193d3a6f2ca4186779f48 (diff)
downloadml-3484c5284b7b6b49471c56737637215c2a7d700d.tar.gz
Merge "Fix null ptr dereference in squeeze cpu implementation." into rvc-dev
Diffstat (limited to 'nn')
-rw-r--r--nn/common/operations/Squeeze.cpp11
-rw-r--r--nn/runtime/test/generated/spec_V1_2/squeeze_b155238914.example.cpp87
-rw-r--r--nn/runtime/test/specs/V1_2/squeeze_b155238914.mod.py32
3 files changed, 127 insertions, 3 deletions
diff --git a/nn/common/operations/Squeeze.cpp b/nn/common/operations/Squeeze.cpp
index 977856d2d..276461d1e 100644
--- a/nn/common/operations/Squeeze.cpp
+++ b/nn/common/operations/Squeeze.cpp
@@ -110,9 +110,14 @@ bool prepare(IOperationExecutionContext* context) {
// Sets output dimensions.
std::vector<uint32_t> outDims(numInputDims - numDimsSqueezed);
- for (int32_t inIdx = 0, outIdx = 0; inIdx < numInputDims; ++inIdx) {
- if (!shouldSqueeze[inIdx]) {
- outDims[outIdx++] = getSizeOfDimension(inputShape, inIdx);
+ if (numInputDims == numDimsSqueezed) {
+ // Handle edge case where squeeze removes all dimensions.
+ outDims.push_back(1);
+ } else {
+ for (int32_t inIdx = 0, outIdx = 0; inIdx < numInputDims; ++inIdx) {
+ if (!shouldSqueeze[inIdx]) {
+ outDims[outIdx++] = getSizeOfDimension(inputShape, inIdx);
+ }
}
}
Shape outputShape(inputShape);
diff --git a/nn/runtime/test/generated/spec_V1_2/squeeze_b155238914.example.cpp b/nn/runtime/test/generated/spec_V1_2/squeeze_b155238914.example.cpp
new file mode 100644
index 000000000..c2fad450f
--- /dev/null
+++ b/nn/runtime/test/generated/spec_V1_2/squeeze_b155238914.example.cpp
@@ -0,0 +1,87 @@
+// Generated from squeeze_b155238914.mod.py
+// DO NOT EDIT
+// clang-format off
+#include "TestHarness.h"
+using namespace test_helper;
+
+namespace generated_tests::squeeze_b155238914 {
+
+const TestModel& get_test_model() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {0},
+ .operands = {{ // op0
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<float>({0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}),
+ .dimensions = {9, 1, 1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT32,
+ .zeroPoint = 0
+ }, { // op1
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<float>({0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f}),
+ .dimensions = {9, 1, 1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT32,
+ .zeroPoint = 0
+ }, { // op5
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<float>({0.0f}),
+ .dimensions = {1, 1, 1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT32,
+ .zeroPoint = 0
+ }, { // op7
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({}),
+ .dimensions = {0},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::NO_VALUE,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_INT32,
+ .zeroPoint = 0
+ }, { // op8
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<float>({}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+ .numberOfConsumers = 0,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT32,
+ .zeroPoint = 0
+ }},
+ .operations = {{
+ .inputs = {0},
+ .outputs = {1},
+ .type = TestOperationType::FLOOR
+ }, {
+ .inputs = {2, 3},
+ .outputs = {4},
+ .type = TestOperationType::SQUEEZE
+ }},
+ .outputIndexes = {1}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model = TestModelManager::get().add("squeeze_b155238914", get_test_model());
+
+} // namespace generated_tests::squeeze_b155238914
+
diff --git a/nn/runtime/test/specs/V1_2/squeeze_b155238914.mod.py b/nn/runtime/test/specs/V1_2/squeeze_b155238914.mod.py
new file mode 100644
index 000000000..70e41c6d3
--- /dev/null
+++ b/nn/runtime/test/specs/V1_2/squeeze_b155238914.mod.py
@@ -0,0 +1,32 @@
+#
+# Copyright (C) 2020 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Model operands
+op0 = Input("op0", ["TENSOR_FLOAT32", [9, 1, 1]])
+op1 = Output("op1", ["TENSOR_FLOAT32", [9, 1, 1]])
+op5 = Parameter("op5", ["TENSOR_FLOAT32", [1, 1, 1]], [0])
+op7 = Parameter("op7", ["TENSOR_INT32", [0]], value=None) # omitted
+op8 = Internal("op8", ["TENSOR_FLOAT32", []])
+
+# Model operations
+model = Model()
+model.Operation("FLOOR", op0).To(op1)
+model.Operation("SQUEEZE", op5, op7).To(op8)
+
+# Example
+Example({
+ op0: [0, 0, 0, 0, 0, 0, 0, 0, 0],
+ op1: [0, 0, 0, 0, 0, 0, 0, 0, 0],
+}, model=model).DisableLifeTimeVariation()