Add FILL and RANK ops

Fix: 148050168
Fix: 148049333
Test: NNTest_static and VtsHalNeuralnetworksV1_3TargetTest
Change-Id: I5438cdd7c0cc52e49067529edcee537278c8f7ad
Merged-In: I5438cdd7c0cc52e49067529edcee537278c8f7ad
(cherry picked from commit 2e630a474954b5cad805573c32e5d88bf5841812)
diff --git a/runtime/NeuralNetworks.cpp b/runtime/NeuralNetworks.cpp
index 78fdca0..c88e4f1 100644
--- a/runtime/NeuralNetworks.cpp
+++ b/runtime/NeuralNetworks.cpp
@@ -196,6 +196,8 @@
 static_assert(ANEURALNETWORKS_WHILE == 97, "ANEURALNETWORKS_WHILE has changed");
 static_assert(ANEURALNETWORKS_ELU == 98, "ANEURALNETWORKS_ELU has changed");
 static_assert(ANEURALNETWORKS_HARD_SWISH == 99, "ANEURALNETWORKS_HARD_SWISH has changed");
+static_assert(ANEURALNETWORKS_FILL == 100, "ANEURALNETWORKS_FILL has changed");
+static_assert(ANEURALNETWORKS_RANK == 101, "ANEURALNETWORKS_RANK has changed");
 
 static_assert(ANEURALNETWORKS_OEM_OPERATION == 10000, "ANEURALNETWORKS_OEM_OPERATION has changed");
 
@@ -533,6 +535,10 @@
               "OperationType::ELU != ANEURALNETWORKS_ELU");
 static_assert(static_cast<int32_t>(OperationType::HARD_SWISH) == ANEURALNETWORKS_HARD_SWISH,
               "OperationType::HARD_SWISH != ANEURALNETWORKS_HARD_SWISH");
+static_assert(static_cast<int32_t>(OperationType::FILL) == ANEURALNETWORKS_FILL,
+              "OperationType::FILL != ANEURALNETWORKS_FILL");
+static_assert(static_cast<int32_t>(OperationType::RANK) == ANEURALNETWORKS_RANK,
+              "OperationType::RANK != ANEURALNETWORKS_RANK");
 
 static_assert(static_cast<int32_t>(DeviceType::OTHER) == ANEURALNETWORKS_DEVICE_OTHER,
               "DeviceType::OTHER != ANEURALNETWORKS_DEVICE_OTHER");
diff --git a/runtime/include/NeuralNetworks.h b/runtime/include/NeuralNetworks.h
index de8f056..b4d59cb 100644
--- a/runtime/include/NeuralNetworks.h
+++ b/runtime/include/NeuralNetworks.h
@@ -5386,6 +5386,60 @@
      * Available since API level 30.
      */
     ANEURALNETWORKS_HARD_SWISH = 99,
+
+    /**
+     * Creates a tensor filled with a scalar value.
+     *
+     * Supported output tensor {@link OperandCode}:
+     * * {@link ANEURALNETWORKS_TENSOR_FLOAT16}
+     * * {@link ANEURALNETWORKS_TENSOR_FLOAT32}
+     * * {@link ANEURALNETWORKS_TENSOR_INT32}
+     *
+     * Inputs:
+     * * 0: A 1-D tensor, specifying the desired output tensor shape.
+     * * 1: A scalar, specifying the value to fill the output tensors with.
+     *      For output tensor of {@link ANEURALNETWORKS_TENSOR_FLOAT16},
+     *      the scalar must be of {@link ANEURALNETWORKS_FLOAT16}.
+     *      For output tensor of {@link ANEURALNETWORKS_TENSOR_FLOAT32},
+     *      the scalar must be of {@link ANEURALNETWORKS_FLOAT32}.
+     *      For output tensor of {@link ANEURALNETWORKS_TENSOR_INT32},
+     *      the scalar must be of {@link ANEURALNETWORKS_INT32}.
+     *
+     * Outputs:
+     * * 0: The output tensor.
+     *
+     * Available since API level 30.
+     */
+    ANEURALNETWORKS_FILL = 100,
+
+    /**
+     * Returns the rank of a tensor.
+     *
+     * The rank of a tensor is the number of dimensions in it. Also known as
+     * "order", "degree", "ndims".
+     *
+     * Supported tensor {@link OperandCode}:
+     * * {@link ANEURALNETWORKS_TENSOR_FLOAT16}
+     * * {@link ANEURALNETWORKS_TENSOR_FLOAT32}
+     * * {@link ANEURALNETWORKS_TENSOR_INT32}
+     * * {@link ANEURALNETWORKS_TENSOR_QUANT8_ASYMM}
+     * * {@link ANEURALNETWORKS_TENSOR_QUANT16_SYMM}
+     * * {@link ANEURALNETWORKS_TENSOR_BOOL8}
+     * * {@link ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL}
+     * * {@link ANEURALNETWORKS_TENSOR_QUANT16_ASYMM}
+     * * {@link ANEURALNETWORKS_TENSOR_QUANT8_SYMM}
+     * * {@link ANEURALNETWORKS_TENSOR_QUANT8_ASYMM_SIGNED}
+     *
+     * Inputs:
+     * * 0: The input tensor.
+     *
+     * Outputs:
+     * * 0: A scalar of {@link ANEURALNETWORKS_INT32}, specifying the rank
+     *      of the input tensor.
+     *
+     * Available since API level 30.
+     */
+    ANEURALNETWORKS_RANK = 101,
 } OperationCode;
 
 /**
diff --git a/runtime/test/TestValidateOperations.cpp b/runtime/test/TestValidateOperations.cpp
index 72f5f39..304935f 100644
--- a/runtime/test/TestValidateOperations.cpp
+++ b/runtime/test/TestValidateOperations.cpp
@@ -155,6 +155,10 @@
             if (mOpCode == ANEURALNETWORKS_LSH_PROJECTION && i == 1) {
                 continue;
             }
+            // RANK can have input of any type.
+            if (mOpCode == ANEURALNETWORKS_RANK) {
+                continue;
+            }
             OperandTypeWithExtraParams newType = mValidInputs[i];
             int32_t originalOperandCode = mValidInputs[i].operandType.type;
             std::set<int32_t> operandTypesToSkip;
@@ -3717,4 +3721,54 @@
     test.testOpsValidations();
 }
 
+void fillTest(int32_t valueOperandType, int32_t outputOperandType) {
+    uint32_t inputDimensions[1] = {3};
+    ANeuralNetworksOperandType input0 = getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, inputDimensions);
+    ANeuralNetworksOperandType input1 = getOpType(valueOperandType);
+    uint32_t outputDimensions[3] = {3, 4, 5};
+    ANeuralNetworksOperandType output = getOpType(outputOperandType, 3, outputDimensions);
+    OperationTestBase test(ANEURALNETWORKS_FILL, {input0, input1}, {output});
+    test.testOpsValidations();
+}
+
+TEST(OperationValidationTest, FILL_float16) {
+    fillTest(ANEURALNETWORKS_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16);
+}
+
+TEST(OperationValidationTest, FILL_float32) {
+    fillTest(ANEURALNETWORKS_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32);
+}
+
+TEST(OperationValidationTest, FILL_int32) {
+    fillTest(ANEURALNETWORKS_INT32, ANEURALNETWORKS_TENSOR_INT32);
+}
+
+void rankTest(int32_t inputOperandType) {
+    uint32_t inputDimensions[3] = {3, 4, 5};
+    ANeuralNetworksOperandType input = getOpType(inputOperandType, 3, inputDimensions);
+    ANeuralNetworksOperandType output = getOpType(ANEURALNETWORKS_INT32);
+    OperationTestBase test(ANEURALNETWORKS_RANK, {input}, {output});
+    test.testOpsValidations();
+}
+
+TEST(OperationValidationTest, RANK_float16) {
+    rankTest(ANEURALNETWORKS_TENSOR_FLOAT16);
+}
+
+TEST(OperationValidationTest, RANK_float32) {
+    rankTest(ANEURALNETWORKS_TENSOR_FLOAT32);
+}
+
+TEST(OperationValidationTest, RANK_int32) {
+    rankTest(ANEURALNETWORKS_TENSOR_INT32);
+}
+
+TEST(OperationValidationTest, RANK_quant8) {
+    rankTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
+}
+
+TEST(OperationValidationTest, RANK_quant8_signed) {
+    rankTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM_SIGNED);
+}
+
 }  // end namespace
diff --git a/runtime/test/generated/spec_V1_3/fill.example.cpp b/runtime/test/generated/spec_V1_3/fill.example.cpp
new file mode 100644
index 0000000..869b734
--- /dev/null
+++ b/runtime/test/generated/spec_V1_3/fill.example.cpp
@@ -0,0 +1,492 @@
+// Generated from fill.mod.py
+// DO NOT EDIT
+// clang-format off
+#include "TestHarness.h"
+using namespace test_helper;
+
+namespace generated_tests::fill {
+
+const TestModel& get_test_model_1d() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({5}),
+                .dimensions = {1},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::TENSOR_INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<float>({3.0f}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::FLOAT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<float>({3.0f, 3.0f, 3.0f, 3.0f, 3.0f}),
+                .dimensions = {5},
+                .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::FILL
+            }},
+        .outputIndexes = {2}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d = TestModelManager::get().add("fill_1d", get_test_model_1d());
+
+}  // namespace generated_tests::fill
+
+namespace generated_tests::fill {
+
+const TestModel& get_test_model_1d_float16() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({5}),
+                .dimensions = {1},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::TENSOR_INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<_Float16>({3.0f}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::FLOAT16,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<_Float16>({3.0f, 3.0f, 3.0f, 3.0f, 3.0f}),
+                .dimensions = {5},
+                .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::FILL
+            }},
+        .outputIndexes = {2}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_float16 = TestModelManager::get().add("fill_1d_float16", get_test_model_1d_float16());
+
+}  // namespace generated_tests::fill
+
+namespace generated_tests::fill {
+
+const TestModel& get_test_model_1d_int32() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({5}),
+                .dimensions = {1},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::TENSOR_INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({3}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({3, 3, 3, 3, 3}),
+                .dimensions = {5},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::TENSOR_INT32,
+                .zeroPoint = 0
+            }},
+        .operations = {{
+                .inputs = {0, 1},
+                .outputs = {2},
+                .type = TestOperationType::FILL
+            }},
+        .outputIndexes = {2}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_int32 = TestModelManager::get().add("fill_1d_int32", get_test_model_1d_int32());
+
+}  // namespace generated_tests::fill
+
+namespace generated_tests::fill {
+
+const TestModel& get_test_model_3d() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({2, 3, 4}),
+                .dimensions = {3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::TENSOR_INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<float>({3.0f}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::FLOAT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<float>({3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f}),
+                .dimensions = {2, 3, 4},
+                .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::FILL
+            }},
+        .outputIndexes = {2}
+    };
+    return model;
+}
+
+const auto dummy_test_model_3d = TestModelManager::get().add("fill_3d", get_test_model_3d());
+
+}  // namespace generated_tests::fill
+
+namespace generated_tests::fill {
+
+const TestModel& get_test_model_3d_float16() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({2, 3, 4}),
+                .dimensions = {3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::TENSOR_INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<_Float16>({3.0f}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::FLOAT16,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<_Float16>({3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f}),
+                .dimensions = {2, 3, 4},
+                .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::FILL
+            }},
+        .outputIndexes = {2}
+    };
+    return model;
+}
+
+const auto dummy_test_model_3d_float16 = TestModelManager::get().add("fill_3d_float16", get_test_model_3d_float16());
+
+}  // namespace generated_tests::fill
+
+namespace generated_tests::fill {
+
+const TestModel& get_test_model_3d_int32() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({2, 3, 4}),
+                .dimensions = {3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::TENSOR_INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({3}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}),
+                .dimensions = {2, 3, 4},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::TENSOR_INT32,
+                .zeroPoint = 0
+            }},
+        .operations = {{
+                .inputs = {0, 1},
+                .outputs = {2},
+                .type = TestOperationType::FILL
+            }},
+        .outputIndexes = {2}
+    };
+    return model;
+}
+
+const auto dummy_test_model_3d_int32 = TestModelManager::get().add("fill_3d_int32", get_test_model_3d_int32());
+
+}  // namespace generated_tests::fill
+
+namespace generated_tests::fill {
+
+const TestModel& get_test_model_5d() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({1, 2, 3, 4, 5}),
+                .dimensions = {5},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::TENSOR_INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<float>({3.0f}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::FLOAT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<float>({3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f}),
+                .dimensions = {1, 2, 3, 4, 5},
+                .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::FILL
+            }},
+        .outputIndexes = {2}
+    };
+    return model;
+}
+
+const auto dummy_test_model_5d = TestModelManager::get().add("fill_5d", get_test_model_5d());
+
+}  // namespace generated_tests::fill
+
+namespace generated_tests::fill {
+
+const TestModel& get_test_model_5d_float16() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({1, 2, 3, 4, 5}),
+                .dimensions = {5},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::TENSOR_INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<_Float16>({3.0f}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::FLOAT16,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<_Float16>({3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f}),
+                .dimensions = {1, 2, 3, 4, 5},
+                .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::FILL
+            }},
+        .outputIndexes = {2}
+    };
+    return model;
+}
+
+const auto dummy_test_model_5d_float16 = TestModelManager::get().add("fill_5d_float16", get_test_model_5d_float16());
+
+}  // namespace generated_tests::fill
+
+namespace generated_tests::fill {
+
+const TestModel& get_test_model_5d_int32() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({1, 2, 3, 4, 5}),
+                .dimensions = {5},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::TENSOR_INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({3}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3}),
+                .dimensions = {1, 2, 3, 4, 5},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::TENSOR_INT32,
+                .zeroPoint = 0
+            }},
+        .operations = {{
+                .inputs = {0, 1},
+                .outputs = {2},
+                .type = TestOperationType::FILL
+            }},
+        .outputIndexes = {2}
+    };
+    return model;
+}
+
+const auto dummy_test_model_5d_int32 = TestModelManager::get().add("fill_5d_int32", get_test_model_5d_int32());
+
+}  // namespace generated_tests::fill
+
diff --git a/runtime/test/generated/spec_V1_3/rank.example.cpp b/runtime/test/generated/spec_V1_3/rank.example.cpp
new file mode 100644
index 0000000..956f10d
--- /dev/null
+++ b/runtime/test/generated/spec_V1_3/rank.example.cpp
@@ -0,0 +1,1070 @@
+// Generated from rank.mod.py
+// DO NOT EDIT
+// clang-format off
+#include "TestHarness.h"
+using namespace test_helper;
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<float>({5.0f, 7.0f, 10.0f}),
+                .dimensions = {3},
+                .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::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }},
+        .operations = {{
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d = TestModelManager::get().add("rank_1d", get_test_model_1d());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_all_inputs_as_internal() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {2},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<float>({}),
+                .dimensions = {3},
+                .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::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<float>({5.0f, 7.0f, 10.0f}),
+                .dimensions = {3},
+                .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 = {2, 3, 4},
+                .outputs = {0},
+                .type = TestOperationType::ADD
+            }, {
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_all_inputs_as_internal = TestModelManager::get().add("rank_1d_all_inputs_as_internal", get_test_model_1d_all_inputs_as_internal());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_int32() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({5, 7, 10}),
+                .dimensions = {3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::TENSOR_INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({1}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }},
+        .operations = {{
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_int32 = TestModelManager::get().add("rank_1d_int32", get_test_model_1d_int32());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_float16() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<_Float16>({5.0f, 7.0f, 10.0f}),
+                .dimensions = {3},
+                .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::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }},
+        .operations = {{
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_float16 = TestModelManager::get().add("rank_1d_float16", get_test_model_1d_float16());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_float16_all_inputs_as_internal() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {2},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<_Float16>({}),
+                .dimensions = {3},
+                .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::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<_Float16>({5.0f, 7.0f, 10.0f}),
+                .dimensions = {3},
+                .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 = {2, 3, 4},
+                .outputs = {0},
+                .type = TestOperationType::ADD
+            }, {
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_float16_all_inputs_as_internal = TestModelManager::get().add("rank_1d_float16_all_inputs_as_internal", get_test_model_1d_float16_all_inputs_as_internal());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_quant8() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<uint8_t>({178, 198, 228}),
+                .dimensions = {3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.1f,
+                .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+                .zeroPoint = 128
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({1}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }},
+        .operations = {{
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_quant8 = TestModelManager::get().add("rank_1d_quant8", get_test_model_1d_quant8());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_quant8_all_inputs_as_internal() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {2},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<uint8_t>({}),
+                .dimensions = {3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+                .numberOfConsumers = 1,
+                .scale = 0.1f,
+                .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+                .zeroPoint = 128
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({1}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<uint8_t>({178, 198, 228}),
+                .dimensions = {3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.1f,
+                .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+                .zeroPoint = 128
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<uint8_t>({128}),
+                .dimensions = {1},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+                .numberOfConsumers = 1,
+                .scale = 0.1f,
+                .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+                .zeroPoint = 128
+            }, {
+                .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 = {2, 3, 4},
+                .outputs = {0},
+                .type = TestOperationType::ADD
+            }, {
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_quant8_all_inputs_as_internal = TestModelManager::get().add("rank_1d_quant8_all_inputs_as_internal", get_test_model_1d_quant8_all_inputs_as_internal());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_quant8_signed() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int8_t>({50, 70, 100}),
+                .dimensions = {3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.1f,
+                .type = TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({1}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }},
+        .operations = {{
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_quant8_signed = TestModelManager::get().add("rank_1d_quant8_signed", get_test_model_1d_quant8_signed());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_quant8_signed_all_inputs_as_internal() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {2},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int8_t>({}),
+                .dimensions = {3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+                .numberOfConsumers = 1,
+                .scale = 0.1f,
+                .type = TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({1}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int8_t>({50, 70, 100}),
+                .dimensions = {3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.1f,
+                .type = TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int8_t>({0}),
+                .dimensions = {1},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+                .numberOfConsumers = 1,
+                .scale = 0.1f,
+                .type = TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED,
+                .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 = {2, 3, 4},
+                .outputs = {0},
+                .type = TestOperationType::ADD
+            }, {
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_quant8_signed_all_inputs_as_internal = TestModelManager::get().add("rank_1d_quant8_signed_all_inputs_as_internal", get_test_model_1d_quant8_signed_all_inputs_as_internal());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_2() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<float>({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
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({2}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }},
+        .operations = {{
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_2 = TestModelManager::get().add("rank_1d_2", get_test_model_1d_2());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_all_inputs_as_internal_2() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {2},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<float>({}),
+                .dimensions = {2, 3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::TENSOR_FLOAT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({2}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<float>({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
+            }, {
+                .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 = {2, 3, 4},
+                .outputs = {0},
+                .type = TestOperationType::ADD
+            }, {
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_all_inputs_as_internal_2 = TestModelManager::get().add("rank_1d_all_inputs_as_internal_2", get_test_model_1d_all_inputs_as_internal_2());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_int32_2() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({1, 2, 3, 4, 5, 6}),
+                .dimensions = {2, 3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::TENSOR_INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({2}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }},
+        .operations = {{
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_int32_2 = TestModelManager::get().add("rank_1d_int32_2", get_test_model_1d_int32_2());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_float16_2() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<_Float16>({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_FLOAT16,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({2}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }},
+        .operations = {{
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_float16_2 = TestModelManager::get().add("rank_1d_float16_2", get_test_model_1d_float16_2());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_float16_all_inputs_as_internal_2() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {2},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<_Float16>({}),
+                .dimensions = {2, 3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+                .numberOfConsumers = 1,
+                .scale = 0.0f,
+                .type = TestOperandType::TENSOR_FLOAT16,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({2}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<_Float16>({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_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 = {2, 3, 4},
+                .outputs = {0},
+                .type = TestOperationType::ADD
+            }, {
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_float16_all_inputs_as_internal_2 = TestModelManager::get().add("rank_1d_float16_all_inputs_as_internal_2", get_test_model_1d_float16_all_inputs_as_internal_2());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_quant8_2() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<uint8_t>({138, 148, 158, 168, 178, 188}),
+                .dimensions = {2, 3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.1f,
+                .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+                .zeroPoint = 128
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({2}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }},
+        .operations = {{
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_quant8_2 = TestModelManager::get().add("rank_1d_quant8_2", get_test_model_1d_quant8_2());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_quant8_all_inputs_as_internal_2() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {2},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<uint8_t>({}),
+                .dimensions = {2, 3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+                .numberOfConsumers = 1,
+                .scale = 0.1f,
+                .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+                .zeroPoint = 128
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({2}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<uint8_t>({138, 148, 158, 168, 178, 188}),
+                .dimensions = {2, 3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.1f,
+                .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+                .zeroPoint = 128
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<uint8_t>({128}),
+                .dimensions = {1},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+                .numberOfConsumers = 1,
+                .scale = 0.1f,
+                .type = TestOperandType::TENSOR_QUANT8_ASYMM,
+                .zeroPoint = 128
+            }, {
+                .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 = {2, 3, 4},
+                .outputs = {0},
+                .type = TestOperationType::ADD
+            }, {
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_quant8_all_inputs_as_internal_2 = TestModelManager::get().add("rank_1d_quant8_all_inputs_as_internal_2", get_test_model_1d_quant8_all_inputs_as_internal_2());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_quant8_signed_2() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {0},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int8_t>({10, 20, 30, 40, 50, 60}),
+                .dimensions = {2, 3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.1f,
+                .type = TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({2}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }},
+        .operations = {{
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_quant8_signed_2 = TestModelManager::get().add("rank_1d_quant8_signed_2", get_test_model_1d_quant8_signed_2());
+
+}  // namespace generated_tests::rank
+
+namespace generated_tests::rank {
+
+const TestModel& get_test_model_1d_quant8_signed_all_inputs_as_internal_2() {
+    static TestModel model = {
+        .expectFailure = false,
+        .expectedMultinomialDistributionTolerance = 0,
+        .inputIndexes = {2},
+        .isRelaxed = false,
+        .minSupportedVersion = TestHalVersion::V1_3,
+        .operands = {{
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int8_t>({}),
+                .dimensions = {2, 3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::TEMPORARY_VARIABLE,
+                .numberOfConsumers = 1,
+                .scale = 0.1f,
+                .type = TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int32_t>({2}),
+                .dimensions = {},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_OUTPUT,
+                .numberOfConsumers = 0,
+                .scale = 0.0f,
+                .type = TestOperandType::INT32,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int8_t>({10, 20, 30, 40, 50, 60}),
+                .dimensions = {2, 3},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::SUBGRAPH_INPUT,
+                .numberOfConsumers = 1,
+                .scale = 0.1f,
+                .type = TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED,
+                .zeroPoint = 0
+            }, {
+                .channelQuant = {},
+                .data = TestBuffer::createFromVector<int8_t>({0}),
+                .dimensions = {1},
+                .isIgnored = false,
+                .lifetime = TestOperandLifeTime::CONSTANT_COPY,
+                .numberOfConsumers = 1,
+                .scale = 0.1f,
+                .type = TestOperandType::TENSOR_QUANT8_ASYMM_SIGNED,
+                .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 = {2, 3, 4},
+                .outputs = {0},
+                .type = TestOperationType::ADD
+            }, {
+                .inputs = {0},
+                .outputs = {1},
+                .type = TestOperationType::RANK
+            }},
+        .outputIndexes = {1}
+    };
+    return model;
+}
+
+const auto dummy_test_model_1d_quant8_signed_all_inputs_as_internal_2 = TestModelManager::get().add("rank_1d_quant8_signed_all_inputs_as_internal_2", get_test_model_1d_quant8_signed_all_inputs_as_internal_2());
+
+}  // namespace generated_tests::rank
+
diff --git a/runtime/test/specs/V1_3/fill.mod.py b/runtime/test/specs/V1_3/fill.mod.py
new file mode 100644
index 0000000..4791c94
--- /dev/null
+++ b/runtime/test/specs/V1_3/fill.mod.py
@@ -0,0 +1,51 @@
+#
+# 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.
+#
+def test(name, input_dims, value, output, input_dims_data, output_data):
+  model = Model().Operation("FILL", input_dims, value).To(output)
+  example = Example({
+      input_dims: input_dims_data,
+      output: output_data,
+  },
+                    model=model,
+                    name=name).AddVariations("float16", "int32")
+
+
+test(
+    name="1d",
+    input_dims=Input("input0", "TENSOR_INT32", "{1}"),
+    value=Float32Scalar("value", 3.0),
+    output=Output("output", "TENSOR_FLOAT32", "{5}"),
+    input_dims_data=[5],
+    output_data=[3.0] * 5,
+)
+
+test(
+    name="3d",
+    input_dims=Input("input0", "TENSOR_INT32", "{3}"),
+    value=Float32Scalar("value", 3.0),
+    output=Output("output", "TENSOR_FLOAT32", "{2, 3, 4}"),
+    input_dims_data=[2, 3, 4],
+    output_data=[3.0] * (2 * 3 * 4),
+)
+
+test(
+    name="5d",
+    input_dims=Input("input0", "TENSOR_INT32", "{5}"),
+    value=Float32Scalar("value", 3.0),
+    output=Output("output", "TENSOR_FLOAT32", "{1, 2, 3, 4, 5}"),
+    input_dims_data=[1, 2, 3, 4, 5],
+    output_data=[3.0] * (1 * 2 * 3 * 4 * 5),
+)
diff --git a/runtime/test/specs/V1_3/rank.mod.py b/runtime/test/specs/V1_3/rank.mod.py
new file mode 100644
index 0000000..e6db532
--- /dev/null
+++ b/runtime/test/specs/V1_3/rank.mod.py
@@ -0,0 +1,43 @@
+#
+# 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.
+#
+def test(name, input0, output0, input0_data, output0_data):
+  model = Model().Operation("RANK", input0).To(output0)
+  quant8 = DataTypeConverter().Identify({
+      input0: ("TENSOR_QUANT8_ASYMM", 0.1, 128),
+  })
+  quant8_signed = DataTypeConverter().Identify({
+      input0: ("TENSOR_QUANT8_ASYMM_SIGNED", 0.1, 0),
+  })
+  example = Example({
+      input0: input0_data,
+      output0: output0_data,
+  }, model=model, name=name).AddVariations("int32", "float16", quant8, quant8_signed)
+
+test(
+    name="1d",
+    input0=Input("input0", "TENSOR_FLOAT32", "{3}"),
+    output0=Output("output0", "INT32", "{}"),
+    input0_data=[5, 7, 10],
+    output0_data=[1],
+)
+
+test(
+    name="1d",
+    input0=Input("input0", "TENSOR_FLOAT32", "{2, 3}"),
+    output0=Output("output0", "INT32", "{}"),
+    input0_data=[1, 2, 3, 4, 5, 6],
+    output0_data=[2],
+)