From 7b9a944b1a21bde77b0af82a27b3c8daa09afc01 Mon Sep 17 00:00:00 2001 From: Xusong Wang Date: Fri, 24 Apr 2020 14:46:28 -0700 Subject: Add STRIDED_SLICE validations on neg stride with shrinkMask. Fixes: 154639297 Test: NNT_static Test: NNT_static_fuzzing Change-Id: I2b37dd7fe07f3239682b5bc7f7cef0ae76134ad0 --- nn/common/operations/StridedSlice.cpp | 7 +- .../fuzzing/operation_signatures/Selection.cpp | 23 +- .../spec_V1_2/strided_slice_invalid.example.cpp | 502 +++++++++++++++++++++ .../strided_slice_invalid_output_dims.example.cpp | 254 ----------- .../test/specs/V1_2/strided_slice_invalid.mod.py | 40 ++ .../V1_2/strided_slice_invalid_output_dims.mod.py | 41 -- 6 files changed, 556 insertions(+), 311 deletions(-) create mode 100644 nn/runtime/test/generated/spec_V1_2/strided_slice_invalid.example.cpp delete mode 100644 nn/runtime/test/generated/spec_V1_2/strided_slice_invalid_output_dims.example.cpp create mode 100644 nn/runtime/test/specs/V1_2/strided_slice_invalid.mod.py delete mode 100644 nn/runtime/test/specs/V1_2/strided_slice_invalid_output_dims.mod.py (limited to 'nn') diff --git a/nn/common/operations/StridedSlice.cpp b/nn/common/operations/StridedSlice.cpp index 88993837a..cd972d3de 100644 --- a/nn/common/operations/StridedSlice.cpp +++ b/nn/common/operations/StridedSlice.cpp @@ -185,10 +185,9 @@ bool prepare(IOperationExecutionContext* context) { if (!(shrinkAxisMask & (1 << idx))) { outDims.push_back(outDim); } else { - if (outDim != 1) { - LOG(ERROR) << "Outdim " << idx << " is " << outDim << ", expected 1"; - NN_RET_CHECK_EQ(outDim, 1); - } + // Only positive stride is allowed on non-range indexing (i.e. shrinkMask is set). + NN_RET_CHECK_GT(stride, 0) << "index = " << idx; + NN_RET_CHECK_EQ(outDim, 1) << "index = " << idx; } } diff --git a/nn/runtime/test/fuzzing/operation_signatures/Selection.cpp b/nn/runtime/test/fuzzing/operation_signatures/Selection.cpp index 6d45d0433..02612c0df 100644 --- a/nn/runtime/test/fuzzing/operation_signatures/Selection.cpp +++ b/nn/runtime/test/fuzzing/operation_signatures/Selection.cpp @@ -320,24 +320,23 @@ static void stridedSliceFinalizer(RandomOperation* op) { // arbitrary value. if (beginMask[i]) begin[i] = getUniform(-inputSize, inputSize - 1); if (endMask[i]) end[i] = getUniform(-inputSize, inputSize - 1); + + // Switch to negative stride. + if (getBernoulli(0.2f)) { + op->inputs[3]->value(i) = -stride; + std::swap(begin[i], end[i]); + std::swap(beginMask[i], endMask[i]); + begin[i]--; + end[i]--; + // end = -1 will be interpreted to inputSize - 1 if not setting endMask. + if (end[i] < 0) endMask[i] = true; + } } else { // When shrink mask is set, the begin and end must define a slice of size 1, e.g. // begin[i] = x, end[i] = x + 1. begin[i] = getUniform(0, inputSize - 1); end[i] = begin[i] + 1; } - - // Switch to negative stride. - // TODO(b/154639297): shrinkMask with negative stride will produce uninitialized output. - if (!shrink && getBernoulli(0.2f)) { - op->inputs[3]->value(i) = -stride; - std::swap(begin[i], end[i]); - std::swap(beginMask[i], endMask[i]); - begin[i]--; - end[i]--; - // end = -1 will be intepreted to inputSize - 1 if not setting endMask. - if (end[i] < 0) endMask[i] = true; - } } op->inputs[4]->setScalarValue(convertToBitMask(beginMask)); op->inputs[5]->setScalarValue(convertToBitMask(endMask)); diff --git a/nn/runtime/test/generated/spec_V1_2/strided_slice_invalid.example.cpp b/nn/runtime/test/generated/spec_V1_2/strided_slice_invalid.example.cpp new file mode 100644 index 000000000..4b7449429 --- /dev/null +++ b/nn/runtime/test/generated/spec_V1_2/strided_slice_invalid.example.cpp @@ -0,0 +1,502 @@ +// Generated from strided_slice_invalid.mod.py +// DO NOT EDIT +// clang-format off +#include "TestHarness.h" +using namespace test_helper; + +namespace generated_tests::strided_slice_invalid { + +const TestModel& get_test_model_output_dims() { + static TestModel model = { + .expectFailure = true, + .expectedMultinomialDistributionTolerance = 0, + .isRelaxed = false, + .main = { // output_dims + .inputIndexes = {0}, + .operands = {{ // input + .channelQuant = {}, + .data = TestBuffer::createFromVector({1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}), + .dimensions = {2, 3}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_FLOAT32, + .zeroPoint = 0 + }, { // param + .channelQuant = {}, + .data = TestBuffer::createFromVector({0, 0}), + .dimensions = {2}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_INT32, + .zeroPoint = 0 + }, { // param1 + .channelQuant = {}, + .data = TestBuffer::createFromVector({2, 3}), + .dimensions = {2}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_INT32, + .zeroPoint = 0 + }, { // param2 + .channelQuant = {}, + .data = TestBuffer::createFromVector({1, 1}), + .dimensions = {2}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_INT32, + .zeroPoint = 0 + }, { // param3 + .channelQuant = {}, + .data = TestBuffer::createFromVector({0}), + .dimensions = {}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::INT32, + .zeroPoint = 0 + }, { // param4 + .channelQuant = {}, + .data = TestBuffer::createFromVector({0}), + .dimensions = {}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::INT32, + .zeroPoint = 0 + }, { // param5 + .channelQuant = {}, + .data = TestBuffer::createFromVector({1}), + .dimensions = {}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::INT32, + .zeroPoint = 0 + }, { // output + .channelQuant = {}, + .data = TestBuffer::createFromVector({1.0f, 2.0f, 3.0f}), + .dimensions = {3}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT, + .numberOfConsumers = 0, + .scale = 0.0f, + .type = TestOperandType::TENSOR_FLOAT32, + .zeroPoint = 0 + }}, + .operations = {{ + .inputs = {0, 1, 2, 3, 4, 5, 6}, + .outputs = {7}, + .type = TestOperationType::STRIDED_SLICE + }}, + .outputIndexes = {7} + }, + .minSupportedVersion = TestHalVersion::V1_2, + .referenced = {} + }; + return model; +} + +const auto dummy_test_model_output_dims = TestModelManager::get().add("strided_slice_invalid_output_dims", get_test_model_output_dims()); + +} // namespace generated_tests::strided_slice_invalid + +namespace generated_tests::strided_slice_invalid { + +const TestModel& get_test_model_output_dims_all_inputs_as_internal() { + static TestModel model = { + .expectFailure = true, + .expectedMultinomialDistributionTolerance = 0, + .isRelaxed = false, + .main = { // output_dims + .inputIndexes = {8}, + .operands = {{ // input + .channelQuant = {}, + .data = TestBuffer::createFromVector({}), + .dimensions = {2, 3}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_FLOAT32, + .zeroPoint = 0 + }, { // param + .channelQuant = {}, + .data = TestBuffer::createFromVector({0, 0}), + .dimensions = {2}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_INT32, + .zeroPoint = 0 + }, { // param1 + .channelQuant = {}, + .data = TestBuffer::createFromVector({2, 3}), + .dimensions = {2}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_INT32, + .zeroPoint = 0 + }, { // param2 + .channelQuant = {}, + .data = TestBuffer::createFromVector({1, 1}), + .dimensions = {2}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_INT32, + .zeroPoint = 0 + }, { // param3 + .channelQuant = {}, + .data = TestBuffer::createFromVector({0}), + .dimensions = {}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::INT32, + .zeroPoint = 0 + }, { // param4 + .channelQuant = {}, + .data = TestBuffer::createFromVector({0}), + .dimensions = {}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::INT32, + .zeroPoint = 0 + }, { // param5 + .channelQuant = {}, + .data = TestBuffer::createFromVector({1}), + .dimensions = {}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::INT32, + .zeroPoint = 0 + }, { // output + .channelQuant = {}, + .data = TestBuffer::createFromVector({1.0f, 2.0f, 3.0f}), + .dimensions = {3}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT, + .numberOfConsumers = 0, + .scale = 0.0f, + .type = TestOperandType::TENSOR_FLOAT32, + .zeroPoint = 0 + }, { // input_new + .channelQuant = {}, + .data = TestBuffer::createFromVector({1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}), + .dimensions = {2, 3}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_FLOAT32, + .zeroPoint = 0 + }, { // dummy + .channelQuant = {}, + .data = TestBuffer::createFromVector({0.0f}), + .dimensions = {1}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_FLOAT32, + .zeroPoint = 0 + }, { // param12 + .channelQuant = {}, + .data = TestBuffer::createFromVector({0}), + .dimensions = {}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::INT32, + .zeroPoint = 0 + }}, + .operations = {{ + .inputs = {8, 9, 10}, + .outputs = {0}, + .type = TestOperationType::ADD + }, { + .inputs = {0, 1, 2, 3, 4, 5, 6}, + .outputs = {7}, + .type = TestOperationType::STRIDED_SLICE + }}, + .outputIndexes = {7} + }, + .minSupportedVersion = TestHalVersion::V1_2, + .referenced = {} + }; + return model; +} + +const auto dummy_test_model_output_dims_all_inputs_as_internal = TestModelManager::get().add("strided_slice_invalid_output_dims_all_inputs_as_internal", get_test_model_output_dims_all_inputs_as_internal()); + +} // namespace generated_tests::strided_slice_invalid + +namespace generated_tests::strided_slice_invalid { + +const TestModel& get_test_model_neg_stride() { + static TestModel model = { + .expectFailure = true, + .expectedMultinomialDistributionTolerance = 0, + .isRelaxed = false, + .main = { // neg_stride + .inputIndexes = {0}, + .operands = {{ // input1 + .channelQuant = {}, + .data = TestBuffer::createFromVector({1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}), + .dimensions = {2, 3}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_FLOAT32, + .zeroPoint = 0 + }, { // param6 + .channelQuant = {}, + .data = TestBuffer::createFromVector({1, 0}), + .dimensions = {2}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_INT32, + .zeroPoint = 0 + }, { // param7 + .channelQuant = {}, + .data = TestBuffer::createFromVector({0, 3}), + .dimensions = {2}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_INT32, + .zeroPoint = 0 + }, { // param8 + .channelQuant = {}, + .data = TestBuffer::createFromVector({-1, 1}), + .dimensions = {2}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_INT32, + .zeroPoint = 0 + }, { // param9 + .channelQuant = {}, + .data = TestBuffer::createFromVector({0}), + .dimensions = {}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::INT32, + .zeroPoint = 0 + }, { // param10 + .channelQuant = {}, + .data = TestBuffer::createFromVector({0}), + .dimensions = {}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::INT32, + .zeroPoint = 0 + }, { // param11 + .channelQuant = {}, + .data = TestBuffer::createFromVector({1}), + .dimensions = {}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::INT32, + .zeroPoint = 0 + }, { // output1 + .channelQuant = {}, + .data = TestBuffer::createFromVector({4.0f, 5.0f, 6.0f}), + .dimensions = {3}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT, + .numberOfConsumers = 0, + .scale = 0.0f, + .type = TestOperandType::TENSOR_FLOAT32, + .zeroPoint = 0 + }}, + .operations = {{ + .inputs = {0, 1, 2, 3, 4, 5, 6}, + .outputs = {7}, + .type = TestOperationType::STRIDED_SLICE + }}, + .outputIndexes = {7} + }, + .minSupportedVersion = TestHalVersion::V1_2, + .referenced = {} + }; + return model; +} + +const auto dummy_test_model_neg_stride = TestModelManager::get().add("strided_slice_invalid_neg_stride", get_test_model_neg_stride()); + +} // namespace generated_tests::strided_slice_invalid + +namespace generated_tests::strided_slice_invalid { + +const TestModel& get_test_model_neg_stride_all_inputs_as_internal() { + static TestModel model = { + .expectFailure = true, + .expectedMultinomialDistributionTolerance = 0, + .isRelaxed = false, + .main = { // neg_stride + .inputIndexes = {8}, + .operands = {{ // input1 + .channelQuant = {}, + .data = TestBuffer::createFromVector({}), + .dimensions = {2, 3}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_FLOAT32, + .zeroPoint = 0 + }, { // param6 + .channelQuant = {}, + .data = TestBuffer::createFromVector({1, 0}), + .dimensions = {2}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_INT32, + .zeroPoint = 0 + }, { // param7 + .channelQuant = {}, + .data = TestBuffer::createFromVector({0, 3}), + .dimensions = {2}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_INT32, + .zeroPoint = 0 + }, { // param8 + .channelQuant = {}, + .data = TestBuffer::createFromVector({-1, 1}), + .dimensions = {2}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_INT32, + .zeroPoint = 0 + }, { // param9 + .channelQuant = {}, + .data = TestBuffer::createFromVector({0}), + .dimensions = {}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::INT32, + .zeroPoint = 0 + }, { // param10 + .channelQuant = {}, + .data = TestBuffer::createFromVector({0}), + .dimensions = {}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::INT32, + .zeroPoint = 0 + }, { // param11 + .channelQuant = {}, + .data = TestBuffer::createFromVector({1}), + .dimensions = {}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::INT32, + .zeroPoint = 0 + }, { // output1 + .channelQuant = {}, + .data = TestBuffer::createFromVector({4.0f, 5.0f, 6.0f}), + .dimensions = {3}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT, + .numberOfConsumers = 0, + .scale = 0.0f, + .type = TestOperandType::TENSOR_FLOAT32, + .zeroPoint = 0 + }, { // input1_new + .channelQuant = {}, + .data = TestBuffer::createFromVector({1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}), + .dimensions = {2, 3}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_FLOAT32, + .zeroPoint = 0 + }, { // dummy1 + .channelQuant = {}, + .data = TestBuffer::createFromVector({0.0f}), + .dimensions = {1}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::TENSOR_FLOAT32, + .zeroPoint = 0 + }, { // param13 + .channelQuant = {}, + .data = TestBuffer::createFromVector({0}), + .dimensions = {}, + .isIgnored = false, + .lifetime = TestOperandLifeTime::CONSTANT_COPY, + .numberOfConsumers = 1, + .scale = 0.0f, + .type = TestOperandType::INT32, + .zeroPoint = 0 + }}, + .operations = {{ + .inputs = {8, 9, 10}, + .outputs = {0}, + .type = TestOperationType::ADD + }, { + .inputs = {0, 1, 2, 3, 4, 5, 6}, + .outputs = {7}, + .type = TestOperationType::STRIDED_SLICE + }}, + .outputIndexes = {7} + }, + .minSupportedVersion = TestHalVersion::V1_2, + .referenced = {} + }; + return model; +} + +const auto dummy_test_model_neg_stride_all_inputs_as_internal = TestModelManager::get().add("strided_slice_invalid_neg_stride_all_inputs_as_internal", get_test_model_neg_stride_all_inputs_as_internal()); + +} // namespace generated_tests::strided_slice_invalid + diff --git a/nn/runtime/test/generated/spec_V1_2/strided_slice_invalid_output_dims.example.cpp b/nn/runtime/test/generated/spec_V1_2/strided_slice_invalid_output_dims.example.cpp deleted file mode 100644 index dadaef3ee..000000000 --- a/nn/runtime/test/generated/spec_V1_2/strided_slice_invalid_output_dims.example.cpp +++ /dev/null @@ -1,254 +0,0 @@ -// Generated from strided_slice_invalid_output_dims.mod.py -// DO NOT EDIT -// clang-format off -#include "TestHarness.h" -using namespace test_helper; - -namespace generated_tests::strided_slice_invalid_output_dims { - -const TestModel& get_test_model() { - static TestModel model = { - .expectFailure = true, - .expectedMultinomialDistributionTolerance = 0, - .isRelaxed = false, - .main = { - .inputIndexes = {0}, - .operands = {{ // input - .channelQuant = {}, - .data = TestBuffer::createFromVector({1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}), - .dimensions = {2, 3}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::TENSOR_FLOAT32, - .zeroPoint = 0 - }, { // begins - .channelQuant = {}, - .data = TestBuffer::createFromVector({0, 0}), - .dimensions = {2}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::CONSTANT_COPY, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::TENSOR_INT32, - .zeroPoint = 0 - }, { // ends - .channelQuant = {}, - .data = TestBuffer::createFromVector({2, 3}), - .dimensions = {2}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::CONSTANT_COPY, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::TENSOR_INT32, - .zeroPoint = 0 - }, { // strides - .channelQuant = {}, - .data = TestBuffer::createFromVector({1, 1}), - .dimensions = {2}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::CONSTANT_COPY, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::TENSOR_INT32, - .zeroPoint = 0 - }, { // beginMask - .channelQuant = {}, - .data = TestBuffer::createFromVector({0}), - .dimensions = {}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::CONSTANT_COPY, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::INT32, - .zeroPoint = 0 - }, { // endMask - .channelQuant = {}, - .data = TestBuffer::createFromVector({0}), - .dimensions = {}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::CONSTANT_COPY, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::INT32, - .zeroPoint = 0 - }, { // shrinkAxisMask - .channelQuant = {}, - .data = TestBuffer::createFromVector({1}), - .dimensions = {}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::CONSTANT_COPY, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::INT32, - .zeroPoint = 0 - }, { // output - .channelQuant = {}, - .data = TestBuffer::createFromVector({1.0f, 2.0f, 3.0f}), - .dimensions = {3}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT, - .numberOfConsumers = 0, - .scale = 0.0f, - .type = TestOperandType::TENSOR_FLOAT32, - .zeroPoint = 0 - }}, - .operations = {{ - .inputs = {0, 1, 2, 3, 4, 5, 6}, - .outputs = {7}, - .type = TestOperationType::STRIDED_SLICE - }}, - .outputIndexes = {7} - }, - .minSupportedVersion = TestHalVersion::V1_2, - .referenced = {} - }; - return model; -} - -const auto dummy_test_model = TestModelManager::get().add("strided_slice_invalid_output_dims", get_test_model()); - -} // namespace generated_tests::strided_slice_invalid_output_dims - -namespace generated_tests::strided_slice_invalid_output_dims { - -const TestModel& get_test_model_all_inputs_as_internal() { - static TestModel model = { - .expectFailure = true, - .expectedMultinomialDistributionTolerance = 0, - .isRelaxed = false, - .main = { - .inputIndexes = {8}, - .operands = {{ // input - .channelQuant = {}, - .data = TestBuffer::createFromVector({}), - .dimensions = {2, 3}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::TENSOR_FLOAT32, - .zeroPoint = 0 - }, { // begins - .channelQuant = {}, - .data = TestBuffer::createFromVector({0, 0}), - .dimensions = {2}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::CONSTANT_COPY, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::TENSOR_INT32, - .zeroPoint = 0 - }, { // ends - .channelQuant = {}, - .data = TestBuffer::createFromVector({2, 3}), - .dimensions = {2}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::CONSTANT_COPY, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::TENSOR_INT32, - .zeroPoint = 0 - }, { // strides - .channelQuant = {}, - .data = TestBuffer::createFromVector({1, 1}), - .dimensions = {2}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::CONSTANT_COPY, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::TENSOR_INT32, - .zeroPoint = 0 - }, { // beginMask - .channelQuant = {}, - .data = TestBuffer::createFromVector({0}), - .dimensions = {}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::CONSTANT_COPY, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::INT32, - .zeroPoint = 0 - }, { // endMask - .channelQuant = {}, - .data = TestBuffer::createFromVector({0}), - .dimensions = {}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::CONSTANT_COPY, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::INT32, - .zeroPoint = 0 - }, { // shrinkAxisMask - .channelQuant = {}, - .data = TestBuffer::createFromVector({1}), - .dimensions = {}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::CONSTANT_COPY, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::INT32, - .zeroPoint = 0 - }, { // output - .channelQuant = {}, - .data = TestBuffer::createFromVector({1.0f, 2.0f, 3.0f}), - .dimensions = {3}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT, - .numberOfConsumers = 0, - .scale = 0.0f, - .type = TestOperandType::TENSOR_FLOAT32, - .zeroPoint = 0 - }, { // input_new - .channelQuant = {}, - .data = TestBuffer::createFromVector({1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}), - .dimensions = {2, 3}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::TENSOR_FLOAT32, - .zeroPoint = 0 - }, { // dummy - .channelQuant = {}, - .data = TestBuffer::createFromVector({0.0f}), - .dimensions = {1}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::CONSTANT_COPY, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::TENSOR_FLOAT32, - .zeroPoint = 0 - }, { // param - .channelQuant = {}, - .data = TestBuffer::createFromVector({0}), - .dimensions = {}, - .isIgnored = false, - .lifetime = TestOperandLifeTime::CONSTANT_COPY, - .numberOfConsumers = 1, - .scale = 0.0f, - .type = TestOperandType::INT32, - .zeroPoint = 0 - }}, - .operations = {{ - .inputs = {8, 9, 10}, - .outputs = {0}, - .type = TestOperationType::ADD - }, { - .inputs = {0, 1, 2, 3, 4, 5, 6}, - .outputs = {7}, - .type = TestOperationType::STRIDED_SLICE - }}, - .outputIndexes = {7} - }, - .minSupportedVersion = TestHalVersion::V1_2, - .referenced = {} - }; - return model; -} - -const auto dummy_test_model_all_inputs_as_internal = TestModelManager::get().add("strided_slice_invalid_output_dims_all_inputs_as_internal", get_test_model_all_inputs_as_internal()); - -} // namespace generated_tests::strided_slice_invalid_output_dims - diff --git a/nn/runtime/test/specs/V1_2/strided_slice_invalid.mod.py b/nn/runtime/test/specs/V1_2/strided_slice_invalid.mod.py new file mode 100644 index 000000000..17a828f92 --- /dev/null +++ b/nn/runtime/test/specs/V1_2/strided_slice_invalid.mod.py @@ -0,0 +1,40 @@ +# +# Copyright (C) 2019 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. +# + +# Based on strided_slice_float_11.mod.py. + +# This test makes sure that executing STRIDED_SLICE results in a failure when +# the deduced output dimension is not one and shrinkAxisMask is set. +# See http://b/79856511#comment2. +i1 = Input("input", "TENSOR_FLOAT32", "{2, 3}") +output = Output("output", "TENSOR_FLOAT32", "{3}") +Model("output_dims").Operation("STRIDED_SLICE", i1, [0, 0], [2, 3], [1, 1], 0, 0, 1).To(output) +Example({ + i1: [1, 2, 3, 4, 5, 6], + output: [1, 2, 3], +}).ExpectFailure() + + +# This test makes sure that executing STRIDED_SLICE results in a failure when +# the stride is negative and shrinkAxisMask is set. +# See http://b/154639297#comment11. +i1 = Input("input", "TENSOR_FLOAT32", "{2, 3}") +output = Output("output", "TENSOR_FLOAT32", "{3}") +Model("neg_stride").Operation("STRIDED_SLICE", i1, [1, 0], [0, 3], [-1, 1], 0, 0, 1).To(output) +Example({ + i1: [1, 2, 3, 4, 5, 6], + output: [4, 5, 6], +}).ExpectFailure() diff --git a/nn/runtime/test/specs/V1_2/strided_slice_invalid_output_dims.mod.py b/nn/runtime/test/specs/V1_2/strided_slice_invalid_output_dims.mod.py deleted file mode 100644 index 76d2179d7..000000000 --- a/nn/runtime/test/specs/V1_2/strided_slice_invalid_output_dims.mod.py +++ /dev/null @@ -1,41 +0,0 @@ -# -# Copyright (C) 2019 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. -# - -# TODO: Move this spec to V1_3 directory? -# -# This test makes sure that executing STRIDED_SLICE results in a failure when -# the output dimensions do not match shrinkAxisMask. -# -# Based on strided_slice_float_11.mod.py. - -model = Model() -i1 = Input("input", "TENSOR_FLOAT32", "{2, 3}") -begins = Parameter("begins", "TENSOR_INT32", "{2}", [0, 0]) -# The value "2" below makes the test invalid. See http://b/79856511#comment2. -ends = Parameter("ends", "TENSOR_INT32", "{2}", [2, 3]) -strides = Parameter("strides", "TENSOR_INT32", "{2}", [1, 1]) -beginMask = Int32Scalar("beginMask", 0) -endMask = Int32Scalar("endMask", 0) -shrinkAxisMask = Int32Scalar("shrinkAxisMask", 1) - -output = Output("output", "TENSOR_FLOAT32", "{3}") - -model = model.Operation("STRIDED_SLICE", i1, begins, ends, strides, beginMask, endMask, shrinkAxisMask).To(output) - -Example({ - i1: [1, 2, 3, 4, 5, 6], - output: [1, 2, 3], -}).ExpectFailure() -- cgit v1.2.3