summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2020-03-20 12:55:39 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2020-03-20 12:55:39 +0000
commit005742de054649ed20b85021c5cc5228dd9b067e (patch)
treee4e63cfcf72785ba34da07be4a9dad126d357ace
parent7720040c82375804419366c8c00f5a540b6ddab8 (diff)
parentc0f74da9faad6671bda8d947f8122bfd5141220f (diff)
downloadml-005742de054649ed20b85021c5cc5228dd9b067e.tar.gz
Merge changes I97e66261,I8d1eccd3 into rvc-dev
* changes: Document and test L2_NORMALIZATION with input of all zeros. Add tests for corner cases of quant8 l2 norm.
-rw-r--r--nn/common/operations/L2Normalization.cpp3
-rw-r--r--nn/runtime/include/NeuralNetworks.h4
-rw-r--r--nn/runtime/test/fuzzing/TestRandomGraph.cpp5
-rw-r--r--nn/runtime/test/generated/spec_V1_2/l2_normalization_axis.example.cpp888
-rw-r--r--nn/runtime/test/generated/spec_V1_3/l2_normalization_zeros.example.cpp746
-rw-r--r--nn/runtime/test/specs/V1_2/l2_normalization_axis.mod.py13
-rw-r--r--nn/runtime/test/specs/V1_3/l2_normalization_zeros.mod.py41
-rw-r--r--nn/tools/api/types.spec18
8 files changed, 1710 insertions, 8 deletions
diff --git a/nn/common/operations/L2Normalization.cpp b/nn/common/operations/L2Normalization.cpp
index 31206e236..1925d5471 100644
--- a/nn/common/operations/L2Normalization.cpp
+++ b/nn/common/operations/L2Normalization.cpp
@@ -47,6 +47,7 @@ using namespace hal;
inline bool l2normFloat32Impl(const float* inputData, const Shape& inputShape, int32_t axis,
float* outputData, const Shape& outputShape) {
NNTRACE_TRANS("l2normFloat32");
+ constexpr float kEpsilon = 1e-6f;
const uint32_t outerSize = getNumberOfElements(inputShape, 0, axis);
const uint32_t axisSize = getSizeOfDimension(inputShape, axis);
const uint32_t innerSize =
@@ -61,7 +62,7 @@ inline bool l2normFloat32Impl(const float* inputData, const Shape& inputShape, i
float val = *p;
sum += val * val;
}
- float l2_norm = std::sqrt(sum);
+ float l2_norm = std::max(std::sqrt(sum), kEpsilon);
float* pOut = outputBeg;
for (const float* p = inputBeg; p < inputEnd; p += innerSize, pOut += innerSize) {
*pOut = *p / l2_norm;
diff --git a/nn/runtime/include/NeuralNetworks.h b/nn/runtime/include/NeuralNetworks.h
index 923531b3e..79008daf4 100644
--- a/nn/runtime/include/NeuralNetworks.h
+++ b/nn/runtime/include/NeuralNetworks.h
@@ -1013,6 +1013,10 @@ typedef enum {
* For {@link ANEURALNETWORKS_TENSOR_QUANT8_ASYMM_SIGNED},
* the scale must be 1.f / 128 and the zeroPoint must be 0.
*
+ * NOTE: Before API level 30, if the elements along an axis are all zeros,
+ * the result is undefined. Since API level 30, if the elements along an axis
+ * are all zeros, the result is logical zero.
+ *
* Available since API level 27.
*/
ANEURALNETWORKS_L2_NORMALIZATION = 11,
diff --git a/nn/runtime/test/fuzzing/TestRandomGraph.cpp b/nn/runtime/test/fuzzing/TestRandomGraph.cpp
index 25cf86a40..7facc363a 100644
--- a/nn/runtime/test/fuzzing/TestRandomGraph.cpp
+++ b/nn/runtime/test/fuzzing/TestRandomGraph.cpp
@@ -205,6 +205,11 @@ class RandomGraphTest : public ::testing::TestWithParam<uint32_t> {
featureLevel <= __ANDROID_API_Q__) {
return true;
}
+ // L2_NORMALIZATION on axis of all zeros is undefined before R.
+ if (op.type == TestOperationType::L2_NORMALIZATION &&
+ featureLevel <= __ANDROID_API_Q__) {
+ return true;
+ }
// TODO(xusongw): Remove after b/151328024 is resolved.
if (op.type == TestOperationType::ROI_ALIGN) {
return true;
diff --git a/nn/runtime/test/generated/spec_V1_2/l2_normalization_axis.example.cpp b/nn/runtime/test/generated/spec_V1_2/l2_normalization_axis.example.cpp
index 88ad5574b..ad15c7d04 100644
--- a/nn/runtime/test/generated/spec_V1_2/l2_normalization_axis.example.cpp
+++ b/nn/runtime/test/generated/spec_V1_2/l2_normalization_axis.example.cpp
@@ -11844,3 +11844,891 @@ const auto dummy_test_model_dim1_axis0_neg_quant8_all_inputs_as_internal = TestM
} // namespace generated_tests::l2_normalization_axis
+namespace generated_tests::l2_normalization_axis {
+
+const TestModel& get_test_model_corner_case_dim2_axis0() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {0},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({245, 247}),
+ .dimensions = {1, 2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({0}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({0, 255}),
+ .dimensions = {1, 2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0078125f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 128
+ }},
+ .operations = {{
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_corner_case_dim2_axis0 = TestModelManager::get().add("l2_normalization_axis_corner_case_dim2_axis0", get_test_model_corner_case_dim2_axis0());
+
+} // namespace generated_tests::l2_normalization_axis
+
+namespace generated_tests::l2_normalization_axis {
+
+const TestModel& get_test_model_corner_case_dim2_axis0_all_inputs_as_internal() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {3},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({}),
+ .dimensions = {1, 2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({0}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({0, 255}),
+ .dimensions = {1, 2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0078125f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 128
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({245, 247}),
+ .dimensions = {1, 2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({246}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({0}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }},
+ .operations = {{
+ .inputs = {3, 4, 5},
+ .outputs = {0},
+ .type = TestOperationType::ADD
+ }, {
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_corner_case_dim2_axis0_all_inputs_as_internal = TestModelManager::get().add("l2_normalization_axis_corner_case_dim2_axis0_all_inputs_as_internal", get_test_model_corner_case_dim2_axis0_all_inputs_as_internal());
+
+} // namespace generated_tests::l2_normalization_axis
+
+namespace generated_tests::l2_normalization_axis {
+
+const TestModel& get_test_model_corner_case_dim2_axis0_neg() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {0},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({245, 247}),
+ .dimensions = {1, 2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({-2}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({0, 255}),
+ .dimensions = {1, 2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0078125f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 128
+ }},
+ .operations = {{
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_corner_case_dim2_axis0_neg = TestModelManager::get().add("l2_normalization_axis_corner_case_dim2_axis0_neg", get_test_model_corner_case_dim2_axis0_neg());
+
+} // namespace generated_tests::l2_normalization_axis
+
+namespace generated_tests::l2_normalization_axis {
+
+const TestModel& get_test_model_corner_case_dim2_axis0_neg_all_inputs_as_internal() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {3},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({}),
+ .dimensions = {1, 2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({-2}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({0, 255}),
+ .dimensions = {1, 2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0078125f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 128
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({245, 247}),
+ .dimensions = {1, 2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({246}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({0}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }},
+ .operations = {{
+ .inputs = {3, 4, 5},
+ .outputs = {0},
+ .type = TestOperationType::ADD
+ }, {
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_corner_case_dim2_axis0_neg_all_inputs_as_internal = TestModelManager::get().add("l2_normalization_axis_corner_case_dim2_axis0_neg_all_inputs_as_internal", get_test_model_corner_case_dim2_axis0_neg_all_inputs_as_internal());
+
+} // namespace generated_tests::l2_normalization_axis
+
+namespace generated_tests::l2_normalization_axis {
+
+const TestModel& get_test_model_corner_case_dim2_axis1() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {0},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({245, 247}),
+ .dimensions = {2, 1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({1}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({0, 255}),
+ .dimensions = {2, 1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0078125f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 128
+ }},
+ .operations = {{
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_corner_case_dim2_axis1 = TestModelManager::get().add("l2_normalization_axis_corner_case_dim2_axis1", get_test_model_corner_case_dim2_axis1());
+
+} // namespace generated_tests::l2_normalization_axis
+
+namespace generated_tests::l2_normalization_axis {
+
+const TestModel& get_test_model_corner_case_dim2_axis1_all_inputs_as_internal() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {3},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({}),
+ .dimensions = {2, 1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({1}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({0, 255}),
+ .dimensions = {2, 1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0078125f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 128
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({245, 247}),
+ .dimensions = {2, 1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({246}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({0}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }},
+ .operations = {{
+ .inputs = {3, 4, 5},
+ .outputs = {0},
+ .type = TestOperationType::ADD
+ }, {
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_corner_case_dim2_axis1_all_inputs_as_internal = TestModelManager::get().add("l2_normalization_axis_corner_case_dim2_axis1_all_inputs_as_internal", get_test_model_corner_case_dim2_axis1_all_inputs_as_internal());
+
+} // namespace generated_tests::l2_normalization_axis
+
+namespace generated_tests::l2_normalization_axis {
+
+const TestModel& get_test_model_corner_case_dim2_axis1_neg() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {0},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({245, 247}),
+ .dimensions = {2, 1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({-1}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({0, 255}),
+ .dimensions = {2, 1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0078125f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 128
+ }},
+ .operations = {{
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_corner_case_dim2_axis1_neg = TestModelManager::get().add("l2_normalization_axis_corner_case_dim2_axis1_neg", get_test_model_corner_case_dim2_axis1_neg());
+
+} // namespace generated_tests::l2_normalization_axis
+
+namespace generated_tests::l2_normalization_axis {
+
+const TestModel& get_test_model_corner_case_dim2_axis1_neg_all_inputs_as_internal() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {3},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({}),
+ .dimensions = {2, 1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({-1}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({0, 255}),
+ .dimensions = {2, 1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0078125f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 128
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({245, 247}),
+ .dimensions = {2, 1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({246}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({0}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }},
+ .operations = {{
+ .inputs = {3, 4, 5},
+ .outputs = {0},
+ .type = TestOperationType::ADD
+ }, {
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_corner_case_dim2_axis1_neg_all_inputs_as_internal = TestModelManager::get().add("l2_normalization_axis_corner_case_dim2_axis1_neg_all_inputs_as_internal", get_test_model_corner_case_dim2_axis1_neg_all_inputs_as_internal());
+
+} // namespace generated_tests::l2_normalization_axis
+
+namespace generated_tests::l2_normalization_axis {
+
+const TestModel& get_test_model_corner_case_dim1_axis0() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {0},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({245}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({0}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({0}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0078125f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 128
+ }},
+ .operations = {{
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_corner_case_dim1_axis0 = TestModelManager::get().add("l2_normalization_axis_corner_case_dim1_axis0", get_test_model_corner_case_dim1_axis0());
+
+} // namespace generated_tests::l2_normalization_axis
+
+namespace generated_tests::l2_normalization_axis {
+
+const TestModel& get_test_model_corner_case_dim1_axis0_all_inputs_as_internal() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {3},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({0}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({0}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0078125f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 128
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({245}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({246}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({0}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }},
+ .operations = {{
+ .inputs = {3, 4, 5},
+ .outputs = {0},
+ .type = TestOperationType::ADD
+ }, {
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_corner_case_dim1_axis0_all_inputs_as_internal = TestModelManager::get().add("l2_normalization_axis_corner_case_dim1_axis0_all_inputs_as_internal", get_test_model_corner_case_dim1_axis0_all_inputs_as_internal());
+
+} // namespace generated_tests::l2_normalization_axis
+
+namespace generated_tests::l2_normalization_axis {
+
+const TestModel& get_test_model_corner_case_dim1_axis0_neg() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {0},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({245}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({-1}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({0}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0078125f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 128
+ }},
+ .operations = {{
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_corner_case_dim1_axis0_neg = TestModelManager::get().add("l2_normalization_axis_corner_case_dim1_axis0_neg", get_test_model_corner_case_dim1_axis0_neg());
+
+} // namespace generated_tests::l2_normalization_axis
+
+namespace generated_tests::l2_normalization_axis {
+
+const TestModel& get_test_model_corner_case_dim1_axis0_neg_all_inputs_as_internal() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {3},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({-1}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({0}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0078125f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 128
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({245}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({246}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.904414f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 246
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({0}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }},
+ .operations = {{
+ .inputs = {3, 4, 5},
+ .outputs = {0},
+ .type = TestOperationType::ADD
+ }, {
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_corner_case_dim1_axis0_neg_all_inputs_as_internal = TestModelManager::get().add("l2_normalization_axis_corner_case_dim1_axis0_neg_all_inputs_as_internal", get_test_model_corner_case_dim1_axis0_neg_all_inputs_as_internal());
+
+} // namespace generated_tests::l2_normalization_axis
+
diff --git a/nn/runtime/test/generated/spec_V1_3/l2_normalization_zeros.example.cpp b/nn/runtime/test/generated/spec_V1_3/l2_normalization_zeros.example.cpp
new file mode 100644
index 000000000..72734f615
--- /dev/null
+++ b/nn/runtime/test/generated/spec_V1_3/l2_normalization_zeros.example.cpp
@@ -0,0 +1,746 @@
+// Generated from l2_normalization_zeros.mod.py
+// DO NOT EDIT
+// clang-format off
+#include "TestHarness.h"
+using namespace test_helper;
+
+namespace generated_tests::l2_normalization_zeros {
+
+const TestModel& get_test_model() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {0},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<float>({0.0f, 0.0f}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({-1}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<float>({0.0f, 0.0f}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT32,
+ .zeroPoint = 0
+ }},
+ .operations = {{
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model = TestModelManager::get().add("l2_normalization_zeros", get_test_model());
+
+} // namespace generated_tests::l2_normalization_zeros
+
+namespace generated_tests::l2_normalization_zeros {
+
+const TestModel& get_test_model_all_inputs_as_internal() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {3},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<float>({}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({-1}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<float>({0.0f, 0.0f}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<float>({0.0f, 0.0f}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<float>({0.0f}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({0}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }},
+ .operations = {{
+ .inputs = {3, 4, 5},
+ .outputs = {0},
+ .type = TestOperationType::ADD
+ }, {
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_all_inputs_as_internal = TestModelManager::get().add("l2_normalization_zeros_all_inputs_as_internal", get_test_model_all_inputs_as_internal());
+
+} // namespace generated_tests::l2_normalization_zeros
+
+namespace generated_tests::l2_normalization_zeros {
+
+const TestModel& get_test_model_relaxed() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = true,
+ .main = {
+ .inputIndexes = {0},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<float>({0.0f, 0.0f}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({-1}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<float>({0.0f, 0.0f}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT32,
+ .zeroPoint = 0
+ }},
+ .operations = {{
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::UNKNOWN,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_relaxed = TestModelManager::get().add("l2_normalization_zeros_relaxed", get_test_model_relaxed());
+
+} // namespace generated_tests::l2_normalization_zeros
+
+namespace generated_tests::l2_normalization_zeros {
+
+const TestModel& get_test_model_relaxed_all_inputs_as_internal() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = true,
+ .main = {
+ .inputIndexes = {3},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<float>({}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({-1}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<float>({0.0f, 0.0f}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<float>({0.0f, 0.0f}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<float>({0.0f}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({0}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }},
+ .operations = {{
+ .inputs = {3, 4, 5},
+ .outputs = {0},
+ .type = TestOperationType::ADD
+ }, {
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::UNKNOWN,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_relaxed_all_inputs_as_internal = TestModelManager::get().add("l2_normalization_zeros_relaxed_all_inputs_as_internal", get_test_model_relaxed_all_inputs_as_internal());
+
+} // namespace generated_tests::l2_normalization_zeros
+
+namespace generated_tests::l2_normalization_zeros {
+
+const TestModel& get_test_model_float16() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {0},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<_Float16>({0.0f, 0.0f}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT16,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({-1}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<_Float16>({0.0f, 0.0f}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT16,
+ .zeroPoint = 0
+ }},
+ .operations = {{
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_float16 = TestModelManager::get().add("l2_normalization_zeros_float16", get_test_model_float16());
+
+} // namespace generated_tests::l2_normalization_zeros
+
+namespace generated_tests::l2_normalization_zeros {
+
+const TestModel& get_test_model_float16_all_inputs_as_internal() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {3},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<_Float16>({}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT16,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({-1}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<_Float16>({0.0f, 0.0f}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT16,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<_Float16>({0.0f, 0.0f}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT16,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<_Float16>({0.0f}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::TENSOR_FLOAT16,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({0}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }},
+ .operations = {{
+ .inputs = {3, 4, 5},
+ .outputs = {0},
+ .type = TestOperationType::ADD
+ }, {
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_float16_all_inputs_as_internal = TestModelManager::get().add("l2_normalization_zeros_float16_all_inputs_as_internal", get_test_model_float16_all_inputs_as_internal());
+
+} // namespace generated_tests::l2_normalization_zeros
+
+namespace generated_tests::l2_normalization_zeros {
+
+const TestModel& get_test_model_quant8() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {0},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({32, 32}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.1f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 32
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({-1}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({128, 128}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0078125f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 128
+ }},
+ .operations = {{
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_quant8 = TestModelManager::get().add("l2_normalization_zeros_quant8", get_test_model_quant8());
+
+} // namespace generated_tests::l2_normalization_zeros
+
+namespace generated_tests::l2_normalization_zeros {
+
+const TestModel& get_test_model_quant8_all_inputs_as_internal() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {3},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+ .numberOfConsumers = 1,
+ .scale = 0.1f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 32
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({-1}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({128, 128}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0078125f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 128
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({32, 32}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.1f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 32
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<uint8_t>({32}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.1f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+ .zeroPoint = 32
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({0}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }},
+ .operations = {{
+ .inputs = {3, 4, 5},
+ .outputs = {0},
+ .type = TestOperationType::ADD
+ }, {
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_2,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_quant8_all_inputs_as_internal = TestModelManager::get().add("l2_normalization_zeros_quant8_all_inputs_as_internal", get_test_model_quant8_all_inputs_as_internal());
+
+} // namespace generated_tests::l2_normalization_zeros
+
+namespace generated_tests::l2_normalization_zeros {
+
+const TestModel& get_test_model_quant8_signed() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {0},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int8_t>({-96, -96}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.1f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED,
+ .zeroPoint = -96
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({-1}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int8_t>({0, 0}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0078125f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED,
+ .zeroPoint = 0
+ }},
+ .operations = {{
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_3,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_quant8_signed = TestModelManager::get().add("l2_normalization_zeros_quant8_signed", get_test_model_quant8_signed());
+
+} // namespace generated_tests::l2_normalization_zeros
+
+namespace generated_tests::l2_normalization_zeros {
+
+const TestModel& get_test_model_quant8_signed_all_inputs_as_internal() {
+ static TestModel model = {
+ .expectFailure = false,
+ .expectedMultinomialDistributionTolerance = 0,
+ .isRelaxed = false,
+ .main = {
+ .inputIndexes = {3},
+ .operands = {{
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int8_t>({}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+ .numberOfConsumers = 1,
+ .scale = 0.1f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED,
+ .zeroPoint = -96
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({-1}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int8_t>({0, 0}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+ .numberOfConsumers = 0,
+ .scale = 0.0078125f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED,
+ .zeroPoint = 0
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int8_t>({-96, -96}),
+ .dimensions = {2},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+ .numberOfConsumers = 1,
+ .scale = 0.1f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED,
+ .zeroPoint = -96
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int8_t>({-96}),
+ .dimensions = {1},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.1f,
+ .type = TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED,
+ .zeroPoint = -96
+ }, {
+ .channelQuant = {},
+ .data = TestBuffer::createFromVector<int32_t>({0}),
+ .dimensions = {},
+ .isIgnored = false,
+ .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .type = TestOperandType::INT32,
+ .zeroPoint = 0
+ }},
+ .operations = {{
+ .inputs = {3, 4, 5},
+ .outputs = {0},
+ .type = TestOperationType::ADD
+ }, {
+ .inputs = {0, 1},
+ .outputs = {2},
+ .type = TestOperationType::L2_NORMALIZATION
+ }},
+ .outputIndexes = {2}
+ },
+ .minSupportedVersion = TestHalVersion::V1_3,
+ .referenced = {}
+ };
+ return model;
+}
+
+const auto dummy_test_model_quant8_signed_all_inputs_as_internal = TestModelManager::get().add("l2_normalization_zeros_quant8_signed_all_inputs_as_internal", get_test_model_quant8_signed_all_inputs_as_internal());
+
+} // namespace generated_tests::l2_normalization_zeros
+
diff --git a/nn/runtime/test/specs/V1_2/l2_normalization_axis.mod.py b/nn/runtime/test/specs/V1_2/l2_normalization_axis.mod.py
index ba8e24ad6..24852a697 100644
--- a/nn/runtime/test/specs/V1_2/l2_normalization_axis.mod.py
+++ b/nn/runtime/test/specs/V1_2/l2_normalization_axis.mod.py
@@ -14,6 +14,7 @@
# limitations under the License.
#
+# TEST 1: L2_NORMALIZATION with axis parameter
i1 = Input("op1", "TENSOR_FLOAT32", "{2, 2, 2, 3}") # input 0
o1 = Output("op2", "TENSOR_FLOAT32", "{2, 2, 2, 3}") # output 0
axis = Int32Scalar("axis", -1) # last axis
@@ -45,3 +46,15 @@ example0 = {
# All dimensions, with all possible axis parameter
Model().Operation("L2_NORMALIZATION", i1, axis).To(o1)
Example(example0).AddAllDimsAndAxis(i1, o1, axis).AddVariations("relaxed", "float16", quant8)
+
+
+# TEST 2: Corner cases for TENSOR_QUANT8_ASYMM data type.
+i2 = Input("op1", "TENSOR_QUANT8_ASYMM", "{2, 1}, 0.904414f, 246")
+o2 = Output("op2", "TENSOR_QUANT8_ASYMM", "{2, 1}, 0.0078125f, 128")
+axis = Int32Scalar("axis", -1) # last axis
+
+Model("corner_case").Operation("L2_NORMALIZATION", i2, axis).To(o2)
+Example({
+ i2: [245, 247],
+ o2: [0, 255],
+}).AddAllDimsAndAxis(i2, o2, axis)
diff --git a/nn/runtime/test/specs/V1_3/l2_normalization_zeros.mod.py b/nn/runtime/test/specs/V1_3/l2_normalization_zeros.mod.py
new file mode 100644
index 000000000..6af710795
--- /dev/null
+++ b/nn/runtime/test/specs/V1_3/l2_normalization_zeros.mod.py
@@ -0,0 +1,41 @@
+#
+# 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.
+#
+
+# Test L2_NORMALIZATION with inputs of all zeros.
+i1 = Input("op1", "TENSOR_FLOAT32", "{2}") # input 0
+o1 = Output("op2", "TENSOR_FLOAT32", "{2}") # output 0
+axis = Int32Scalar("axis", -1) # last axis
+
+quant8 = DataTypeConverter().Identify({
+ i1: ("TENSOR_QUANT8_ASYMM", 0.1, 32),
+ o1: ("TENSOR_QUANT8_ASYMM", 1.0 / 128, 128)
+})
+
+quant8_signed = DataTypeConverter().Identify({
+ i1: ("TENSOR_QUANT8_ASYMM_SIGNED", 0.1, -96),
+ o1: ("TENSOR_QUANT8_ASYMM_SIGNED", 1.0 / 128, 0)
+})
+
+Model().IntroducedIn("V1_2").Operation("L2_NORMALIZATION", i1, axis).To(o1)
+Example({
+ i1: [0, 0],
+ o1: [0, 0]
+}).AddVariations("relaxed", "float16", quant8, quant8_signed)
+
+# TENSOR_QUANT8_ASYMM_SIGNED is a new data type in V1_3.
+Example.SetVersion("V1_3",
+ "l2_normalization_zeros_quant8_signed",
+ "l2_normalization_zeros_quant8_signed_all_inputs_as_internal")
diff --git a/nn/tools/api/types.spec b/nn/tools/api/types.spec
index 9fb72e2af..2c8a522bf 100644
--- a/nn/tools/api/types.spec
+++ b/nn/tools/api/types.spec
@@ -18,7 +18,7 @@
%define APILevel29 API level 29
%define APILevel30 API level 30
%define BeforeAPILevel29For Before API level 29, for
-%define or_1.2 or {@link ANEURALNETWORKS_%{1}}
+%define or_1.2 or {@link ANEURALNETWORKS_%{1}}
%define-lines AVAIL27
*
* Available since API level 27.
@@ -97,7 +97,7 @@
%kind hal_1.2 hal_1.3
%define BeforeAPILevel29For Before HAL version 1.2, for
-%define or_1.2 or {@link OperandType::%{1}}
+%define or_1.2 or {@link OperandType::%{1}}
%/kind
%kind hal_1.2
@@ -132,7 +132,7 @@
%/kind
%kind ndk hal_1.3
-%define AndQuant8Signed
+%define AndQuant8Signed
%/kind
%kind hal_1.0 hal_1.1 hal_1.2
%define AndQuant8Signed
@@ -522,7 +522,7 @@
%/kind
* * 2: A 1-D tensor, of shape [depth_out], specifying the bias. For input
* tensor of type {@link %{OperandTypeLinkPfx}TENSOR_FLOAT32}
- * %{or_1.2 TENSOR_FLOAT16}the bias must be of the same type.
+ * %{or_1.2 TENSOR_FLOAT16} the bias must be of the same type.
%kind ndk hal_1.3+
* For filter tensor of {@link %{OperandTypeLinkPfx}TENSOR_QUANT8_ASYMM}
* and {@link %{OperandTypeLinkPfx}TENSOR_QUANT8_ASYMM_SIGNED},
@@ -582,7 +582,7 @@
%/kind
* * 2: A 1-D tensor, of shape [depth_out], specifying the bias. For input
* tensor of type {@link %{OperandTypeLinkPfx}TENSOR_FLOAT32}
- * %{or_1.2 TENSOR_FLOAT16}the bias must be of the same
+ * %{or_1.2 TENSOR_FLOAT16} the bias must be of the same
* type.
%kind ndk hal_1.3+
* For filter tensor of {@link %{OperandTypeLinkPfx}TENSOR_QUANT8_ASYMM}
@@ -706,7 +706,7 @@
%/kind
* * 2: A 1-D tensor, of shape [depth_out], specifying the bias. For input
* tensor of type {@link %{OperandTypeLinkPfx}TENSOR_FLOAT32}
- * %{or_1.2 TENSOR_FLOAT16}the bias must be of the same type.
+ * %{or_1.2 TENSOR_FLOAT16} the bias must be of the same type.
%kind ndk hal_1.3+
* For filter tensor of {@link %{OperandTypeLinkPfx}TENSOR_QUANT8_ASYMM}
* and {@link %{OperandTypeLinkPfx}TENSOR_QUANT8_ASYMM_SIGNED},
@@ -761,7 +761,7 @@
* specifying the filter.
* * 2: A 1-D tensor, of shape [depth_out], specifying the bias. For input
* tensor of type {@link %{OperandTypeLinkPfx}TENSOR_FLOAT32}
- * %{or_1.2 TENSOR_FLOAT16}the bias must be of the same type.
+ * %{or_1.2 TENSOR_FLOAT16} the bias must be of the same type.
%kind ndk hal_1.3+
* For filter tensor of {@link %{OperandTypeLinkPfx}TENSOR_QUANT8_ASYMM}
* and {@link %{OperandTypeLinkPfx}TENSOR_QUANT8_ASYMM_SIGNED},
@@ -1154,6 +1154,10 @@
%kind ndk hal_1.3+
* For {@link %{OperandTypeLinkPfx}TENSOR_QUANT8_ASYMM_SIGNED},
* the scale must be 1.f / 128 and the zeroPoint must be 0.
+ *
+ * NOTE: Before %{APILevel30}, if the elements along an axis are all zeros,
+ * the result is undefined. Since %{APILevel30}, if the elements along an axis
+ * are all zeros, the result is logical zero.
%/kind
%insert-lines AVAIL27
*/