summaryrefslogtreecommitdiff
path: root/nn/common
diff options
context:
space:
mode:
authorMichael Butler <butlermichael@google.com>2020-06-29 22:38:51 -0700
committerMichael Butler <butlermichael@google.com>2020-09-21 19:14:32 -0700
commitd3177b9a2ce3ba8543eda5bd57c98141632e366a (patch)
treee96ba1bdf1adeccc9f3513555d33f8787fa36067 /nn/common
parent57223d7b720215034fd4d66d6aa7eaa0336ba92b (diff)
downloadml-d3177b9a2ce3ba8543eda5bd57c98141632e366a.tar.gz
Introduce canonical types in NNAPI
This CL introduces new "canonical" types to represent all NN HAL and runtime types. For example, the canonical Model represents the NN HAL V1_[0123]::Model types as well as a finished ModelBuilder. More specifically, the values representable by the canonical types are a superset of the values representable by all NN HAL and runtime types. Canonical types seek to improve maintainability of the NNAPI in the following ways: 1) They enable the NN runtime to use canonical types instead of relying on HAL types. For example, the HAL Operand type is currently used in the ModelBuilder object. Canonical types allow the NN runtime to continue developing new functionality without requiring a new HAL version immediately. 2) They enable conversion code to be written just to and from any given type and the corresponding canonical type. Instead of maintaining all-to-all conversion code, it is sufficient to use canonical types as an intermediate conversion "hop". 3) They enable utility code (such as validation) to be written only for the canonical types. To support the same utility code for other types, it is sufficient to convert to the canonical type, perform the utility, and either interpret the results or convert the results back. Bug: 160667941 Test: mma Change-Id: I25504b533cb9d96a35f374a1ad85a70ec1dd10b0 Merged-In: I25504b533cb9d96a35f374a1ad85a70ec1dd10b0 (cherry picked from commit 8bea2060ab3191d59bdc8fb5132343083153af78)
Diffstat (limited to 'nn/common')
-rw-r--r--nn/common/Android.bp31
-rw-r--r--nn/common/Types.cpp124
-rw-r--r--nn/common/include/nnapi/OperandTypes.h45
-rw-r--r--nn/common/include/nnapi/OperationTypes.h130
-rw-r--r--nn/common/include/nnapi/Types.h297
5 files changed, 627 insertions, 0 deletions
diff --git a/nn/common/Android.bp b/nn/common/Android.bp
index c484fd15f..65d993247 100644
--- a/nn/common/Android.bp
+++ b/nn/common/Android.bp
@@ -229,6 +229,37 @@ cc_library_static {
}
cc_defaults {
+ name: "neuralnetworks_utils_defaults",
+ host_supported: true,
+ vendor_available: true,
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+}
+
+cc_library_static {
+ name: "neuralnetworks_types",
+ defaults: ["neuralnetworks_utils_defaults"],
+ srcs: [
+ "Types.cpp",
+ ],
+ local_include_dirs: ["include/nnapi"],
+ export_include_dirs: ["include"],
+ shared_libs: [
+ "libbase",
+ "libcutils",
+ "libutils",
+ ],
+ export_shared_lib_headers: [
+ "libbase",
+ "libcutils",
+ "libutils",
+ ],
+}
+
+cc_defaults {
name: "NeuralNetworksTest_common",
defaults: ["neuralnetworks_float16"],
shared_libs: [
diff --git a/nn/common/Types.cpp b/nn/common/Types.cpp
new file mode 100644
index 000000000..a49a8dc35
--- /dev/null
+++ b/nn/common/Types.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include "Types.h"
+
+#include <android-base/logging.h>
+
+#include <algorithm>
+#include <cstddef>
+#include <iterator>
+#include <limits>
+#include <optional>
+#include <utility>
+#include <vector>
+
+#include "OperandTypes.h"
+#include "OperationTypes.h"
+
+namespace android::nn {
+namespace {
+
+constexpr size_t safeDivideRoundedUp(size_t numerator, size_t denominator) {
+ CHECK_NE(denominator, 0u);
+ CHECK_LE(numerator, std::numeric_limits<size_t>::max() - denominator);
+ return (numerator + denominator - 1) / denominator;
+}
+
+constexpr size_t safeMultiply(size_t a, size_t b) {
+ if (b == 0) {
+ return 0;
+ }
+ CHECK_LE(a, std::numeric_limits<size_t>::max() / b);
+ return a * b;
+}
+
+std::vector<AlignedData> allocateAligned(const uint8_t* data, size_t length) {
+ constexpr size_t kElementSize = sizeof(AlignedData);
+ const size_t numberElements = safeDivideRoundedUp(length, kElementSize);
+ std::vector<AlignedData> output(numberElements);
+ std::memcpy(output.data(), data, length);
+ return output;
+}
+
+} // anonymous namespace
+
+Model::OperandValues::OperandValues() {
+ constexpr size_t kNumberBytes = 4 * 1024;
+ constexpr size_t kElementSize = sizeof(AlignedData);
+ constexpr size_t kNumberElements = safeDivideRoundedUp(kNumberBytes, kElementSize);
+ mData.reserve(kNumberElements);
+}
+
+Model::OperandValues::OperandValues(const uint8_t* data, size_t length)
+ : mData(allocateAligned(data, length)) {}
+
+DataLocation Model::OperandValues::append(const uint8_t* data, size_t length) {
+ const size_t offset = size();
+ auto contents = allocateAligned(data, length);
+ mData.insert(mData.end(), contents.begin(), contents.end());
+ CHECK_LE(offset, std::numeric_limits<uint32_t>::max());
+ CHECK_LE(length, std::numeric_limits<uint32_t>::max());
+ return {.offset = static_cast<uint32_t>(offset), .length = static_cast<uint32_t>(length)};
+}
+
+const uint8_t* Model::OperandValues::data() const {
+ return reinterpret_cast<const uint8_t*>(mData.data());
+}
+
+size_t Model::OperandValues::size() const {
+ return safeMultiply(mData.size(), sizeof(AlignedData));
+}
+
+Capabilities::OperandPerformanceTable::OperandPerformanceTable(
+ std::vector<OperandPerformance> operandPerformances)
+ : mSorted(std::move(operandPerformances)) {}
+
+std::optional<Capabilities::OperandPerformanceTable> Capabilities::OperandPerformanceTable::create(
+ std::vector<OperandPerformance> operandPerformances) {
+ const auto notUnique = [](const auto& lhs, const auto& rhs) { return !(lhs.type < rhs.type); };
+ const bool isUnique = std::adjacent_find(operandPerformances.begin(), operandPerformances.end(),
+ notUnique) == operandPerformances.end();
+ if (!isUnique) {
+ LOG(ERROR) << "Failed to create OperandPerformanceTable: Input must be sorted by key (in "
+ "ascending order), and there must be no duplicate keys";
+ return std::nullopt;
+ }
+
+ return Capabilities::OperandPerformanceTable(std::move(operandPerformances));
+}
+
+Capabilities::PerformanceInfo Capabilities::OperandPerformanceTable::lookup(
+ OperandType operandType) const {
+ // Search for operand type in the sorted collection.
+ constexpr auto cmp = [](const auto& performance, auto type) { return performance.type < type; };
+ const auto it = std::lower_bound(mSorted.begin(), mSorted.end(), operandType, cmp);
+
+ // If the operand type is found, return its corresponding info.
+ if (it != mSorted.end() && it->type == operandType) {
+ return it->info;
+ }
+
+ // If no performance info is defined, use the default value (float's max).
+ return Capabilities::PerformanceInfo{};
+}
+
+const std::vector<Capabilities::OperandPerformance>&
+Capabilities::OperandPerformanceTable::asVector() const {
+ return mSorted;
+}
+
+} // namespace android::nn
diff --git a/nn/common/include/nnapi/OperandTypes.h b/nn/common/include/nnapi/OperandTypes.h
new file mode 100644
index 000000000..641ffb658
--- /dev/null
+++ b/nn/common/include/nnapi/OperandTypes.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef ANDROID_FRAMEWORKS_ML_NN_COMMON_NNAPI_OPERAND_TYPES_H
+#define ANDROID_FRAMEWORKS_ML_NN_COMMON_NNAPI_OPERAND_TYPES_H
+
+namespace android::nn {
+
+enum class OperandType {
+ FLOAT32 = 0,
+ INT32 = 1,
+ UINT32 = 2,
+ TENSOR_FLOAT32 = 3,
+ TENSOR_INT32 = 4,
+ TENSOR_QUANT8_ASYMM = 5,
+ BOOL = 6,
+ TENSOR_QUANT16_SYMM = 7,
+ TENSOR_FLOAT16 = 8,
+ TENSOR_BOOL8 = 9,
+ FLOAT16 = 10,
+ TENSOR_QUANT8_SYMM_PER_CHANNEL = 11,
+ TENSOR_QUANT16_ASYMM = 12,
+ TENSOR_QUANT8_SYMM = 13,
+ TENSOR_QUANT8_ASYMM_SIGNED = 14,
+ SUBGRAPH = 15,
+ OEM = 10000,
+ TENSOR_OEM_BYTE = 10001,
+};
+
+} // namespace android::nn
+
+#endif // ANDROID_FRAMEWORKS_ML_NN_COMMON_NNAPI_OPERAND_TYPES_H
diff --git a/nn/common/include/nnapi/OperationTypes.h b/nn/common/include/nnapi/OperationTypes.h
new file mode 100644
index 000000000..5d8c59405
--- /dev/null
+++ b/nn/common/include/nnapi/OperationTypes.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef ANDROID_FRAMEWORKS_ML_NN_COMMON_NNAPI_OPERATION_TYPES_H
+#define ANDROID_FRAMEWORKS_ML_NN_COMMON_NNAPI_OPERATION_TYPES_H
+
+namespace android::nn {
+
+enum class OperationType {
+ ADD = 0,
+ AVERAGE_POOL_2D = 1,
+ CONCATENATION = 2,
+ CONV_2D = 3,
+ DEPTHWISE_CONV_2D = 4,
+ DEPTH_TO_SPACE = 5,
+ DEQUANTIZE = 6,
+ EMBEDDING_LOOKUP = 7,
+ FLOOR = 8,
+ FULLY_CONNECTED = 9,
+ HASHTABLE_LOOKUP = 10,
+ L2_NORMALIZATION = 11,
+ L2_POOL_2D = 12,
+ LOCAL_RESPONSE_NORMALIZATION = 13,
+ LOGISTIC = 14,
+ LSH_PROJECTION = 15,
+ LSTM = 16,
+ MAX_POOL_2D = 17,
+ MUL = 18,
+ RELU = 19,
+ RELU1 = 20,
+ RELU6 = 21,
+ RESHAPE = 22,
+ RESIZE_BILINEAR = 23,
+ RNN = 24,
+ SOFTMAX = 25,
+ SPACE_TO_DEPTH = 26,
+ SVDF = 27,
+ TANH = 28,
+ BATCH_TO_SPACE_ND = 29,
+ DIV = 30,
+ MEAN = 31,
+ PAD = 32,
+ SPACE_TO_BATCH_ND = 33,
+ SQUEEZE = 34,
+ STRIDED_SLICE = 35,
+ SUB = 36,
+ TRANSPOSE = 37,
+ ABS = 38,
+ ARGMAX = 39,
+ ARGMIN = 40,
+ AXIS_ALIGNED_BBOX_TRANSFORM = 41,
+ BIDIRECTIONAL_SEQUENCE_LSTM = 42,
+ BIDIRECTIONAL_SEQUENCE_RNN = 43,
+ BOX_WITH_NMS_LIMIT = 44,
+ CAST = 45,
+ CHANNEL_SHUFFLE = 46,
+ DETECTION_POSTPROCESSING = 47,
+ EQUAL = 48,
+ EXP = 49,
+ EXPAND_DIMS = 50,
+ GATHER = 51,
+ GENERATE_PROPOSALS = 52,
+ GREATER = 53,
+ GREATER_EQUAL = 54,
+ GROUPED_CONV_2D = 55,
+ HEATMAP_MAX_KEYPOINT = 56,
+ INSTANCE_NORMALIZATION = 57,
+ LESS = 58,
+ LESS_EQUAL = 59,
+ LOG = 60,
+ LOGICAL_AND = 61,
+ LOGICAL_NOT = 62,
+ LOGICAL_OR = 63,
+ LOG_SOFTMAX = 64,
+ MAXIMUM = 65,
+ MINIMUM = 66,
+ NEG = 67,
+ NOT_EQUAL = 68,
+ PAD_V2 = 69,
+ POW = 70,
+ PRELU = 71,
+ QUANTIZE = 72,
+ QUANTIZED_16BIT_LSTM = 73,
+ RANDOM_MULTINOMIAL = 74,
+ REDUCE_ALL = 75,
+ REDUCE_ANY = 76,
+ REDUCE_MAX = 77,
+ REDUCE_MIN = 78,
+ REDUCE_PROD = 79,
+ REDUCE_SUM = 80,
+ ROI_ALIGN = 81,
+ ROI_POOLING = 82,
+ RSQRT = 83,
+ SELECT = 84,
+ SIN = 85,
+ SLICE = 86,
+ SPLIT = 87,
+ SQRT = 88,
+ TILE = 89,
+ TOPK_V2 = 90,
+ TRANSPOSE_CONV_2D = 91,
+ UNIDIRECTIONAL_SEQUENCE_LSTM = 92,
+ UNIDIRECTIONAL_SEQUENCE_RNN = 93,
+ RESIZE_NEAREST_NEIGHBOR = 94,
+ QUANTIZED_LSTM = 95,
+ IF = 96,
+ WHILE = 97,
+ ELU = 98,
+ HARD_SWISH = 99,
+ FILL = 100,
+ RANK = 101,
+ OEM_OPERATION = 10000,
+};
+
+} // namespace android::nn
+
+#endif // ANDROID_FRAMEWORKS_ML_NN_COMMON_NNAPI_OPERATION_TYPES_H
diff --git a/nn/common/include/nnapi/Types.h b/nn/common/include/nnapi/Types.h
new file mode 100644
index 000000000..0536a2e2b
--- /dev/null
+++ b/nn/common/include/nnapi/Types.h
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#ifndef ANDROID_FRAMEWORKS_ML_NN_COMMON_NNAPI_TYPES_H
+#define ANDROID_FRAMEWORKS_ML_NN_COMMON_NNAPI_TYPES_H
+
+#include <utils/NativeHandle.h>
+#include <utils/StrongPointer.h>
+
+#include <array>
+#include <chrono>
+#include <limits>
+#include <memory>
+#include <optional>
+#include <string>
+#include <type_traits>
+#include <variant>
+#include <vector>
+
+#include "nnapi/OperandTypes.h"
+#include "nnapi/OperationTypes.h"
+
+namespace android::nn {
+
+// Forward declarations
+
+class IBuffer;
+class IDevice;
+class IPreparedModel;
+
+// Default values
+
+constexpr uint64_t kNoTiming = std::numeric_limits<uint64_t>::max();
+constexpr float kDefaultExecTime = std::numeric_limits<float>::max();
+constexpr float kDefaultPowerUsage = std::numeric_limits<float>::max();
+constexpr uint32_t kByteSizeOfCacheToken = 32;
+constexpr uint32_t kMaxNumberOfCacheFiles = 32;
+constexpr uint8_t kExtensionTypeBits = 16;
+constexpr uint8_t kExtensionPrefixBits = 16;
+
+// Aliases
+
+using AlignedData = std::max_align_t;
+using SharedBuffer = std::shared_ptr<const IBuffer>;
+using SharedDevice = std::shared_ptr<const IDevice>;
+using PreparedModel = std::shared_ptr<const IPreparedModel>;
+
+// Canonical types
+
+enum class DeviceStatus {
+ AVAILABLE = 0,
+ BUSY = 1,
+ OFFLINE = 2,
+ UNKNOWN = 3,
+};
+
+enum class ExecutionPreference {
+ LOW_POWER = 0,
+ FAST_SINGLE_ANSWER = 1,
+ SUSTAINED_SPEED = 2,
+ DEFAULT = FAST_SINGLE_ANSWER,
+};
+
+enum class DeviceType {
+ UNKNOWN = 0,
+ OTHER = 1,
+ CPU = 2,
+ GPU = 3,
+ ACCELERATOR = 4,
+};
+
+enum class MeasureTiming {
+ NO = 0,
+ YES = 1,
+};
+
+enum class Priority {
+ LOW = 0,
+ MEDIUM = 1,
+ HIGH = 2,
+ DEFAULT = MEDIUM,
+};
+
+// TODO: Should more errors from NeuralNetworks.h be incorporated? The left name shows errors that
+// appear in NeuralNetworks.h but not in the HAL, and the right column shows what these values could
+// map to:
+// * OUT_OF_MEMORY ==> GENERAL_FAILURE / RESOURCE_EXHAUSTED_*
+// * INCOMPLETE ==> GENERAL_FAILURE
+// * UNEXPECTED_NULL ==> INVALID_ARGUMENT
+// * UNMAPPABLE ==> GENERAL_FAILURE
+// * BAD_STATE ==> INVALID_ARGUMENT
+enum class ErrorStatus {
+ NONE = 0,
+ DEVICE_UNAVAILABLE = 1,
+ GENERAL_FAILURE = 2,
+ OUTPUT_INSUFFICIENT_SIZE = 3,
+ INVALID_ARGUMENT = 4,
+ MISSED_DEADLINE_TRANSIENT = 5,
+ MISSED_DEADLINE_PERSISTENT = 6,
+ RESOURCE_EXHAUSTED_TRANSIENT = 7,
+ RESOURCE_EXHAUSTED_PERSISTENT = 8,
+ DEAD_OBJECT = 10000,
+};
+
+using Dimension = uint32_t;
+using Dimensions = std::vector<Dimension>;
+
+using CacheToken = std::array<uint8_t, kByteSizeOfCacheToken>;
+
+struct OutputShape {
+ std::vector<uint32_t> dimensions;
+ bool isSufficient = false;
+};
+
+struct Timing {
+ uint64_t timeOnDevice = kNoTiming;
+ uint64_t timeInDriver = kNoTiming;
+};
+
+struct Capabilities {
+ struct PerformanceInfo {
+ float execTime = kDefaultExecTime;
+ float powerUsage = kDefaultPowerUsage;
+ };
+ struct OperandPerformance {
+ OperandType type{};
+ PerformanceInfo info;
+ };
+ class OperandPerformanceTable {
+ public:
+ static std::optional<OperandPerformanceTable> create(
+ std::vector<OperandPerformance> operandPerformances);
+
+ PerformanceInfo lookup(OperandType type) const;
+ const std::vector<OperandPerformance>& asVector() const;
+
+ private:
+ explicit OperandPerformanceTable(std::vector<OperandPerformance> operandPerformances);
+ std::vector<OperandPerformance> mSorted;
+ };
+
+ PerformanceInfo relaxedFloat32toFloat16PerformanceScalar;
+ PerformanceInfo relaxedFloat32toFloat16PerformanceTensor;
+ OperandPerformanceTable operandPerformance;
+ PerformanceInfo ifPerformance;
+ PerformanceInfo whilePerformance;
+};
+
+struct Extension {
+ struct OperandTypeInformation {
+ uint16_t type = 0;
+ bool isTensor = false;
+ uint32_t byteSize = 0;
+ };
+
+ std::string name;
+ std::vector<OperandTypeInformation> operandTypes;
+};
+
+struct Operation {
+ OperationType type{};
+ std::vector<uint32_t> inputs;
+ std::vector<uint32_t> outputs;
+};
+
+struct DataLocation {
+ std::variant<const void*, void*> pointer;
+ uint32_t poolIndex = 0;
+ uint32_t offset = 0;
+ uint32_t length = 0;
+};
+
+struct Operand {
+ enum class LifeTime {
+ TEMPORARY_VARIABLE = 0,
+ SUBGRAPH_INPUT = 1,
+ SUBGRAPH_OUTPUT = 2,
+ CONSTANT_COPY = 3,
+ CONSTANT_REFERENCE = 4,
+ NO_VALUE = 5,
+ SUBGRAPH = 6,
+ POINTER = 7,
+ };
+ using NoParams = std::monostate;
+ struct SymmPerChannelQuantParams {
+ std::vector<float> scales;
+ uint32_t channelDim = 0;
+ };
+ using ExtensionParams = std::vector<uint8_t>;
+ using ExtraParams = std::variant<NoParams, SymmPerChannelQuantParams, ExtensionParams>;
+
+ OperandType type{};
+ Dimensions dimensions;
+ float scale = 0.0f;
+ int32_t zeroPoint = 0;
+ LifeTime lifetime{};
+ DataLocation location;
+ ExtraParams extraParams;
+};
+
+using NativeHandle = ::android::sp<::android::NativeHandle>;
+
+struct Memory {
+ NativeHandle handle;
+ size_t size = 0;
+ std::string name;
+};
+
+struct Model {
+ struct Subgraph {
+ std::vector<Operand> operands;
+ std::vector<Operation> operations;
+ std::vector<uint32_t> inputIndexes;
+ std::vector<uint32_t> outputIndexes;
+ };
+ class OperandValues {
+ public:
+ OperandValues();
+ OperandValues(const uint8_t* data, size_t length);
+
+ DataLocation append(const uint8_t* data, size_t length);
+
+ const uint8_t* data() const;
+ size_t size() const;
+
+ private:
+ std::vector<AlignedData> mData;
+ };
+ struct ExtensionNameAndPrefix {
+ std::string name;
+ uint16_t prefix = 0;
+ };
+
+ Subgraph main;
+ std::vector<Subgraph> referenced;
+ OperandValues operandValues;
+ std::vector<Memory> pools;
+ bool relaxComputationFloat32toFloat16 = false;
+ std::vector<ExtensionNameAndPrefix> extensionNameToPrefix;
+};
+
+struct BufferDesc {
+ Dimensions dimensions;
+};
+
+struct BufferRole {
+ uint32_t modelIndex = 0;
+ uint32_t ioIndex = 0;
+ float frequency = 0.0f;
+};
+
+struct Request {
+ struct Argument {
+ enum class LifeTime {
+ POOL = 0,
+ NO_VALUE = 1,
+ POINTER = 2,
+ };
+
+ LifeTime lifetime{};
+ DataLocation location;
+ Dimensions dimensions;
+ };
+ enum class MemoryDomainToken : uint32_t {};
+ using MemoryPool = std::variant<Memory, MemoryDomainToken, SharedBuffer>;
+
+ std::vector<Argument> inputs;
+ std::vector<Argument> outputs;
+ std::vector<MemoryPool> pools;
+};
+
+using Clock = std::chrono::steady_clock;
+
+using TimePoint = std::chrono::time_point<Clock, std::chrono::nanoseconds>;
+using OptionalTimePoint = std::optional<TimePoint>;
+
+using TimeoutDuration = std::chrono::nanoseconds;
+using OptionalTimeoutDuration = std::optional<TimeoutDuration>;
+
+enum class Version { ANDROID_OC_MR1, ANDROID_P, ANDROID_Q, ANDROID_R, CURRENT_RUNTIME, INVALID };
+
+} // namespace android::nn
+
+#endif // ANDROID_FRAMEWORKS_ML_NN_COMMON_NNAPI_TYPES_H