1 /* 2 * Copyright (C) 2018 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_ML_NN_RUNTIME_VERSIONED_INTERFACES_H 18 #define ANDROID_ML_NN_RUNTIME_VERSIONED_INTERFACES_H 19 20 #include "HalInterfaces.h" 21 22 #include <android-base/macros.h> 23 #include <cstddef> 24 #include <functional> 25 #include <memory> 26 #include <optional> 27 #include <shared_mutex> 28 #include <string> 29 #include <tuple> 30 #include <utility> 31 #include "Callbacks.h" 32 33 namespace android { 34 namespace nn { 35 36 // forward declarations 37 class ExecutionBurstController; 38 class IDeviceDeathHandler; 39 class IModelSlicer; 40 class IPreparedModelDeathHandler; 41 class VersionedIPreparedModel; 42 43 /** 44 * Each class (VersionedIDevice, VersionedIPreparedModel) wraps a HIDL interface 45 * of any version to abstract away version differences. It allows the remainder 46 * of the runtime to always use the most up-to-date version of all HIDL types. 47 * As such, any reference to a HIDL type in the rest of the runtime 48 * will--by default--be the latest HIDL version. 49 * 50 * Each class will attempt to call the latest version of each interface method 51 * if possible. If the latest method is unavailable, the versioned class 52 * will attempt to upcast the type (e.g., V1_1::Model to V1_0::Model), and 53 * invoke the latest interface method possible. If the versioned class 54 * fails to find a matching applicable function, it will return an error. 55 */ 56 57 /** This class wraps an IDevice object of any version. */ 58 class VersionedIDevice { 59 DISALLOW_IMPLICIT_CONSTRUCTORS(VersionedIDevice); 60 61 // forward declaration of nested class 62 class Core; 63 64 public: 65 /** 66 * Create a VersionedIDevice object. 67 * 68 * Prefer using this function over the constructor, as it adds more 69 * protections. 70 * 71 * @param serviceName The name of the service that provides "device". 72 * @param device A device object that is at least version 1.0 of the IDevice 73 * interface. 74 * @return A valid VersionedIDevice object, otherwise nullptr. 75 */ 76 static std::shared_ptr<VersionedIDevice> create(std::string serviceName, 77 sp<V1_0::IDevice> device); 78 79 /** 80 * Constructor for the VersionedIDevice object. 81 * 82 * VersionedIDevice will default to using the latest version of all IDevice 83 * interface methods automatically. 84 * 85 * @param serviceName The name of the service that provides core.getDevice<V1_0::IDevice>(). 86 * @param core An object that encapsulates a V1_0::IDevice, any appropriate downcasts to 87 * newer interfaces, and a hidl_death_recipient that will proactively handle 88 * the case when the service containing the IDevice object crashes. 89 */ 90 VersionedIDevice(std::string serviceName, Core core); 91 92 /** 93 * Gets the capabilities of a driver. 94 * 95 * @return status Error status of the call, must be: 96 * - NONE if successful 97 * - DEVICE_UNAVAILABLE if driver is offline or busy 98 * - GENERAL_FAILURE if there is an unspecified error 99 * @return capabilities Capabilities of the driver. 100 */ 101 std::pair<ErrorStatus, Capabilities> getCapabilities(); 102 103 /** 104 * Gets information about extensions supported by the driver implementation. 105 * 106 * Extensions of category ExtensionCategory::BASE must not appear 107 * in the list. 108 * 109 * All extension operations and operands must be fully supported for the 110 * extension to appear in the list of supported extensions. 111 * 112 * @return status Error status of the call, must be: 113 * - NONE if successful 114 * - DEVICE_UNAVAILABLE if driver is offline or busy 115 * - GENERAL_FAILURE if there is an unspecified error 116 * @return extensions A list of supported extensions. 117 */ 118 std::pair<ErrorStatus, hidl_vec<Extension>> getSupportedExtensions(); 119 120 /** 121 * Gets the supported operations in a model. 122 * 123 * getSupportedOperations indicates which operations of a model are fully 124 * supported by the vendor driver. If an operation may not be supported for 125 * any reason, getSupportedOperations must return false for that operation. 126 * 127 * @param model A model whose operations--and their corresponding 128 * operands--are to be verified by the driver. 129 * @param slicer When the model is not compliant with the HAL version of the 130 * vendor driver, the slicer (if any) is employed to query the 131 * vendor driver about which of the subset of compliant 132 * operations are supported. See the IModelSlicer class in 133 * Utils.h for more details. 134 * @return status Error status of the call, must be: 135 * - NONE if successful 136 * - DEVICE_UNAVAILABLE if driver is offline or busy 137 * - GENERAL_FAILURE if there is an unspecified error 138 * - INVALID_ARGUMENT if provided model is invalid 139 * @return supportedOperations A list of supported operations, where true 140 * indicates the operation is supported and 141 * false indicates the operation is not 142 * supported. The index of "supported" 143 * corresponds with the index of the operation 144 * it is describing. 145 */ 146 std::pair<ErrorStatus, hidl_vec<bool>> getSupportedOperations(const Model& model, 147 IModelSlicer* slicer = nullptr); 148 149 /** 150 * Synchronously creates a prepared model for execution and optionally saves it 151 * into cache files. 152 * 153 * prepareModel is used to make any necessary transformations or alternative 154 * representations to a model for execution, possibly including 155 * transformations on the constant data, optimization on the model's graph, 156 * or compilation into the device's native binary format. The model itself 157 * is not changed. 158 * 159 * Optionally, caching information may be provided for the driver to save 160 * the prepared model to cache files for faster model compilation time 161 * when the same model preparation is requested in the future. There are 162 * two types of cache file handles provided to the driver: model cache 163 * and data cache. For more information on the two types of cache handles, 164 * refer to getNumberOfCacheFilesNeeded. 165 * 166 * The file descriptors must be opened with read and write permission. A file may 167 * have any size, and the corresponding file descriptor may have any offset. The 168 * driver must truncate a file to zero size before writing to that file. The file 169 * descriptors may be closed by the client once the asynchronous preparation has 170 * finished. The driver must dup a file descriptor if it wants to get access to 171 * the cache file later. 172 * 173 * The model is prepared synchronously with respect to the caller. The 174 * prepareModel function must verify the inputs to the preparedModel 175 * function related to preparing the model (as opposed to saving the 176 * prepared model to cache) are correct. If there is an error, prepareModel 177 * must immediately return the appropriate ErrorStatus value and nullptr for 178 * the VersionedIPreparedModel. If the inputs to the prepareModel function 179 * that are related to preparing the model are valid and there is no error, 180 * prepareModel must prepare the model. 181 * 182 * If the model was prepared successfully, prepareModel must return 183 * ErrorStatus::NONE and the produced VersionedIPreparedModel object. If an 184 * error occurred preparing the model, prepareModel must return the 185 * appropriate ErrorStatus value and nullptr for the 186 * VersionedIPreparedModel. 187 * 188 * Optionally, the driver may save the prepared model to cache during 189 * preparation. Any error that occurs when saving to cache must not affect 190 * the status of preparing the model. Even if the input arguments related to 191 * the cache may be invalid, or the driver may fail to save to cache, the 192 * prepareModel function must finish preparing the model. The driver may 193 * choose not to save to cache even if the caching information is provided 194 * and valid. 195 * 196 * The only information that may be unknown to the model at this stage is 197 * the shape of the tensors, which may only be known at execution time. As 198 * such, some driver services may return partially prepared models, where 199 * the prepared model may only be finished when it is paired with a set of 200 * inputs to the model. Note that the same prepared model object may be 201 * used with different shapes of inputs on different (possibly concurrent) 202 * executions. 203 * 204 * Multiple threads may call prepareModel on the same model concurrently. 205 * 206 * @param model The model to be prepared for execution. 207 * @param preference Indicates the intended execution behavior of a prepared 208 * model. 209 * @param modelCache A vector of handles with each entry holding exactly one 210 * cache file descriptor for the security-sensitive cache. The length of 211 * the vector must either be 0 indicating that caching information is not provided, 212 * or match the numModelCache returned from getNumberOfCacheFilesNeeded. The cache 213 * handles will be provided in the same order when retrieving the 214 * preparedModel from cache files with prepareModelFromCache. 215 * @param dataCache A vector of handles with each entry holding exactly one 216 * cache file descriptor for the constants' cache. The length of 217 * the vector must either be 0 indicating that caching information is not provided, 218 * or match the numDataCache returned from getNumberOfCacheFilesNeeded. The cache 219 * handles will be provided in the same order when retrieving the 220 * preparedModel from cache files with prepareModelFromCache. 221 * @param token A caching token of length Constant::BYTE_SIZE_OF_CACHE_TOKEN 222 * identifying the prepared model. The same token will be provided when retrieving 223 * the prepared model from the cache files with prepareModelFromCache. 224 * Tokens should be chosen to have a low rate of collision for a particular 225 * application. The driver cannot detect a collision; a collision will result 226 * in a failed execution or in a successful execution that produces incorrect 227 * output values. If both modelCache and dataCache are empty indicating that 228 * caching information is not provided, this token must be ignored. 229 * @return A pair of: 230 * - status Error status of preparing the model; must be: 231 * - NONE if preparation succeeded 232 * - DEVICE_UNAVAILABLE if driver is offline or busy 233 * - GENERAL_FAILURE if there is an unspecified error 234 * - INVALID_ARGUMENT if one of the input arguments related to 235 * preparing the model is invalid 236 * - preparedModel A VersionedIPreparedModel object representing a model 237 * that has been prepared for execution, else nullptr. 238 */ 239 std::pair<ErrorStatus, std::shared_ptr<VersionedIPreparedModel>> prepareModel( 240 const Model& model, ExecutionPreference preference, 241 const hidl_vec<hidl_handle>& modelCache, const hidl_vec<hidl_handle>& dataCache, 242 const hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>& 243 token); 244 245 /** 246 * Creates a prepared model from cache files for execution. 247 * 248 * prepareModelFromCache is used to retrieve a prepared model directly from 249 * cache files to avoid slow model compilation time. There are 250 * two types of cache file handles provided to the driver: model cache 251 * and data cache. For more information on the two types of cache handles, 252 * refer to getNumberOfCacheFilesNeeded. 253 * 254 * The file descriptors must be opened with read and write permission. A file may 255 * have any size, and the corresponding file descriptor may have any offset. The 256 * driver must truncate a file to zero size before writing to that file. The file 257 * descriptors may be closed by the client once the asynchronous preparation has 258 * finished. The driver must dup a file descriptor if it wants to get access to 259 * the cache file later. 260 * 261 * The model is prepared synchronously with respect to the caller. The 262 * prepareModelFromCache function must verify the inputs to the 263 * prepareModelFromCache function are correct, and that the 264 * security-sensitive cache has not been modified since it was last written 265 * by the driver. If there is an error, or if compilation caching is not 266 * supported, or if the security-sensitive cache has been modified, 267 * prepareModelFromCache must return the appropriate ErrorStatus value and 268 * nullptr for the VersionedIPreparedModel. If the inputs to the 269 * prepareModelFromCache function are valid, the security-sensitive cache is 270 * not modified, and there is no error, prepareModelFromCache must prepare 271 * the model. 272 * 273 * If the model was prepared successfully, prepareModelFromCache must return 274 * ErrorStatus::NONE and the produced VersionedIPreparedModel object. If an 275 * error occurred preparing the model, prepareModelFromCache must return the 276 * appropriate ErrorStatus value and nullptr for the 277 * VersionedIPreparedModel. 278 * 279 * The only information that may be unknown to the model at this stage is 280 * the shape of the tensors, which may only be known at execution time. As 281 * such, some driver services may return partially prepared models, where 282 * the prepared model may only be finished when it is paired with a set of 283 * inputs to the model. Note that the same prepared model object may be 284 * used with different shapes of inputs on different (possibly concurrent) 285 * executions. 286 * 287 * @param modelCache A vector of handles with each entry holding exactly one 288 * cache file descriptor for the security-sensitive cache. The length of 289 * the vector must match the numModelCache returned from getNumberOfCacheFilesNeeded. 290 * The cache handles will be provided in the same order as with prepareModel_1_2. 291 * @param dataCache A vector of handles with each entry holding exactly one 292 * cache file descriptor for the constants' cache. The length of the vector 293 * must match the numDataCache returned from getNumberOfCacheFilesNeeded. 294 * The cache handles will be provided in the same order as with prepareModel_1_2. 295 * @param token A caching token of length Constant::BYTE_SIZE_OF_CACHE_TOKEN 296 * identifying the prepared model. It is the same token provided when saving 297 * the cache files with prepareModel_1_2. Tokens should be chosen 298 * to have a low rate of collision for a particular application. The driver 299 * cannot detect a collision; a collision will result in a failed execution 300 * or in a successful execution that produces incorrect output values. 301 * @return A pair of: 302 * - status Error status of preparing the model; must be: 303 * - NONE if preparation succeeded 304 * - DEVICE_UNAVAILABLE if driver is offline or busy 305 * - GENERAL_FAILURE if caching is not supported or if there is an 306 * unspecified error 307 * - INVALID_ARGUMENT if one of the input arguments is invalid 308 * - preparedModel A VersionedIPreparedModel object representing a model 309 * that has been prepared for execution, else nullptr. 310 */ 311 std::pair<ErrorStatus, std::shared_ptr<VersionedIPreparedModel>> prepareModelFromCache( 312 const hidl_vec<hidl_handle>& modelCache, const hidl_vec<hidl_handle>& dataCache, 313 const hidl_array<uint8_t, static_cast<uint32_t>(Constant::BYTE_SIZE_OF_CACHE_TOKEN)>& 314 token); 315 316 /** 317 * Returns the current status of a driver. 318 * 319 * @return status Status of the driver, one of: 320 * - DeviceStatus::AVAILABLE 321 * - DeviceStatus::BUSY 322 * - DeviceStatus::OFFLINE 323 * - DeviceStatus::UNKNOWN 324 */ 325 DeviceStatus getStatus(); 326 327 /** 328 * Returns the feature level of a driver. 329 * 330 * @return featureLevel The API level of the most advanced feature this driver implements. 331 * For example, if the driver implements the features introduced in 332 * Android P, the value would be 28. 333 * Return -1 if the driver is offline or busy, or the query resulted in 334 * an unspecified error. 335 */ 336 int64_t getFeatureLevel(); 337 338 /** 339 * Returns the device type of a driver. 340 * 341 * @return deviceType The type of a given device, which can help application developers 342 * developers to distribute Machine Learning workloads and other workloads 343 * such as graphical rendering. E.g., for an app which renders AR scenes 344 * based on real time object detection results, the developer could choose 345 * an ACCELERATOR type device for ML workloads, and reserve GPU for 346 * graphical rendering. 347 * Return -1 if the driver is offline or busy, or the query resulted in 348 * an unspecified error. 349 */ 350 int32_t getType() const; 351 352 /** 353 * Get the version string of the driver implementation. 354 * 355 * The version string must be a unique token among the set of version strings of 356 * drivers of a specific device. The token identifies the device driver's 357 * implementation. The token must not be confused with the feature level which is solely 358 * defined by the interface version. This API is opaque to the Android framework, but the 359 * Android framework may use the information for debugging or to pass on to NNAPI applications. 360 * 361 * Application developers sometimes have specific requirements to ensure good user experiences, 362 * and they need more information to make intelligent decisions when the Android framework 363 * cannot. For example, combined with the device name and other information, the token can help 364 * NNAPI applications filter devices based on their needs: 365 * - An application demands a certain level of performance, but a specific version of 366 * the driver cannot meet that requirement because of a performance regression. 367 * The application can blacklist the driver based on the version provided. 368 * - An application has a minimum precision requirement, but certain versions of 369 * the driver cannot meet that requirement because of bugs or certain optimizations. 370 * The application can filter out versions of these drivers. 371 * 372 * @return status Error status returned from querying the version string. Must be: 373 * - NONE if the query was successful 374 * - DEVICE_UNAVAILABLE if driver is offline or busy 375 * - GENERAL_FAILURE if the query resulted in an 376 * unspecified error 377 * @return version The version string of the device implementation. 378 * Must have nonzero length if the query is successful, and must be an empty string if not. 379 */ 380 std::pair<ErrorStatus, hidl_string> getVersionString(); 381 382 /** 383 * Gets the caching requirements of the driver implementation. 384 * 385 * There are two types of cache file descriptors provided to the driver: model cache 386 * and data cache. 387 * 388 * The data cache is for caching constant data, possibly including preprocessed 389 * and transformed tensor buffers. Any modification to the data cache should 390 * have no worse effect than generating bad output values at execution time. 391 * 392 * The model cache is for caching security-sensitive data such as compiled 393 * executable machine code in the device's native binary format. A modification 394 * to the model cache may affect the driver's execution behavior, and a malicious 395 * client could make use of this to execute beyond the granted permission. Thus, 396 * the driver must always check whether the model cache is corrupted before 397 * preparing the model from cache. 398 * 399 * getNumberOfCacheFilesNeeded returns how many of each type of cache files the driver 400 * implementation needs to cache a single prepared model. Returning 0 for both types 401 * indicates compilation caching is not supported by this driver. The driver may 402 * still choose not to cache certain compiled models even if it reports that caching 403 * is supported. 404 * 405 * If the device reports that caching is not supported, the user may avoid calling 406 * IDevice::prepareModelFromCache or providing cache file descriptors to 407 * IDevice::prepareModel_1_2. 408 * 409 * @return status Error status of the call, must be: 410 * - NONE if successful 411 * - DEVICE_UNAVAILABLE if driver is offline or busy 412 * - GENERAL_FAILURE if there is an unspecified error 413 * @return numModelCache An unsigned integer indicating how many files for model cache 414 * the driver needs to cache a single prepared model. It must 415 * be less than or equal to Constant::MAX_NUMBER_OF_CACHE_FILES. 416 * @return numDataCache An unsigned integer indicating how many files for data cache 417 * the driver needs to cache a single prepared model. It must 418 * be less than or equal to Constant::MAX_NUMBER_OF_CACHE_FILES. 419 */ 420 std::tuple<ErrorStatus, uint32_t, uint32_t> getNumberOfCacheFilesNeeded(); 421 422 /** 423 * Returns the name of the service that implements the driver 424 * 425 * @return serviceName The name of the service. 426 */ getServiceName()427 std::string getServiceName() const { return mServiceName; } 428 429 /** 430 * Returns whether this handle to an IDevice object is valid or not. 431 * 432 * @return bool true if V1_0::IDevice (which could be V1_1::IDevice) is 433 * valid, false otherwise. 434 */ 435 bool operator!=(nullptr_t) const; 436 437 /** 438 * Returns whether this handle to an IDevice object is valid or not. 439 * 440 * @return bool true if V1_0::IDevice (which could be V1_1::IDevice) is 441 * invalid, false otherwise. 442 */ 443 bool operator==(nullptr_t) const; 444 445 private: 446 /** 447 * This is a utility class for VersionedIDevice that encapsulates a 448 * V1_0::IDevice, any appropriate downcasts to newer interfaces, and a 449 * hidl_death_recipient that will proactively handle the case when the 450 * service containing the IDevice object crashes. 451 * 452 * This is a convenience class to help VersionedIDevice recover from an 453 * IDevice object crash: It bundles together all the data that needs to 454 * change when recovering from a crash, and simplifies the process of 455 * instantiating that data (at VersionedIDevice creation time) and 456 * re-instantiating that data (at crash recovery time). 457 */ 458 class Core { 459 public: 460 /** 461 * Constructor for the Core object. 462 * 463 * Core is constructed with a V1_0::IDevice object, which represents a 464 * device that is at least v1.0 of the interface. The constructor 465 * downcasts to the latest version of the IDevice interface, allowing 466 * VersionedIDevice to default to using the latest version of all 467 * IDevice interface methods automatically. 468 * 469 * @param device A device object that is at least version 1.0 of the IDevice 470 * interface. 471 * @param deathHandler A hidl_death_recipient that will proactively handle 472 * the case when the service containing the IDevice 473 * object crashes. 474 */ 475 Core(sp<V1_0::IDevice> device, sp<IDeviceDeathHandler> deathHandler); 476 477 /** 478 * Destructor for the Core object. 479 * 480 * This destructor unlinksToDeath this object's hidl_death_recipient as it 481 * no longer needs to handle the case where the IDevice's service crashes. 482 */ 483 ~Core(); 484 485 // Support move but not copy 486 Core(Core&&) noexcept; 487 Core& operator=(Core&&) noexcept; 488 Core(const Core&) = delete; 489 Core& operator=(const Core&) = delete; 490 491 /** 492 * Create a Core object. 493 * 494 * Prefer using this function over the constructor, as it adds more 495 * protections. 496 * 497 * This call linksToDeath a hidl_death_recipient that can 498 * proactively handle the case when the service containing the IDevice 499 * object crashes. 500 * 501 * @param device A device object that is at least version 1.0 of the IDevice 502 * interface. 503 * @return A valid Core object, otherwise nullopt. 504 */ 505 static std::optional<Core> create(sp<V1_0::IDevice> device); 506 507 /** 508 * Returns sp<*::IDevice> that is a downcast of the sp<V1_0::IDevice> 509 * passed to the constructor. This will be nullptr if that IDevice is 510 * not actually of the specified downcast type. 511 */ 512 template <typename T_IDevice> 513 sp<T_IDevice> getDevice() const; 514 template <> getDevice()515 sp<V1_0::IDevice> getDevice() const { 516 return mDeviceV1_0; 517 } 518 template <> getDevice()519 sp<V1_1::IDevice> getDevice() const { 520 return mDeviceV1_1; 521 } 522 template <> getDevice()523 sp<V1_2::IDevice> getDevice() const { 524 return mDeviceV1_2; 525 } 526 527 /** 528 * Returns sp<*::IDevice> (as per getDevice()) and the 529 * hidl_death_recipient that will proactively handle the case when the 530 * service containing the IDevice object crashes. 531 */ 532 template <typename T_IDevice> 533 std::pair<sp<T_IDevice>, sp<IDeviceDeathHandler>> getDeviceAndDeathHandler() const; 534 535 private: 536 /** 537 * All versions of IDevice are necessary because the driver could be v1.0, 538 * v1.1, or a later version. All these pointers logically represent the same 539 * object. 540 * 541 * The general strategy is: HIDL returns a V1_0 device object, which 542 * (if not nullptr) could be v1.0, v1.1, or a greater version. The V1_0 543 * object is then "dynamically cast" to a V1_1 object. If successful, 544 * mDeviceV1_1 will point to the same object as mDeviceV1_0; otherwise, 545 * mDeviceV1_1 will be nullptr. 546 * 547 * In general: 548 * * If the device is truly v1.0, mDeviceV1_0 will point to a valid object 549 * and mDeviceV1_1 will be nullptr. 550 * * If the device is truly v1.1 or later, both mDeviceV1_0 and mDeviceV1_1 551 * will point to the same valid object. 552 * 553 * Idiomatic usage: if mDeviceV1_1 is non-null, do V1_1 dispatch; otherwise, 554 * do V1_0 dispatch. 555 */ 556 sp<V1_0::IDevice> mDeviceV1_0; 557 sp<V1_1::IDevice> mDeviceV1_1; 558 sp<V1_2::IDevice> mDeviceV1_2; 559 560 /** 561 * HIDL callback to be invoked if the service for mDeviceV1_0 crashes. 562 * 563 * nullptr if this Core instance is a move victim and hence has no 564 * callback to be unlinked. 565 */ 566 sp<IDeviceDeathHandler> mDeathHandler; 567 }; 568 569 // This method retrieves the appropriate mCore.mDevice* field, under a read lock. 570 template <typename T_IDevice> getDevice()571 sp<T_IDevice> getDevice() const EXCLUDES(mMutex) { 572 std::shared_lock lock(mMutex); 573 return mCore.getDevice<T_IDevice>(); 574 } 575 576 // This method retrieves the appropriate mCore.mDevice* fields, under a read lock. 577 template <typename T_IDevice> getDeviceAndDeathHandler()578 auto getDeviceAndDeathHandler() const EXCLUDES(mMutex) { 579 std::shared_lock lock(mMutex); 580 return mCore.getDeviceAndDeathHandler<T_IDevice>(); 581 } 582 583 // This method calls the function fn in a manner that supports recovering 584 // from a driver crash: If the driver implementation is dead because the 585 // driver crashed either before the call to fn or during the call to fn, we 586 // will attempt to obtain a new instance of the same driver and call fn 587 // again. 588 // 589 // If a callback is provided, this method protects it against driver death 590 // and waits for it (callback->wait()). 591 template <typename T_Return, typename T_IDevice, typename T_Callback = std::nullptr_t> 592 Return<T_Return> recoverable(const char* context, 593 const std::function<Return<T_Return>(const sp<T_IDevice>&)>& fn, 594 const T_Callback& callback = nullptr) const EXCLUDES(mMutex); 595 596 // The name of the service that implements the driver. 597 const std::string mServiceName; 598 599 // Guards access to mCore. 600 mutable std::shared_mutex mMutex; 601 602 // Data that can be rewritten during driver recovery. Guarded againt 603 // synchronous access by a mutex: Any number of concurrent read accesses is 604 // permitted, but a write access excludes all other accesses. 605 mutable Core mCore GUARDED_BY(mMutex); 606 }; 607 608 /** This class wraps an IPreparedModel object of any version. */ 609 class VersionedIPreparedModel { 610 DISALLOW_IMPLICIT_CONSTRUCTORS(VersionedIPreparedModel); 611 612 public: 613 /** 614 * Constructor for the VersionedIPreparedModel object. 615 * 616 * This constructor should not be used directly. Instead, 617 * VersionedIPreparedModel should be created via 618 * VersionedIDevice::prepareModel*. 619 * 620 * VersionedIPreparedModel is constructed with the V1_0::IPreparedModel object, which 621 * represents a device that is at least v1.0 of the interface. The constructor downcasts 622 * to the latest version of the IPreparedModel interface, and will default to using the 623 * latest version of all IPreparedModel interface methods automatically. 624 * 625 * @param preparedModel A prepared model object that is least version 1.0 of the 626 * IPreparedModel interface. 627 * @param deathHandler A hidl_death_recipient that will proactively handle 628 * the case when the service containing the IDevice 629 * object crashes. 630 */ 631 VersionedIPreparedModel(sp<V1_0::IPreparedModel> preparedModel, 632 sp<IPreparedModelDeathHandler> deathHandler); 633 634 /** 635 * Destructor for the VersionedIPreparedModel object. 636 * 637 * This destructor unlinksToDeath this object's hidl_death_recipient as it 638 * no longer needs to handle the case where the IPreparedModel's service 639 * crashes. 640 */ 641 ~VersionedIPreparedModel(); 642 643 /** 644 * Launches an asynchronous execution on a prepared model. 645 * 646 * The execution is performed asynchronously with respect to the caller. 647 * execute must verify the inputs to the function are correct. If there is 648 * an error, execute must immediately invoke the callback with the 649 * appropriate ErrorStatus value, then return with the same ErrorStatus. If 650 * the inputs to the function are valid and there is no error, execute must 651 * launch an asynchronous task to perform the execution in the background, 652 * and immediately return with ErrorStatus::NONE. If the asynchronous task 653 * fails to launch, execute must immediately invoke the callback with 654 * ErrorStatus::GENERAL_FAILURE, then return with 655 * ErrorStatus::GENERAL_FAILURE. 656 * 657 * When the asynchronous task has finished its execution, it must 658 * immediately invoke the callback object provided as an input to the 659 * execute function. This callback must be provided with the ErrorStatus of 660 * the execution. 661 * 662 * If the prepared model was prepared from a model wherein all 663 * tensor operands have fully specified dimensions, and the inputs 664 * to the function are valid, then the execution should launch 665 * and complete successfully (ErrorStatus::NONE). There must be 666 * no failure unless the device itself is in a bad state. 667 * 668 * Multiple threads can call the execute and ExecuteSynchronously functions 669 * on the same VersionedIPreparedModel object concurrently with different 670 * requests. 671 * 672 * @param request The input and output information on which the prepared 673 * model is to be executed. 674 * @param measure Specifies whether or not to measure duration of the execution. 675 * @param callback A callback object used to return the error status of 676 * the execution. The callback object's notify function must 677 * be called exactly once, even if the execution was 678 * unsuccessful. 679 * @return status Error status of the call, must be: 680 * - NONE if task is successfully launched 681 * - DEVICE_UNAVAILABLE if driver is offline or busy 682 * - GENERAL_FAILURE if there is an unspecified error 683 * - OUTPUT_INSUFFICIENT_SIZE if provided output buffer is 684 * not large enough to store the resultant values 685 * - INVALID_ARGUMENT if one of the input arguments is 686 * invalid 687 */ 688 ErrorStatus execute(const Request& request, MeasureTiming timing, 689 const sp<ExecutionCallback>& callback); 690 691 /** 692 * Performs a synchronous execution on a prepared model. 693 * 694 * The execution is performed synchronously with respect to the caller. 695 * executeSynchronously must verify the inputs to the function are 696 * correct. If there is an error, executeSynchronously must immediately 697 * return with the appropriate ErrorStatus value. If the inputs to the 698 * function are valid and there is no error, executeSynchronously must 699 * perform the execution, and must not return until the execution is 700 * complete. 701 * 702 * If the prepared model was prepared from a model wherein all tensor 703 * operands have fully specified dimensions, and the inputs to the function 704 * are valid, then the execution should complete successfully 705 * (ErrorStatus::NONE). There must be no failure unless the device itself is 706 * in a bad state. 707 * 708 * Any number of calls to the execute and executeSynchronously 709 * functions, in any combination, may be made concurrently, even on the same 710 * VersionedIPreparedModel object. 711 * 712 * @param request The input and output information on which the prepared 713 * model is to be executed. 714 * @param measure Specifies whether or not to measure duration of the execution. 715 * @return status Error status of the execution, must be: 716 * - NONE if execution is performed successfully 717 * - DEVICE_UNAVAILABLE if driver is offline or busy 718 * - GENERAL_FAILURE if there is an unspecified error 719 * - OUTPUT_INSUFFICIENT_SIZE if at least one output 720 * operand buffer is not large enough to store the 721 * corresponding output 722 * - INVALID_ARGUMENT if one of the input arguments is 723 * invalid 724 * @return outputShapes A list of shape information of model output operands. 725 * The index into "outputShapes" corresponds with the index 726 * of the output operand in the Request outputs vector. 727 * outputShapes nust be empty unless the status is either 728 * NONE or OUTPUT_INSUFFICIENT_SIZE. outputShaps may be 729 * empty if the status is NONE and all model output operands 730 * are fully-specified at execution time. outputShapes must 731 * have the same number of elements as the number of model 732 * output operands if the status is OUTPUT_INSUFFICIENT_SIZE, 733 * or if the status is NONE and the model has at least one 734 * output operand that is not fully-specified. 735 * @return Timing Duration of execution. Unless measure is YES and status is 736 * NONE, all times must be reported as UINT64_MAX. A driver may 737 * choose to report any time as UINT64_MAX, indicating that 738 * measurement is not available. 739 */ 740 std::tuple<ErrorStatus, hidl_vec<OutputShape>, Timing> executeSynchronously( 741 const Request& request, MeasureTiming measure); 742 743 /** 744 * Creates a burst controller on a prepared model. 745 * 746 * @param blocking 'true' if the FMQ should block until data is available. 747 * @return ExecutionBurstController Execution burst controller object. 748 * nullptr is returned if the burst cannot 749 * be configured for any reason. 750 */ 751 std::shared_ptr<ExecutionBurstController> configureExecutionBurst(bool blocking) const; 752 753 /** 754 * Returns whether this handle to an IPreparedModel object is valid or not. 755 * 756 * @return bool true if V1_0::IPreparedModel (which could be V1_2::IPreparedModel) is 757 * valid, false otherwise. 758 */ 759 bool operator!=(nullptr_t) const; 760 761 /** 762 * Returns whether this handle to an IPreparedModel object is valid or not. 763 * 764 * @return bool true if V1_0::IPreparedModel (which could be V1_2::IPreparedModel) is 765 * invalid, false otherwise. 766 */ 767 bool operator==(nullptr_t) const; 768 769 private: 770 /** 771 * All versions of IPreparedModel are necessary because the preparedModel could be v1.0, 772 * v1.2, or a later version. All these pointers logically represent the same object. 773 * 774 * The general strategy is: HIDL returns a V1_0 prepared model object, which 775 * (if not nullptr) could be v1.0, v1.2, or a greater version. The V1_0 776 * object is then "dynamically cast" to a V1_2 object. If successful, 777 * mPreparedModelV1_2 will point to the same object as mPreparedModelV1_0; otherwise, 778 * mPreparedModelV1_2 will be nullptr. 779 * 780 * In general: 781 * * If the prepared model is truly v1.0, mPreparedModelV1_0 will point to a valid object 782 * and mPreparedModelV1_2 will be nullptr. 783 * * If the prepared model is truly v1.2 or later, both mPreparedModelV1_0 and 784 * mPreparedModelV1_2 will point to the same valid object. 785 * 786 * Idiomatic usage: if mPreparedModelV1_2 is non-null, do V1_2 dispatch; otherwise, 787 * do V1_0 dispatch. 788 */ 789 sp<V1_0::IPreparedModel> mPreparedModelV1_0; 790 sp<V1_2::IPreparedModel> mPreparedModelV1_2; 791 792 /** 793 * HIDL callback to be invoked if the service for mPreparedModelV1_0 crashes. 794 */ 795 const sp<IPreparedModelDeathHandler> mDeathHandler; 796 }; 797 798 } // namespace nn 799 } // namespace android 800 801 #endif // ANDROID_ML_NN_RUNTIME_VERSIONED_INTERFACES_H 802