Merge "Move NNAPI type information to types.spec" am: a23a3613bc am: 0018455816 am: 5c293f05dd

Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1642100

Change-Id: Id90999e2ebafeef9a08b4efba7dc2b7adfe535c7
diff --git a/neuralnetworks/1.0/types.t b/neuralnetworks/1.0/types.t
index d7b26aa..be1ee07 100644
--- a/neuralnetworks/1.0/types.t
+++ b/neuralnetworks/1.0/types.t
@@ -63,361 +63,25 @@
     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.
diff --git a/neuralnetworks/1.1/types.t b/neuralnetworks/1.1/types.t
index 75ac2e7..8c22b30 100644
--- a/neuralnetworks/1.1/types.t
+++ b/neuralnetworks/1.1/types.t
@@ -31,128 +31,10 @@
 %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
diff --git a/neuralnetworks/1.2/types.t b/neuralnetworks/1.2/types.t
index 4c9fd02..b490f7f 100644
--- a/neuralnetworks/1.2/types.t
+++ b/neuralnetworks/1.2/types.t
@@ -97,379 +97,23 @@
     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 @@
     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
diff --git a/neuralnetworks/1.3/types.t b/neuralnetworks/1.3/types.t
index 9f69c9e..96d1a1b 100644
--- a/neuralnetworks/1.3/types.t
+++ b/neuralnetworks/1.3/types.t
@@ -90,459 +90,25 @@
     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)