Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 08662c6f authored by Lev Proleev's avatar Lev Proleev Committed by Przemyslaw Szczepaniak
Browse files

Add new OperandType BOOL.

- Add new enum OperandType::BOOL.
- Add v1.2 Operand, OperandType.
- Add VTS validation tests for BOOL.

Bug: 117423393

Test: NeuralNetworksTest_static
Test: VtsHalNeuralnetworksV1_2TargetTest

Change-Id: I420e2afeb09b881a499eee6b138c1f26e9874f5a
Merged-In: I420e2afeb09b881a499eee6b138c1f26e9874f5a
(cherry picked from commit abad9eac)
parent 618028b8
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -34,9 +34,11 @@ namespace hardware {
namespace neuralnetworks {
namespace V1_1 {

using V1_0::Request;
using V1_0::DeviceStatus;
using V1_0::ErrorStatus;
using V1_0::Operand;
using V1_0::OperandType;
using V1_0::Request;

namespace vts {
namespace functional {
+2 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@ hidl_interface {
    ],
    types: [
        "Model",
        "Operand",
        "OperandType",
        "Operation",
        "OperationType",
    ],
+108 −1
Original line number Diff line number Diff line
@@ -16,10 +16,22 @@

package android.hardware.neuralnetworks@1.2;

import @1.0::Operand;
import @1.0::DataLocation;
import @1.0::OperandLifeTime;
import @1.0::OperandType;
import @1.0::PerformanceInfo;
import @1.1::OperationType;

enum OperandType : @1.0::OperandType {
    /**
     * An 8 bit boolean scalar value.
     *
     * Values of this operand type are either true or false. A zero value
     * represents false; any other value represents true.
     */
    BOOL = 6,
};

/**
 * Operation types.
 *
@@ -101,6 +113,101 @@ struct Operation {
    vec<uint32_t> outputs;
};

/**
 * Describes one operand of the model's graph.
 */
struct Operand {
    /**
     * Data type of the operand.
     */
    OperandType type;

    /**
     * Dimensions of the operand.
     *
     * For a scalar operand, dimensions.size() must be 0.
     *
     * For a tensor operand, dimensions.size() must be at least 1;
     * however, any of the dimensions may be unspecified.
     *
     * A tensor operand with all dimensions specified has "fully
     * specified" dimensions. Whenever possible (i.e., whenever the
     * dimensions are known at model construction time), a tensor
     * operand should have (but is not required to have) fully
     * specified dimensions, in order to enable the best possible
     * performance.
     *
     * If a tensor operand's dimensions are not fully specified, the
     * dimensions of the operand are deduced from the operand
     * dimensions and values of the operation for which that operand
     * is an output.
     *
     * In the following situations, a tensor operand's dimensions must
     * be fully specified:
     *
     *     . The operand has lifetime CONSTANT_COPY or
     *       CONSTANT_REFERENCE.
     *
     *     . The operand has lifetime MODEL_INPUT or MODEL_OUTPUT. Fully
     *       specified dimensions must either be present in the
     *       Operand or they must be provided in the corresponding
     *       RequestArgument.
     *       EXCEPTION: If the input or output is optional and omitted
     *       (by setting the hasNoValue field of the corresponding
     *       RequestArgument to true) then it need not have fully
     *       specified dimensions.
     *
     * A tensor operand with some number of unspecified dimensions is
     * represented by setting each unspecified dimension to 0.
     */
    vec<uint32_t> dimensions;

    /**
     * The number of times this operand appears as an operation input.
     *
     * (For example, if this operand appears once in one operation's
     * input list, and three times in another operation's input list,
     * then numberOfConsumers = 4.)
     */
    uint32_t numberOfConsumers;

    /**
     * Quantized scale of the operand.
     *
     * Only applicable if the operand is of type TENSOR_QUANT8_ASYMM or
     * TENSOR_INT32.
     */
    float scale;

    /**
     * Quantized zero-point offset of the operand.
     *
     * Only applicable if the operand is of type TENSOR_QUANT8_ASYMM.
     */
    int32_t zeroPoint;

    /**
     * How the operand is used.
     */
    OperandLifeTime lifetime;

    /**
     * Where to find the data for this operand.
     * If the lifetime is TEMPORARY_VARIABLE, MODEL_INPUT, MODEL_OUTPUT, or
     * NO_VALUE:
     * - All the fields must be 0.
     * If the lifetime is CONSTANT_COPY:
     * - location.poolIndex is 0.
     * - location.offset is the offset in bytes into Model.operandValues.
     * - location.length is set.
     * If the lifetime is CONSTANT_REFERENCE:
     * - location.poolIndex is set.
     * - location.offset is the offset in bytes into the specified pool.
     * - location.length is set.
     */
    DataLocation location;
};

/**
 * A Neural Network Model.
 *
+8 −6
Original line number Diff line number Diff line
@@ -26,9 +26,7 @@ namespace neuralnetworks {
namespace V1_2 {

using V1_0::IPreparedModel;
using V1_0::Operand;
using V1_0::OperandLifeTime;
using V1_0::OperandType;
using V1_1::ExecutionPreference;

namespace vts {
@@ -132,7 +130,7 @@ static uint32_t addOperand(Model* model, OperandLifeTime lifetime) {

static const int32_t invalidOperandTypes[] = {
    static_cast<int32_t>(OperandType::FLOAT32) - 1,          // lower bound fundamental
    static_cast<int32_t>(OperandType::TENSOR_QUANT8_ASYMM) + 1,  // upper bound fundamental
    static_cast<int32_t>(OperandType::BOOL) + 1,             // upper bound fundamental
    static_cast<int32_t>(OperandType::OEM) - 1,              // lower bound OEM
    static_cast<int32_t>(OperandType::TENSOR_OEM_BYTE) + 1,  // upper bound OEM
};
@@ -157,6 +155,7 @@ static uint32_t getInvalidRank(OperandType type) {
        case OperandType::FLOAT32:
        case OperandType::INT32:
        case OperandType::UINT32:
        case OperandType::BOOL:
            return 1;
        case OperandType::TENSOR_FLOAT32:
        case OperandType::TENSOR_INT32:
@@ -185,6 +184,7 @@ static float getInvalidScale(OperandType type) {
        case OperandType::FLOAT32:
        case OperandType::INT32:
        case OperandType::UINT32:
        case OperandType::BOOL:
        case OperandType::TENSOR_FLOAT32:
            return 1.0f;
        case OperandType::TENSOR_INT32:
@@ -214,6 +214,7 @@ static std::vector<int32_t> getInvalidZeroPoints(OperandType type) {
        case OperandType::FLOAT32:
        case OperandType::INT32:
        case OperandType::UINT32:
        case OperandType::BOOL:
        case OperandType::TENSOR_FLOAT32:
        case OperandType::TENSOR_INT32:
            return {1};
@@ -253,6 +254,7 @@ static void mutateOperand(Operand* operand, OperandType type) {
        case OperandType::FLOAT32:
        case OperandType::INT32:
        case OperandType::UINT32:
        case OperandType::BOOL:
            newOperand.dimensions = hidl_vec<uint32_t>();
            newOperand.scale = 0.0f;
            newOperand.zeroPoint = 0;