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