From 47c0423b29d3e37548ab45b7410659dc8cd76e9d Mon Sep 17 00:00:00 2001 From: Sadik Armagan Date: Mon, 13 Jun 2022 08:29:05 +0100 Subject: IVGCVSW-6956 'Use utility function to convert Pointer Memory to Memory Pool where necessary' Signed-off-by: Sadik Armagan Change-Id: Id9f8e6b3063a6a1748cceb5b9c5f802b0a757b5c --- shim/sl/canonical/ArmnnPreparedModel.cpp | 145 ++++++++++++++++++++----------- shim/sl/canonical/ArmnnPreparedModel.hpp | 9 +- 2 files changed, 96 insertions(+), 58 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, Timing, std::string> -ArmnnPreparedModel::PrepareMemoryForIO(armnn::InputTensors& inputs, - armnn::OutputTensors& outputs, - std::vector& memPools, - const Request& request) const +ErrorStatus ArmnnPreparedModel::PrepareMemoryForIO(armnn::InputTensors& inputs, + armnn::OutputTensors& outputs, + std::vector& 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 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, Timing>> ArmnnPreparedModel::execute( @@ -305,33 +325,41 @@ ExecutionResult, 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::optional maybeRequestInShared; + // allocate the tensors on the heap, as they are passed to the request thread + auto inputTensors = std::make_shared(); + auto outputTensors = std::make_shared(); + + 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 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(); - auto outputTensors = std::make_shared(); - - 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, 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> ArmnnPreparedMode auto memPools = std::make_shared>(); // allocate the tensors on the heap, as they are passed to the request thread - auto inputs = std::make_shared(); - auto outputs = std::make_shared(); + auto inputTensors = std::make_shared(); + auto outputTensors = std::make_shared(); + + ErrorStatus theErrorStatus = ErrorStatus::NONE; - std::optional 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 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> 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(); } diff --git a/shim/sl/canonical/ArmnnPreparedModel.hpp b/shim/sl/canonical/ArmnnPreparedModel.hpp index 920c7fb314..e97e7d7bd5 100644 --- a/shim/sl/canonical/ArmnnPreparedModel.hpp +++ b/shim/sl/canonical/ArmnnPreparedModel.hpp @@ -110,11 +110,10 @@ private: const Request& request, const std::vector& memPools) const; - std::tuple, Timing, std::string> PrepareMemoryForIO( - armnn::InputTensors& inputs, - armnn::OutputTensors& outputs, - std::vector& memPools, - const Request& request) const; + ErrorStatus PrepareMemoryForIO(armnn::InputTensors& inputs, + armnn::OutputTensors& outputs, + std::vector& memPools, + const Request& request) const; template void DumpTensorsIfRequired(char const* tensorNamePrefix, const TensorBindingCollection& tensorBindings) const; -- cgit v1.2.1