Merge "NNAPI Burst -- HAL interface"
diff --git a/neuralnetworks/1.2/Android.bp b/neuralnetworks/1.2/Android.bp
index d8762b0..9057b94 100644
--- a/neuralnetworks/1.2/Android.bp
+++ b/neuralnetworks/1.2/Android.bp
@@ -8,6 +8,8 @@
     },
     srcs: [
         "types.hal",
+        "IBurstCallback.hal",
+        "IBurstContext.hal",
         "IDevice.hal",
         "IExecutionCallback.hal",
         "IPreparedModel.hal",
@@ -20,6 +22,9 @@
         "android.hidl.safe_union@1.0",
     ],
     types: [
+        "DeviceType",
+        "FmqRequestDatum",
+        "FmqResultDatum",
         "Model",
         "Operand",
         "OperandType",
@@ -28,6 +33,7 @@
         "OperationType",
         "OperationTypeRange",
         "OutputShape",
+        "SymmPerChannelQuantParams",
     ],
     gen_java: false,
 }
diff --git a/neuralnetworks/1.2/IBurstCallback.hal b/neuralnetworks/1.2/IBurstCallback.hal
new file mode 100644
index 0000000..3f82e31
--- /dev/null
+++ b/neuralnetworks/1.2/IBurstCallback.hal
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.neuralnetworks@1.2;
+
+import @1.0::ErrorStatus;
+
+/**
+ * Callback object used by a service to retreive memory objects based on unique
+ * identifiers ("slots").
+ */
+interface IBurstCallback {
+    /**
+     * Get the memory regions that correspond to slot ids. The slot ids are are
+     * unique to the burst object.
+     *
+     * @param slots Values uniquely identifying memory regions within a Burst.
+     * @return status Indicates whether the memories were successfully returned;
+     *                must be:
+     *                - NONE if the memory region was successfully retrieved
+     *                - GENERAL_FAILURE if there is an unspecified error
+     *                - INVALID_ARGUMENT if a slot number is invalid
+     * @return buffers Memory buffers corresponding to the slot numbers. If an
+     *                 error occurs, an empty vector must be returned for
+     *                 buffers, otherwise slots.size() == buffers.size().
+     */
+    getMemories(vec<int32_t> slots) generates (ErrorStatus status, vec<memory> buffers);
+};
diff --git a/neuralnetworks/1.2/IBurstContext.hal b/neuralnetworks/1.2/IBurstContext.hal
new file mode 100644
index 0000000..60bf53b
--- /dev/null
+++ b/neuralnetworks/1.2/IBurstContext.hal
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.neuralnetworks@1.2;
+
+/**
+ * Context object to manage the resources of a burst.
+ */
+interface IBurstContext {
+    /**
+     * freeMemory is used by the client to signal to the service that a memory
+     * buffer corresponding to a slot number is no longer needed by the client.
+     *
+     * The slot ids are unique to the burst object.
+     *
+     * @param slot Value uniquely identifying a memory region.
+     */
+    freeMemory(int32_t slot);
+};
diff --git a/neuralnetworks/1.2/IPreparedModel.hal b/neuralnetworks/1.2/IPreparedModel.hal
index 044ca28..2d4e572 100644
--- a/neuralnetworks/1.2/IPreparedModel.hal
+++ b/neuralnetworks/1.2/IPreparedModel.hal
@@ -19,6 +19,8 @@
 import @1.0::ErrorStatus;
 import @1.0::IPreparedModel;
 import @1.0::Request;
+import IBurstCallback;
+import IBurstContext;
 import IExecutionCallback;
 
 /**
@@ -113,4 +115,34 @@
      */
     executeSynchronously(Request request)
         generates (ErrorStatus status, vec<OutputShape> outputShapes);
+
+    /**
+     * Configure a Burst object used to execute multiple inferences on a
+     * prepared model in rapid succession.
+     *
+     * @param callback A callback object used to retrieve memory resources
+     *                 corresponding to a unique identifiers ("slots").
+     * @param requestChannel Used by the client to send a serialized Request to
+     *                       the Burst for execution. requestChannel must not be
+     *                       used to pass a second Request object until a result
+     *                       has been received from resultChannel.
+     * @param resultChannel Used by the service to return the results of an
+     *                      execution to the client: the status of the execution
+     *                      and OutputShape of all output tensors. resultChannel
+     *                      must be used to return the results if a Request was
+     *                      sent through the requestChannel.
+     * @return status Error status of configuring the execution burst, must be:
+     *                - NONE if the burst is successfully configured
+     *                - DEVICE_UNAVAILABLE if driver is offline or busy
+     *                - GENERAL_FAILURE if there is an unspecified error
+     *                - INVALID_ARGUMENT if one of the input arguments is
+     *                  invalid
+     * @return context Object containing all resources (such as cached
+     *                 hidl_memory) related to a Burst if successful, otherwise
+     *                 nullptr.
+     */
+    configureExecutionBurst(IBurstCallback callback,
+                            fmq_sync<FmqRequestDatum> requestChannel,
+                            fmq_sync<FmqResultDatum> resultChannel)
+                 generates (ErrorStatus status, IBurstContext context);
 };
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index ac944c8..ce993d7 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -17,6 +17,7 @@
 package android.hardware.neuralnetworks@1.2;
 
 import @1.0::DataLocation;
+import @1.0::ErrorStatus;
 import @1.0::OperandLifeTime;
 import @1.0::OperandType;
 import @1.0::PerformanceInfo;
@@ -444,3 +445,195 @@
      */
     bool isSufficient;
 };
+
+/**
+ * FmqRequestDatum is a single element of a serialized representation of a
+ * {@link @1.0::Request} object which is sent across FastMessageQueue.
+ *
+ * The serialized representation for a particular execution is referred to later
+ * in these descriptions as a 'packet'.
+ *
+ * FastMessageQueue can only pass HIDL-defined types that do not involve nested
+ * buffers, handles, or interfaces.
+ *
+ * The {@link @1.0::Request} is serialized as follows:
+ * 1) 'packetInformation'
+ * 2) For each input operand:
+ *    2.1) 'inputOperandInformation'
+ *    2.2) For each dimension element of the operand:
+ *         2.2.1) 'inputOperandDimensionValue'
+ * 3) For each output operand:
+ *    3.1) 'outputOperandInformation'
+ *    3.2) For each dimension element of the operand:
+ *         3.2.1) 'outputOperandDimensionValue'
+ * 4) For each pool:
+ *    4.1) 'poolIdentifier'
+ */
+safe_union FmqRequestDatum {
+    /**
+     * Type to describe the high-level layout of the packet.
+     */
+    struct PacketInformation {
+        /**
+         * How many elements the packet contains, including the
+         * "packetInformation" datum.
+         */
+        uint32_t packetSize;
+
+        /**
+         * Number of input operands.
+         */
+        uint32_t numberOfInputOperands;
+
+        /**
+         * Number of output operands.
+         */
+        uint32_t numberOfOutputOperands;
+
+        /**
+         * Number of pool identifiers.
+         */
+        uint32_t numberOfPools;
+    };
+
+    /**
+     * Type representing the information for each operand.
+     */
+    struct OperandInformation {
+        /**
+         * 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, 'numberOfDimensions' is set to 0,  and the
+         * dimensions information is omitted from the serialization.
+         */
+        bool hasNoValue;
+
+        /**
+         * The location within one of the memory pools passed in the Request.
+         */
+        DataLocation location;
+
+        /**
+         * Number of subsequent elements that belong to the dimensions vector.
+         */
+        uint32_t numberOfDimensions;
+    };
+
+    /**
+     * packetInformation is the first element of the packet and describes the
+     * remainder of the packet.
+     */
+    PacketInformation packetInformation;
+
+    /**
+     * Information for each input operand.
+     */
+    OperandInformation inputOperandInformation;
+
+    /**
+     * Element of the dimensions vector.
+     */
+    uint32_t inputOperandDimensionValue;
+
+    /**
+     * Information for each output operand.
+     */
+    OperandInformation outputOperandInformation;
+
+    /**
+     * Element of the dimensions vector.
+     */
+    uint32_t outputOperandDimensionValue;
+
+    /**
+     * Unique identifier for a pool.
+     *
+     * A {@link @1.0::Request} passes across one or more pools of shared memory
+     * for the inputs and outputs of an execution. However, these memory pools
+     * are not able to be sent across FastMessageQueue directly. Instead, the
+     * producing side of the FMQ represents each different pool with a unique
+     * identifier, and sends this identifier across the FMQ. Whenever the
+     * consuming side of the FMQ needs the memory corresponding to this unique
+     * identifier, it can pass the identifier to
+     * {@link IBurstCallback::getMemories} to retreive the memory. Although this
+     * HIDL Binder call is expensive compared to communication across FMQ, it is
+     * only needed in the cases when the consumer does not recognize the unique
+     * identifier.
+     */
+    int32_t poolIdentifier;
+};
+
+/**
+ * FmqResultDatum is a single element of a serialized representation of the
+ * values returned from an execution ({@link @1.0::ErrorStatus} and
+ * vec<{@link OutputShape}>) which is returned via FastMessageQueue.
+ *
+ * The serialized representation for a particular execution is referred to later
+ * in these descriptions as a 'packet'.
+ *
+ * FastMessageQueue can only pass HIDL-defined types that do not involve nested
+ * buffers, handles, or interfaces.
+ *
+ * The execution return values ({@link @1.0::ErrorStatus} and
+ * vec<{@link OutputShape}>) are serialized as follows:
+ * 1) 'packetInformation'
+ * 2) For each returned operand:
+ *    2.1) 'operandInformation'
+ *    2.2) For each dimension element of the operand:
+ *         2.2.1) 'operandDimensionValue'
+ */
+safe_union FmqResultDatum {
+    /**
+     * Type to describe the high-level layout of the packet.
+     */
+    struct PacketInformation {
+        /**
+         * How many elements the packet contains, including the
+         * "packetInformation" datum.
+         */
+        uint32_t packetSize;
+
+        /**
+         * Status of the execution.
+         */
+        ErrorStatus errorStatus;
+
+        /**
+         * Number of returned operands.
+         */
+        uint32_t numberOfOperands;
+    };
+
+    /**
+     * Type representing the information for each operand.
+     */
+    struct OperandInformation {
+        /**
+         * Indicates whether the operand's output buffer is large enough to
+         * store the operand's result data.
+         */
+        bool isSufficient;
+
+        /**
+         * Number of subsequent elements that belong to the dimensions vector.
+         */
+        uint32_t numberOfDimensions;
+    };
+
+    /**
+     * packetInformation is the first element of the packet and describes the
+     * remainder of the packet. It additionally includes the status of the
+     * execution.
+     */
+    PacketInformation packetInformation;
+
+    /**
+     * Information for each returned operand.
+     */
+    OperandInformation operandInformation;
+
+    /**
+     * Element of the dimensions vector.
+     */
+    uint32_t operandDimensionValue;
+};