1033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler/* 2033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * Copyright (C) 2017 The Android Open Source Project 3033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 4033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * Licensed under the Apache License, Version 2.0 (the "License"); 5033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * you may not use this file except in compliance with the License. 6033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * You may obtain a copy of the License at 7033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 8033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * http://www.apache.org/licenses/LICENSE-2.0 9033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 10033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * Unless required by applicable law or agreed to in writing, software 11033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * distributed under the License is distributed on an "AS IS" BASIS, 12033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * See the License for the specific language governing permissions and 14033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * limitations under the License. 15033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler */ 16033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 17033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler#ifndef ANDROID_HARDWARE_NEURALNETWORKS_V1_0_CALLBACKS_H 18033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler#define ANDROID_HARDWARE_NEURALNETWORKS_V1_0_CALLBACKS_H 19033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 20033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler#include <android/hardware/neuralnetworks/1.0/IExecutionCallback.h> 21033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler#include <android/hardware/neuralnetworks/1.0/IPreparedModelCallback.h> 22033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler#include <chrono> 23033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler#include <condition_variable> 24033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler#include <functional> 25033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler#include <hidl/MQDescriptor.h> 26033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler#include <hidl/Status.h> 27033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler#include <mutex> 28033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler#include <thread> 29033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 30033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlernamespace android { 31033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlernamespace hardware { 32033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlernamespace neuralnetworks { 33033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlernamespace V1_0 { 34033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlernamespace implementation { 35033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 36033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlerusing ::android::hardware::hidl_array; 37033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlerusing ::android::hardware::hidl_memory; 38033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlerusing ::android::hardware::hidl_string; 39033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlerusing ::android::hardware::hidl_vec; 40033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlerusing ::android::hardware::Return; 41033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlerusing ::android::hardware::Void; 42033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlerusing ::android::sp; 43033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 44033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler/** 45033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * The CallbackBase class is used internally by the NeuralNetworks runtime to 46033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * synchronize between different threads. An asynchronous task is launched 47033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * paired with a callback object. When a client thread requires the output being 48033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * generated by the asynchronous task, the client thread can wait for the result 49033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * and be blocked until it has completed or a timeout condition has been 50033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * reached. Any wait* may safely be called concurrently, even on the same 51033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * callback object. When the asynchronous task has finished its workload, it 52033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * must immediately call "notify". If the asynchronous task has failed to launch, 53033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * the function that tried to launch the asynchronous task must immediately call 54033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * "notify". This "notify" call awakens any client threads waiting on the 55033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * callback object. 56033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 57033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * The CallbackBase class implements some of the base synchronization common to 58033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * both PrepareModelCallback and ExecutionCallback. For consistency, any HIDL 59033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * callback class must inherit from CallbackBase as well as the HIDL callback 60033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * interface it implements. 61033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 62033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * This class exists to enable synchronization across HIDL. When synchronization 63033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * is only required in the same process, consider using std::future, std::mutex, 64033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * std::condition_variable, or std::experimental::latch instead. 65033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler */ 66033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlerclass CallbackBase { 67033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler public: 68033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler CallbackBase(); 69033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler ~CallbackBase(); 70033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 71033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler /** 72033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * CallbackBase::wait blocks until notify has been called on the callback 73033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * object. 74033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler */ 75033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler void wait(); 76033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 77033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler /** 78033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * CallbackBase::wait_for blocks until notify has been called on the 79033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * callback object or the time duration from the time the wait_for function 80033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * was called has expired, whichever comes first. 81033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 82033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * @return Status std::cv_status::no_timeout if the callback was notified 83033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * before the time duration expired, std::cv_status::timeout 84033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * otherwise. 85033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler */ 86033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler template<class Rep, class Period> 87033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler std::cv_status wait_for(const std::chrono::duration<Rep,Period>& timeout_duration); 88033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 89033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler /** 90033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * CallbackBase::on_finish binds a function to the callback object. This 91033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * bound function will be executed when CallbackBase::notify is called, 92033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * before any calls to wait* return. (Note that CallbackBase::wait_for can 93033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * return std::cv_status::timeout before CallbackBase::notify is called for 94033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * the first time, and hence before the bound function is executed.) 95033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 96033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * The bound function must not synchronize with or otherwise access the 97033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * callback object it is bound to, as this could cause a deadlock. 98033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 99033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * CallbackBase::on_finish can be called at most once on a given callback 100033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * object, and the call to CallbackBase::on_finish must finish before 101033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * CallbackBase::notify is called. 102033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 103033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * @param post_work Function to be invoked the first time 104033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * CallbackBase::notify is called. Must have a target -- 105033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * i.e., must not compare equal to nullptr. post_work 106033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * returns true if it successfully completes, false if it 107033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * fails. 108033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * @return bool True if the function was successfully bound, false if 109033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * unsuccessful. 110033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 111033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * TODO: Why does the return value of the callback matter? 112033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler */ 113033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler bool on_finish(std::function<bool(void)> post_work); 114033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 115033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler /** 116033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * CallbackBase::bind_thread binds a thread to the event for later use by 117033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * CallbackBase::join_thread. 118033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 119033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * The thread must be passed using std::move. 120033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 121033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * Once a thread is bound with CallbackBase::bind_thread, the client code 122033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * should ensure that one of the following occurs before the event is 123033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * destroyed: 124033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - CallbackBase::join_thread has been called. 125033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - CallbackBase::wait has been called. 126033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - CallbackBase::wait_for has been called and returned other than 127033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * std::cv_status::no_timeout. 128033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 129033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * The bound thread shall not call any CallbackBase method with the 130033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * exception of CallbackBase::notify, which it must call when the thread has 131033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * finished its computation. 132033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 133033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * CallbackBase::bind_thread can be called at most once on a given callback 134033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * object. 135033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 136033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * @param asyncThread Thread to be bound to the callback object. The thread 137033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * object must represent a thread of execution -- i.e., 138033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * asyncThread.joinable() must be true. 139033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * @return bool True if successful, false if thread was not properly bound. 140033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler */ 141033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler bool bind_thread(std::thread&& asyncThread); 142033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 143033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler /** 144033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * CallbackBase::join_thread ensures that the thread (if any) bound to this 145033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * event with CallbackBase::bind_thread has fully finished and cleaned its 146033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * resources. It is legal to call this function multiple times, concurrently 147033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * or sequentially. 148033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler */ 149033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler void join_thread(); 150033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 151033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler protected: 152033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler /** 153033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * CallbackBase::notify enables all prior and future wait* calls on the 154033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * callback object to proceed. The call to CallbackBase::notify happens 155033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * before any wait* calls on this callback object return (except in the case 156033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * of wait_for timing out). The asynchronous call the callback object is 157033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * paired with must ensure that any update to state that should be visible 158033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * to the caller of wait* happens before the call to CallbackBase::notify. 159033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 160033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * CallbackBase::notify must be called exactly once on a given callback 161033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * object. 162033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler */ 163033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler void notify(); 164033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 165033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler private: 166033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler // Same as CallbackBase::join_thread but assumes we already hold a lock on 167033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler // mMutex. 168033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler void join_thread_locked(); 169033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 170033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler bool mNotified; 171033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler std::mutex mMutex; 172033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler std::condition_variable mCondition; 173033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler std::function<bool(void)> mPostWork; 174033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler std::thread mThread; 175033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler}; 176033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 177033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler/** 178033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * The PreparedModelCallback class is used to receive the error status of 179033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * preparing a model as well as the prepared model from a task executing 180033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * asynchronously with respect to the runtime. If a calling thread calls wait* 181033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * or get* on a PreparedModelCallback object and the corresponding asynchronous 182033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * task has not finished preparing the model, the calling thread will block 183033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * until the asynchronous task has called notify. For more information on the 184033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * synchronization behavior, refer to the CallbackBase class. 185033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 186033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * This class inherits the basic blocking and signaling calls from 187033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * CallbackBase, and implements the HIDL notify call from 188033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * IPreparedModelCallback. This callback object is passed as an argument to 189033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * IDevice::prepareModel. 190033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler */ 191033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlerclass PreparedModelCallback : public CallbackBase, public IPreparedModelCallback { 192033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler public: 193033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler PreparedModelCallback(); 194033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler ~PreparedModelCallback() override; 195033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 196033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler /** 197033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * IPreparedModelCallback::notify marks the callback object with the return 198033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * status of the asynchronous model preparation along with the prepared 199033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * model, and calls CallbackBase::notify, enabling all prior and future 200033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * wait* calls on the PreparedModelCallback object to proceed. For more 201033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * information on the synchronization behavior, refer to the CallbackBase 202033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * class. 203033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 204033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * IPreparedModelCallback::notify must be called exactly once on a given 205033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * PreparedModelCallback object. 206033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 207033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * @param status Error status returned from asynchronously preparing the 208033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * model; will be: 209033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - NONE if the asynchronous preparation was successful 210033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - DEVICE_UNAVAILABLE if driver is offline or busy 211033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - GENERAL_FAILURE if there is an unspecified error 212033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - INVALID_ARGUMENT if the input model is invalid 213033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * @param preparedModel Returned model that has been prepared for execution, 214033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * nullptr if the model was unable to be prepared. 215033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler */ 216033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler Return<void> notify(ErrorStatus status, const sp<IPreparedModel>& preparedModel) override; 217033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 218033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler /** 219033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * Retrieves the error status returned from the asynchronous task launched 220033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * by IDevice::prepareModel. If IDevice::prepareModel has not finished 221033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * asynchronously preparing the model, this call will block until the 222033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * asynchronous task notifies the object. 223033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 224033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * @return status Error status returned from asynchronously preparing the 225033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * model; will be: 226033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - NONE if the asynchronous preparation was successful 227033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - DEVICE_UNAVAILABLE if driver is offline or busy 228033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - GENERAL_FAILURE if there is an unspecified error 229033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - INVALID_ARGUMENT if the input model is invalid 230033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler */ 231033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler ErrorStatus getStatus(); 232033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 233033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler /** 234033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * Retrieves the model that has been prepared for execution from the 235033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * asynchronous task launched by IDevice::prepareModel. If 236033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * IDevice::prepareModel has not finished asynchronously preparing the 237033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * model, this call will block until the asynchronous task notifies the 238033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * object. 239033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 240033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * @return preparedModel Returned model that has been prepared for 241033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * execution, nullptr if the model was unable to be 242033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * prepared. 243033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler */ 244033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler sp<IPreparedModel> getPreparedModel(); 245033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 246033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler private: 247033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler ErrorStatus mErrorStatus; 248033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler sp<IPreparedModel> mPreparedModel; 249033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler}; 250033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 251033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler/** 252033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * The ExecutionCallback class is used to receive the error status of the 253033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * execution from a task executing asynchronously with respect to the runtime. 254033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * If a calling thread calls wait* or get* on a PreparedModelCallback object and 255033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * the corresponding asynchronous task has not finished the execution, the 256033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * calling thread will block until the asynchronous task has called notify. For 257033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * more information on the synchronization behavior, refer to the CallbackBase 258033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * class. 259033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 260033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * This class inherits the basic blocking and signaling calls from 261033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * CallbackBase, and implements the HIDL notify call from 262033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * IExecutionCallback. This callback object is passed as an argument to 263033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * IPreparedModel::execute. 264033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler */ 265033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlerclass ExecutionCallback : public CallbackBase, public IExecutionCallback { 266033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler public: 267033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler ExecutionCallback(); 268033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler ~ExecutionCallback() override; 269033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 270033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler /** 271033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * IExecutionCallback::notify marks the callback object with the return 272033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * status of the asynchronous execution that held this callback and enables 273033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * all prior and future wait* calls on the ExecutionCallback object to 274033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * proceed. For more information on the synchronization behavior, refer to 275033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * the CallbackBase class. 276033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 277033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * IExecutionCallback::notify must be called exactly once on a given 278033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * ExecutionCallback object. 279033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 280033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * @param status Error status returned from asynchronously preparing the 281033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * model; will be: 282033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - NONE if the asynchronous execution was successful 283033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - DEVICE_UNAVAILABLE if driver is offline or busy 284033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - GENERAL_FAILURE if there is an unspecified error 285033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - OUTPUT_INSUFFICIENT_SIZE if provided output buffer is 286033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * not large enough to store the resultant values 287033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - INVALID_ARGUMENT if the input request is invalid 288033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler */ 289033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler Return<void> notify(ErrorStatus status) override; 290033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 291033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler /** 292033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * Retrieves the error status returned from the asynchronous task launched 293033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * by IPreparedModel::execute. If IPreparedModel::execute has not finished 294033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * asynchronously executing, this call will block until the asynchronous task 295033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * notifies the object. 296033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * 297033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * @return status Error status returned from asynchronously preparing the 298033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * model; will be: 299033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - NONE if the asynchronous execution was successful 300033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - DEVICE_UNAVAILABLE if driver is offline or busy 301033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - GENERAL_FAILURE if there is an unspecified error 302033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - OUTPUT_INSUFFICIENT_SIZE if provided output buffer is 303033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * not large enough to store the resultant values 304033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler * - INVALID_ARGUMENT if the input request is invalid 305033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler */ 306033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler ErrorStatus getStatus(); 307033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 308033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler private: 309033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler ErrorStatus mErrorStatus; 310033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler}; 311033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 312033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 313033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler// template function implementation(s) below this point 314033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 315033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlertemplate<class Rep, class Period> 316033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butlerstd::cv_status CallbackBase::wait_for(const std::chrono::duration<Rep,Period>& timeout_duration) { 317033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler std::unique_lock<std::mutex> lock(mMutex); 318033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler std::cv_status status = mCondition.wait_for(lock, timeout_duration, [this]{return mNotified;}); 319033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler if (status != std::cv_status::timeout) { 320033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler join_thread_locked(); 321033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler } 322033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler return status; 323033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler} 324033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 325033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler} // namespace implementation 326033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler} // namespace V1_0 327033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler} // namespace neuralnetworks 328033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler} // namespace hardware 329033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler} // namespace android 330033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler 331033b8a6ce8ebd2a01ecccc6bae96d0fff8d4964eMichael Butler#endif // ANDROID_HARDWARE_NEURALNETWORKS_V1_0_CALLBACKS_H 332