aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSadik Armagan <sadik.armagan@arm.com>2022-06-13 08:29:05 +0100
committerSadik Armagan <sadik.armagan@arm.com>2022-06-14 14:27:50 +0000
commit47c0423b29d3e37548ab45b7410659dc8cd76e9d (patch)
tree9827b7c0b528720c2f7be5f0b5c5953004eb56ae
parentb693be549eb0f2f113ec8cdff3c50e9336b57c7e (diff)
downloadarmnn-47c0423b29d3e37548ab45b7410659dc8cd76e9d.tar.gz
IVGCVSW-6956 'Use utility function to convert Pointer Memory to Memory Pool where necessary'
Signed-off-by: Sadik Armagan <sadik.armagan@arm.com> Change-Id: Id9f8e6b3063a6a1748cceb5b9c5f802b0a757b5c
-rw-r--r--shim/sl/canonical/ArmnnPreparedModel.cpp145
-rw-r--r--shim/sl/canonical/ArmnnPreparedModel.hpp9
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<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();
}
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<android::nn::RunTimePoolInfo>& memPools) const;
- std::tuple<ErrorStatus, std::vector<OutputShape>, Timing, std::string> PrepareMemoryForIO(
- armnn::InputTensors& inputs,
- armnn::OutputTensors& outputs,
- std::vector<android::nn::RunTimePoolInfo>& memPools,
- const Request& request) const;
+ ErrorStatus PrepareMemoryForIO(armnn::InputTensors& inputs,
+ armnn::OutputTensors& outputs,
+ std::vector<android::nn::RunTimePoolInfo>& memPools,
+ const Request& request) const;
template <typename TensorBindingCollection>
void DumpTensorsIfRequired(char const* tensorNamePrefix, const TensorBindingCollection& tensorBindings) const;