summaryrefslogtreecommitdiff
path: root/neuralnetworks/utils/adapter/aidl/src
diff options
context:
space:
mode:
authorXusong Wang <xusongw@google.com>2021-10-05 14:10:41 -0700
committerXusong Wang <xusongw@google.com>2022-01-18 10:51:29 -0800
commit11f30c81ef7d45fd97bf0dcc3f3ba2ae42689504 (patch)
tree251f0fb62aa0f9d55b4a0d121f41f73507261163 /neuralnetworks/utils/adapter/aidl/src
parent018fc3cac8b2361ad28a97685f9449a99326c9cd (diff)
Reusable execution at HAL level -- HAL.
This CL modifies the canonical/AIDL adapter to use IExecution object if available. Bug: 202405342 Bug: 202431255 Test: NNT_static Test: CtsNNAPITestCases Test: VtsHalNeuralnetworksTargetTest Change-Id: I6aac3c57f97ac87a5ba3f78cfd843fcc403decff Merged-In: I6aac3c57f97ac87a5ba3f78cfd843fcc403decff (cherry picked from commit 7f5c7d293c2dad462dc9c0f1f1a160fb2c2c9a9b)
Diffstat (limited to 'neuralnetworks/utils/adapter/aidl/src')
-rw-r--r--neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp99
1 files changed, 99 insertions, 0 deletions
diff --git a/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp b/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp
index 71ed1a857b..5cab62c625 100644
--- a/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp
+++ b/neuralnetworks/utils/adapter/aidl/src/PreparedModel.cpp
@@ -17,6 +17,7 @@
#include "PreparedModel.h"
#include "Burst.h"
+#include "Execution.h"
#include <aidl/android/hardware/neuralnetworks/BnFencedExecutionCallback.h>
#include <aidl/android/hardware/neuralnetworks/BnPreparedModel.h>
@@ -26,6 +27,7 @@
#include <aidl/android/hardware/neuralnetworks/Request.h>
#include <android-base/logging.h>
#include <android/binder_auto_utils.h>
+#include <nnapi/IExecution.h>
#include <nnapi/IPreparedModel.h>
#include <nnapi/Result.h>
#include <nnapi/SharedMemory.h>
@@ -167,6 +169,56 @@ nn::GeneralResult<FencedExecutionResult> executeFenced(
.syncFence = std::move(fileDescriptor)};
}
+nn::GeneralResult<nn::SharedExecution> createReusableExecution(
+ const nn::IPreparedModel& preparedModel, const Request& request, bool measureTiming,
+ int64_t loopTimeoutDurationNs) {
+ const auto nnRequest = NN_TRY(convertInput(request));
+ const auto nnMeasureTiming = measureTiming ? nn::MeasureTiming::YES : nn::MeasureTiming::NO;
+ const auto nnLoopTimeoutDuration = NN_TRY(makeOptionalDuration(loopTimeoutDurationNs));
+ return preparedModel.createReusableExecution(nnRequest, nnMeasureTiming, nnLoopTimeoutDuration);
+}
+
+nn::ExecutionResult<ExecutionResult> executeSynchronously(const nn::IExecution& execution,
+ int64_t deadlineNs) {
+ const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs));
+
+ const auto result = execution.compute(nnDeadline);
+
+ if (!result.ok() && result.error().code == nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) {
+ const auto& [message, code, outputShapes] = result.error();
+ LOG(ERROR) << "executeSynchronously failed with " << code << ": " << message;
+ return ExecutionResult{.outputSufficientSize = false,
+ .outputShapes = utils::convert(outputShapes).value(),
+ .timing = {.timeInDriverNs = -1, .timeOnDeviceNs = -1}};
+ }
+
+ const auto& [outputShapes, timing] = NN_TRY(result);
+ return ExecutionResult{.outputSufficientSize = true,
+ .outputShapes = utils::convert(outputShapes).value(),
+ .timing = utils::convert(timing).value()};
+}
+
+nn::GeneralResult<FencedExecutionResult> executeFenced(
+ const nn::IExecution& execution, const std::vector<ndk::ScopedFileDescriptor>& waitFor,
+ int64_t deadlineNs, int64_t durationNs) {
+ const auto nnWaitFor = NN_TRY(convertSyncFences(waitFor));
+ const auto nnDeadline = NN_TRY(makeOptionalTimePoint(deadlineNs));
+ const auto nnDuration = NN_TRY(makeOptionalDuration(durationNs));
+
+ auto [syncFence, executeFencedInfoCallback] =
+ NN_TRY(execution.computeFenced(nnWaitFor, nnDeadline, nnDuration));
+
+ ndk::ScopedFileDescriptor fileDescriptor;
+ if (syncFence.hasFd()) {
+ auto uniqueFd = NN_TRY(nn::dupFd(syncFence.getFd()));
+ fileDescriptor = ndk::ScopedFileDescriptor(uniqueFd.release());
+ }
+
+ return FencedExecutionResult{.callback = ndk::SharedRefBase::make<FencedExecutionCallback>(
+ std::move(executeFencedInfoCallback)),
+ .syncFence = std::move(fileDescriptor)};
+}
+
} // namespace
PreparedModel::PreparedModel(nn::SharedPreparedModel preparedModel)
@@ -222,4 +274,51 @@ nn::SharedPreparedModel PreparedModel::getUnderlyingPreparedModel() const {
return kPreparedModel;
}
+ndk::ScopedAStatus PreparedModel::createReusableExecution(const Request& request,
+ bool measureTiming,
+ int64_t loopTimeoutDurationNs,
+ std::shared_ptr<IExecution>* execution) {
+ auto result = adapter::createReusableExecution(*kPreparedModel, request, measureTiming,
+ loopTimeoutDurationNs);
+ if (!result.has_value()) {
+ const auto& [message, code] = result.error();
+ const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+ return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ static_cast<int32_t>(aidlCode), message.c_str());
+ }
+ *execution = ndk::SharedRefBase::make<Execution>(std::move(result).value());
+ return ndk::ScopedAStatus::ok();
+}
+
+Execution::Execution(nn::SharedExecution execution) : kExecution(std::move(execution)) {
+ CHECK(kExecution != nullptr);
+}
+
+ndk::ScopedAStatus Execution::executeSynchronously(int64_t deadlineNs,
+ ExecutionResult* executionResult) {
+ auto result = adapter::executeSynchronously(*kExecution, deadlineNs);
+ if (!result.has_value()) {
+ const auto& [message, code, _] = result.error();
+ const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+ return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ static_cast<int32_t>(aidlCode), message.c_str());
+ }
+ *executionResult = std::move(result).value();
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Execution::executeFenced(const std::vector<ndk::ScopedFileDescriptor>& waitFor,
+ int64_t deadlineNs, int64_t durationNs,
+ FencedExecutionResult* executionResult) {
+ auto result = adapter::executeFenced(*kExecution, waitFor, deadlineNs, durationNs);
+ if (!result.has_value()) {
+ const auto& [message, code] = result.error();
+ const auto aidlCode = utils::convert(code).value_or(ErrorStatus::GENERAL_FAILURE);
+ return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+ static_cast<int32_t>(aidlCode), message.c_str());
+ }
+ *executionResult = std::move(result).value();
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::neuralnetworks::adapter