You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
9.1 KiB
210 lines
9.1 KiB
/*
|
|
* Copyright (C) 2017 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef ANDROID_FRAMEWORKS_ML_NN_RUNTIME_TEST_PREPARED_MODEL_CALLBACK_H
|
|
#define ANDROID_FRAMEWORKS_ML_NN_RUNTIME_TEST_PREPARED_MODEL_CALLBACK_H
|
|
|
|
#include <HalInterfaces.h>
|
|
#include <Utils.h>
|
|
#include <android-base/thread_annotations.h>
|
|
#include <nnapi/Types.h>
|
|
|
|
#include <condition_variable>
|
|
#include <functional>
|
|
#include <mutex>
|
|
#include <thread>
|
|
#include <vector>
|
|
|
|
/*
|
|
* The Callback classes are used internally by the NeuralNetworks runtime to
|
|
* synchronize between different threads. An asynchronous task is launched
|
|
* paired with a callback object. When a client thread requires the output being
|
|
* generated by the asynchronous task, the client thread can wait for the result
|
|
* and be blocked until it has completed. Any wait may safely be called
|
|
* concurrently, even on the same callback object. When the asynchronous task
|
|
* has finished its workload, it must immediately call "notify*". If the
|
|
* asynchronous task has failed to launch, the function that tried to launch the
|
|
* asynchronous task must immediately call "notify*". This "notify*" call
|
|
* awakens any client threads waiting on the callback object.
|
|
*
|
|
* These classes exist to enable synchronization across HIDL. When
|
|
* synchronization is only required in the same process, consider using
|
|
* std::future, std::mutex, std::condition_variable, or std::experimental::latch
|
|
* instead.
|
|
*/
|
|
|
|
namespace android::nn {
|
|
|
|
/**
|
|
* The PreparedModelCallback class is used to receive the error status of
|
|
* preparing a model as well as the prepared model from a task executing
|
|
* asynchronously with respect to the runtime. If a calling thread calls wait
|
|
* or get* on a PreparedModelCallback object and the corresponding asynchronous
|
|
* task has not finished preparing the model, the calling thread will block
|
|
* until the asynchronous task has called notify*.
|
|
*
|
|
* If the callback object is notified more than once, only the results of the
|
|
* first call to notify* are used, and the results from subsequent calls are
|
|
* discarded.
|
|
*
|
|
* This callback object is passed as an argument to IDevice::prepareModel*.
|
|
*/
|
|
class PreparedModelCallback : public V1_3::IPreparedModelCallback {
|
|
public:
|
|
/**
|
|
* IPreparedModelCallback::notify marks the callback object with the return
|
|
* status of the asynchronous model preparation along with the prepared
|
|
* model, and allows all prior and future wait calls on the
|
|
* PreparedModelCallback object to proceed.
|
|
*
|
|
* One of IPreparedModelCallback::notify, IPreparedModelCallback::notify_1_2,
|
|
* or IPreparedModelCallback::notify_1_3 must be called on a given
|
|
* PreparedModelCallback object.
|
|
*
|
|
* If the callback object is notified more than once, only the results of
|
|
* the first call to notify* are used, and the results from subsequent calls
|
|
* are discarded.
|
|
*
|
|
* @param status Error status returned from asynchronously preparing the
|
|
* model; will be:
|
|
* - NONE if the asynchronous preparation was successful
|
|
* - DEVICE_UNAVAILABLE if driver is offline or busy
|
|
* - GENERAL_FAILURE if there is an unspecified error
|
|
* - INVALID_ARGUMENT if the input model is invalid
|
|
* @param preparedModel Returned model that has been prepared for execution,
|
|
* nullptr if the model was unable to be prepared.
|
|
*/
|
|
hardware::Return<void> notify(V1_0::ErrorStatus status,
|
|
const sp<V1_0::IPreparedModel>& preparedModel) override;
|
|
|
|
/**
|
|
* IPreparedModelCallback::notify_1_2 marks the callback object with the
|
|
* return status of the asynchronous model preparation along with the
|
|
* prepared model, and allows all prior and future wait calls on the
|
|
* PreparedModelCallback object to proceed.
|
|
*
|
|
* One of IPreparedModelCallback::notify, IPreparedModelCallback::notify_1_2,
|
|
* or IPreparedModelCallback::notify_1_3 must be called on a given
|
|
* PreparedModelCallback object.
|
|
*
|
|
* If the callback object is notified more than once, only the results of
|
|
* the first call to notify* are used, and the results from subsequent calls
|
|
* are discarded.
|
|
*
|
|
* @param status Error status returned from asynchronously preparing the
|
|
* model; will be:
|
|
* - NONE if the asynchronous preparation was successful
|
|
* - DEVICE_UNAVAILABLE if driver is offline or busy
|
|
* - GENERAL_FAILURE if there is an unspecified error
|
|
* - INVALID_ARGUMENT if the input model is invalid
|
|
* @param preparedModel Returned model that has been prepared for execution,
|
|
* nullptr if the model was unable to be prepared.
|
|
*/
|
|
hardware::Return<void> notify_1_2(V1_0::ErrorStatus status,
|
|
const sp<V1_2::IPreparedModel>& preparedModel) override;
|
|
|
|
/**
|
|
* IPreparedModelCallback::notify_1_3 marks the callback object with the
|
|
* return status of the asynchronous model preparation along with the
|
|
* prepared model, and allows all prior and future wait calls on the
|
|
* PreparedModelCallback object to proceed.
|
|
*
|
|
* One of IPreparedModelCallback::notify, IPreparedModelCallback::notify_1_2,
|
|
* or IPreparedModelCallback::notify_1_3 must be called on a given
|
|
* PreparedModelCallback object.
|
|
*
|
|
* If the callback object is notified more than once, only the results of
|
|
* the first call to notify* are used, and the results from subsequent calls
|
|
* are discarded.
|
|
*
|
|
* @param status Error status returned from asynchronously preparing the
|
|
* model; will be:
|
|
* - NONE if the asynchronous preparation was successful
|
|
* - DEVICE_UNAVAILABLE if driver is offline or busy
|
|
* - GENERAL_FAILURE if there is an unspecified error
|
|
* - INVALID_ARGUMENT if the input model is invalid
|
|
* - MISSED_DEADLINE_* if the deadline could not be met
|
|
* - RESOURCE_EXHAUSTED_* if the task was aborted by the driver
|
|
* @param preparedModel Returned model that has been prepared for execution,
|
|
* nullptr if the model was unable to be prepared.
|
|
*/
|
|
hardware::Return<void> notify_1_3(V1_3::ErrorStatus status,
|
|
const sp<V1_3::IPreparedModel>& preparedModel) override;
|
|
|
|
/**
|
|
* Mark the callback object as a dead object. This acts as a call to notify.
|
|
*/
|
|
void notifyAsDeadObject();
|
|
|
|
/**
|
|
* PreparedModelCallback::wait blocks until notify* has been called on the
|
|
* callback object.
|
|
*/
|
|
void wait() const;
|
|
|
|
/**
|
|
* Retrieves the error status returned from the asynchronous task launched
|
|
* by IDevice::prepareModel*. If IDevice::prepareModel* has not finished
|
|
* asynchronously preparing the model, this call will block until the
|
|
* asynchronous task notifies the object.
|
|
*
|
|
* @return status Error status returned from asynchronously preparing the
|
|
* model; will be:
|
|
* - NONE if the asynchronous preparation was successful
|
|
* - DEVICE_UNAVAILABLE if driver is offline or busy
|
|
* - GENERAL_FAILURE if there is an unspecified error
|
|
* - INVALID_ARGUMENT if the input model is invalid
|
|
* - MISSED_DEADLINE_* if the deadline could not be met
|
|
* - RESOURCE_EXHAUSTED_* if the task was aborted by the driver
|
|
* - DEAD_OBJECT if the driver crashed without returning a result
|
|
*/
|
|
ErrorStatus getStatus() const;
|
|
|
|
/**
|
|
* Retrieves the model that has been prepared for execution from the
|
|
* asynchronous task launched by IDevice::prepareModel*. If
|
|
* IDevice::prepareModel* has not finished asynchronously preparing the
|
|
* model, this call will block until the asynchronous task notifies the
|
|
* object.
|
|
*
|
|
* @return preparedModel Returned model that has been prepared for
|
|
* execution, nullptr if the model was unable to be prepared.
|
|
*/
|
|
sp<V1_0::IPreparedModel> getPreparedModel() const;
|
|
|
|
/**
|
|
* Queries whether the object is dead.
|
|
*
|
|
* @return 'true' if dead, 'false' otherwise.
|
|
*/
|
|
bool isDeadObject() const;
|
|
|
|
private:
|
|
hardware::Return<void> notifyInternal(bool deadObject, ErrorStatus errorStatus,
|
|
const sp<V1_0::IPreparedModel>& preparedModel);
|
|
|
|
mutable std::mutex mMutex;
|
|
mutable std::condition_variable mCondition;
|
|
bool mNotified GUARDED_BY(mMutex) = false;
|
|
bool mDeadObject = false;
|
|
ErrorStatus mErrorStatus = ErrorStatus::GENERAL_FAILURE;
|
|
sp<V1_0::IPreparedModel> mPreparedModel;
|
|
};
|
|
|
|
} // namespace android::nn
|
|
|
|
#endif // ANDROID_FRAMEWORKS_ML_NN_RUNTIME_TEST_PREPARED_MODEL_CALLBACK_H
|