diff options
Diffstat (limited to 'shim/sl/canonical/ArmnnPreparedModel.cpp')
-rw-r--r-- | shim/sl/canonical/ArmnnPreparedModel.cpp | 145 |
1 files changed, 92 insertions, 53 deletions
diff --git a/shim/sl/canonical/ArmnnPreparedModel.cpp b/shim/sl/canonical/ArmnnPreparedModel.cpp index 7b900a9418..22e09008ba 100644 --- a/shim/sl/canonical/ArmnnPreparedModel.cpp +++ b/shim/sl/canonical/ArmnnPreparedModel.cpp @@ -89,6 +89,27 @@ inline std::string BuildTensorName(const char* tensorNamePrefix, std::size_t ind return tensorNamePrefix + std::to_string(index); } +bool IsPointerTypeMemory(const Request& request) +{ + for (auto& input : request.inputs) + { + if (input.lifetime == Request::Argument::LifeTime::POINTER) + { + return true; + } + } + + for (auto& output: request.outputs) + { + if (output.lifetime == Request::Argument::LifeTime::POINTER) + { + return true; + } + } + + return false; +} + } // anonymous namespace using namespace android::nn; @@ -228,11 +249,10 @@ ErrorStatus ArmnnPreparedModel::PrepareMemoryForOutputs( return ErrorStatus::NONE; } -std::tuple<ErrorStatus, std::vector<OutputShape>, Timing, std::string> -ArmnnPreparedModel::PrepareMemoryForIO(armnn::InputTensors& inputs, - armnn::OutputTensors& outputs, - std::vector<android::nn::RunTimePoolInfo>& memPools, - const Request& request) const +ErrorStatus ArmnnPreparedModel::PrepareMemoryForIO(armnn::InputTensors& inputs, + armnn::OutputTensors& outputs, + std::vector<android::nn::RunTimePoolInfo>& memPools, + const Request& request) const { //Check memory pools are not empty // add the inputs and outputs with their data @@ -240,13 +260,13 @@ ArmnnPreparedModel::PrepareMemoryForIO(armnn::InputTensors& inputs, { if (!setRunTimePoolInfosFromMemoryPools(&memPools, request.pools)) { - return {ErrorStatus::INVALID_ARGUMENT, {}, g_NoTiming, "ArmnnPreparedModel::execute"}; + return ErrorStatus::INVALID_ARGUMENT; } if (PrepareMemoryForInputs(inputs, request, memPools) != ErrorStatus::NONE) { VLOG(DRIVER) << "Failed when preparing memory for Inputs"; - return {ErrorStatus::GENERAL_FAILURE, {}, g_NoTiming, "ArmnnPreparedModel::execute"}; + return ErrorStatus::GENERAL_FAILURE; } std::vector<OutputShape> outputShapes(request.outputs.size()); @@ -254,21 +274,21 @@ ArmnnPreparedModel::PrepareMemoryForIO(armnn::InputTensors& inputs, auto errorStatus = PrepareMemoryForOutputs(outputs, outputShapes, request, memPools); if (errorStatus != ErrorStatus::NONE) { - return {errorStatus, outputShapes, g_NoTiming, "ArmnnPreparedModel::execute"}; + return errorStatus; } } catch (armnn::Exception& e) { VLOG(DRIVER) << "armnn::Exception caught while preparing for EnqueueWorkload: " << e.what(); - return {ErrorStatus::GENERAL_FAILURE, {}, g_NoTiming, "ArmnnPreparedModel::execute"}; + return ErrorStatus::GENERAL_FAILURE; } catch (std::exception& e) { VLOG(DRIVER) << "std::exception caught while preparing for EnqueueWorkload: " << e.what(); - return {ErrorStatus::GENERAL_FAILURE, {}, g_NoTiming, "ArmnnPreparedModel::execute"}; + return ErrorStatus::GENERAL_FAILURE; } - return {ErrorStatus::NONE, {}, g_NoTiming, "ArmnnPreparedModel::execute"}; + return ErrorStatus::NONE; } ExecutionResult<std::pair<std::vector<OutputShape>, Timing>> ArmnnPreparedModel::execute( @@ -305,33 +325,41 @@ ExecutionResult<std::pair<std::vector<OutputShape>, Timing>> ArmnnPreparedModel: // use a shared memory pools vector on the heap, as it is passed to the request thread auto memPools = std::make_shared<std::vector<android::nn::RunTimePoolInfo>>(); - std::optional<nn::Request> maybeRequestInShared; + // allocate the tensors on the heap, as they are passed to the request thread + auto inputTensors = std::make_shared<armnn::InputTensors>(); + auto outputTensors = std::make_shared<armnn::OutputTensors>(); + + ErrorStatus theErrorStatus = ErrorStatus::NONE; + + auto isPointerTypeMemory = IsPointerTypeMemory(request); nn::RequestRelocation relocation; - auto executionResult = - nn::convertRequestFromPointerToShared( - &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding, - &maybeRequestInShared, &relocation); - if(!executionResult.has_value()) - { - VLOG(DRIVER) << "ArmnnPreparedModel::PrepareMemoryForIO::Failed to convertRequestFromPointerToShared."; - return NN_ERROR(ErrorStatus::GENERAL_FAILURE) << "ArmnnPreparedModel convertRequestFromPointerToShared failed"; - } - const nn::Request& requestInShared = std::move(executionResult).value(); + if (isPointerTypeMemory) + { + std::optional<nn::Request> maybeRequestInShared; + auto executionResult = + nn::convertRequestFromPointerToShared( + &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding, + &maybeRequestInShared, &relocation); + if(!executionResult.has_value()) + { + VLOG(DRIVER) << "ArmnnPreparedModel::PrepareMemoryForIO::Failed to convertRequestFromPointerToShared."; + return NN_ERROR(ErrorStatus::GENERAL_FAILURE) + << "ArmnnPreparedModel convertRequestFromPointerToShared failed"; + } + const nn::Request& requestInShared = std::move(executionResult).value(); + if (relocation.input) + { + relocation.input->flush(); + } - if (relocation.input) + theErrorStatus = PrepareMemoryForIO(*inputTensors, *outputTensors, *memPools, requestInShared); + } + else { - relocation.input->flush(); + theErrorStatus = PrepareMemoryForIO(*inputTensors, *outputTensors, *memPools, request); } - // allocate the tensors on the heap, as they are passed to the request thread - auto inputTensors = std::make_shared<armnn::InputTensors>(); - auto outputTensors = std::make_shared<armnn::OutputTensors>(); - - auto [status, outShapes, timing, message] = PrepareMemoryForIO(*inputTensors, - *outputTensors, - *memPools, - requestInShared); - switch(status) + switch(theErrorStatus) { case ErrorStatus::OUTPUT_INSUFFICIENT_SIZE: return NN_ERROR(ErrorStatus::OUTPUT_INSUFFICIENT_SIZE); @@ -361,7 +389,7 @@ ExecutionResult<std::pair<std::vector<OutputShape>, Timing>> ArmnnPreparedModel: return NN_ERROR(errorStatus) << "execute() failed"; } VLOG(DRIVER) << "ArmnnPreparedModel::execute(...) after ExecuteGraph"; - if (relocation.output) + if (isPointerTypeMemory && relocation.output) { relocation.output->flush(); } @@ -488,29 +516,40 @@ GeneralResult<std::pair<SyncFence, ExecuteFencedInfoCallback>> ArmnnPreparedMode auto memPools = std::make_shared<std::vector<android::nn::RunTimePoolInfo>>(); // allocate the tensors on the heap, as they are passed to the request thread - auto inputs = std::make_shared<armnn::InputTensors>(); - auto outputs = std::make_shared<armnn::OutputTensors>(); + auto inputTensors = std::make_shared<armnn::InputTensors>(); + auto outputTensors = std::make_shared<armnn::OutputTensors>(); + + ErrorStatus theErrorStatus = ErrorStatus::NONE; - std::optional<nn::Request> maybeRequestInShared; + auto isPointerTypeMemory = IsPointerTypeMemory(request); nn::RequestRelocation relocation; - auto executionResult = - nn::convertRequestFromPointerToShared( - &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding, - &maybeRequestInShared, &relocation); - if(!executionResult.has_value()) - { - VLOG(DRIVER) << "rmnnPreparedModel::PrepareMemoryForIO::Failed to convertRequestFromPointerToShared."; - return NN_ERROR(ErrorStatus::GENERAL_FAILURE) << "ArmnnPreparedModel convertRequestFromPointerToShared failed"; - } - const nn::Request& requestInShared = std::move(executionResult).value(); + if (isPointerTypeMemory) + { + std::optional<nn::Request> maybeRequestInShared; + auto executionResult = + nn::convertRequestFromPointerToShared( + &request, nn::kDefaultRequestMemoryAlignment, nn::kMinMemoryPadding, + &maybeRequestInShared, &relocation); + if(!executionResult.has_value()) + { + VLOG(DRIVER) << "ArmnnPreparedModel::PrepareMemoryForIO::Failed to convertRequestFromPointerToShared."; + return NN_ERROR(ErrorStatus::GENERAL_FAILURE) + << "ArmnnPreparedModel convertRequestFromPointerToShared failed"; + } + const nn::Request& requestInShared = std::move(executionResult).value(); + if (relocation.input) + { + relocation.input->flush(); + } - if (relocation.input) + theErrorStatus = PrepareMemoryForIO(*inputTensors, *outputTensors, *memPools, requestInShared); + } + else { - relocation.input->flush(); + theErrorStatus = PrepareMemoryForIO(*inputTensors, *outputTensors, *memPools, request); } - auto [status, outShapes, timings, message] = PrepareMemoryForIO(*inputs, *outputs, *memPools, requestInShared); - if (status != ErrorStatus::NONE) + if (theErrorStatus != ErrorStatus::NONE) { return NN_ERROR(ErrorStatus::INVALID_ARGUMENT) << "executeFenced() failed"; } @@ -526,9 +565,9 @@ GeneralResult<std::pair<SyncFence, ExecuteFencedInfoCallback>> ArmnnPreparedMode } VLOG(DRIVER) << "ArmnnCanonicalPreparedModel::executeFenced(...) before ExecuteGraph"; - auto errorStatus = ExecuteGraph(memPools, *inputs, *outputs, ctx); + auto errorStatus = ExecuteGraph(memPools, *inputTensors, *outputTensors, ctx); VLOG(DRIVER) << "ArmnnCanonicalPreparedModel::executeFenced(...) after ExecuteGraph"; - if (relocation.output) + if (isPointerTypeMemory && relocation.output) { relocation.output->flush(); } |