Merge "Move NNAPI type information to types.spec"

This commit is contained in:
Treehugger Robot 2021-03-22 12:42:40 +00:00 committed by Gerrit Code Review
commit a23a3613bc
4 changed files with 34 additions and 1320 deletions

View file

@ -63,361 +63,25 @@ enum FusedActivationFunc : int32_t {
RELU6 = 3,
};
/**
* How an operand is used.
*/
enum OperandLifeTime : int32_t {
/**
* The operand is internal to the model. It's created by an operation and
* consumed by other operations. It must be an output operand of
* exactly one operation.
*/
TEMPORARY_VARIABLE,
%insert OperandLifeTime
/**
* The operand is an input of the model. It must not be an output
* operand of any operation.
*
* An operand can't be both input and output of a model.
*/
MODEL_INPUT,
%insert DeviceStatus
/**
* The operand is an output of the model. It must be an output
* operand of exactly one operation.
*
* An operand can't be both input and output of a model.
*/
MODEL_OUTPUT,
%insert PerformanceInfo
/**
* The operand is a constant found in Model.operandValues. It must
* not be an output operand of any operation.
*/
CONSTANT_COPY,
%insert Capabilities
/**
* The operand is a constant that was specified via a Memory
* object. It must not be an output operand of any operation.
*/
CONSTANT_REFERENCE,
%insert DataLocation
/**
* The operand does not have a value. This is valid only for optional
* arguments of operations.
*/
NO_VALUE,
};
%insert Operand
/**
* Status of a device.
*/
enum DeviceStatus : int32_t {
AVAILABLE,
BUSY,
OFFLINE,
UNKNOWN,
};
%insert Operation
/**
* Performance information for the reference workload.
*
* Used by a driver to report its performance characteristics.
*/
struct PerformanceInfo {
/**
* Ratio of the time taken by the driver to execute the
* workload compared to the time the CPU would take for the
* same workload. A lower number is better.
*/
float execTime;
%insert Model
/**
* Ratio of the energy used by the driver compared to what
* the CPU would use for doing the same workload. A lower number
* is better.
*/
float powerUsage;
};
%insert RequestArgument
/**
* The capabilities of a driver.
*/
struct Capabilities {
/**
* Driver performance when operating on float32 data.
*/
PerformanceInfo float32Performance;
/**
* Driver performance when operating on asymmetric 8-bit quantized data.
*/
PerformanceInfo quantized8Performance;
};
/**
* Describes the location of a data object.
*/
struct DataLocation {
/**
* The index of the memory pool where this location is found.
*/
uint32_t poolIndex;
/**
* Offset in bytes from the start of the pool.
*/
uint32_t offset;
/**
* The length of the data in bytes.
*/
uint32_t length;
};
/**
* 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;
};
/**
* Describes one operation of the model's graph.
*/
struct Operation {
/**
* The operation type.
*/
OperationType type;
/**
* Describes the table that contains the indexes of the inputs of the
* operation. The offset is the index in the operandIndexes table.
*/
vec<uint32_t> inputs;
/**
* Describes the table that contains the indexes of the outputs of the
* operation. The offset is the index in the operandIndexes table.
*/
vec<uint32_t> outputs;
};
/**
* A Neural Network Model.
*
* This includes not only the execution graph, but also constant data such as
* weights or scalars added at construction time. The only information that
* might not be known is the shape of the input tensors.
*/
struct Model {
/**
* All operands included in the model.
*/
vec<Operand> operands;
/**
* All operations included in the model.
*
* The operations are sorted into execution order. Every operand
* with lifetime MODEL_OUTPUT or TEMPORARY_VARIABLE must be
* written before it is read.
*/
vec<Operation> operations;
/**
* Input indexes of the model. There must be at least one.
*
* Each value corresponds to the index of the operand in "operands".
*/
vec<uint32_t> inputIndexes;
/**
* Output indexes of the model. There must be at least one.
*
* Each value corresponds to the index of the operand in "operands".
*/
vec<uint32_t> outputIndexes;
/**
* A byte buffer containing operand data that were copied into the model.
*
* An operand's value must be located here if and only if Operand::lifetime
* equals OperandLifeTime::CONSTANT_COPY.
*/
vec<uint8_t> operandValues;
/**
* A collection of shared memory pools containing operand values.
*
* An operand's value must be located here if and only if Operand::lifetime
* equals OperandLifeTime::CONSTANT_REFERENCE.
*/
vec<memory> pools;
};
/**
* Metadata information specifying the location of the input or output data and
* any updates to the input or output operand.
*/
struct RequestArgument {
/**
* If true, the argument does not have a value. This can be used for
* operations that take optional arguments. If true, the fields of location
* are set to 0 and the dimensions vector is left empty.
*/
bool hasNoValue;
/**
* The location within one of the memory pools passed in the Request.
*/
DataLocation location;
/**
* Updated dimension information.
*
* If dimensions.size() > 0, dimension information was provided
* along with the argument. This can be the case for models that
* accept inputs of varying size. This can't change the rank, just
* the value of the dimensions that were unspecified in the
* model. If dimensions.size() > 0, then all dimensions must be
* specified here; and any dimension that was specified in the
* model must have the same value here.
*
* If the dimensions in the model are not fully specified, then
* they must be fully specified here, unless hasNoValue is set to
* true. If the dimensions in the model are fully specified, then
* either dimensions.size() may be 0, or the dimensions in the
* model must be identical to the dimensions here.
*/
vec<uint32_t> dimensions;
};
/**
* Inputs to be sent to and outputs to be retrieved from a prepared model.
*
* A Request serves two primary tasks:
* 1) Provides the input and output data to be used when executing the model.
* 2) Specifies any updates to the input operand metadata that were left
* unspecified at model preparation time.
*
* An output must not overlap with any other output, with an input, or
* with an operand of lifetime CONSTANT_REFERENCE.
*/
struct Request {
/**
* Input data and information to be used in the execution of a prepared
* model.
*
* The index of the input corresponds to the index in Model.inputIndexes.
* E.g., input[i] corresponds to Model.inputIndexes[i].
*/
vec<RequestArgument> inputs;
/**
* Output data and information to be used in the execution of a prepared
* model.
*
* The index of the output corresponds to the index in Model.outputIndexes.
* E.g., output[i] corresponds to Model.outputIndexes[i].
*/
vec<RequestArgument> outputs;
/**
* A collection of shared memory pools containing operand data for both the
* inputs and the outputs to a model.
*/
vec<memory> pools;
};
%insert Request
/**
* Return status of a function.

View file

@ -31,128 +31,10 @@ enum OperationType : @1.0::OperationType {
%insert Operation_1.1
};
/**
* The capabilities of a driver.
*/
struct Capabilities {
/**
* Driver performance when operating on float32 data.
*/
PerformanceInfo float32Performance;
%insert Capabilities
/**
* Driver performance when operating on asymmetric 8-bit quantized data.
*/
PerformanceInfo quantized8Performance;
%insert Operation
/**
* Driver performance when operating on float32 data but performing
* calculations with range and/or precision as low as that of the IEEE
* 754 16-bit floating-point format.
*/
PerformanceInfo relaxedFloat32toFloat16Performance;
};
%insert Model
/**
* Describes one operation of the model's graph.
*/
struct Operation {
/**
* The operation type.
*/
OperationType type;
/**
* Describes the table that contains the indexes of the inputs of the
* operation. The offset is the index in the operandIndexes table.
*/
vec<uint32_t> inputs;
/**
* Describes the table that contains the indexes of the outputs of the
* operation. The offset is the index in the operandIndexes table.
*/
vec<uint32_t> outputs;
};
/**
* A Neural Network Model.
*
* This includes not only the execution graph, but also constant data such as
* weights or scalars added at construction time. The only information that
* may not be known is the shape of the input tensors.
*/
struct Model {
/**
* All operands included in the model.
*/
vec<Operand> operands;
/**
* All operations included in the model.
*
* The operations are sorted into execution order. Every operand
* with lifetime MODEL_OUTPUT or TEMPORARY_VARIABLE must be
* written before it is read.
*/
vec<Operation> operations;
/**
* Input indexes of the model. There must be at least one.
*
* Each value corresponds to the index of the operand in "operands".
*/
vec<uint32_t> inputIndexes;
/**
* Output indexes of the model. There must be at least one.
*
* Each value corresponds to the index of the operand in "operands".
*/
vec<uint32_t> outputIndexes;
/**
* A byte buffer containing operand data that were copied into the model.
*
* An operand's value must be located here if and only if Operand::lifetime
* equals OperandLifeTime::CONSTANT_COPY.
*/
vec<uint8_t> operandValues;
/**
* A collection of shared memory pools containing operand values.
*
* An operand's value must be located here if and only if Operand::lifetime
* equals OperandLifeTime::CONSTANT_REFERENCE.
*/
vec<memory> pools;
/**
* 'true' indicates TENSOR_FLOAT32 may be calculated with range and/or
* precision as low as that of the IEEE 754 16-bit floating-point format.
* 'false' indicates TENSOR_FLOAT32 must be calculated using at least the
* range and precision of the IEEE 754 32-bit floating-point format.
*/
bool relaxComputationFloat32toFloat16;
};
/**
* Execution preferences.
*/
enum ExecutionPreference : int32_t {
/**
* Prefer executing in a way that minimizes battery drain.
* This is desirable for compilations that will be executed often.
*/
LOW_POWER = 0,
/**
* Prefer returning a single answer as fast as possible, even if this causes
* more power consumption.
*/
FAST_SINGLE_ANSWER = 1,
/**
* Prefer maximizing the throughput of successive frames, for example when
* processing successive frames coming from the camera.
*/
SUSTAINED_SPEED = 2,
};
%insert ExecutionPreference

View file

@ -97,379 +97,23 @@ enum OperationTypeRange : uint32_t {
BASE_MAX = 0xFFFF,
};
/**
* Device types.
*
* The type of NNAPI device.
*/
enum DeviceType : int32_t {
// Leaving 0 unused as it means unknown type in NDK NNAPI. There is no
// HAL equivalent of unknown type and a 1.2 HAL implementation must belong
// to one of the categories below.
/** The device does not fall into any category below. */
OTHER = 1,
/** The device runs NNAPI models on single or multi-core CPU. */
CPU = 2,
/** The device can run NNAPI models and also accelerate graphics APIs such
* as OpenGL ES and Vulkan. */
GPU = 3,
/** Dedicated accelerator for Machine Learning workloads. */
ACCELERATOR = 4,
};
%insert DeviceType
/**
* The capabilities of a driver.
*
* Performance of an operation comes from the type of its first operand.
* This represents performance for non extension operand types.
*/
struct Capabilities {
/**
* Driver performance when operating on float32 data but performing
* calculations with range and/or precision as low as that of the IEEE
* 754 16-bit floating-point format.
*/
PerformanceInfo relaxedFloat32toFloat16PerformanceScalar;
PerformanceInfo relaxedFloat32toFloat16PerformanceTensor;
%insert Capabilities
/**
* Driver performance when operating on a particular data type.
* In the case of float32 data, this is used when the calculations
* are not relaxed.
*/
struct OperandPerformance {
OperandType type;
PerformanceInfo info;
};
%insert Operation
/**
* Performance by operand type. Must be sorted by OperandType.
* If a particular OperandType is not present in operandPerformance,
* its performance is treated as { .execTime = FLT_MAX, .powerUsage = FLT_MAX }.
*/
vec<OperandPerformance> operandPerformance;
};
%insert SymmPerChannelQuantParams
/**
* Describes one operation of the model's graph.
*/
struct Operation {
/**
* The operation type.
*
* Besides the values listed in {@link OperationType}, any value above
* {@link OperationTypeRange::BASE_MAX} is possible and should be interpreted
* as an extension type according to {@link Model::extensionNameToPrefix}.
*/
OperationType type;
%insert Operand
/**
* Describes the table that contains the indexes of the inputs of the
* operation. The offset is the index in the operandIndexes table.
*/
vec<uint32_t> inputs;
%insert Model
/**
* Describes the table that contains the indexes of the outputs of the
* operation. The offset is the index in the operandIndexes table.
*/
vec<uint32_t> outputs;
};
%insert OutputShape
/**
* Parameters for TENSOR_QUANT8_SYMM_PER_CHANNEL operand.
*/
struct SymmPerChannelQuantParams {
/** Array of scaling values for each channel. Each value must be greater than zero. */
vec<float> scales;
/** Index of the channel dimension */
uint32_t channelDim;
};
%insert MeasureTiming
/**
* Describes one operand of the model's graph.
*/
struct Operand {
/**
* The data type.
*
* Besides the values listed in {@link OperandType}, any value above
* {@link OperandTypeRange::BASE_MAX} is possible and should be interpreted
* as an extension type according to {@link Model::extensionNameToPrefix}.
*/
OperandType type;
/**
* Dimensions of the operand.
*
* For a scalar operand, dimensions.size() must be 0.
*
* 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. Fully
* specified dimensions must either be present in the
* Operand or they must be provided in the corresponding
* RequestArgument.
* EXCEPTION: If the input 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.
*
* A tensor operand with unspecified rank is represented by providing
* an empty dimensions vector.
*/
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.
*
* Must be 0 when not applicable to an operand type.
*
* See {@link OperandType}.
*/
float scale;
/**
* Quantized zero-point offset of the operand.
*
* Must be 0 when not applicable to an operand type.
*
* See {@link OperandType}.
*/
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;
/**
* Additional parameters specific to a particular operand type.
*/
safe_union ExtraParams {
/**
* No additional parameters.
*/
Monostate none;
/**
* Symmetric per-channel quantization parameters.
*
* Only applicable to operands of type TENSOR_QUANT8_SYMM_PER_CHANNEL.
*/
SymmPerChannelQuantParams channelQuant;
/**
* Extension operand parameters.
*
* The framework treats this as an opaque data blob.
* The format is up to individual extensions.
*/
vec<uint8_t> extension;
} extraParams;
};
/**
* A Neural Network Model.
*
* This includes not only the execution graph, but also constant data such as
* weights or scalars added at construction time. The only information that
* may not be known is the shape of the input tensors.
*/
struct Model {
/**
* All operands included in the model.
*/
vec<Operand> operands;
/**
* All operations included in the model.
*
* The operations are sorted into execution order. Every operand
* with lifetime MODEL_OUTPUT or TEMPORARY_VARIABLE must be
* written before it is read.
*/
vec<Operation> operations;
/**
* Input indexes of the model. There must be at least one.
*
* Each value corresponds to the index of the operand in "operands".
*/
vec<uint32_t> inputIndexes;
/**
* Output indexes of the model. There must be at least one.
*
* Each value corresponds to the index of the operand in "operands".
*/
vec<uint32_t> outputIndexes;
/**
* A byte buffer containing operand data that were copied into the model.
*
* An operand's value must be located here if and only if Operand::lifetime
* equals OperandLifeTime::CONSTANT_COPY.
*/
vec<uint8_t> operandValues;
/**
* A collection of shared memory pools containing operand values.
*
* An operand's value must be located here if and only if Operand::lifetime
* equals OperandLifeTime::CONSTANT_REFERENCE.
*/
vec<memory> pools;
/**
* 'true' indicates TENSOR_FLOAT32 may be calculated with range and/or
* precision as low as that of the IEEE 754 16-bit floating-point format.
* 'false' indicates TENSOR_FLOAT32 must be calculated using at least the
* range and precision of the IEEE 754 32-bit floating-point format.
*/
bool relaxComputationFloat32toFloat16;
/**
* The mapping between extension names and prefixes of operand and
* operation type values.
*
* An operand or operation whose numeric type value is above
* {@link OperandTypeRange::BASE_MAX} or
* {@link OperationTypeRange::BASE_MAX} respectively should be interpreted
* as an extension operand. The low
* {@link Model::ExtensionTypeEncoding::LOW_BITS_TYPE} bits of the value
* correspond to the type ID within the extension and the high
* {@link Model::ExtensionTypeEncoding::HIGH_BITS_PREFIX} bits encode
* the "prefix", which maps uniquely to the extension name.
*
* For example, if a model contains an operation whose value is
* 0xAAAABBBB and extensionNameToPrefix contains an entry with
* prefix=0xAAAA and name="vendor.test.test_extension", then
* the operation should be interpreted as the operation 0xBBBB
* of the extension named vendor.test.test_extension.
*
* This is a one-to-one correspondence. That is, there must be at most one
* prefix corresponding to each extension name and at most one extension
* name corresponding to each prefix.
*/
vec<ExtensionNameAndPrefix> extensionNameToPrefix;
/**
* A correspondence between an extension name and a prefix of operand and
* operation type values.
*/
struct ExtensionNameAndPrefix {
/**
* The extension name.
*
* See {@link Extension::name} for the format specification.
*/
string name;
/**
* The unique extension identifier within the model.
*
* See {@link Model::extensionNameToPrefix}.
*/
uint16_t prefix;
};
/**
* Numeric values of extension operand and operation types have the
* following structure:
* - 16 high bits represent the "prefix", which corresponds uniquely to the
* extension name.
* - 16 low bits represent the type ID within the extension.
*/
enum ExtensionTypeEncoding : uint8_t {
HIGH_BITS_PREFIX = 16,
LOW_BITS_TYPE = 16,
};
};
/**
* Describes the shape information of an output operand after execution.
*/
struct OutputShape {
/**
* Dimensions of the operand.
*/
vec<uint32_t> dimensions;
/**
* Whether the provided buffer size is sufficient for the output.
*/
bool isSufficient;
};
/**
* Specifies whether or not to measure timing information during execution.
*/
enum MeasureTiming : int32_t {
NO = 0,
YES = 1,
};
/**
* Timing information measured during execution. Each time is a duration from
* the beginning of some task to the end of that task, including time when that
* task is not active (for example, preempted by some other task, or
* waiting for some resource to become available).
*
* Times are measured in microseconds.
* When a time is not available, it must be reported as UINT64_MAX.
*/
struct Timing {
/** Execution time on device (not driver, which runs on host processor). */
uint64_t timeOnDevice;
/** Execution time in driver (including time on device). */
uint64_t timeInDriver;
};
%insert Timing
/**
* FmqRequestDatum is a single element of a serialized representation of an
@ -683,46 +327,4 @@ safe_union FmqResultDatum {
Timing executionTiming;
};
/**
* Information about an extension.
*/
struct Extension {
/**
* The extension name.
*
* The name must consist of lowercase latin letters, numbers, periods, and
* underscore signs. The name must contain at least one period.
*
* The name must start with the reverse domain name of the vendor.
*
* Example: com.google.test_extension
*/
string name;
/**
* Information about an extension operand type.
*/
struct OperandTypeInformation {
/**
* The extension operand type.
*/
uint16_t type;
/**
* Indicates whether the extension operand type represents a tensor or
* a scalar.
*/
bool isTensor;
/**
* The byte size of the operand (if scalar) or of a single element (if
* tensor).
*/
uint32_t byteSize;
};
/**
* Information about operand types defined by the extension.
*/
vec<OperandTypeInformation> operandTypes;
};
%insert Extension

View file

@ -90,459 +90,25 @@ enum OperationTypeRange : uint32_t {
BASE_MAX = 0xFFFF,
};
/**
* Priority given to a prepared model for execution.
*/
enum Priority : int32_t {
LOW,
MEDIUM,
HIGH,
};
%insert Priority
/**
* The capabilities of a driver.
*
* This represents performance of non-extension operations.
*
* Performance of an operation other than {@link OperationType::IF} and
* {@link OperationType::WHILE} comes from the type of its first operand.
*/
struct Capabilities {
/**
* Driver performance when operating on float32 data but performing
* calculations with range and/or precision as low as that of the IEEE
* 754 16-bit floating-point format.
*/
PerformanceInfo relaxedFloat32toFloat16PerformanceScalar;
PerformanceInfo relaxedFloat32toFloat16PerformanceTensor;
%insert Capabilities
/**
* Driver performance when operating on a particular data type.
* In the case of float32 data, this is used when the calculations
* are not relaxed.
*/
struct OperandPerformance {
OperandType type;
PerformanceInfo info;
};
%insert Operation
/**
* Performance by operand type. Must be sorted by OperandType.
*
* If a particular {@link OperandType} is not present in operandPerformance,
* its performance is treated as
* { .execTime = FLT_MAX, .powerUsage = FLT_MAX }.
*
* Performance does not apply to {@link OperandType::SUBGRAPH}, and a driver
* must not report operand performance for {@link OperandType::SUBGRAPH}.
*/
vec<OperandPerformance> operandPerformance;
%insert OperandLifeTime
/**
* Performance of an {@link OperationType::IF} operation is the sum of
* {@link Capabilities::ifPerformance} and the mean of performance for the
* two branch subgraphs, where performance for a subgraph is the sum of the
* performance of all operations within the subgraph.
*/
PerformanceInfo ifPerformance;
%insert Operand
/**
* Performance of a {@link OperationType::WHILE} operation is the sum of
* {@link Capabilities::whilePerformance}, performance for the condition
* subgraph and performance for the body subgraph, where performance for a
* subgraph is the sum of the performance of all operations within the
* subgraph.
*/
PerformanceInfo whilePerformance;
};
%insert Model
/**
* Describes one operation of the model's graph.
*/
struct Operation {
/**
* The operation type.
*
* Besides the values listed in {@link OperationType}, any value above
* {@link OperationTypeRange::BASE_MAX} is possible and should be interpreted
* as an extension type according to {@link Model::extensionNameToPrefix}.
*/
OperationType type;
%insert Subgraph
/**
* Describes the table that contains the indexes of the inputs of the
* operation. The offset is the index in the operandIndexes table.
*/
vec<uint32_t> inputs;
%insert BufferDesc
/**
* Describes the table that contains the indexes of the outputs of the
* operation. The offset is the index in the operandIndexes table.
*/
vec<uint32_t> outputs;
};
%insert BufferRole
/**
* How an operand is used.
*/
enum OperandLifeTime : int32_t {
/**
* The operand is internal to the model. It's created by an operation and
* consumed by other operations. It must be an output operand of
* exactly one operation.
*/
TEMPORARY_VARIABLE,
/**
* The operand is an input of a subgraph. It must not be an output
* operand of any operation.
*
* An operand can't be both input and output of a subgraph.
*/
SUBGRAPH_INPUT,
/**
* The operand is an output of a subgraph. It must be an output
* operand of exactly one operation.
*
* An operand can't be both input and output of a subgraph.
*/
SUBGRAPH_OUTPUT,
/**
* The operand is a constant found in Model.operandValues. It must
* not be an output operand of any operation.
*/
CONSTANT_COPY,
/**
* The operand is a constant that was specified via a Memory
* object. It must not be an output operand of any operation.
*/
CONSTANT_REFERENCE,
/**
* The operand does not have a value. This is valid only for optional
* arguments of operations.
*/
NO_VALUE,
/**
* The operand is a reference to a subgraph. It must be an input to one
* or more {@link OperationType::IF} or {@link OperationType::WHILE}
* operations.
*/
SUBGRAPH,
};
/**
* Describes one operand of the model's graph.
*/
struct Operand {
/**
* The data type.
*
* Besides the values listed in {@link OperandType}, any value above
* {@link OperandTypeRange::BASE_MAX} is possible and should be interpreted
* as an extension type according to {@link Model::extensionNameToPrefix}.
*/
OperandType type;
/**
* Dimensions of the operand.
*
* For a scalar operand, dimensions.size() must be 0.
*
* 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 or from the corresponding {@link OperationType::IF} or
* {@link OperationType::WHILE} operation input operand dimensions in the
* case of referenced subgraph input operands.
*
* 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 SUBGRAPH_INPUT and belongs to the main
* subgraph. Fully specified dimensions must either be present in the
* Operand or they must be provided in the corresponding
* RequestArgument.
* EXCEPTION: If the input 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.
*
* A tensor operand with unspecified rank is represented by providing
* an empty dimensions vector.
*/
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.
*
* Must be 0 when not applicable to an operand type.
*
* See {@link OperandType}.
*/
float scale;
/**
* Quantized zero-point offset of the operand.
*
* Must be 0 when not applicable to an operand type.
*
* See {@link OperandType}.
*/
int32_t zeroPoint;
/**
* How the operand is used.
*/
OperandLifeTime lifetime;
/**
* Where to find the data for this operand.
* If the lifetime is TEMPORARY_VARIABLE, SUBGRAPH_INPUT, SUBGRAPH_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.
* If the lifetime is SUBGRAPH:
* - location.poolIndex is 0.
* - location.offset is the index of the referenced subgraph in
* {@link Model::referenced}.
* - location.length is 0.
*/
DataLocation location;
/**
* Additional parameters specific to a particular operand type.
*/
@1.2::Operand.ExtraParams extraParams;
};
/**
* A Neural Network Model.
*
* This includes not only the execution graph, but also constant data such as
* weights or scalars added at construction time. The only information that
* may not be known is the shape of the input tensors.
*/
struct Model {
/**
* The top-level subgraph.
*/
Subgraph main;
/**
* Referenced subgraphs.
*
* Each subgraph is referenced by the main subgraph or at least one other
* referenced subgraph.
*
* There must be no reference cycles.
*/
vec<Subgraph> referenced;
/**
* A byte buffer containing operand data that were copied into the model.
*
* An operand's value must be located here if and only if Operand::lifetime
* equals OperandLifeTime::CONSTANT_COPY.
*/
vec<uint8_t> operandValues;
/**
* A collection of shared memory pools containing operand values.
*
* An operand's value must be located here if and only if Operand::lifetime
* equals OperandLifeTime::CONSTANT_REFERENCE.
*/
vec<memory> pools;
/**
* 'true' indicates TENSOR_FLOAT32 may be calculated with range and/or
* precision as low as that of the IEEE 754 16-bit floating-point format.
* 'false' indicates TENSOR_FLOAT32 must be calculated using at least the
* range and precision of the IEEE 754 32-bit floating-point format.
*/
bool relaxComputationFloat32toFloat16;
/**
* The mapping between extension names and prefixes of operand and
* operation type values.
*
* An operand or operation whose numeric type value is above
* {@link OperandTypeRange::BASE_MAX} or
* {@link OperationTypeRange::BASE_MAX} respectively should be interpreted
* as an extension operand. The low
* {@link @1.2::Model::ExtensionTypeEncoding::LOW_BITS_TYPE} bits of the
* value correspond to the type ID within the extension and the high
* {@link @1.2::Model::ExtensionTypeEncoding::HIGH_BITS_PREFIX} bits encode
* the "prefix", which maps uniquely to the extension name.
*
* For example, if a model contains an operation whose value is
* 0xAAAABBBB and extensionNameToPrefix contains an entry with
* prefix=0xAAAA and name="vendor.test.test_extension", then
* the operation should be interpreted as the operation 0xBBBB
* of the extension named vendor.test.test_extension.
*
* This is a one-to-one correspondence. That is, there must be at most one
* prefix corresponding to each extension name and at most one extension
* name corresponding to each prefix.
*/
vec<@1.2::Model.ExtensionNameAndPrefix> extensionNameToPrefix;
};
/**
* An excerpt of the execution graph.
*/
struct Subgraph {
/**
* All operands included in the subgraph.
*/
vec<Operand> operands;
/**
* All operations included in the subgraph.
*
* The operations are sorted into execution order. Every operand
* with lifetime SUBGRAPH_OUTPUT or TEMPORARY_VARIABLE must be
* written before it is read.
*/
vec<Operation> operations;
/**
* Input indexes of the subgraph. There must be at least one.
*
* Each value corresponds to the index of the operand in "operands".
*/
vec<uint32_t> inputIndexes;
/**
* Output indexes of the subgraph. There must be at least one.
*
* Each value corresponds to the index of the operand in "operands".
*/
vec<uint32_t> outputIndexes;
};
/**
* A buffer descriptor. Describes the properties of a buffer.
*/
struct BufferDesc {
/**
* Dimensions of the buffer. May have unknown dimensions or rank. A buffer with some number
* of unspecified dimensions is represented by setting each unspecified dimension to 0. A
* buffer with unspecified rank is represented by providing an empty dimensions vector.
*/
vec<uint32_t> dimensions;
};
/**
* Describes a role of an input or output to a prepared model.
*/
struct BufferRole {
/**
* The index of the IPreparedModel within the "preparedModel" argument passed in
* IDevice::allocate.
*/
uint32_t modelIndex;
/**
* The index of the input or output operand.
*/
uint32_t ioIndex;
/**
* A floating-point value within the range (0.0, 1.0]. Describes how likely the
* buffer is to be used in the specified role. This is provided as a hint to
* optimize the case when multiple roles prefer different buffer locations or data
* layouts.
*/
float frequency;
};
/**
* Inputs to be sent to and outputs to be retrieved from a prepared model.
*
* A Request serves two primary tasks:
* 1) Provides the input and output data to be used when executing the model.
* 2) Specifies any updates to the input operand metadata that were left
* unspecified at model preparation time.
*
* An output must not overlap with any other output, with an input, or
* with an operand of lifetime CONSTANT_REFERENCE.
*/
struct Request {
/**
* Input data and information to be used in the execution of a prepared
* model.
*
* The index of the input corresponds to the index in Model.main.inputIndexes.
* E.g., input[i] corresponds to Model.main.inputIndexes[i].
*/
vec<RequestArgument> inputs;
/**
* Output data and information to be used in the execution of a prepared
* model.
*
* The index of the output corresponds to the index in Model.main.outputIndexes.
* E.g., output[i] corresponds to Model.main.outputIndexes[i].
*/
vec<RequestArgument> outputs;
/**
* A memory pool.
*/
safe_union MemoryPool {
/**
* Specifies a client-managed shared memory pool.
*/
memory hidlMemory;
/**
* Specifies a driver-managed buffer. It is the token returned from IDevice::allocate,
* and is specific to the IDevice object.
*/
uint32_t token;
};
/**
* A collection of memory pools containing operand data for both the
* inputs and the outputs to a model.
*/
vec<MemoryPool> pools;
};
%insert Request
/**
* Optional time point of the steady clock (as from std::chrono::steady_clock)