summaryrefslogtreecommitdiff
path: root/neuralnetworks/1.2/utils/src
diff options
context:
space:
mode:
Diffstat (limited to 'neuralnetworks/1.2/utils/src')
-rw-r--r--neuralnetworks/1.2/utils/src/Burst.cpp (renamed from neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp)155
-rw-r--r--neuralnetworks/1.2/utils/src/BurstUtils.cpp (renamed from neuralnetworks/1.2/utils/src/ExecutionBurstUtils.cpp)6
-rw-r--r--neuralnetworks/1.2/utils/src/Callbacks.cpp11
-rw-r--r--neuralnetworks/1.2/utils/src/Conversions.cpp126
-rw-r--r--neuralnetworks/1.2/utils/src/Device.cpp24
-rw-r--r--neuralnetworks/1.2/utils/src/Execution.cpp1
-rw-r--r--neuralnetworks/1.2/utils/src/ExecutionBurstServer.cpp268
-rw-r--r--neuralnetworks/1.2/utils/src/PreparedModel.cpp52
8 files changed, 189 insertions, 454 deletions
diff --git a/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp b/neuralnetworks/1.2/utils/src/Burst.cpp
index b4b6f680d3..23e80709a0 100644
--- a/neuralnetworks/1.2/utils/src/ExecutionBurstController.cpp
+++ b/neuralnetworks/1.2/utils/src/Burst.cpp
@@ -14,10 +14,8 @@
* limitations under the License.
*/
-#define LOG_TAG "ExecutionBurstController"
-
-#include "ExecutionBurstController.h"
-#include "ExecutionBurstUtils.h"
+#include "Burst.h"
+#include "BurstUtils.h"
#include <android-base/logging.h>
#include <android-base/thread_annotations.h>
@@ -28,9 +26,9 @@
#include <nnapi/Types.h>
#include <nnapi/Validation.h>
#include <nnapi/hal/1.0/Conversions.h>
+#include <nnapi/hal/1.0/HandleError.h>
+#include <nnapi/hal/1.0/ProtectCallback.h>
#include <nnapi/hal/CommonUtils.h>
-#include <nnapi/hal/HandleError.h>
-#include <nnapi/hal/ProtectCallback.h>
#include <nnapi/hal/TransferValue.h>
#include <algorithm>
@@ -57,14 +55,13 @@ class BurstExecution final : public nn::IExecution,
public:
static nn::GeneralResult<std::shared_ptr<const BurstExecution>> create(
- std::shared_ptr<const ExecutionBurstController> controller,
- std::vector<FmqRequestDatum> request, hal::utils::RequestRelocation relocation,
- std::vector<ExecutionBurstController::OptionalCacheHold> cacheHolds);
+ std::shared_ptr<const Burst> controller, std::vector<FmqRequestDatum> request,
+ hal::utils::RequestRelocation relocation,
+ std::vector<Burst::OptionalCacheHold> cacheHolds);
- BurstExecution(PrivateConstructorTag tag,
- std::shared_ptr<const ExecutionBurstController> controller,
+ BurstExecution(PrivateConstructorTag tag, std::shared_ptr<const Burst> controller,
std::vector<FmqRequestDatum> request, hal::utils::RequestRelocation relocation,
- std::vector<ExecutionBurstController::OptionalCacheHold> cacheHolds);
+ std::vector<Burst::OptionalCacheHold> cacheHolds);
nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> compute(
const nn::OptionalTimePoint& deadline) const override;
@@ -74,16 +71,16 @@ class BurstExecution final : public nn::IExecution,
const nn::OptionalDuration& timeoutDurationAfterFence) const override;
private:
- const std::shared_ptr<const ExecutionBurstController> kController;
+ const std::shared_ptr<const Burst> kController;
const std::vector<FmqRequestDatum> kRequest;
const hal::utils::RequestRelocation kRelocation;
- const std::vector<ExecutionBurstController::OptionalCacheHold> kCacheHolds;
+ const std::vector<Burst::OptionalCacheHold> kCacheHolds;
};
nn::GeneralResult<sp<IBurstContext>> executionBurstResultCallback(
V1_0::ErrorStatus status, const sp<IBurstContext>& burstContext) {
- HANDLE_HAL_STATUS(status) << "IPreparedModel::configureExecutionBurst failed with status "
- << toString(status);
+ HANDLE_STATUS_HIDL(status) << "IPreparedModel::configureExecutionBurst failed with status "
+ << toString(status);
if (burstContext == nullptr) {
return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
<< "IPreparedModel::configureExecutionBurst returned nullptr for burst";
@@ -92,8 +89,7 @@ nn::GeneralResult<sp<IBurstContext>> executionBurstResultCallback(
}
nn::GeneralResult<hidl_vec<hidl_memory>> getMemoriesHelper(
- const hidl_vec<int32_t>& slots,
- const std::shared_ptr<ExecutionBurstController::MemoryCache>& memoryCache) {
+ const hidl_vec<int32_t>& slots, const std::shared_ptr<Burst::MemoryCache>& memoryCache) {
hidl_vec<hidl_memory> memories(slots.size());
for (size_t i = 0; i < slots.size(); ++i) {
const int32_t slot = slots[i];
@@ -110,7 +106,7 @@ nn::GeneralResult<hidl_vec<hidl_memory>> getMemoriesHelper(
// MemoryCache methods
-ExecutionBurstController::MemoryCache::MemoryCache() {
+Burst::MemoryCache::MemoryCache() {
constexpr size_t kPreallocatedCount = 1024;
std::vector<int32_t> freeSlotsSpace;
freeSlotsSpace.reserve(kPreallocatedCount);
@@ -119,13 +115,13 @@ ExecutionBurstController::MemoryCache::MemoryCache() {
mCacheCleaner.reserve(kPreallocatedCount);
}
-void ExecutionBurstController::MemoryCache::setBurstContext(sp<IBurstContext> burstContext) {
+void Burst::MemoryCache::setBurstContext(sp<IBurstContext> burstContext) {
std::lock_guard guard(mMutex);
mBurstContext = std::move(burstContext);
}
-std::pair<int32_t, ExecutionBurstController::MemoryCache::SharedCleanup>
-ExecutionBurstController::MemoryCache::cacheMemory(const nn::SharedMemory& memory) {
+std::pair<int32_t, Burst::MemoryCache::SharedCleanup> Burst::MemoryCache::cacheMemory(
+ const nn::SharedMemory& memory) {
std::unique_lock lock(mMutex);
base::ScopedLockAssertion lockAssert(mMutex);
@@ -163,7 +159,7 @@ ExecutionBurstController::MemoryCache::cacheMemory(const nn::SharedMemory& memor
return std::make_pair(slot, std::move(cleaner));
}
-nn::GeneralResult<nn::SharedMemory> ExecutionBurstController::MemoryCache::getMemory(int32_t slot) {
+nn::GeneralResult<nn::SharedMemory> Burst::MemoryCache::getMemory(int32_t slot) {
std::lock_guard guard(mMutex);
if (slot < 0 || static_cast<size_t>(slot) >= mMemoryCache.size()) {
return NN_ERROR() << "Invalid slot: " << slot << " vs " << mMemoryCache.size();
@@ -171,12 +167,15 @@ nn::GeneralResult<nn::SharedMemory> ExecutionBurstController::MemoryCache::getMe
return mMemoryCache[slot];
}
-void ExecutionBurstController::MemoryCache::freeMemory(const nn::SharedMemory& memory) {
+void Burst::MemoryCache::freeMemory(const nn::SharedMemory& memory) {
{
std::lock_guard guard(mMutex);
const int32_t slot = mMemoryIdToSlot.at(memory);
if (mBurstContext) {
- mBurstContext->freeMemory(slot);
+ const auto ret = mBurstContext->freeMemory(slot);
+ if (!ret.isOk()) {
+ LOG(ERROR) << "IBustContext::freeMemory failed: " << ret.description();
+ }
}
mMemoryIdToSlot.erase(memory);
mMemoryCache[slot] = {};
@@ -186,7 +185,7 @@ void ExecutionBurstController::MemoryCache::freeMemory(const nn::SharedMemory& m
mCond.notify_all();
}
-int32_t ExecutionBurstController::MemoryCache::allocateSlotLocked() {
+int32_t Burst::MemoryCache::allocateSlotLocked() {
constexpr size_t kMaxNumberOfSlots = std::numeric_limits<int32_t>::max();
// If there is a free slot, use it.
@@ -207,18 +206,18 @@ int32_t ExecutionBurstController::MemoryCache::allocateSlotLocked() {
// ExecutionBurstCallback methods
-ExecutionBurstController::ExecutionBurstCallback::ExecutionBurstCallback(
+Burst::ExecutionBurstCallback::ExecutionBurstCallback(
const std::shared_ptr<MemoryCache>& memoryCache)
: kMemoryCache(memoryCache) {
CHECK(memoryCache != nullptr);
}
-Return<void> ExecutionBurstController::ExecutionBurstCallback::getMemories(
- const hidl_vec<int32_t>& slots, getMemories_cb cb) {
+Return<void> Burst::ExecutionBurstCallback::getMemories(const hidl_vec<int32_t>& slots,
+ getMemories_cb cb) {
const auto memoryCache = kMemoryCache.lock();
if (memoryCache == nullptr) {
- LOG(ERROR) << "ExecutionBurstController::ExecutionBurstCallback::getMemories called after "
- "the MemoryCache has been freed";
+ LOG(ERROR) << "Burst::ExecutionBurstCallback::getMemories called after the MemoryCache has "
+ "been freed";
cb(V1_0::ErrorStatus::GENERAL_FAILURE, {});
return Void();
}
@@ -226,8 +225,8 @@ Return<void> ExecutionBurstController::ExecutionBurstCallback::getMemories(
const auto maybeMemories = getMemoriesHelper(slots, memoryCache);
if (!maybeMemories.has_value()) {
const auto& [message, code] = maybeMemories.error();
- LOG(ERROR) << "ExecutionBurstController::ExecutionBurstCallback::getMemories failed with "
- << code << ": " << message;
+ LOG(ERROR) << "Burst::ExecutionBurstCallback::getMemories failed with " << code << ": "
+ << message;
cb(V1_0::ErrorStatus::INVALID_ARGUMENT, {});
return Void();
}
@@ -236,14 +235,14 @@ Return<void> ExecutionBurstController::ExecutionBurstCallback::getMemories(
return Void();
}
-// ExecutionBurstController methods
+// Burst methods
-nn::GeneralResult<std::shared_ptr<const ExecutionBurstController>> ExecutionBurstController::create(
+nn::GeneralResult<std::shared_ptr<const Burst>> Burst::create(
nn::SharedPreparedModel preparedModel, const sp<V1_2::IPreparedModel>& hidlPreparedModel,
std::chrono::microseconds pollingTimeWindow) {
// check inputs
if (preparedModel == nullptr || hidlPreparedModel == nullptr) {
- return NN_ERROR() << "ExecutionBurstController::create passed a nullptr";
+ return NN_ERROR() << "Burst::create passed a nullptr";
}
// create FMQ objects
@@ -279,18 +278,18 @@ nn::GeneralResult<std::shared_ptr<const ExecutionBurstController>> ExecutionBurs
deathHandler.protectCallbackForLifetimeOfDeathHandler(resultChannelReceiver.get());
// make and return controller
- return std::make_shared<const ExecutionBurstController>(
+ return std::make_shared<const Burst>(
PrivateConstructorTag{}, std::move(preparedModel), std::move(requestChannelSender),
std::move(resultChannelReceiver), std::move(burstCallback), std::move(burstContext),
std::move(memoryCache), std::move(deathHandler));
}
-ExecutionBurstController::ExecutionBurstController(
- PrivateConstructorTag /*tag*/, nn::SharedPreparedModel preparedModel,
- std::unique_ptr<RequestChannelSender> requestChannelSender,
- std::unique_ptr<ResultChannelReceiver> resultChannelReceiver,
- sp<ExecutionBurstCallback> callback, sp<IBurstContext> burstContext,
- std::shared_ptr<MemoryCache> memoryCache, neuralnetworks::utils::DeathHandler deathHandler)
+Burst::Burst(PrivateConstructorTag /*tag*/, nn::SharedPreparedModel preparedModel,
+ std::unique_ptr<RequestChannelSender> requestChannelSender,
+ std::unique_ptr<ResultChannelReceiver> resultChannelReceiver,
+ sp<ExecutionBurstCallback> callback, sp<IBurstContext> burstContext,
+ std::shared_ptr<MemoryCache> memoryCache,
+ neuralnetworks::utils::DeathHandler deathHandler)
: kPreparedModel(std::move(preparedModel)),
mRequestChannelSender(std::move(requestChannelSender)),
mResultChannelReceiver(std::move(resultChannelReceiver)),
@@ -299,44 +298,41 @@ ExecutionBurstController::ExecutionBurstController(
mMemoryCache(std::move(memoryCache)),
kDeathHandler(std::move(deathHandler)) {}
-ExecutionBurstController::OptionalCacheHold ExecutionBurstController::cacheMemory(
- const nn::SharedMemory& memory) const {
+Burst::OptionalCacheHold Burst::cacheMemory(const nn::SharedMemory& memory) const {
auto [slot, hold] = mMemoryCache->cacheMemory(memory);
return hold;
}
-nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>>
-ExecutionBurstController::execute(const nn::Request& request, nn::MeasureTiming measure,
- const nn::OptionalTimePoint& deadline,
- const nn::OptionalDuration& loopTimeoutDuration) const {
+nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> Burst::execute(
+ const nn::Request& request, nn::MeasureTiming measure,
+ const nn::OptionalTimePoint& deadline, const nn::OptionalDuration& loopTimeoutDuration,
+ const std::vector<nn::TokenValuePair>& /*hints*/,
+ const std::vector<nn::ExtensionNameAndPrefix>& /*extensionNameToPrefix*/) const {
// This is the first point when we know an execution is occurring, so begin to collect
// systraces. Note that the first point we can begin collecting systraces in
// ExecutionBurstServer is when the RequestChannelReceiver realizes there is data in the FMQ, so
// ExecutionBurstServer collects systraces at different points in the code.
- NNTRACE_RT(NNTRACE_PHASE_EXECUTION, "ExecutionBurstController::execute");
+ NNTRACE_RT(NNTRACE_PHASE_EXECUTION, "Burst::execute");
// if the request is valid but of a higher version than what's supported in burst execution,
// fall back to another execution path
- if (const auto version = NN_TRY(hal::utils::makeExecutionFailure(nn::validate(request)));
- version > nn::Version::ANDROID_Q) {
+ if (!compliantVersion(request).ok()) {
// fallback to another execution path if the packet could not be sent
- return kPreparedModel->execute(request, measure, deadline, loopTimeoutDuration);
+ return kPreparedModel->execute(request, measure, deadline, loopTimeoutDuration, {}, {});
}
// ensure that request is ready for IPC
std::optional<nn::Request> maybeRequestInShared;
hal::utils::RequestRelocation relocation;
- const nn::Request& requestInShared =
- NN_TRY(hal::utils::makeExecutionFailure(hal::utils::convertRequestFromPointerToShared(
- &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding,
- &maybeRequestInShared, &relocation)));
+ const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared(
+ &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding,
+ &maybeRequestInShared, &relocation));
// clear pools field of request, as they will be provided via slots
const auto requestWithoutPools = nn::Request{
.inputs = requestInShared.inputs, .outputs = requestInShared.outputs, .pools = {}};
- auto hidlRequest = NN_TRY(
- hal::utils::makeExecutionFailure(V1_0::utils::unvalidatedConvert(requestWithoutPools)));
- const auto hidlMeasure = NN_TRY(hal::utils::makeExecutionFailure(convert(measure)));
+ auto hidlRequest = NN_TRY(V1_0::utils::unvalidatedConvert(requestWithoutPools));
+ const auto hidlMeasure = NN_TRY(convert(measure));
std::vector<int32_t> slots;
std::vector<OptionalCacheHold> holds;
@@ -351,23 +347,25 @@ ExecutionBurstController::execute(const nn::Request& request, nn::MeasureTiming
// send request packet
const auto requestPacket = serialize(hidlRequest, hidlMeasure, slots);
const auto fallback = [this, &request, measure, &deadline, &loopTimeoutDuration] {
- return kPreparedModel->execute(request, measure, deadline, loopTimeoutDuration);
+ return kPreparedModel->execute(request, measure, deadline, loopTimeoutDuration, {}, {});
};
return executeInternal(requestPacket, relocation, fallback);
}
// See IBurst::createReusableExecution for information on this method.
-nn::GeneralResult<nn::SharedExecution> ExecutionBurstController::createReusableExecution(
+nn::GeneralResult<nn::SharedExecution> Burst::createReusableExecution(
const nn::Request& request, nn::MeasureTiming measure,
- const nn::OptionalDuration& loopTimeoutDuration) const {
- NNTRACE_RT(NNTRACE_PHASE_EXECUTION, "ExecutionBurstController::createReusableExecution");
+ const nn::OptionalDuration& loopTimeoutDuration,
+ const std::vector<nn::TokenValuePair>& /*hints*/,
+ const std::vector<nn::ExtensionNameAndPrefix>& /*extensionNameToPrefix*/) const {
+ NNTRACE_RT(NNTRACE_PHASE_EXECUTION, "Burst::createReusableExecution");
// if the request is valid but of a higher version than what's supported in burst execution,
// fall back to another execution path
- if (const auto version = NN_TRY(hal::utils::makeGeneralFailure(nn::validate(request)));
- version > nn::Version::ANDROID_Q) {
+ if (!compliantVersion(request).ok()) {
// fallback to another execution path if the packet could not be sent
- return kPreparedModel->createReusableExecution(request, measure, loopTimeoutDuration);
+ return kPreparedModel->createReusableExecution(request, measure, loopTimeoutDuration, {},
+ {});
}
// ensure that request is ready for IPC
@@ -398,12 +396,10 @@ nn::GeneralResult<nn::SharedExecution> ExecutionBurstController::createReusableE
std::move(relocation), std::move(holds));
}
-nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>>
-ExecutionBurstController::executeInternal(const std::vector<FmqRequestDatum>& requestPacket,
- const hal::utils::RequestRelocation& relocation,
- FallbackFunction fallback) const {
- NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION,
- "ExecutionBurstController::executeInternal");
+nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> Burst::executeInternal(
+ const std::vector<FmqRequestDatum>& requestPacket,
+ const hal::utils::RequestRelocation& relocation, FallbackFunction fallback) const {
+ NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION, "Burst::executeInternal");
// Ensure that at most one execution is in flight at any given time.
const bool alreadyInFlight = mExecutionInFlight.test_and_set();
@@ -427,8 +423,7 @@ ExecutionBurstController::executeInternal(const std::vector<FmqRequestDatum>& re
}
// get result packet
- const auto [status, outputShapes, timing] =
- NN_TRY(hal::utils::makeExecutionFailure(mResultChannelReceiver->getBlocking()));
+ const auto [status, outputShapes, timing] = NN_TRY(mResultChannelReceiver->getBlocking());
if (relocation.output) {
relocation.output->flush();
@@ -437,9 +432,9 @@ ExecutionBurstController::executeInternal(const std::vector<FmqRequestDatum>& re
}
nn::GeneralResult<std::shared_ptr<const BurstExecution>> BurstExecution::create(
- std::shared_ptr<const ExecutionBurstController> controller,
- std::vector<FmqRequestDatum> request, hal::utils::RequestRelocation relocation,
- std::vector<ExecutionBurstController::OptionalCacheHold> cacheHolds) {
+ std::shared_ptr<const Burst> controller, std::vector<FmqRequestDatum> request,
+ hal::utils::RequestRelocation relocation,
+ std::vector<Burst::OptionalCacheHold> cacheHolds) {
if (controller == nullptr) {
return NN_ERROR() << "V1_2::utils::BurstExecution::create must have non-null controller";
}
@@ -450,10 +445,10 @@ nn::GeneralResult<std::shared_ptr<const BurstExecution>> BurstExecution::create(
}
BurstExecution::BurstExecution(PrivateConstructorTag /*tag*/,
- std::shared_ptr<const ExecutionBurstController> controller,
+ std::shared_ptr<const Burst> controller,
std::vector<FmqRequestDatum> request,
hal::utils::RequestRelocation relocation,
- std::vector<ExecutionBurstController::OptionalCacheHold> cacheHolds)
+ std::vector<Burst::OptionalCacheHold> cacheHolds)
: kController(std::move(controller)),
kRequest(std::move(request)),
kRelocation(std::move(relocation)),
diff --git a/neuralnetworks/1.2/utils/src/ExecutionBurstUtils.cpp b/neuralnetworks/1.2/utils/src/BurstUtils.cpp
index 38710cf3fd..c4c096da2d 100644
--- a/neuralnetworks/1.2/utils/src/ExecutionBurstUtils.cpp
+++ b/neuralnetworks/1.2/utils/src/BurstUtils.cpp
@@ -14,9 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "ExecutionBurstUtils"
-
-#include "ExecutionBurstUtils.h"
+#include "BurstUtils.h"
#include <android-base/logging.h>
#include <android-base/properties.h>
@@ -27,7 +25,7 @@
#include <hidl/MQDescriptor.h>
#include <nnapi/Result.h>
#include <nnapi/Types.h>
-#include <nnapi/hal/ProtectCallback.h>
+#include <nnapi/hal/1.0/ProtectCallback.h>
#include <atomic>
#include <chrono>
diff --git a/neuralnetworks/1.2/utils/src/Callbacks.cpp b/neuralnetworks/1.2/utils/src/Callbacks.cpp
index 9f54bb12dd..cb61f21775 100644
--- a/neuralnetworks/1.2/utils/src/Callbacks.cpp
+++ b/neuralnetworks/1.2/utils/src/Callbacks.cpp
@@ -29,10 +29,10 @@
#include <nnapi/Types.h>
#include <nnapi/hal/1.0/Callbacks.h>
#include <nnapi/hal/1.0/Conversions.h>
+#include <nnapi/hal/1.0/HandleError.h>
#include <nnapi/hal/1.0/PreparedModel.h>
+#include <nnapi/hal/1.0/ProtectCallback.h>
#include <nnapi/hal/CommonUtils.h>
-#include <nnapi/hal/HandleError.h>
-#include <nnapi/hal/ProtectCallback.h>
#include <nnapi/hal/TransferValue.h>
#include <utility>
@@ -62,7 +62,7 @@ convertExecutionGeneralResultsHelper(const hidl_vec<OutputShape>& outputShapes,
nn::GeneralResult<nn::SharedPreparedModel> prepareModelCallback(
V1_0::ErrorStatus status, const sp<IPreparedModel>& preparedModel) {
- HANDLE_HAL_STATUS(status) << "model preparation failed with " << toString(status);
+ HANDLE_STATUS_HIDL(status) << "model preparation failed with " << toString(status);
return NN_TRY(PreparedModel::create(preparedModel, /*executeSynchronously=*/true));
}
@@ -74,9 +74,8 @@ nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> executi
return NN_ERROR(nn::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE, std::move(canonicalOutputShapes))
<< "execution failed with " << toString(status);
}
- HANDLE_HAL_STATUS(status) << "execution failed with " << toString(status);
- return hal::utils::makeExecutionFailure(
- convertExecutionGeneralResultsHelper(outputShapes, timing));
+ HANDLE_STATUS_HIDL(status) << "execution failed with " << toString(status);
+ return convertExecutionGeneralResultsHelper(outputShapes, timing);
}
Return<void> PreparedModelCallback::notify(V1_0::ErrorStatus status,
diff --git a/neuralnetworks/1.2/utils/src/Conversions.cpp b/neuralnetworks/1.2/utils/src/Conversions.cpp
index 29945b75e5..78d71cf990 100644
--- a/neuralnetworks/1.2/utils/src/Conversions.cpp
+++ b/neuralnetworks/1.2/utils/src/Conversions.cpp
@@ -28,7 +28,6 @@
#include <nnapi/hal/1.0/Conversions.h>
#include <nnapi/hal/1.1/Conversions.h>
#include <nnapi/hal/CommonUtils.h>
-#include <nnapi/hal/HandleError.h>
#include <algorithm>
#include <functional>
@@ -120,9 +119,8 @@ GeneralResult<Capabilities> unvalidatedConvert(const hal::V1_2::Capabilities& ca
NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
auto operandPerformance = NN_TRY(unvalidatedConvert(capabilities.operandPerformance));
- auto table = NN_TRY(hal::utils::makeGeneralFailure(
- Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)),
- nn::ErrorStatus::GENERAL_FAILURE));
+ auto table =
+ NN_TRY(Capabilities::OperandPerformanceTable::create(std::move(operandPerformance)));
return Capabilities{
.relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
@@ -133,15 +131,18 @@ GeneralResult<Capabilities> unvalidatedConvert(const hal::V1_2::Capabilities& ca
GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
const hal::V1_2::Capabilities::OperandPerformance& operandPerformance) {
+ const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
+ const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
return Capabilities::OperandPerformance{
- .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
- .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
+ .type = type,
+ .info = info,
};
}
GeneralResult<Operation> unvalidatedConvert(const hal::V1_2::Operation& operation) {
+ const auto type = NN_TRY(unvalidatedConvert(operation.type));
return Operation{
- .type = NN_TRY(unvalidatedConvert(operation.type)),
+ .type = type,
.inputs = operation.inputs,
.outputs = operation.outputs,
};
@@ -156,14 +157,18 @@ GeneralResult<Operand::SymmPerChannelQuantParams> unvalidatedConvert(
}
GeneralResult<Operand> unvalidatedConvert(const hal::V1_2::Operand& operand) {
+ const auto type = NN_TRY(unvalidatedConvert(operand.type));
+ const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+ const auto location = NN_TRY(unvalidatedConvert(operand.location));
+ auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
return Operand{
- .type = NN_TRY(unvalidatedConvert(operand.type)),
+ .type = type,
.dimensions = operand.dimensions,
.scale = operand.scale,
.zeroPoint = operand.zeroPoint,
- .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
- .location = NN_TRY(unvalidatedConvert(operand.location)),
- .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
+ .lifetime = lifetime,
+ .location = location,
+ .extraParams = std::move(extraParams),
};
}
@@ -188,7 +193,7 @@ GeneralResult<Model> unvalidatedConvert(const hal::V1_2::Model& model) {
// Verify number of consumers.
const auto numberOfConsumers =
- NN_TRY(hal::utils::countNumberOfConsumers(model.operands.size(), operations));
+ NN_TRY(countNumberOfConsumers(model.operands.size(), operations));
CHECK(model.operands.size() == numberOfConsumers.size());
for (size_t i = 0; i < model.operands.size(); ++i) {
if (model.operands[i].numberOfConsumers != numberOfConsumers[i]) {
@@ -198,25 +203,29 @@ GeneralResult<Model> unvalidatedConvert(const hal::V1_2::Model& model) {
}
}
+ auto operands = NN_TRY(unvalidatedConvert(model.operands));
auto main = Model::Subgraph{
- .operands = NN_TRY(unvalidatedConvert(model.operands)),
+ .operands = std::move(operands),
.operations = std::move(operations),
.inputIndexes = model.inputIndexes,
.outputIndexes = model.outputIndexes,
};
+ auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+ auto pools = NN_TRY(unvalidatedConvert(model.pools));
+ auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
return Model{
.main = std::move(main),
- .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
- .pools = NN_TRY(unvalidatedConvert(model.pools)),
+ .operandValues = std::move(operandValues),
+ .pools = std::move(pools),
.relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
- .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
+ .extensionNameToPrefix = std::move(extensionNameToPrefix),
};
}
-GeneralResult<Model::ExtensionNameAndPrefix> unvalidatedConvert(
+GeneralResult<ExtensionNameAndPrefix> unvalidatedConvert(
const hal::V1_2::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) {
- return Model::ExtensionNameAndPrefix{
+ return ExtensionNameAndPrefix{
.name = extensionNameAndPrefix.name,
.prefix = extensionNameAndPrefix.prefix,
};
@@ -250,9 +259,10 @@ GeneralResult<Timing> unvalidatedConvert(const hal::V1_2::Timing& timing) {
}
GeneralResult<Extension> unvalidatedConvert(const hal::V1_2::Extension& extension) {
+ auto operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes));
return Extension{
.name = extension.name,
- .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes)),
+ .operandTypes = std::move(operandTypes),
};
}
@@ -265,14 +275,6 @@ GeneralResult<Extension::OperandTypeInformation> unvalidatedConvert(
};
}
-GeneralResult<SharedHandle> unvalidatedConvert(const hidl_handle& hidlHandle) {
- if (hidlHandle.getNativeHandle() == nullptr) {
- return nullptr;
- }
- auto handle = NN_TRY(hal::utils::sharedHandleFromNativeHandle(hidlHandle.getNativeHandle()));
- return std::make_shared<const Handle>(std::move(handle));
-}
-
GeneralResult<DeviceType> convert(const hal::V1_2::DeviceType& deviceType) {
return validatedConvert(deviceType);
}
@@ -335,6 +337,10 @@ nn::GeneralResult<hidl_vec<uint8_t>> unvalidatedConvert(
return V1_0::utils::unvalidatedConvert(operandValues);
}
+nn::GeneralResult<hidl_handle> unvalidatedConvert(const nn::SharedHandle& handle) {
+ return V1_0::utils::unvalidatedConvert(handle);
+}
+
nn::GeneralResult<hidl_memory> unvalidatedConvert(const nn::SharedMemory& memory) {
return V1_0::utils::unvalidatedConvert(memory);
}
@@ -412,35 +418,41 @@ nn::GeneralResult<DeviceType> unvalidatedConvert(const nn::DeviceType& deviceTyp
}
nn::GeneralResult<Capabilities> unvalidatedConvert(const nn::Capabilities& capabilities) {
- std::vector<nn::Capabilities::OperandPerformance> operandPerformance;
- operandPerformance.reserve(capabilities.operandPerformance.asVector().size());
+ std::vector<nn::Capabilities::OperandPerformance> filteredOperandPerformances;
+ filteredOperandPerformances.reserve(capabilities.operandPerformance.asVector().size());
std::copy_if(capabilities.operandPerformance.asVector().begin(),
capabilities.operandPerformance.asVector().end(),
- std::back_inserter(operandPerformance),
+ std::back_inserter(filteredOperandPerformances),
[](const nn::Capabilities::OperandPerformance& operandPerformance) {
return compliantVersion(operandPerformance.type).has_value();
});
+ const auto relaxedFloat32toFloat16PerformanceScalar =
+ NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar));
+ const auto relaxedFloat32toFloat16PerformanceTensor =
+ NN_TRY(unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor));
+ auto operandPerformance = NN_TRY(unvalidatedConvert(filteredOperandPerformances));
return Capabilities{
- .relaxedFloat32toFloat16PerformanceScalar = NN_TRY(
- unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceScalar)),
- .relaxedFloat32toFloat16PerformanceTensor = NN_TRY(
- unvalidatedConvert(capabilities.relaxedFloat32toFloat16PerformanceTensor)),
- .operandPerformance = NN_TRY(unvalidatedConvert(operandPerformance)),
+ .relaxedFloat32toFloat16PerformanceScalar = relaxedFloat32toFloat16PerformanceScalar,
+ .relaxedFloat32toFloat16PerformanceTensor = relaxedFloat32toFloat16PerformanceTensor,
+ .operandPerformance = std::move(operandPerformance),
};
}
nn::GeneralResult<Capabilities::OperandPerformance> unvalidatedConvert(
const nn::Capabilities::OperandPerformance& operandPerformance) {
+ const auto type = NN_TRY(unvalidatedConvert(operandPerformance.type));
+ const auto info = NN_TRY(unvalidatedConvert(operandPerformance.info));
return Capabilities::OperandPerformance{
- .type = NN_TRY(unvalidatedConvert(operandPerformance.type)),
- .info = NN_TRY(unvalidatedConvert(operandPerformance.info)),
+ .type = type,
+ .info = info,
};
}
nn::GeneralResult<Operation> unvalidatedConvert(const nn::Operation& operation) {
+ const auto type = NN_TRY(unvalidatedConvert(operation.type));
return Operation{
- .type = NN_TRY(unvalidatedConvert(operation.type)),
+ .type = type,
.inputs = operation.inputs,
.outputs = operation.outputs,
};
@@ -455,15 +467,19 @@ nn::GeneralResult<SymmPerChannelQuantParams> unvalidatedConvert(
}
nn::GeneralResult<Operand> unvalidatedConvert(const nn::Operand& operand) {
+ const auto type = NN_TRY(unvalidatedConvert(operand.type));
+ const auto lifetime = NN_TRY(unvalidatedConvert(operand.lifetime));
+ const auto location = NN_TRY(unvalidatedConvert(operand.location));
+ auto extraParams = NN_TRY(unvalidatedConvert(operand.extraParams));
return Operand{
- .type = NN_TRY(unvalidatedConvert(operand.type)),
+ .type = type,
.dimensions = operand.dimensions,
.numberOfConsumers = 0,
.scale = operand.scale,
.zeroPoint = operand.zeroPoint,
- .lifetime = NN_TRY(unvalidatedConvert(operand.lifetime)),
- .location = NN_TRY(unvalidatedConvert(operand.location)),
- .extraParams = NN_TRY(unvalidatedConvert(operand.extraParams)),
+ .lifetime = lifetime,
+ .location = location,
+ .extraParams = std::move(extraParams),
};
}
@@ -482,26 +498,30 @@ nn::GeneralResult<Model> unvalidatedConvert(const nn::Model& model) {
// Update number of consumers.
const auto numberOfConsumers =
- NN_TRY(hal::utils::countNumberOfConsumers(operands.size(), model.main.operations));
+ NN_TRY(countNumberOfConsumers(operands.size(), model.main.operations));
CHECK(operands.size() == numberOfConsumers.size());
for (size_t i = 0; i < operands.size(); ++i) {
operands[i].numberOfConsumers = numberOfConsumers[i];
}
+ auto operations = NN_TRY(unvalidatedConvert(model.main.operations));
+ auto operandValues = NN_TRY(unvalidatedConvert(model.operandValues));
+ auto pools = NN_TRY(unvalidatedConvert(model.pools));
+ auto extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix));
return Model{
.operands = std::move(operands),
- .operations = NN_TRY(unvalidatedConvert(model.main.operations)),
+ .operations = std::move(operations),
.inputIndexes = model.main.inputIndexes,
.outputIndexes = model.main.outputIndexes,
- .operandValues = NN_TRY(unvalidatedConvert(model.operandValues)),
- .pools = NN_TRY(unvalidatedConvert(model.pools)),
+ .operandValues = std::move(operandValues),
+ .pools = std::move(pools),
.relaxComputationFloat32toFloat16 = model.relaxComputationFloat32toFloat16,
- .extensionNameToPrefix = NN_TRY(unvalidatedConvert(model.extensionNameToPrefix)),
+ .extensionNameToPrefix = std::move(extensionNameToPrefix),
};
}
nn::GeneralResult<Model::ExtensionNameAndPrefix> unvalidatedConvert(
- const nn::Model::ExtensionNameAndPrefix& extensionNameAndPrefix) {
+ const nn::ExtensionNameAndPrefix& extensionNameAndPrefix) {
return Model::ExtensionNameAndPrefix{
.name = extensionNameAndPrefix.name,
.prefix = extensionNameAndPrefix.prefix,
@@ -530,9 +550,10 @@ nn::GeneralResult<Timing> unvalidatedConvert(const nn::Timing& timing) {
}
nn::GeneralResult<Extension> unvalidatedConvert(const nn::Extension& extension) {
+ auto operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes));
return Extension{
.name = extension.name,
- .operandTypes = NN_TRY(unvalidatedConvert(extension.operandTypes)),
+ .operandTypes = std::move(operandTypes),
};
}
@@ -545,13 +566,6 @@ nn::GeneralResult<Extension::OperandTypeInformation> unvalidatedConvert(
};
}
-nn::GeneralResult<hidl_handle> unvalidatedConvert(const nn::SharedHandle& handle) {
- if (handle == nullptr) {
- return {};
- }
- return hal::utils::hidlHandleFromSharedHandle(*handle);
-}
-
nn::GeneralResult<DeviceType> convert(const nn::DeviceType& deviceType) {
return validatedConvert(deviceType);
}
diff --git a/neuralnetworks/1.2/utils/src/Device.cpp b/neuralnetworks/1.2/utils/src/Device.cpp
index 9fe0de25b3..3a58d2c7cc 100644
--- a/neuralnetworks/1.2/utils/src/Device.cpp
+++ b/neuralnetworks/1.2/utils/src/Device.cpp
@@ -30,10 +30,10 @@
#include <nnapi/OperandTypes.h>
#include <nnapi/Result.h>
#include <nnapi/Types.h>
+#include <nnapi/hal/1.0/HandleError.h>
+#include <nnapi/hal/1.0/ProtectCallback.h>
#include <nnapi/hal/1.1/Conversions.h>
#include <nnapi/hal/CommonUtils.h>
-#include <nnapi/hal/HandleError.h>
-#include <nnapi/hal/ProtectCallback.h>
#include <functional>
#include <memory>
@@ -49,31 +49,31 @@ namespace {
nn::GeneralResult<nn::Capabilities> capabilitiesCallback(V1_0::ErrorStatus status,
const Capabilities& capabilities) {
- HANDLE_HAL_STATUS(status) << "getting capabilities failed with " << toString(status);
+ HANDLE_STATUS_HIDL(status) << "getting capabilities failed with " << toString(status);
return nn::convert(capabilities);
}
nn::GeneralResult<std::string> versionStringCallback(V1_0::ErrorStatus status,
const hidl_string& versionString) {
- HANDLE_HAL_STATUS(status) << "getVersionString failed with " << toString(status);
+ HANDLE_STATUS_HIDL(status) << "getVersionString failed with " << toString(status);
return versionString;
}
nn::GeneralResult<nn::DeviceType> deviceTypeCallback(V1_0::ErrorStatus status,
DeviceType deviceType) {
- HANDLE_HAL_STATUS(status) << "getDeviceType failed with " << toString(status);
+ HANDLE_STATUS_HIDL(status) << "getDeviceType failed with " << toString(status);
return nn::convert(deviceType);
}
nn::GeneralResult<std::vector<nn::Extension>> supportedExtensionsCallback(
V1_0::ErrorStatus status, const hidl_vec<Extension>& extensions) {
- HANDLE_HAL_STATUS(status) << "getExtensions failed with " << toString(status);
+ HANDLE_STATUS_HIDL(status) << "getExtensions failed with " << toString(status);
return nn::convert(extensions);
}
nn::GeneralResult<std::pair<uint32_t, uint32_t>> numberOfCacheFilesNeededCallback(
V1_0::ErrorStatus status, uint32_t numModelCache, uint32_t numDataCache) {
- HANDLE_HAL_STATUS(status) << "getNumberOfCacheFilesNeeded failed with " << toString(status);
+ HANDLE_STATUS_HIDL(status) << "getNumberOfCacheFilesNeeded failed with " << toString(status);
if (numModelCache > nn::kMaxNumberOfCacheFiles) {
return NN_ERROR() << "getNumberOfCacheFilesNeeded returned numModelCache files greater "
"than allowed max ("
@@ -192,7 +192,7 @@ const std::string& Device::getVersionString() const {
}
nn::Version Device::getFeatureLevel() const {
- return nn::Version::ANDROID_Q;
+ return kVersion;
}
nn::DeviceType Device::getType() const {
@@ -236,7 +236,9 @@ nn::GeneralResult<std::vector<bool>> Device::getSupportedOperations(const nn::Mo
nn::GeneralResult<nn::SharedPreparedModel> Device::prepareModel(
const nn::Model& model, nn::ExecutionPreference preference, nn::Priority /*priority*/,
nn::OptionalTimePoint /*deadline*/, const std::vector<nn::SharedHandle>& modelCache,
- const std::vector<nn::SharedHandle>& dataCache, const nn::CacheToken& token) const {
+ const std::vector<nn::SharedHandle>& dataCache, const nn::CacheToken& token,
+ const std::vector<nn::TokenValuePair>& /*hints*/,
+ const std::vector<nn::ExtensionNameAndPrefix>& /*extensionNameToPrefix*/) const {
// Ensure that model is ready for IPC.
std::optional<nn::Model> maybeModelInShared;
const nn::Model& modelInShared =
@@ -254,7 +256,7 @@ nn::GeneralResult<nn::SharedPreparedModel> Device::prepareModel(
const auto ret = kDevice->prepareModel_1_2(hidlModel, hidlPreference, hidlModelCache,
hidlDataCache, hidlToken, cb);
const auto status = HANDLE_TRANSPORT_FAILURE(ret);
- HANDLE_HAL_STATUS(status) << "model preparation failed with " << toString(status);
+ HANDLE_STATUS_HIDL(status) << "model preparation failed with " << toString(status);
return cb->get();
}
@@ -271,7 +273,7 @@ nn::GeneralResult<nn::SharedPreparedModel> Device::prepareModelFromCache(
const auto ret = kDevice->prepareModelFromCache(hidlModelCache, hidlDataCache, hidlToken, cb);
const auto status = HANDLE_TRANSPORT_FAILURE(ret);
- HANDLE_HAL_STATUS(status) << "model preparation from cache failed with " << toString(status);
+ HANDLE_STATUS_HIDL(status) << "model preparation from cache failed with " << toString(status);
return cb->get();
}
diff --git a/neuralnetworks/1.2/utils/src/Execution.cpp b/neuralnetworks/1.2/utils/src/Execution.cpp
index 18d1c90edd..320b0e1e2f 100644
--- a/neuralnetworks/1.2/utils/src/Execution.cpp
+++ b/neuralnetworks/1.2/utils/src/Execution.cpp
@@ -29,7 +29,6 @@
#include <nnapi/TypeUtils.h>
#include <nnapi/Types.h>
#include <nnapi/hal/CommonUtils.h>
-#include <nnapi/hal/HandleError.h>
#include <memory>
#include <utility>
diff --git a/neuralnetworks/1.2/utils/src/ExecutionBurstServer.cpp b/neuralnetworks/1.2/utils/src/ExecutionBurstServer.cpp
deleted file mode 100644
index c67159e895..0000000000
--- a/neuralnetworks/1.2/utils/src/ExecutionBurstServer.cpp
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#define LOG_TAG "ExecutionBurstServer"
-
-#include "ExecutionBurstServer.h"
-#include "Conversions.h"
-#include "ExecutionBurstUtils.h"
-
-#include <android-base/logging.h>
-#include <nnapi/IBurst.h>
-#include <nnapi/Result.h>
-#include <nnapi/TypeUtils.h>
-#include <nnapi/Types.h>
-#include <nnapi/Validation.h>
-#include <nnapi/hal/1.0/Conversions.h>
-#include <nnapi/hal/HandleError.h>
-#include <nnapi/hal/ProtectCallback.h>
-#include <nnapi/hal/TransferValue.h>
-
-#include <algorithm>
-#include <cstring>
-#include <limits>
-#include <map>
-#include <memory>
-#include <tuple>
-#include <utility>
-#include <vector>
-
-#include "Tracing.h"
-
-namespace android::hardware::neuralnetworks::V1_2::utils {
-namespace {
-
-using neuralnetworks::utils::makeExecutionFailure;
-
-constexpr V1_2::Timing kNoTiming = {std::numeric_limits<uint64_t>::max(),
- std::numeric_limits<uint64_t>::max()};
-
-nn::GeneralResult<std::vector<nn::SharedMemory>> getMemoriesCallback(
- V1_0::ErrorStatus status, const hidl_vec<hidl_memory>& memories) {
- HANDLE_HAL_STATUS(status) << "getting burst memories failed with " << toString(status);
- std::vector<nn::SharedMemory> canonicalMemories;
- canonicalMemories.reserve(memories.size());
- for (const auto& memory : memories) {
- canonicalMemories.push_back(NN_TRY(nn::convert(memory)));
- }
- return canonicalMemories;
-}
-
-} // anonymous namespace
-
-ExecutionBurstServer::MemoryCache::MemoryCache(nn::SharedBurst burstExecutor,
- sp<IBurstCallback> burstCallback)
- : kBurstExecutor(std::move(burstExecutor)), kBurstCallback(std::move(burstCallback)) {
- CHECK(kBurstExecutor != nullptr);
- CHECK(kBurstCallback != nullptr);
-}
-
-nn::GeneralResult<std::vector<std::pair<nn::SharedMemory, nn::IBurst::OptionalCacheHold>>>
-ExecutionBurstServer::MemoryCache::getCacheEntries(const std::vector<int32_t>& slots) {
- std::lock_guard guard(mMutex);
- NN_TRY(ensureCacheEntriesArePresentLocked(slots));
-
- std::vector<std::pair<nn::SharedMemory, nn::IBurst::OptionalCacheHold>> results;
- results.reserve(slots.size());
- for (int32_t slot : slots) {
- results.push_back(NN_TRY(getCacheEntryLocked(slot)));
- }
-
- return results;
-}
-
-nn::GeneralResult<void> ExecutionBurstServer::MemoryCache::ensureCacheEntriesArePresentLocked(
- const std::vector<int32_t>& slots) {
- const auto slotIsKnown = [this](int32_t slot)
- REQUIRES(mMutex) { return mCache.count(slot) > 0; };
-
- // find unique unknown slots
- std::vector<int32_t> unknownSlots = slots;
- std::sort(unknownSlots.begin(), unknownSlots.end());
- auto unknownSlotsEnd = std::unique(unknownSlots.begin(), unknownSlots.end());
- unknownSlotsEnd = std::remove_if(unknownSlots.begin(), unknownSlotsEnd, slotIsKnown);
- unknownSlots.erase(unknownSlotsEnd, unknownSlots.end());
-
- // quick-exit if all slots are known
- if (unknownSlots.empty()) {
- return {};
- }
-
- auto cb = neuralnetworks::utils::CallbackValue(getMemoriesCallback);
-
- const auto ret = kBurstCallback->getMemories(unknownSlots, cb);
- HANDLE_TRANSPORT_FAILURE(ret);
-
- auto returnedMemories = NN_TRY(cb.take());
-
- if (returnedMemories.size() != unknownSlots.size()) {
- return NN_ERROR()
- << "ExecutionBurstServer::MemoryCache::ensureCacheEntriesArePresentLocked: Error "
- "retrieving memories -- count mismatch between requested memories ("
- << unknownSlots.size() << ") and returned memories (" << returnedMemories.size()
- << ")";
- }
-
- // add memories to unknown slots
- for (size_t i = 0; i < unknownSlots.size(); ++i) {
- addCacheEntryLocked(unknownSlots[i], std::move(returnedMemories[i]));
- }
-
- return {};
-}
-
-nn::GeneralResult<std::pair<nn::SharedMemory, nn::IBurst::OptionalCacheHold>>
-ExecutionBurstServer::MemoryCache::getCacheEntryLocked(int32_t slot) {
- if (const auto iter = mCache.find(slot); iter != mCache.end()) {
- return iter->second;
- }
- return NN_ERROR()
- << "ExecutionBurstServer::MemoryCache::getCacheEntryLocked failed because slot " << slot
- << " is not present in the cache";
-}
-
-void ExecutionBurstServer::MemoryCache::addCacheEntryLocked(int32_t slot, nn::SharedMemory memory) {
- auto hold = kBurstExecutor->cacheMemory(memory);
- mCache.emplace(slot, std::make_pair(std::move(memory), std::move(hold)));
-}
-
-void ExecutionBurstServer::MemoryCache::removeCacheEntry(int32_t slot) {
- std::lock_guard guard(mMutex);
- mCache.erase(slot);
-}
-
-// ExecutionBurstServer methods
-
-nn::GeneralResult<sp<ExecutionBurstServer>> ExecutionBurstServer::create(
- const sp<IBurstCallback>& callback, const MQDescriptorSync<FmqRequestDatum>& requestChannel,
- const MQDescriptorSync<FmqResultDatum>& resultChannel, nn::SharedBurst burstExecutor,
- std::chrono::microseconds pollingTimeWindow) {
- // check inputs
- if (callback == nullptr || burstExecutor == nullptr) {
- return NN_ERROR() << "ExecutionBurstServer::create passed a nullptr";
- }
-
- // create FMQ objects
- auto requestChannelReceiver =
- NN_TRY(RequestChannelReceiver::create(requestChannel, pollingTimeWindow));
- auto resultChannelSender = NN_TRY(ResultChannelSender::create(resultChannel));
-
- // check FMQ objects
- CHECK(requestChannelReceiver != nullptr);
- CHECK(resultChannelSender != nullptr);
-
- // make and return context
- return sp<ExecutionBurstServer>::make(PrivateConstructorTag{}, callback,
- std::move(requestChannelReceiver),
- std::move(resultChannelSender), std::move(burstExecutor));
-}
-
-ExecutionBurstServer::ExecutionBurstServer(PrivateConstructorTag /*tag*/,
- const sp<IBurstCallback>& callback,
- std::unique_ptr<RequestChannelReceiver> requestChannel,
- std::unique_ptr<ResultChannelSender> resultChannel,
- nn::SharedBurst burstExecutor)
- : mCallback(callback),
- mRequestChannelReceiver(std::move(requestChannel)),
- mResultChannelSender(std::move(resultChannel)),
- mBurstExecutor(std::move(burstExecutor)),
- mMemoryCache(mBurstExecutor, mCallback) {
- // TODO: highly document the threading behavior of this class
- mWorker = std::thread([this] { task(); });
-}
-
-ExecutionBurstServer::~ExecutionBurstServer() {
- // set teardown flag
- mTeardown = true;
- mRequestChannelReceiver->invalidate();
-
- // wait for task thread to end
- mWorker.join();
-}
-
-Return<void> ExecutionBurstServer::freeMemory(int32_t slot) {
- mMemoryCache.removeCacheEntry(slot);
- return Void();
-}
-
-void ExecutionBurstServer::task() {
- // loop until the burst object is being destroyed
- while (!mTeardown) {
- // receive request
- auto arguments = mRequestChannelReceiver->getBlocking();
-
- // if the request packet was not properly received, return a generic error and skip the
- // execution
- //
- // if the burst is being torn down, skip the execution so the "task" function can end
- if (!arguments.has_value()) {
- if (!mTeardown) {
- mResultChannelSender->send(V1_0::ErrorStatus::GENERAL_FAILURE, {}, kNoTiming);
- }
- continue;
- }
-
- // unpack the arguments; types are Request, std::vector<int32_t>, and MeasureTiming,
- // respectively
- const auto [requestWithoutPools, slotsOfPools, measure] = std::move(arguments).value();
-
- auto result = execute(requestWithoutPools, slotsOfPools, measure);
-
- // return result
- if (result.has_value()) {
- const auto& [outputShapes, timing] = result.value();
- mResultChannelSender->send(V1_0::ErrorStatus::NONE, outputShapes, timing);
- } else {
- const auto& [message, code, outputShapes] = result.error();
- LOG(ERROR) << "IBurst::execute failed with " << code << ": " << message;
- mResultChannelSender->send(convert(code).value(), convert(outputShapes).value(),
- kNoTiming);
- }
- }
-}
-
-nn::ExecutionResult<std::pair<hidl_vec<OutputShape>, Timing>> ExecutionBurstServer::execute(
- const V1_0::Request& requestWithoutPools, const std::vector<int32_t>& slotsOfPools,
- MeasureTiming measure) {
- NNTRACE_FULL(NNTRACE_LAYER_IPC, NNTRACE_PHASE_EXECUTION,
- "ExecutionBurstServer getting memory, executing, and returning results");
-
- // ensure executor with cache has required memory
- const auto cacheEntries =
- NN_TRY(makeExecutionFailure(mMemoryCache.getCacheEntries(slotsOfPools)));
-
- // convert request, populating its pools
- // This code performs an unvalidated convert because the request object without its pools is
- // invalid because it is incomplete. Instead, the validation is performed after the memory pools
- // have been added to the request.
- auto canonicalRequest =
- NN_TRY(makeExecutionFailure(nn::unvalidatedConvert(requestWithoutPools)));
- CHECK(canonicalRequest.pools.empty());
- std::transform(cacheEntries.begin(), cacheEntries.end(),
- std::back_inserter(canonicalRequest.pools),
- [](const auto& cacheEntry) { return cacheEntry.first; });
- NN_TRY(makeExecutionFailure(validate(canonicalRequest)));
-
- nn::MeasureTiming canonicalMeasure = NN_TRY(makeExecutionFailure(nn::convert(measure)));
-
- const auto [outputShapes, timing] =
- NN_TRY(mBurstExecutor->execute(canonicalRequest, canonicalMeasure, {}, {}));
-
- return std::make_pair(NN_TRY(makeExecutionFailure(convert(outputShapes))),
- NN_TRY(makeExecutionFailure(convert(timing))));
-}
-
-} // namespace android::hardware::neuralnetworks::V1_2::utils
diff --git a/neuralnetworks/1.2/utils/src/PreparedModel.cpp b/neuralnetworks/1.2/utils/src/PreparedModel.cpp
index d0ef36e7b5..feb3951a4a 100644
--- a/neuralnetworks/1.2/utils/src/PreparedModel.cpp
+++ b/neuralnetworks/1.2/utils/src/PreparedModel.cpp
@@ -16,11 +16,11 @@
#include "PreparedModel.h"
+#include "Burst.h"
+#include "BurstUtils.h"
#include "Callbacks.h"
#include "Conversions.h"
#include "Execution.h"
-#include "ExecutionBurstController.h"
-#include "ExecutionBurstUtils.h"
#include "Utils.h"
#include <android/hardware/neuralnetworks/1.0/types.h>
@@ -31,9 +31,9 @@
#include <nnapi/Result.h>
#include <nnapi/Types.h>
#include <nnapi/hal/1.0/Conversions.h>
+#include <nnapi/hal/1.0/HandleError.h>
+#include <nnapi/hal/1.0/ProtectCallback.h>
#include <nnapi/hal/CommonUtils.h>
-#include <nnapi/hal/HandleError.h>
-#include <nnapi/hal/ProtectCallback.h>
#include <chrono>
#include <memory>
@@ -82,7 +82,7 @@ PreparedModel::executeAsynchronously(const V1_0::Request& request, MeasureTiming
const auto ret = kPreparedModel->execute_1_2(request, measure, cb);
const auto status = HANDLE_TRANSPORT_FAILURE(ret);
if (status != V1_0::ErrorStatus::OUTPUT_INSUFFICIENT_SIZE) {
- HANDLE_HAL_STATUS(status) << "execution failed with " << toString(status);
+ HANDLE_STATUS_HIDL(status) << "execution failed with " << toString(status);
}
return cb->get();
@@ -91,17 +91,18 @@ PreparedModel::executeAsynchronously(const V1_0::Request& request, MeasureTiming
nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> PreparedModel::execute(
const nn::Request& request, nn::MeasureTiming measure,
const nn::OptionalTimePoint& /*deadline*/,
- const nn::OptionalDuration& /*loopTimeoutDuration*/) const {
+ const nn::OptionalDuration& /*loopTimeoutDuration*/,
+ const std::vector<nn::TokenValuePair>& /*hints*/,
+ const std::vector<nn::ExtensionNameAndPrefix>& /*extensionNameToPrefix*/) const {
// Ensure that request is ready for IPC.
std::optional<nn::Request> maybeRequestInShared;
hal::utils::RequestRelocation relocation;
- const nn::Request& requestInShared =
- NN_TRY(hal::utils::makeExecutionFailure(hal::utils::convertRequestFromPointerToShared(
- &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding,
- &maybeRequestInShared, &relocation)));
+ const nn::Request& requestInShared = NN_TRY(hal::utils::convertRequestFromPointerToShared(
+ &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding,
+ &maybeRequestInShared, &relocation));
- const auto hidlRequest = NN_TRY(hal::utils::makeExecutionFailure(convert(requestInShared)));
- const auto hidlMeasure = NN_TRY(hal::utils::makeExecutionFailure(convert(measure)));
+ const auto hidlRequest = NN_TRY(convert(requestInShared));
+ const auto hidlMeasure = NN_TRY(convert(measure));
return executeInternal(hidlRequest, hidlMeasure, relocation);
}
@@ -124,19 +125,22 @@ PreparedModel::executeInternal(const V1_0::Request& request, MeasureTiming measu
}
nn::GeneralResult<std::pair<nn::SyncFence, nn::ExecuteFencedInfoCallback>>
-PreparedModel::executeFenced(const nn::Request& /*request*/,
- const std::vector<nn::SyncFence>& /*waitFor*/,
- nn::MeasureTiming /*measure*/,
- const nn::OptionalTimePoint& /*deadline*/,
- const nn::OptionalDuration& /*loopTimeoutDuration*/,
- const nn::OptionalDuration& /*timeoutDurationAfterFence*/) const {
+PreparedModel::executeFenced(
+ const nn::Request& /*request*/, const std::vector<nn::SyncFence>& /*waitFor*/,
+ nn::MeasureTiming /*measure*/, const nn::OptionalTimePoint& /*deadline*/,
+ const nn::OptionalDuration& /*loopTimeoutDuration*/,
+ const nn::OptionalDuration& /*timeoutDurationAfterFence*/,
+ const std::vector<nn::TokenValuePair>& /*hints*/,
+ const std::vector<nn::ExtensionNameAndPrefix>& /*extensionNameToPrefix*/) const {
return NN_ERROR(nn::ErrorStatus::GENERAL_FAILURE)
<< "IPreparedModel::executeFenced is not supported on 1.2 HAL service";
}
nn::GeneralResult<nn::SharedExecution> PreparedModel::createReusableExecution(
const nn::Request& request, nn::MeasureTiming measure,
- const nn::OptionalDuration& /*loopTimeoutDuration*/) const {
+ const nn::OptionalDuration& /*loopTimeoutDuration*/,
+ const std::vector<nn::TokenValuePair>& /*hints*/,
+ const std::vector<nn::ExtensionNameAndPrefix>& /*extensionNameToPrefix*/) const {
// Ensure that request is ready for IPC.
std::optional<nn::Request> maybeRequestInShared;
hal::utils::RequestRelocation relocation;
@@ -151,16 +155,8 @@ nn::GeneralResult<nn::SharedExecution> PreparedModel::createReusableExecution(
}
nn::GeneralResult<nn::SharedBurst> PreparedModel::configureExecutionBurst() const {
- auto self = shared_from_this();
- auto fallback = [preparedModel = std::move(self)](
- const nn::Request& request, nn::MeasureTiming measure,
- const nn::OptionalTimePoint& deadline,
- const nn::OptionalDuration& loopTimeoutDuration)
- -> nn::ExecutionResult<std::pair<std::vector<nn::OutputShape>, nn::Timing>> {
- return preparedModel->execute(request, measure, deadline, loopTimeoutDuration);
- };
const auto pollingTimeWindow = getBurstControllerPollingTimeWindow();
- return ExecutionBurstController::create(shared_from_this(), kPreparedModel, pollingTimeWindow);
+ return Burst::create(shared_from_this(), kPreparedModel, pollingTimeWindow);
}
std::any PreparedModel::getUnderlyingResource() const {