1 /* 2 * Copyright (C) 2019 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_FRAMEWORKS_ML_NN_RUNTIME_TYPE_MANAGER_H 18 #define ANDROID_FRAMEWORKS_ML_NN_RUNTIME_TYPE_MANAGER_H 19 20 #include <map> 21 #include <set> 22 #include <string> 23 #include <vector> 24 25 #include "HalInterfaces.h" 26 #include "Manager.h" 27 28 namespace android { 29 namespace nn { 30 31 // Manages runtime operand and operation type information. 32 // 33 // This class gathers information about extension types from all devices 34 // and provides a unified way to access information about any known type. 35 class TypeManager { 36 public: get()37 static TypeManager* get() { 38 static TypeManager manager; 39 return &manager; 40 } 41 42 // Creates an operand/operation type corresponding to a given extension 43 // name and type within extension. 44 // 45 // Returns false if the extension is unknown. 46 bool getExtensionType(const char* extensionName, uint16_t typeWithinExtension, int32_t* type); 47 48 // Looks up information about the extension corresponding to the given prefix 49 // 50 // Returns false if no extension corresponds to the given prefix. 51 bool getExtensionInfo(uint16_t prefix, const hal::Extension** extension) const; 52 53 // Looks up information about an extension operand type 54 // 55 // Returns false if the extension or type is unknown. 56 bool getExtensionOperandTypeInfo(hal::OperandType type, 57 const hal::Extension::OperandTypeInformation** info) const; 58 59 // Returns true if an operand type is a tensor type. 60 // 61 // Aborts if the type is an unknown extension type. 62 bool isTensorType(hal::OperandType type) const; 63 64 // Returns the amount of space needed to store a value of the dimensions and 65 // type of this operand. For a tensor with unspecified rank or at least one 66 // unspecified dimension, returns zero. 67 // 68 // Aborts if the type is an unknown extension type. 69 // Aborts if the size would overflow the return type. getSizeOfData(const hal::Operand & operand)70 uint32_t getSizeOfData(const hal::Operand& operand) const { 71 return getSizeOfData(operand.type, operand.dimensions); 72 } 73 74 // Returns the amount of space needed to store a value of the specified 75 // dimensions and type. For a tensor with unspecified rank or at least one 76 // unspecified dimension, returns zero. 77 // 78 // Aborts if the type is an unknown extension type. 79 uint32_t getSizeOfData(hal::OperandType type, const std::vector<uint32_t>& dimensions) const; 80 81 // Returns true if the amount of space needed to store a value of the specified 82 // dimensions and element size overflows the uint32_t type. 83 // 84 // See also TypeManager::sizeOfDataOverflowsUInt32(). 85 bool sizeOfDataOverflowsUInt32(hal::OperandType type, 86 const std::vector<uint32_t>& dimensions) const; 87 88 // Returns true if extensions usage is allowed in current process. areExtensionsAllowed()89 bool areExtensionsAllowed() const { return mExtensionsAllowed; } 90 91 // This method is intended for use only by internal unit tests. 92 // 93 // Registers an extension. 94 // 95 // Returns true if the registration was successful. forTest_registerExtension(const hal::Extension & extension)96 bool forTest_registerExtension(const hal::Extension& extension) { 97 return registerExtension(extension, "INTERNAL TEST"); 98 } 99 100 // This method is intended for use only by internal unit tests. 101 // 102 // Resets the internal state. 103 // 104 // After calling forTest_registerExtension() any number of times, call 105 // forTest_reset() to return to the state as if forTest_registerExtension() 106 // had never been called. Note that forTest_reset() resets all internal 107 // state (including assigned prefixes) and re-discovers extensions from 108 // available devices. forTest_reset()109 void forTest_reset() { *this = TypeManager(); } 110 111 // Collection of app-related arguments for the isExtensionsUseAllowed method. 112 struct AppPackageInfo { 113 // Path of the binary (/proc/$PID/exe) 114 std::string binaryPath; 115 // Package name of the Android app (empty string if not Android app). 116 std::string appPackageName; 117 // Is the app a system app? (false if not an Android app) 118 bool appIsSystemApp; 119 // Is the app preinstalled on vendor image? (false if not an Android app) 120 bool appIsOnVendorImage; 121 // Is the app preinstalled on product image? (false if not an Android app) 122 bool appIsOnProductImage; 123 }; 124 125 // Check if NNAPI Vendor extensions are usable in the process with the given app 126 // and supplemental infomation. 127 // 128 // useOnProductImageEnabled - whether apps/binaries preinstalled on /product partition 129 // can be enabled for extensions use. 130 // allowlist - list of apps/binaries which are allowed to use extensions. 131 static bool isExtensionsUseAllowed(const AppPackageInfo& appPackageInfo, 132 bool useOnProductImageEnabled, 133 const std::vector<std::string>& allowlist); 134 135 private: 136 TypeManager(); 137 void findAvailableExtensions(); 138 bool registerExtension(hal::Extension extension, const std::string& deviceName); 139 140 // Returns the numeric "prefix" value corresponding to an extension. 141 // 142 // Returns false when assigning a new prefix would overflow uint16_t. 143 bool getExtensionPrefix(const std::string& extensionName, uint16_t* prefix); 144 145 const DeviceManager* mDeviceManager = DeviceManager::get(); 146 147 // Contains all registered extensions. 148 std::map<std::string, hal::Extension> mExtensionNameToExtension; 149 150 // Contains the name of the first discovered device that supports an 151 // extension. Used for error reporting. 152 std::map<std::string, std::string> mExtensionNameToFirstDevice; 153 154 // When multiple devices report conflicting information about an extension, 155 // the extension is disabled. 156 std::set<std::string> mDisabledExtensions; 157 158 // The fields below are used to support efficient extension name to 159 // prefix mapping. New prefixes are created by getExtensionPrefix. 160 std::map<std::string, uint16_t> mExtensionNameToPrefix; 161 // Entries of mPrefixToExtension point into mExtensionNameToExtension. 162 // prefix=0 corresponds to no extension and should never be looked up. 163 std::vector<hal::Extension*> mPrefixToExtension = {nullptr}; 164 165 // True if Extensions can be used in current process. 166 bool mExtensionsAllowed = false; 167 }; 168 169 } // namespace nn 170 } // namespace android 171 172 #endif // ANDROID_FRAMEWORKS_ML_NN_RUNTIME_TYPE_MANAGER_H 173