aboutsummaryrefslogtreecommitdiff
path: root/1.3
diff options
context:
space:
mode:
Diffstat (limited to '1.3')
-rw-r--r--1.3/ArmnnDriver.hpp90
-rw-r--r--1.3/ArmnnDriverImpl.cpp452
-rw-r--r--1.3/ArmnnDriverImpl.hpp29
-rw-r--r--1.3/HalPolicy.cpp116
-rw-r--r--1.3/HalPolicy.hpp29
5 files changed, 595 insertions, 121 deletions
diff --git a/1.3/ArmnnDriver.hpp b/1.3/ArmnnDriver.hpp
index 451b5ab5..6d2e0b7a 100644
--- a/1.3/ArmnnDriver.hpp
+++ b/1.3/ArmnnDriver.hpp
@@ -21,6 +21,8 @@
#include "../1.0/ArmnnDriverImpl.hpp"
#include "../1.0/HalPolicy.hpp"
+#include <armnn/BackendHelper.hpp>
+
#include <log/log.h>
namespace armnn_driver
@@ -31,6 +33,7 @@ namespace hal_1_3
class ArmnnDriver : public ArmnnDevice, public V1_3::IDevice
{
public:
+ using HidlToken = android::hardware::hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
ArmnnDriver(DriverOptions options)
: ArmnnDevice(std::move(options))
@@ -39,9 +42,7 @@ public:
}
~ArmnnDriver() {}
- using HidlToken = android::hardware::hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
-public:
Return<void> getCapabilities(V1_0::IDevice::getCapabilities_cb cb) override
{
ALOGV("hal_1_3::ArmnnDriver::getCapabilities()");
@@ -131,10 +132,13 @@ public:
cb);
}
- Return<V1_0::ErrorStatus> prepareModel_1_2(const V1_2::Model& model, V1_1::ExecutionPreference preference,
- const android::hardware::hidl_vec<android::hardware::hidl_handle>&,
- const android::hardware::hidl_vec<android::hardware::hidl_handle>&, const HidlToken&,
- const android::sp<V1_2::IPreparedModelCallback>& cb)
+ Return<V1_0::ErrorStatus> prepareModel_1_2(
+ const V1_2::Model& model,
+ V1_1::ExecutionPreference preference,
+ const android::hardware::hidl_vec<android::hardware::hidl_handle>& modelCacheHandle,
+ const android::hardware::hidl_vec<android::hardware::hidl_handle>& dataCacheHandle,
+ const HidlToken& token,
+ const android::sp<V1_2::IPreparedModelCallback>& cb)
{
ALOGV("hal_1_3::ArmnnDriver::prepareModel_1_2()");
@@ -151,6 +155,9 @@ public:
m_ClTunedParameters,
m_Options,
model,
+ modelCacheHandle,
+ dataCacheHandle,
+ token,
cb,
model.relaxComputationFloat32toFloat16
&& m_Options.GetFp16Enabled());
@@ -174,14 +181,15 @@ public:
cb);
}
- Return<V1_3::ErrorStatus> prepareModel_1_3(const V1_3::Model& model,
- V1_1::ExecutionPreference preference,
- V1_3::Priority priority,
- const V1_3::OptionalTimePoint&,
- const android::hardware::hidl_vec<android::hardware::hidl_handle>&,
- const android::hardware::hidl_vec<android::hardware::hidl_handle>&,
- const HidlToken&,
- const android::sp<V1_3::IPreparedModelCallback>& cb)
+ Return<V1_3::ErrorStatus> prepareModel_1_3(
+ const V1_3::Model& model,
+ V1_1::ExecutionPreference preference,
+ V1_3::Priority priority,
+ const V1_3::OptionalTimePoint&,
+ const android::hardware::hidl_vec<android::hardware::hidl_handle>& modelCache,
+ const android::hardware::hidl_vec<android::hardware::hidl_handle>& dataCache,
+ const HidlToken& token,
+ const android::sp<V1_3::IPreparedModelCallback>& cb)
{
ALOGV("hal_1_3::ArmnnDriver::prepareModel_1_3()");
@@ -199,11 +207,13 @@ public:
return V1_3::ErrorStatus::INVALID_ARGUMENT;
}
-
return ArmnnDriverImpl::prepareArmnnModel_1_3(m_Runtime,
m_ClTunedParameters,
m_Options,
model,
+ modelCache,
+ dataCache,
+ token,
cb,
model.relaxComputationFloat32toFloat16
&& m_Options.GetFp16Enabled(),
@@ -219,10 +229,13 @@ public:
Return<void> getNumberOfCacheFilesNeeded(getNumberOfCacheFilesNeeded_cb cb)
{
- ALOGV("hal_1_3::ArmnnDriver::getSupportedExtensions()");
-
- // Set both numbers to be 0 for cache not supported.
- cb(V1_0::ErrorStatus::NONE, 0, 0);
+ ALOGV("hal_1_3::ArmnnDriver::getNumberOfCacheFilesNeeded()");
+ unsigned int numberOfCachedModelFiles = 0;
+ for (auto& backend : m_Options.GetBackends())
+ {
+ numberOfCachedModelFiles += GetNumberOfCacheFiles(backend);
+ }
+ cb(V1_0::ErrorStatus::NONE, numberOfCachedModelFiles, 1ul);
return Void();
}
@@ -244,32 +257,41 @@ public:
Return<void> getType(getType_cb cb)
{
ALOGV("hal_1_3::ArmnnDriver::getType()");
-
- cb(V1_0::ErrorStatus::NONE, V1_2::DeviceType::CPU);
+ const auto device_type = hal_1_2::HalPolicy::GetDeviceTypeFromOptions(this->m_Options);
+ cb(V1_0::ErrorStatus::NONE, device_type);
return Void();
}
Return<V1_0::ErrorStatus> prepareModelFromCache(
- const android::hardware::hidl_vec<android::hardware::hidl_handle>&,
- const android::hardware::hidl_vec<android::hardware::hidl_handle>&,
- const HidlToken&,
- const android::sp<V1_2::IPreparedModelCallback>& callback)
+ const android::hardware::hidl_vec<android::hardware::hidl_handle>& modelCacheHandle,
+ const android::hardware::hidl_vec<android::hardware::hidl_handle>& dataCacheHandle,
+ const HidlToken& token,
+ const android::sp<V1_2::IPreparedModelCallback>& cb)
{
ALOGV("hal_1_3::ArmnnDriver::prepareModelFromCache()");
- callback->notify_1_2(V1_0::ErrorStatus::GENERAL_FAILURE, nullptr);
- return V1_0::ErrorStatus::GENERAL_FAILURE;
+ return hal_1_2::ArmnnDriverImpl::prepareModelFromCache(m_Runtime,
+ m_Options,
+ modelCacheHandle,
+ dataCacheHandle,
+ token,
+ cb);
}
Return<V1_3::ErrorStatus> prepareModelFromCache_1_3(
const V1_3::OptionalTimePoint&,
- const android::hardware::hidl_vec<android::hardware::hidl_handle>&,
- const android::hardware::hidl_vec<android::hardware::hidl_handle>&,
- const HidlToken&,
- const android::sp<V1_3::IPreparedModelCallback>& callback)
+ const android::hardware::hidl_vec<android::hardware::hidl_handle>& modelCacheHandle,
+ const android::hardware::hidl_vec<android::hardware::hidl_handle>& dataCacheHandle,
+ const HidlToken& token,
+ const android::sp<V1_3::IPreparedModelCallback>& cb)
{
- ALOGV("hal_1_3::ArmnnDriver::prepareModelFromCache()");
- callback->notify_1_3(V1_3::ErrorStatus::GENERAL_FAILURE, nullptr);
- return V1_3::ErrorStatus::GENERAL_FAILURE;
+ ALOGV("hal_1_3::ArmnnDriver::prepareModelFromCache_1_3()");
+
+ return ArmnnDriverImpl::prepareModelFromCache_1_3(m_Runtime,
+ m_Options,
+ modelCacheHandle,
+ dataCacheHandle,
+ token,
+ cb);
}
Return<void> allocate(const V1_3::BufferDesc& /*desc*/,
diff --git a/1.3/ArmnnDriverImpl.cpp b/1.3/ArmnnDriverImpl.cpp
index 6d8fbe64..ec176d59 100644
--- a/1.3/ArmnnDriverImpl.cpp
+++ b/1.3/ArmnnDriverImpl.cpp
@@ -1,5 +1,5 @@
//
-// Copyright © 2020 Arm Ltd. All rights reserved.
+// Copyright © 2020, 2023 Arm Ltd. All rights reserved.
// SPDX-License-Identifier: MIT
//
@@ -8,8 +8,13 @@
#include "../ModelToINetworkConverter.hpp"
#include "../SystemPropertiesUtils.hpp"
+#include <armnnDeserializer/IDeserializer.hpp>
+
#include <log/log.h>
+#include <sys/stat.h>
+#include <chrono>
+
namespace
{
const char *g_RelaxedFloat32toFloat16PerformanceExecTime = "ArmNN.relaxedFloat32toFloat16Performance.execTime";
@@ -100,12 +105,17 @@ Return<V1_3::ErrorStatus> ArmnnDriverImpl::prepareArmnnModel_1_3(
const armnn::IGpuAccTunedParametersPtr& clTunedParameters,
const DriverOptions& options,
const V1_3::Model& model,
+ const android::hardware::hidl_vec<android::hardware::hidl_handle>& modelCacheHandle,
+ const android::hardware::hidl_vec<android::hardware::hidl_handle>& dataCacheHandle,
+ const HidlToken& token,
const android::sp<V1_3::IPreparedModelCallback>& cb,
bool float32ToFloat16,
V1_3::Priority priority)
{
ALOGV("ArmnnDriverImpl::prepareArmnnModel_1_3()");
+ std::chrono::time_point<std::chrono::system_clock> prepareModelTimepoint = std::chrono::system_clock::now();
+
if (cb.get() == nullptr)
{
ALOGW("ArmnnDriverImpl::prepareModel: Invalid callback passed to prepareModel");
@@ -138,20 +148,56 @@ Return<V1_3::ErrorStatus> ArmnnDriverImpl::prepareArmnnModel_1_3(
// Serialize the network graph to a .armnn file if an output directory
// has been specified in the drivers' arguments.
+ std::vector<uint8_t> dataCacheData;
+ bool serializeToFile = dataCacheHandle.size() < 1 ? false : true;
auto serializedNetworkFileName =
- SerializeNetwork(*modelConverter.GetINetwork(), options.GetRequestInputsAndOutputsDumpDir());
+ SerializeNetwork(*modelConverter.GetINetwork(),
+ options.GetRequestInputsAndOutputsDumpDir(),
+ dataCacheData,
+ serializeToFile);
// Optimize the network
armnn::IOptimizedNetworkPtr optNet(nullptr, nullptr);
- armnn::OptimizerOptions OptOptions;
- OptOptions.m_ReduceFp32ToFp16 = float32ToFloat16;
+ armnn::OptimizerOptionsOpaque OptOptions;
+ OptOptions.SetReduceFp32ToFp16(float32ToFloat16);
+ OptOptions.SetProfilingEnabled(options.IsGpuProfilingEnabled());
+
+ int cachedFd = -1;
+ bool saveCachedNetwork = options.SaveCachedNetwork();
+
+ unsigned int numberOfCachedModelFiles = 0;
+ if (modelCacheHandle.size() > 0)
+ {
+ unsigned int index = 0;
+ for (auto& backend : options.GetBackends())
+ {
+ // modelCacheHandle size should be equal to numberOfCachedModelFiles
+ // modelCacheHandle vector should be in same order as backends
+ auto numberOfCacheFiles = GetNumberOfCacheFiles(backend);
+ if (numberOfCacheFiles > 0)
+ {
+ numberOfCachedModelFiles += numberOfCacheFiles;
+ if (modelCacheHandle[index]->numFds == 1)
+ {
+ // For GpuAcc numberOfCachedFiles is 1
+ if (backend == armnn::Compute::GpuAcc)
+ {
+ cachedFd = modelCacheHandle[index]->data[0];
+ saveCachedNetwork = true;
+ }
+ }
+ index += numberOfCachedModelFiles;
+ }
+ }
+ }
armnn::BackendOptions gpuAcc("GpuAcc",
{
{ "FastMathEnabled", options.IsFastMathEnabled() },
- { "SaveCachedNetwork", options.SaveCachedNetwork() },
+ { "SaveCachedNetwork", saveCachedNetwork },
{ "CachedNetworkFilePath", options.GetCachedNetworkFilePath() },
- { "MLGOTuningFilePath", options.GetClMLGOTunedParametersFile() }
+ { "MLGOTuningFilePath", options.GetClMLGOTunedParametersFile() },
+ { "CachedFileDescriptor", cachedFd }
});
armnn::BackendOptions cpuAcc("CpuAcc",
@@ -159,8 +205,8 @@ Return<V1_3::ErrorStatus> ArmnnDriverImpl::prepareArmnnModel_1_3(
{ "FastMathEnabled", options.IsFastMathEnabled() },
{ "NumberOfThreads", options.GetNumberOfThreads() }
});
- OptOptions.m_ModelOptions.push_back(gpuAcc);
- OptOptions.m_ModelOptions.push_back(cpuAcc);
+ OptOptions.AddModelOption(gpuAcc);
+ OptOptions.AddModelOption(cpuAcc);
std::vector<std::string> errMessages;
try
@@ -199,9 +245,17 @@ Return<V1_3::ErrorStatus> ArmnnDriverImpl::prepareArmnnModel_1_3(
// Load it into the runtime.
armnn::NetworkId netId = 0;
+ std::string msg;
+ armnn::INetworkProperties networkProperties(options.isAsyncModelExecutionEnabled(),
+ MemorySource::Undefined,
+ MemorySource::Undefined,
+ options.IsGpuProfilingEnabled());
+
+ auto numInputs = getMainModel(model).inputIndexes.size();
+ auto numOutputs = getMainModel(model).outputIndexes.size();
try
{
- if (runtime->LoadNetwork(netId, move(optNet)) != armnn::Status::Success)
+ if (runtime->LoadNetwork(netId, move(optNet), msg, networkProperties) != armnn::Status::Success)
{
return FailPrepareModel(V1_3::ErrorStatus::GENERAL_FAILURE, "Network could not be loaded", cb);
}
@@ -228,32 +282,390 @@ Return<V1_3::ErrorStatus> ArmnnDriverImpl::prepareArmnnModel_1_3(
model,
options.GetRequestInputsAndOutputsDumpDir(),
options.IsGpuProfilingEnabled(),
- priority));
+ priority,
+ options.isAsyncModelExecutionEnabled(),
+ options.getNoOfArmnnThreads(),
+ options.isImportEnabled(),
+ options.isExportEnabled()));
// Run a single 'dummy' inference of the model. This means that CL kernels will get compiled (and tuned if
// this is enabled) before the first 'real' inference which removes the overhead of the first inference.
- if (!preparedModel->ExecuteWithDummyInputs())
+ // Only run this if the GpuAcc backend has been added to options
+ if (std::find(options.GetBackends().begin(),
+ options.GetBackends().end(),
+ armnn::Compute::GpuAcc) != options.GetBackends().end())
+ {
+ if (!preparedModel->ExecuteWithDummyInputs(numInputs, numOutputs))
+ {
+ return FailPrepareModel(V1_3::ErrorStatus::GENERAL_FAILURE, "Network could not be executed", cb);
+ }
+
+ if (clTunedParameters &&
+ options.GetClTunedParametersMode() == armnn::IGpuAccTunedParameters::Mode::UpdateTunedParameters)
+ {
+ // Now that we've done one inference the CL kernel parameters will have been tuned,
+ // so save the updated file.
+ try
+ {
+ clTunedParameters->Save(options.GetClTunedParametersFile().c_str());
+ }
+ catch (std::exception& error)
+ {
+ ALOGE("ArmnnDriverImpl::prepareModel: Failed to save CL tuned parameters file '%s': %s",
+ options.GetClTunedParametersFile().c_str(), error.what());
+ }
+ }
+ }
+ size_t hashValue = 0;
+ // Cache the model
+ if (dataCacheHandle.size() > 0)
+ {
+ // Cache the Arm NN model
+ if (dataCacheHandle.size() != 1)
+ {
+ NotifyCallbackAndCheck(cb, V1_3::ErrorStatus::NONE, preparedModel.release());
+ return V1_3::ErrorStatus::NONE;
+ }
+
+ if (dataCacheHandle[0]->numFds != 1)
+ {
+ ALOGW("ArmnnDriverImpl::prepareArmnnModel_1_3: Cannot cache the data, numFds != 1.");
+ NotifyCallbackAndCheck(cb, V1_3::ErrorStatus::NONE, preparedModel.release());
+ return V1_3::ErrorStatus::NONE;
+ }
+
+ if (dataCacheHandle[0]->data[0] < 0)
+ {
+ ALOGW("ArmnnDriverImpl::prepareArmnnModel_1_3: Cannot cache the data, fd < 0");
+ NotifyCallbackAndCheck(cb, V1_3::ErrorStatus::NONE, preparedModel.release());
+ return V1_3::ErrorStatus::NONE;
+ }
+
+ int dataCacheFileAccessMode = fcntl(dataCacheHandle[0]->data[0], F_GETFL) & O_ACCMODE;
+ if (dataCacheFileAccessMode != O_RDWR)
+ {
+ ALOGW("ArmnnDriverImpl::prepareModelFromCache_1_3(): Invalid Access Mode.");
+ NotifyCallbackAndCheck(cb, V1_3::ErrorStatus::NONE, preparedModel.release());
+ return V1_3::ErrorStatus::NONE;
+ }
+
+ write(dataCacheHandle[0]->data[0], dataCacheData.data(), dataCacheData.size());
+ hashValue = CacheDataHandlerInstance().Hash(dataCacheData);
+ }
+
+ // Cache the model data
+ if (modelCacheHandle.size() > 0)
+ {
+ if (modelCacheHandle.size() != numberOfCachedModelFiles)
+ {
+ NotifyCallbackAndCheck(cb, V1_3::ErrorStatus::NONE, preparedModel.release());
+ return V1_3::ErrorStatus::NONE;
+ }
+
+ for (uint32_t i = 0; i < modelCacheHandle.size(); ++i)
+ {
+ if (modelCacheHandle[i]->numFds == 1)
+ {
+ int modelCacheFileAccessMode = fcntl(modelCacheHandle[i]->data[0], F_GETFL) & O_ACCMODE;
+ if (modelCacheFileAccessMode != O_RDONLY)
+ {
+ struct stat statBuffer;
+ if (fstat(modelCacheHandle[i]->data[0], &statBuffer) == 0)
+ {
+ long modelDataSize = statBuffer.st_size;
+ if (modelDataSize > 0)
+ {
+ std::vector<uint8_t> modelData(modelDataSize);
+ pread(modelCacheHandle[i]->data[0], modelData.data(), modelData.size(), 0);
+ hashValue ^= CacheDataHandlerInstance().Hash(modelData);
+ }
+ }
+ }
+ }
+ }
+ }
+ if (hashValue != 0)
+ {
+ CacheDataHandlerInstance().Register(token, hashValue, dataCacheData.size());
+ }
+
+ NotifyCallbackAndCheck(cb, V1_3::ErrorStatus::NONE, preparedModel.release());
+
+ ALOGV("ArmnnDriverImpl::prepareModel cache timing = %lld µs", std::chrono::duration_cast<std::chrono::microseconds>
+ (std::chrono::system_clock::now() - prepareModelTimepoint).count());
+
+
+ return V1_3::ErrorStatus::NONE;
+}
+
+Return<V1_3::ErrorStatus> ArmnnDriverImpl::prepareModelFromCache_1_3(
+ const armnn::IRuntimePtr& runtime,
+ const DriverOptions& options,
+ const android::hardware::hidl_vec<android::hardware::hidl_handle>& modelCacheHandle,
+ const android::hardware::hidl_vec<android::hardware::hidl_handle>& dataCacheHandle,
+ const HidlToken& token,
+ const android::sp<V1_3::IPreparedModelCallback>& cb)
+{
+ ALOGV("ArmnnDriverImpl::prepareModelFromCache_1_3()");
+ std::chrono::time_point<std::chrono::system_clock> modelFromCacheTimepoint = std::chrono::system_clock::now();
+
+ if (token.size() != ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN)
+ {
+ cb->notify_1_3(V1_3::ErrorStatus::GENERAL_FAILURE, nullptr);
+ return V1_3::ErrorStatus::GENERAL_FAILURE;
+ }
+
+ if (cb.get() == nullptr)
+ {
+ ALOGW("ArmnnDriverImpl::prepareModelFromCache_1_3: Invalid callback passed to prepareModelFromCache_1_3");
+ return V1_3::ErrorStatus::INVALID_ARGUMENT;
+ }
+
+ if (!runtime)
+ {
+ ALOGW("ArmnnDriverImpl::prepareModelFromCache_1_3: Device unavailable");
+ return V1_3::ErrorStatus::DEVICE_UNAVAILABLE;
+ }
+
+ // DataCacheHandle size should always be 1
+ // Arm NN model
+ if (dataCacheHandle.size() != 1)
+ {
+ cb->notify_1_3(V1_3::ErrorStatus::GENERAL_FAILURE, nullptr);
+ return V1_3::ErrorStatus::GENERAL_FAILURE;
+ }
+
+ // Check if model files cached they match the expected value
+ unsigned int numberOfCachedModelFiles = 0;
+ for (auto& backend : options.GetBackends())
+ {
+ numberOfCachedModelFiles += GetNumberOfCacheFiles(backend);
+ }
+ if (modelCacheHandle.size() != numberOfCachedModelFiles)
+ {
+ cb->notify_1_3(V1_3::ErrorStatus::GENERAL_FAILURE, nullptr);
+ return V1_3::ErrorStatus::GENERAL_FAILURE;
+ }
+
+ if (dataCacheHandle[0]->numFds != 1)
+ {
+ ALOGW("ArmnnDriverImpl::prepareModelFromCache_1_3(): Cannot read from the cache data, numFds != 1.");
+ cb->notify_1_3(V1_3::ErrorStatus::GENERAL_FAILURE, nullptr);
+ return V1_3::ErrorStatus::GENERAL_FAILURE;
+ }
+
+ if (dataCacheHandle[0]->data[0] < 0)
+ {
+ ALOGW("ArmnnDriverImpl::prepareModelFromCache_1_3(): Cannot read from the cache data, fd < 0");
+ cb->notify_1_3(V1_3::ErrorStatus::GENERAL_FAILURE, nullptr);
+ return V1_3::ErrorStatus::GENERAL_FAILURE;
+ }
+
+ int dataCacheFileAccessMode = fcntl(dataCacheHandle[0]->data[0], F_GETFL) & O_ACCMODE;
+ if (dataCacheFileAccessMode != O_RDWR)
{
- return FailPrepareModel(V1_3::ErrorStatus::GENERAL_FAILURE, "Network could not be executed", cb);
+ cb->notify_1_3(V1_3::ErrorStatus::GENERAL_FAILURE, nullptr);
+ return V1_3::ErrorStatus::GENERAL_FAILURE;
}
- if (clTunedParameters &&
- options.GetClTunedParametersMode() == armnn::IGpuAccTunedParameters::Mode::UpdateTunedParameters)
+ auto dataSize = CacheDataHandlerInstance().GetCacheSize(token);
+ if (dataSize == 0)
{
- // Now that we've done one inference the CL kernel parameters will have been tuned, so save the updated file.
- try
+ ALOGW("ArmnnDriverImpl::prepareModelFromCache_1_3: Invalid data to deserialize!");
+ cb->notify_1_3(V1_3::ErrorStatus::GENERAL_FAILURE, nullptr);
+ return V1_3::ErrorStatus::GENERAL_FAILURE;
+ }
+
+ int offset = 0;
+ {
+ struct stat statBuffer;
+ if (fstat(dataCacheHandle[0]->data[0], &statBuffer) == 0)
+ {
+ unsigned long bufferSize = statBuffer.st_size;
+ if (bufferSize != dataSize)
+ {
+ ALOGW("ArmnnDriverImpl::prepareModelFromCache_1_3: Invalid data to deserialize!");
+ cb->notify_1_3(V1_3::ErrorStatus::GENERAL_FAILURE, nullptr);
+ return V1_3::ErrorStatus::GENERAL_FAILURE;
+ }
+ }
+ }
+ std::vector<uint8_t> dataCacheData(dataSize);
+ pread(dataCacheHandle[0]->data[0], dataCacheData.data(), dataCacheData.size(), offset);
+ auto hashValue = CacheDataHandlerInstance().Hash(dataCacheData);
+
+ int gpuAccCachedFd = -1;
+ bool saveCachedNetwork = false;
+ if (modelCacheHandle.size() > 0)
+ {
+ unsigned int index = 0;
+ for (auto& backend : options.GetBackends())
+ {
+ // modelCacheHandle size should be equal to numberOfCachedModelFiles
+ // modelCacheHandle vector should be in same order as backends
+ auto numberOfCacheFiles = GetNumberOfCacheFiles(backend);
+ if (numberOfCacheFiles > 0)
+ {
+ if (modelCacheHandle[index]->numFds != 1)
+ {
+ ALOGW(
+ "ArmnnDriverImpl::prepareModelFromCache_1_3(): Cannot read from the model cache, numFds != 1.");
+ cb->notify_1_3(V1_3::ErrorStatus::GENERAL_FAILURE, nullptr);
+ return V1_3::ErrorStatus::GENERAL_FAILURE;
+ }
+ auto cachedFd = modelCacheHandle[index]->data[0];
+
+ int modelCacheFileAccessMode = fcntl(cachedFd, F_GETFL) & O_ACCMODE;
+ if (modelCacheFileAccessMode != O_RDWR)
+ {
+ cb->notify_1_3(V1_3::ErrorStatus::GENERAL_FAILURE, nullptr);
+ return V1_3::ErrorStatus::GENERAL_FAILURE;
+ }
+
+ struct stat statBuffer;
+ if (cachedFd != -1 && fstat(cachedFd, &statBuffer) == 0)
+ {
+ long modelDataSize = statBuffer.st_size;
+ if (modelDataSize <= 0)
+ {
+ ALOGW("ArmnnDriverImpl::prepareModelFromCache_1_3(): Wrong cached model size!");
+ cb->notify_1_3(V1_3::ErrorStatus::GENERAL_FAILURE, nullptr);
+ return V1_3::ErrorStatus::NONE;
+ }
+ std::vector<uint8_t> modelData(modelDataSize);
+ pread(cachedFd, modelData.data(), modelData.size(), 0);
+ hashValue ^= CacheDataHandlerInstance().Hash(modelData);
+
+ // For GpuAcc numberOfCachedFiles is 1
+ if (backend == armnn::Compute::GpuAcc)
+ {
+ gpuAccCachedFd = cachedFd;
+ }
+ }
+ index += numberOfCacheFiles;
+ }
+ }
+ }
+
+ if (!CacheDataHandlerInstance().Validate(token, hashValue, dataCacheData.size()))
+ {
+ ALOGW("ArmnnDriverImpl::prepareModelFromCache_1_3: ValidateHash() failed!");
+ cb->notify_1_3(V1_3::ErrorStatus::GENERAL_FAILURE, nullptr);
+ return V1_3::ErrorStatus::GENERAL_FAILURE;
+ }
+
+ // Deserialize the network..
+ armnn::INetworkPtr network = armnn::INetworkPtr(nullptr, [](armnn::INetwork*){});
+ try
+ {
+ network = armnnDeserializer::IDeserializer::Create()->CreateNetworkFromBinary(dataCacheData);
+ }
+ catch (std::exception&)
+ {
+ ALOGW("ArmnnDriverImpl::prepareModelFromCache_1_3: Exception caught from Deserializer!");
+ cb->notify_1_3(V1_3::ErrorStatus::GENERAL_FAILURE, nullptr);
+ return V1_3::ErrorStatus::GENERAL_FAILURE;
+ }
+
+ // Optimize the network
+ armnn::IOptimizedNetworkPtr optNet(nullptr, nullptr);
+ armnn::OptimizerOptionsOpaque OptOptions;
+ OptOptions.SetReduceFp32ToFp16(options.GetFp16Enabled());
+ OptOptions.SetProfilingEnabled(options.IsGpuProfilingEnabled());
+
+ armnn::BackendOptions gpuAcc("GpuAcc",
+ {
+ {"FastMathEnabled", options.IsFastMathEnabled()},
+ {"SaveCachedNetwork", saveCachedNetwork},
+ {"CachedNetworkFilePath", options.GetCachedNetworkFilePath()},
+ {"MLGOTuningFilePath", options.GetClMLGOTunedParametersFile()},
+ {"CachedFileDescriptor", gpuAccCachedFd}
+ });
+
+ armnn::BackendOptions cpuAcc("CpuAcc",
+ {
+ {"FastMathEnabled", options.IsFastMathEnabled()},
+ {"NumberOfThreads", options.GetNumberOfThreads()}
+ });
+ OptOptions.AddModelOption(gpuAcc);
+ OptOptions.AddModelOption(cpuAcc);
+
+ std::vector<std::string> errMessages;
+ try
+ {
+ optNet = armnn::Optimize(*network.get(),
+ options.GetBackends(),
+ runtime->GetDeviceSpec(),
+ OptOptions,
+ errMessages);
+ }
+ catch (std::exception& e)
+ {
+ std::stringstream message;
+ message << "Exception (" << e.what() << ") caught from optimize.";
+ FailPrepareModel(V1_3::ErrorStatus::GENERAL_FAILURE, message.str(), cb);
+ return V1_3::ErrorStatus::NONE;
+ }
+
+ // Check that the optimized network is valid.
+ if (!optNet)
+ {
+ std::stringstream message;
+ message << "Invalid optimized network";
+ for (const std::string& msg : errMessages)
{
- clTunedParameters->Save(options.GetClTunedParametersFile().c_str());
+ message << "\n" << msg;
}
- catch (std::exception& error)
+ FailPrepareModel(V1_3::ErrorStatus::GENERAL_FAILURE, message.str(), cb);
+ return V1_3::ErrorStatus::NONE;
+ }
+
+ // Export the optimized network graph to a dot file if an output dump directory
+ // has been specified in the drivers' arguments.
+ std::string dotGraphFileName = ExportNetworkGraphToDotFile(*optNet,
+ options.GetRequestInputsAndOutputsDumpDir());
+
+ // Load it into the runtime.
+ armnn::NetworkId netId = 0;
+ std::string msg;
+ armnn::INetworkProperties networkProperties(options.isAsyncModelExecutionEnabled(),
+ MemorySource::Undefined,
+ MemorySource::Undefined,
+ options.IsGpuProfilingEnabled());
+
+ try
+ {
+ if (runtime->LoadNetwork(netId, move(optNet), msg, networkProperties) != armnn::Status::Success)
{
- ALOGE("ArmnnDriverImpl::prepareModel: Failed to save CL tuned parameters file '%s': %s",
- options.GetClTunedParametersFile().c_str(), error.what());
+ return FailPrepareModel(V1_3::ErrorStatus::GENERAL_FAILURE, msg, cb);
}
}
+ catch (std::exception& e)
+ {
+ std::stringstream message;
+ message << "Exception (" << e.what() << ") caught from LoadNetwork.";
+ FailPrepareModel(V1_3::ErrorStatus::GENERAL_FAILURE, message.str(), cb);
+ return V1_3::ErrorStatus::NONE;
+ }
+
+ std::unique_ptr<ArmnnPreparedModel_1_3<hal_1_3::HalPolicy>> preparedModel(
+ new ArmnnPreparedModel_1_3<hal_1_3::HalPolicy>(netId,
+ runtime.get(),
+ options.GetRequestInputsAndOutputsDumpDir(),
+ options.IsGpuProfilingEnabled(),
+ V1_3::Priority::MEDIUM,
+ options.isAsyncModelExecutionEnabled(),
+ options.getNoOfArmnnThreads(),
+ options.isImportEnabled(),
+ options.isExportEnabled(),
+ true));
NotifyCallbackAndCheck(cb, V1_3::ErrorStatus::NONE, preparedModel.release());
+ ALOGV("ArmnnDriverImpl::prepareModelFromCache timing = %lld µs",
+ std::chrono::duration_cast<std::chrono::microseconds>
+ (std::chrono::system_clock::now() - modelFromCacheTimepoint).count());
+
return V1_3::ErrorStatus::NONE;
}
diff --git a/1.3/ArmnnDriverImpl.hpp b/1.3/ArmnnDriverImpl.hpp
index 3c094fe5..a482edac 100644
--- a/1.3/ArmnnDriverImpl.hpp
+++ b/1.3/ArmnnDriverImpl.hpp
@@ -7,6 +7,7 @@
#include <HalInterfaces.h>
+#include "../CacheDataHandler.hpp"
#include "../DriverOptions.hpp"
#include <armnn/ArmNN.hpp>
@@ -31,13 +32,27 @@ namespace hal_1_3
class ArmnnDriverImpl
{
public:
- static Return<V1_3::ErrorStatus> prepareArmnnModel_1_3(const armnn::IRuntimePtr& runtime,
- const armnn::IGpuAccTunedParametersPtr& clTunedParameters,
- const DriverOptions& options,
- const V1_3::Model& model,
- const android::sp<V1_3::IPreparedModelCallback>& cb,
- bool float32ToFloat16 = false,
- V1_3::Priority priority = V1_3::Priority::MEDIUM);
+ using HidlToken = android::hardware::hidl_array<uint8_t, ANEURALNETWORKS_BYTE_SIZE_OF_CACHE_TOKEN>;
+
+ static Return<V1_3::ErrorStatus> prepareArmnnModel_1_3(
+ const armnn::IRuntimePtr& runtime,
+ const armnn::IGpuAccTunedParametersPtr& clTunedParameters,
+ const DriverOptions& options,
+ const V1_3::Model& model,
+ const android::hardware::hidl_vec<android::hardware::hidl_handle>& modelCacheHandle,
+ const android::hardware::hidl_vec<android::hardware::hidl_handle>& dataCacheHandle,
+ const HidlToken& token,
+ const android::sp<V1_3::IPreparedModelCallback>& cb,
+ bool float32ToFloat16 = false,
+ V1_3::Priority priority = V1_3::Priority::MEDIUM);
+
+ static Return<V1_3::ErrorStatus> prepareModelFromCache_1_3(
+ const armnn::IRuntimePtr& runtime,
+ const DriverOptions& options,
+ const android::hardware::hidl_vec<android::hardware::hidl_handle>& modelCacheHandle,
+ const android::hardware::hidl_vec<android::hardware::hidl_handle>& dataCacheHandle,
+ const HidlToken& token,
+ const android::sp<V1_3::IPreparedModelCallback>& cb);
static Return<void> getCapabilities_1_3(const armnn::IRuntimePtr& runtime,
V1_3::IDevice::getCapabilities_1_3_cb cb);
diff --git a/1.3/HalPolicy.cpp b/1.3/HalPolicy.cpp
index d58ac6c6..e5f295fd 100644
--- a/1.3/HalPolicy.cpp
+++ b/1.3/HalPolicy.cpp
@@ -1,5 +1,5 @@
//
-// Copyright © 2020 Arm Ltd. All rights reserved.
+// Copyright © 2020-2023 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//
@@ -24,7 +24,7 @@ bool HalPolicy::ConvertOperation(const Operation& operation, const Model& model,
case V1_3::OperationType::ABS:
return ConvertElementwiseUnary(operation, model, data, UnaryOperation::Abs);
case V1_3::OperationType::ADD:
- return ConvertAdd(operation, model, data);
+ return ConvertElementwiseBinary(operation, model, data, BinaryOperation::Add);
case V1_3::OperationType::ARGMAX:
return ConvertArgMinMax(operation, model, data, ArgMinMaxFunction::Max);
case V1_3::OperationType::ARGMIN:
@@ -33,6 +33,10 @@ bool HalPolicy::ConvertOperation(const Operation& operation, const Model& model,
return ConvertAveragePool2d(operation, model, data);
case V1_3::OperationType::BATCH_TO_SPACE_ND:
return ConvertBatchToSpaceNd(operation, model, data);
+ case V1_3::OperationType::CAST:
+ return ConvertCast(operation, model, data);
+ case V1_3::OperationType::CHANNEL_SHUFFLE:
+ return ConvertChannelShuffle(operation, model, data);
case V1_3::OperationType::CONCATENATION:
return ConvertConcatenation(operation, model, data);
case V1_3::OperationType::CONV_2D:
@@ -44,7 +48,7 @@ bool HalPolicy::ConvertOperation(const Operation& operation, const Model& model,
case V1_3::OperationType::DEQUANTIZE:
return ConvertDequantize(operation, model, data);
case V1_3::OperationType::DIV:
- return ConvertDiv(operation, model, data);
+ return ConvertElementwiseBinary(operation, model, data, BinaryOperation::Div);
case V1_3::OperationType::ELU:
return ConvertElu(operation, model, data);
case V1_3::OperationType::EQUAL:
@@ -81,6 +85,8 @@ bool HalPolicy::ConvertOperation(const Operation& operation, const Model& model,
return ConvertComparison(operation, model, data, ComparisonOperation::LessOrEqual);
case V1_3::OperationType::LOCAL_RESPONSE_NORMALIZATION:
return ConvertLocalResponseNormalization(operation, model, data);
+ case V1_3::OperationType::LOG:
+ return ConvertElementwiseUnary(operation, model, data, UnaryOperation::Log);
case V1_3::OperationType::LOGICAL_AND:
return ConvertLogicalBinary(operation, model, data, LogicalBinaryOperation::LogicalAnd);
case V1_3::OperationType::LOGICAL_NOT:
@@ -96,13 +102,13 @@ bool HalPolicy::ConvertOperation(const Operation& operation, const Model& model,
case V1_3::OperationType::MAX_POOL_2D:
return ConvertMaxPool2d(operation, model, data);
case V1_3::OperationType::MAXIMUM:
- return ConvertMaximum(operation, model, data);
+ return ConvertElementwiseBinary(operation, model, data, BinaryOperation::Maximum);
case V1_3::OperationType::MEAN:
return ConvertMean(operation, model, data);
case V1_3::OperationType::MINIMUM:
- return ConvertMinimum(operation, model, data);
+ return ConvertElementwiseBinary(operation, model, data, BinaryOperation::Minimum);
case V1_3::OperationType::MUL:
- return ConvertMul(operation, model, data);
+ return ConvertElementwiseBinary(operation, model, data, BinaryOperation::Mul);
case V1_3::OperationType::NEG:
return ConvertElementwiseUnary(operation, model, data, UnaryOperation::Neg);
case V1_3::OperationType::NOT_EQUAL:
@@ -111,6 +117,8 @@ bool HalPolicy::ConvertOperation(const Operation& operation, const Model& model,
return ConvertPad(operation, model, data);
case V1_3::OperationType::PAD_V2:
return ConvertPadV2(operation, model, data);
+ case V1_3::OperationType::POW:
+ return ConvertElementwiseBinary(operation, model, data, BinaryOperation::Power);
case V1_3::OperationType::PRELU:
return ConvertPrelu(operation, model, data);
case V1_3::OperationType::QUANTIZE:
@@ -125,6 +133,8 @@ bool HalPolicy::ConvertOperation(const Operation& operation, const Model& model,
return ConvertReduce(operation, model, data, ReduceOperation::Max);
case V1_3::OperationType::REDUCE_MIN:
return ConvertReduce(operation, model, data, ReduceOperation::Min);
+ case V1_3::OperationType::REDUCE_PROD:
+ return ConvertReduce(operation, model, data, ReduceOperation::Prod);
case V1_3::OperationType::REDUCE_SUM:
return ConvertReduce(operation, model, data, ReduceOperation::Sum);
case V1_3::OperationType::RELU:
@@ -141,38 +151,40 @@ bool HalPolicy::ConvertOperation(const Operation& operation, const Model& model,
return ConvertResize(operation, model, data, ResizeMethod::NearestNeighbor);
case V1_3::OperationType::RSQRT:
return ConvertElementwiseUnary(operation, model, data, UnaryOperation::Rsqrt);
+ case V1_3::OperationType::SIN:
+ return ConvertElementwiseUnary(operation, model, data, UnaryOperation::Sin);
+ case V1_3::OperationType::SOFTMAX:
+ return ConvertSoftmax(operation, model, data);
+ case V1_3::OperationType::SPACE_TO_BATCH_ND :
+ return ConvertSpaceToBatchNd(operation, model, data);
+ case V1_3::OperationType::SPACE_TO_DEPTH:
+ return ConvertSpaceToDepth(operation, model, data);
+ case V1_3::OperationType::SPLIT:
+ return ConvertSplit(operation, model, data);
case V1_3::OperationType::SQRT:
return ConvertSqrt(operation, model, data);
case V1_3::OperationType::SQUEEZE:
return ConvertSqueeze(operation, model, data);
case V1_3::OperationType::STRIDED_SLICE:
return ConvertStridedSlice(operation, model, data);
+ case V1_3::OperationType::SUB:
+ return ConvertElementwiseBinary(operation, model, data, BinaryOperation::Sub);
case V1_3::OperationType::TRANSPOSE:
return ConvertTranspose(operation, model, data);
case V1_3::OperationType::TRANSPOSE_CONV_2D:
return ConvertTransposeConv2d(operation, model, data);
- case V1_3::OperationType::SOFTMAX:
- return ConvertSoftmax(operation, model, data);
- case V1_3::OperationType::SPACE_TO_BATCH_ND :
- return ConvertSpaceToBatchNd(operation, model, data);
- case V1_3::OperationType::SPACE_TO_DEPTH:
- return ConvertSpaceToDepth(operation, model, data);
- case V1_3::OperationType::SUB:
- return ConvertSub(operation, model, data);
case V1_3::OperationType::TANH:
return ConvertTanH(operation, model, data);
+ case V1_3::OperationType::TILE:
+ return ConvertTile(operation, model, data);
+ case V1_3::OperationType::UNIDIRECTIONAL_SEQUENCE_LSTM:
+ return ConvertUnidirectionalSequenceLstm(operation, model, data);
default:
return Fail("%s: Operation type %s not supported in ArmnnDriver",
__func__, toString(operation.type).c_str());
}
}
-bool HalPolicy::ConvertAdd(const Operation& operation, const Model& model, ConversionData& data)
-{
- ALOGV("hal_1_3::HalPolicy::ConvertAdd()");
- return ::ConvertAdd<hal_1_3::HalPolicy>(operation, model, data);
-}
-
bool HalPolicy::ConvertArgMinMax(const V1_3::Operation& operation,
const V1_3::Model& model,
ConversionData& data,
@@ -194,6 +206,18 @@ bool HalPolicy::ConvertBatchToSpaceNd(const Operation& operation, const Model& m
return ::ConvertBatchToSpaceNd<hal_1_3::HalPolicy>(operation, model, data);
}
+bool HalPolicy::ConvertCast(const Operation& operation, const Model& model, ConversionData& data)
+{
+ ALOGV("hal_1_3::HalPolicy::ConvertCast()");
+ return ::ConvertCast<hal_1_3::HalPolicy>(operation, model, data);
+}
+
+bool HalPolicy::ConvertChannelShuffle(const Operation& operation, const Model& model, ConversionData& data)
+{
+ ALOGV("hal_1_3::HalPolicy::ConvertChannelShuffle()");
+ return ::ConvertChannelShuffle<hal_1_3::HalPolicy>(operation, model, data);
+}
+
bool HalPolicy::ConvertComparison(const Operation& operation,
const Model& model,
ConversionData& data,
@@ -203,7 +227,6 @@ bool HalPolicy::ConvertComparison(const Operation& operation,
return ::ConvertComparison_1_2<hal_1_3::HalPolicy>(operation, model, data, comparisonOperation);
}
-
bool HalPolicy::ConvertConcatenation(const Operation& operation, const Model& model, ConversionData& data)
{
ALOGV("hal_1_3::HalPolicy::ConvertConcatenation()");
@@ -234,10 +257,13 @@ bool HalPolicy::ConvertDequantize(const Operation& operation, const Model& model
return ::ConvertDequantize_1_2<hal_1_3::HalPolicy>(operation, model, data);
}
-bool HalPolicy::ConvertDiv(const Operation& operation, const Model& model, ConversionData& data)
+bool HalPolicy::ConvertElementwiseBinary(const Operation& operation,
+ const Model& model,
+ ConversionData& data,
+ BinaryOperation binaryOperation)
{
- ALOGV("hal_1_3::HalPolicy::ConvertDiv()");
- return ::ConvertDiv<hal_1_3::HalPolicy>(operation, model, data);
+ ALOGV("hal_1_3::HalPolicy::ConvertElementwiseBinary()");
+ return ::ConvertElementwiseBinary<hal_1_3::HalPolicy>(operation, model, data, binaryOperation);
}
bool HalPolicy::ConvertElementwiseUnary(const Operation& operation,
@@ -359,30 +385,12 @@ bool HalPolicy::ConvertMaxPool2d(const Operation& operation, const Model& model,
return ConvertPooling2d<hal_1_3::HalPolicy>(operation, __func__, PoolingAlgorithm::Max, model, data);
}
-bool HalPolicy::ConvertMaximum(const Operation& operation, const Model& model, ConversionData& data)
-{
- ALOGV("hal_1_3::HalPolicy::ConvertMaximum()");
- return ::ConvertMaximum<hal_1_3::HalPolicy>(operation, model, data);
-}
-
bool HalPolicy::ConvertMean(const Operation& operation, const Model& model, ConversionData& data)
{
ALOGV("hal_1_3::HalPolicy::ConvertMean()");
return ::ConvertMean<hal_1_3::HalPolicy>(operation, model, data);
}
-bool HalPolicy::ConvertMinimum(const Operation& operation, const Model& model, ConversionData& data)
-{
- ALOGV("hal_1_3::HalPolicy::ConvertMinimum()");
- return ::ConvertMinimum<hal_1_3::HalPolicy>(operation, model, data);
-}
-
-bool HalPolicy::ConvertMul(const Operation& operation, const Model& model, ConversionData& data)
-{
- ALOGV("hal_1_3::HalPolicy::ConvertMul()");
- return ::ConvertMul<hal_1_3::HalPolicy>(operation, model, data);
-}
-
bool HalPolicy::ConvertPad(const Operation& operation, const Model& model, ConversionData& data)
{
ALOGV("hal_1_3::HalPolicy::ConvertPad()");
@@ -485,12 +493,6 @@ bool HalPolicy::ConvertSoftmax(const Operation& operation, const Model& model, C
return ::ConvertSoftmax<hal_1_3::HalPolicy>(operation, model, data);
}
-bool HalPolicy::ConvertSub(const Operation& operation, const Model& model, ConversionData& data)
-{
- ALOGV("hal_1_3::HalPolicy::ConvertSub()");
- return ::ConvertSub<hal_1_3::HalPolicy>(operation, model, data);
-}
-
bool HalPolicy::ConvertTanH(const Operation& operation, const Model& model, ConversionData& data)
{
ALOGV("hal_1_3::HalPolicy::ConvertTanH()");
@@ -503,6 +505,18 @@ bool HalPolicy::ConvertTransposeConv2d(const Operation& operation, const Model&
return ::ConvertTransposeConv2d<hal_1_3::HalPolicy>(operation, model, data);
}
+bool HalPolicy::ConvertSplit(const Operation& operation, const Model& model, ConversionData& data)
+{
+ ALOGV("hal_1_3::HalPolicy::ConvertSplit()");
+ return ::ConvertSplit<hal_1_3::HalPolicy>(operation, model, data);
+}
+
+bool HalPolicy::ConvertTile(const Operation& operation, const Model& model, ConversionData& data)
+{
+ ALOGV("hal_1_3::HalPolicy::ConvertTile()");
+ return ::ConvertTile<hal_1_3::HalPolicy>(operation, model, data);
+}
+
bool HalPolicy::ConvertSqrt(const Operation& operation, const Model& model, ConversionData& data)
{
ALOGV("hal_1_3::HalPolicy::ConvertSqrt()");
@@ -530,5 +544,11 @@ bool HalPolicy::ConvertTranspose(const Operation& operation, const Model& model,
return ::ConvertTranspose<hal_1_3::HalPolicy>(operation, model, data);
}
+bool HalPolicy::ConvertUnidirectionalSequenceLstm(const Operation& operation, const Model& model, ConversionData& data)
+{
+ ALOGV("hal_1_3::HalPolicy::ConvertUnidirectionalSequenceLstm()");
+ return ::ConvertUnidirectionalSequenceLstm<hal_1_3::HalPolicy>(operation, model, data);
+}
+
} // namespace hal_1_3
} // namespace armnn_driver
diff --git a/1.3/HalPolicy.hpp b/1.3/HalPolicy.hpp
index 6dfb8856..c876da19 100644
--- a/1.3/HalPolicy.hpp
+++ b/1.3/HalPolicy.hpp
@@ -1,5 +1,5 @@
//
-// Copyright © 2020 Arm Ltd. All rights reserved.
+// Copyright © 2020-2023 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//
@@ -36,8 +36,6 @@ public:
static bool ConvertOperation(const Operation& operation, const Model& model, ConversionData& data);
private:
- static bool ConvertAdd(const Operation& operation, const Model& model, ConversionData& data);
-
static bool ConvertArgMinMax(const Operation& operation,
const Model& model,
ConversionData& data,
@@ -47,6 +45,10 @@ private:
static bool ConvertBatchToSpaceNd(const Operation& operation, const Model& model, ConversionData& data);
+ static bool ConvertCast(const Operation& operation, const Model& model, ConversionData& data);
+
+ static bool ConvertChannelShuffle(const Operation& operation, const Model& model, ConversionData& data);
+
static bool ConvertComparison(const Operation& operation,
const Model& model,
ConversionData& data,
@@ -62,7 +64,10 @@ private:
static bool ConvertDequantize(const Operation& operation, const Model& model, ConversionData& data);
- static bool ConvertDiv(const Operation& operation, const Model& model, ConversionData& data);
+ static bool ConvertElementwiseBinary(const Operation& operation,
+ const Model& model,
+ ConversionData& data,
+ armnn::BinaryOperation binaryOperation);
static bool ConvertElementwiseUnary(const Operation& operation,
const Model& model,
@@ -108,14 +113,8 @@ private:
static bool ConvertMaxPool2d(const Operation& operation, const Model& model, ConversionData& data);
- static bool ConvertMaximum(const Operation& operation, const Model& model, ConversionData& data);
-
static bool ConvertMean(const Operation& operation, const Model& model, ConversionData& data);
- static bool ConvertMinimum(const Operation& operation, const Model& model, ConversionData& data);
-
- static bool ConvertMul(const Operation& operation, const Model& model, ConversionData& data);
-
static bool ConvertPad(const Operation& operation, const Model& model, ConversionData& data);
static bool ConvertPadV2(const Operation& operation, const Model& model, ConversionData& data);
@@ -154,19 +153,25 @@ private:
static bool ConvertSpaceToDepth(const Operation& operation, const Model& model, ConversionData& data);
+ static bool ConvertSplit(const Operation& operation, const Model& model, ConversionData& data);
+
static bool ConvertSqrt(const Operation& operation, const Model& model, ConversionData& data);
static bool ConvertSqueeze(const Operation& operation, const Model& model, ConversionData& data);
static bool ConvertStridedSlice(const Operation& operation, const Model& model, ConversionData& data);
- static bool ConvertSub(const Operation& operation, const Model& model, ConversionData& data);
-
static bool ConvertTanH(const Operation& operation, const Model& model, ConversionData& data);
static bool ConvertTranspose(const Operation& operation, const Model& model, ConversionData& data);
static bool ConvertTransposeConv2d(const Operation& operation, const Model& model, ConversionData& data);
+
+ static bool ConvertTile(const Operation& operation, const Model& model, ConversionData& data);
+
+ static bool ConvertUnidirectionalSequenceLstm(const Operation& operation,
+ const Model& model,
+ ConversionData& data);
};
} // namespace hal_1_3