1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_PACKAGES_MODULES_NEURALNETWORKS_COMMON_TYPES_NNAPI_VALIDATION_H 18 #define ANDROID_PACKAGES_MODULES_NEURALNETWORKS_COMMON_TYPES_NNAPI_VALIDATION_H 19 20 #include <functional> 21 #include <memory> 22 #include <set> 23 #include <tuple> 24 #include <vector> 25 26 #include "nnapi/Result.h" 27 #include "nnapi/Types.h" 28 29 namespace android::nn { 30 31 // Utility functions 32 33 // Takes two minimum versions needed for two features and returns a the minimum version that must be 34 // supported in order to support both features. 35 Version combineVersions(Version minVersionNeeded1, Version minVersionNeeded2); 36 37 // Indicates whether a feature at version `minVersionNeeded` is supported on version 38 // `maxVersionSupported`. For example: 39 // * a feature at kVersionFeatureLevel2 is supported on a driver at kVersionFeatureLevel3. 40 // * a feature at kVersionFeatureLevel3 is supported on a driver at kVersionFeatureLevel3. 41 // * a feature at kVersionFeatureLevel5 is not supported on a driver at kVersionFeatureLevel3. 42 // * a feature that is runtime only (i.e., invalid with respect to the HAL specification) is not 43 // supported on a driver that does not support runtime-only features. 44 bool isCompliantVersion(Version minVersionNeeded, Version maxVersionSupported); 45 46 Result<Version> validate(const DeviceStatus& deviceStatus); 47 Result<Version> validate(const ExecutionPreference& executionPreference); 48 Result<Version> validate(const DeviceType& deviceType); 49 Result<Version> validate(const MeasureTiming& measureTiming); 50 Result<Version> validate(const OperandType& operandType); 51 Result<Version> validate(const Priority& priority); 52 Result<Version> validate(const ErrorStatus& errorStatus); 53 Result<Version> validate(const FusedActivationFunc& activation); 54 Result<Version> validate(const OutputShape& outputShape); 55 Result<Version> validate(const Timing& timing); 56 Result<Version> validate(const Capabilities& capabilities); 57 Result<Version> validate(const Extension& extension); 58 Result<Version> validate(const SharedHandle& handle); 59 Result<Version> validate(const SharedMemory& memory); 60 Result<Version> validate(const Model& model); 61 Result<Version> validate(const BufferDesc& bufferDesc); 62 Result<Version> validate(const BufferRole& bufferRole); 63 Result<Version> validate(const Request& request); 64 Result<Version> validate(const OptionalTimePoint& optionalTimePoint); 65 Result<Version> validate(const OptionalDuration& optionalTimeoutDuration); 66 Result<Version> validate(const CacheToken& cacheToken); 67 Result<Version> validate(const SyncFence& syncFence); 68 Result<Version> validate(const TokenValuePair& tokenValuePair); 69 70 Result<Version> validate(const std::vector<OutputShape>& outputShapes); 71 Result<Version> validate(const std::vector<Extension>& extensions); 72 Result<Version> validate(const std::vector<SharedHandle>& handles); 73 Result<Version> validate(const std::vector<BufferRole>& bufferRoles); 74 Result<Version> validate(const std::vector<SyncFence>& syncFences); 75 Result<Version> validate(const std::vector<TokenValuePair>& metaData); 76 Result<Version> validate(const std::vector<ExtensionNameAndPrefix>& extensionNamesAndPrefixes); 77 78 // Validate request applied to model. 79 // This function assumes that `model` has already been validated, and the returned Version does not 80 // account for the version the model. 81 Result<Version> validateRequestForModel(const Request& request, const Model& model, 82 bool allowUnspecifiedOutput = true); 83 84 // Validate memory descriptor. 85 enum class IOType { INPUT, OUTPUT }; 86 using PreparedModelRole = std::tuple<const IPreparedModel*, IOType, uint32_t>; 87 88 // Verifies that the input arguments to IDevice::allocate are valid. 89 // Optionally, this function can return a flattened prepared model roles and a combined operand. 90 // Pass nullptr if either value is not needed. 91 // IMPORTANT: This function cannot validate dimensions and extraParams with extension operand type. 92 // Each driver should do their own validation of extension type dimensions and extraParams. 93 Result<Version> validateMemoryDesc( 94 const BufferDesc& desc, const std::vector<SharedPreparedModel>& preparedModels, 95 const std::vector<BufferRole>& inputRoles, const std::vector<BufferRole>& outputRoles, 96 const std::function<const Model*(const SharedPreparedModel&)>& getModel, 97 std::set<PreparedModelRole>* preparedModelRoles, Operand* combinedOperand); 98 99 Result<void> validateOperandSymmPerChannelQuantParams( 100 const Operand& operand, const Operand::SymmPerChannelQuantParams& channelQuant, 101 const char* tag); 102 103 // Validates an operand type. 104 // 105 // extensionOperandTypeInfo must be nullptr iff the type is not an extension type. 106 // 107 // If allowPartial is true, the dimensions may be underspecified. 108 Result<void> validateOperandType(const Operand& type, 109 const Extension::OperandTypeInformation* extensionOperandTypeInfo, 110 const char* tag, bool allowPartial); 111 Result<void> validateOperandList(const std::vector<uint32_t>& list, size_t operandCount, 112 const char* tag); 113 114 // Validates the operation, and ensures it uses subgraphs in a valid way, but does not validate any 115 // subgraphs or operands themselves. 116 // 117 // This function is currently used by ModelBuilder. 118 Result<void> validateOperationButNotOperands(const Operation& operation, 119 const std::vector<Operand>& operands, 120 const std::vector<Model::Subgraph>& subgraphs); 121 122 // Forward declaration for a utility class for caching a referenced subgraph's version. 123 struct SubgraphVersionCache; 124 125 // Function to create an opaque handle to a utility class for caching a referenced subgraph's 126 // version. 127 std::unique_ptr<SubgraphVersionCache, void (*)(SubgraphVersionCache*)> createSubgraphVersionCache( 128 size_t subgraphCount); 129 130 // Validate the operation or operand, also validating any subgraphs and operands it may use, 131 // recursively. 132 // 133 // `subgraphVersionCache` is used to cache validation information for `subgraphs`, which would 134 // otherwise be unnecessarily re-validated. For this reason, `subgraphVersionCache` must be non-null 135 // and must have been created with the number of referenced subgraphs in `subgraphs`. The provided 136 // subgraphs must not form a reference cycle. 137 // 138 // These functions are currently used by MetaModel. 139 Result<Version> validateOperationAndAnythingItDependsOn( 140 const Operation& operation, const std::vector<Operand>& operands, size_t operandValuesSize, 141 const std::vector<size_t>& poolSizes, const std::vector<Model::Subgraph>& subgraphs, 142 SubgraphVersionCache* subgraphVersionCache); 143 Result<Version> validateOperandAndAnythingItDependsOn(const Operand& operand, 144 size_t operandValuesSize, 145 const std::vector<size_t>& poolSizes, 146 const std::vector<Model::Subgraph>& subgraphs, 147 SubgraphVersionCache* subgraphVersionCache); 148 149 } // namespace android::nn 150 151 #endif // ANDROID_PACKAGES_MODULES_NEURALNETWORKS_COMMON_TYPES_NNAPI_VALIDATION_H 152