Merge changes from topic "get-supported-extensions"
* changes:
Add getSupportedExtensions to NNAPI IDevice
Define NNAPI Extensions types
diff --git a/neuralnetworks/1.2/IDevice.hal b/neuralnetworks/1.2/IDevice.hal
index de249b0..b9fa388 100644
--- a/neuralnetworks/1.2/IDevice.hal
+++ b/neuralnetworks/1.2/IDevice.hal
@@ -76,6 +76,21 @@
getType() generates (ErrorStatus status, DeviceType type);
/**
+ * Gets information about extensions supported by the driver implementation.
+ *
+ * All extension operations and operands must be fully supported for the
+ * extension to appear in the list of supported extensions.
+ *
+ * @return status Error status of the call, must be:
+ * - NONE if successful
+ * - DEVICE_UNAVAILABLE if driver is offline or busy
+ * - GENERAL_FAILURE if there is an unspecified error
+ * @return extensions A list of supported extensions.
+ */
+ getSupportedExtensions()
+ generates (ErrorStatus status, vec<Extension> extensions);
+
+ /**
* Gets the supported operations in a model.
*
* getSupportedOperations indicates which operations of a model are fully
diff --git a/neuralnetworks/1.2/types.hal b/neuralnetworks/1.2/types.hal
index 4d5f0f4..9e7d8f0 100644
--- a/neuralnetworks/1.2/types.hal
+++ b/neuralnetworks/1.2/types.hal
@@ -73,10 +73,11 @@
* These fields are located inside Operand's extraParams union, inside the
* SymmPerChannelQuantParams struct.
*
- * An Operand of this type must use 'channelQuant' field of its extraParams
- * union.
+ * An Operand of this type must use the 'channelQuant' variant of its
+ * extraParams field.
*
- * The channel dimension of this tensor must not be unknown (dimensions[channelDim] != 0).
+ * The channel dimension of this tensor must be known, i.e.
+ * dimensions[channelDim] must be non-zero.
*
* The formula for real values:
* realValue[..., C, ...] =
@@ -108,10 +109,12 @@
* The range of operand values in the OperandType enum.
*/
enum OperandTypeRange : uint32_t {
+ BASE_MIN = 0,
FUNDAMENTAL_MIN = 0,
FUNDAMENTAL_MAX = 12,
- OEM_MIN = 10000,
- OEM_MAX = 10001,
+ OEM_MIN = 10000,
+ OEM_MAX = 10001,
+ BASE_MAX = 0xFFFF,
};
/**
@@ -189,10 +192,12 @@
* The range of values in the OperationType enum.
*/
enum OperationTypeRange : uint32_t {
+ BASE_MIN = 0,
FUNDAMENTAL_MIN = 0,
FUNDAMENTAL_MAX = 93,
- OEM_MIN = 10000,
- OEM_MAX = 10000,
+ OEM_MIN = 10000,
+ OEM_MAX = 10000,
+ BASE_MAX = 0xFFFF,
};
/**
@@ -221,6 +226,10 @@
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;
@@ -247,21 +256,16 @@
uint32_t channelDim;
};
-// TODO(slavash): Operand Extension support
-// /**
-// * Parameters for an unknown (as of 1.2) operand extension. This is
-// * a vendor-specific extension or a platform extension (backport of
-// * functionality from newer NNAPI interface).
-// */
-// struct OperandParamsUnknown {
-// };
-
/**
* Describes one operand of the model's graph.
*/
struct Operand {
/**
- * Data type of the 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;
@@ -351,25 +355,28 @@
DataLocation location;
/**
- * Union of extra parameters, used by some types of Operands that need additional
- * information for the complete definition of an Operand.
+ * Additional parameters specific to a particular operand type.
*/
safe_union ExtraParams {
/**
- * Placeholder for operand with no extra parameters.
+ * No additional parameters.
*/
Monostate none;
/**
- * Used with TENSOR_QUANT8_SYMM_PER_CHANNEL operand type.
+ * Symmetric per-channel quantization parameters.
+ *
+ * Only applicable to operands of type TENSOR_QUANT8_SYMM_PER_CHANNEL.
*/
SymmPerChannelQuantParams channelQuant;
- // TODO(slavash): Operand Extension support
- // /**
- // * Used with Extension operand type.
- // */
- // OperandParamsUnknown unknown;
+ /**
+ * Extension operand parameters.
+ *
+ * The framework treats this as an opaque data blob.
+ * The format is up to individual extensions.
+ */
+ vec<uint8_t> extension;
} extraParams;
};
@@ -432,6 +439,63 @@
* 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 value 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}.
+ */
+ 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,
+ };
};
/**
@@ -685,3 +749,43 @@
*/
Timing executionTiming;
};
+
+/**
+ * Information about an extension.
+ */
+struct Extension {
+ /**
+ * The extension name.
+ *
+ * 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;
+};
diff --git a/neuralnetworks/1.2/vts/functional/BasicTests.cpp b/neuralnetworks/1.2/vts/functional/BasicTests.cpp
index 8c3ad15..0eec365 100644
--- a/neuralnetworks/1.2/vts/functional/BasicTests.cpp
+++ b/neuralnetworks/1.2/vts/functional/BasicTests.cpp
@@ -55,6 +55,23 @@
});
EXPECT_TRUE(ret.isOk());
}
+
+// device supported extensions test
+TEST_F(NeuralnetworksHidlTest, GetDeviceSupportedExtensionsTest) {
+ Return<void> ret = device->getSupportedExtensions(
+ [](ErrorStatus status, const hidl_vec<Extension>& extensions) {
+ EXPECT_EQ(ErrorStatus::NONE, status);
+ for (auto& extension : extensions) {
+ std::string extensionName = extension.name;
+ EXPECT_FALSE(extensionName.empty());
+ EXPECT_NE(extensionName.find("."), std::string::npos)
+ << "Extension name must start with the reverse domain name of the "
+ "vendor";
+ }
+ });
+ EXPECT_TRUE(ret.isOk());
+}
+
} // namespace functional
} // namespace vts
} // namespace V1_2