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