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

Commit 1191f516 authored by Przemyslaw Szczepaniak's avatar Przemyslaw Szczepaniak Committed by Gerrit Code Review
Browse files

Merge changes from topic "nnapi-cherrypick-from-master-and-pi-dev-to-aosp2"

* changes:
  Adds TENSOR_FLOAT16 operand type.
  Add TENSOR_QUANT16_ASYMM to operand types
  Add new OperandType BOOL.
  Add HAL entry to allow querying device impl version.
parents ad9708f5 5dd84125
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",
    ],
+30 −0
Original line number Diff line number Diff line
@@ -25,6 +25,36 @@ import @1.1::IDevice;
 * This interface represents a device driver.
 */
interface IDevice extends @1.1::IDevice {
    /**
     * Get the version string of the driver implementation.
     *
     * The version string must be a unique token among the set of version strings of
     * drivers of a specific device. The token identifies the device driver's
     * implementation. The token must not be confused with the feature level which is solely
     * defined by the interface version. This API is opaque to the Android framework, but the
     * Android framework may use the information for debugging or to pass on to NNAPI applications.
     *
     * Application developers sometimes have specific requirements to ensure good user experiences,
     * and they need more information to make intelligent decisions when the Android framework cannot.
     * For example, combined with the device name and other information, the token can help
     * NNAPI applications filter devices based on their needs:
     *     - An application demands a certain level of performance, but a specific version of
     *       the driver cannot meet that requirement because of a performance regression.
     *       The application can blacklist the driver based on the version provided.
     *     - An application has a minimum precision requirement, but certain versions of
     *       the driver cannot meet that requirement because of bugs or certain optimizations.
     *       The application can filter out versions of these drivers.
     *
     * @return status Error status returned from querying the version string. Must be:
     *     - NONE if the query was successful
     *     - DEVICE_UNAVAILABLE if driver is offline or busy
     *     - GENERAL_FAILURE if the query resulted in an
     *       unspecified error
     * @return version The version string of the device implementation.
     *     Must have nonzero length
     */
    getVersionString() generates (ErrorStatus status, string version);

    /**
     * Gets the supported operations in a model.
     *
+122 −1
Original line number Diff line number Diff line
@@ -16,10 +16,36 @@

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,
    /**
     * A tensor of 16 bit signed integers that represent real numbers.
     *
     * Attached to this tensor are two numbers that are used to convert the 16
     * bit integer to the real value and vice versa. These two numbers are:
     * - scale: a 32 bit floating point value greater than zero.
     * - zeroPoint: a 32 bit integer, in range [-32768, 32767].
     *
     * The formula is:
     * realValue = (integerValue - zeroPoint) * scale.
     */
    TENSOR_QUANT16_ASYMM = 7,
    /** A tensor of 16 bit floating point values. */
    TENSOR_FLOAT16 = 8,
};

/**
 * Operation types.
 *
@@ -101,6 +127,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 −0
Original line number Diff line number Diff line
@@ -37,6 +37,14 @@ TEST_F(NeuralnetworksHidlTest, StatusTest) {
    EXPECT_EQ(DeviceStatus::AVAILABLE, static_cast<DeviceStatus>(status));
}

// device version test
TEST_F(NeuralnetworksHidlTest, GetDeviceVersionStringTest) {
    Return<void> ret = device->getVersionString([](ErrorStatus status, const hidl_string& version) {
        EXPECT_EQ(ErrorStatus::NONE, status);
        EXPECT_LT(0, version.size());
    });
    EXPECT_TRUE(ret.isOk());
}
}  // namespace functional
}  // namespace vts
}  // namespace V1_2
Loading