1 //
2 // Copyright © 2017, 2023 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5
6 #define LOG_TAG "ArmnnDriver"
7
8 #include "ArmnnDevice.hpp"
9
10 #include <OperationsUtils.h>
11
12 #include <log/log.h>
13
14 #include <memory>
15 #include <string>
16
17 using namespace android;
18
19 namespace
20 {
21
GetBackendString(const armnn_driver::DriverOptions & options)22 std::string GetBackendString(const armnn_driver::DriverOptions& options)
23 {
24 std::stringstream backends;
25 for (auto&& b : options.GetBackends())
26 {
27 backends << b << " ";
28 }
29 return backends.str();
30 }
31
32 } // anonymous namespace
33
34 namespace armnn_driver
35 {
36
ArmnnDevice(DriverOptions options)37 ArmnnDevice::ArmnnDevice(DriverOptions options)
38 : m_Runtime(nullptr, nullptr)
39 , m_ClTunedParameters(nullptr)
40 , m_Options(std::move(options))
41 {
42 ALOGV("ArmnnDevice::ArmnnDevice()");
43
44 armnn::ConfigureLogging(false, m_Options.IsVerboseLoggingEnabled(), armnn::LogSeverity::Trace);
45 if (m_Options.IsVerboseLoggingEnabled())
46 {
47 SetMinimumLogSeverity(base::VERBOSE);
48 }
49 else
50 {
51 SetMinimumLogSeverity(base::INFO);
52 }
53
54 armnn::IRuntime::CreationOptions runtimeOptions;
55
56 #if defined(ARMCOMPUTECL_ENABLED)
57 try
58 {
59 if (!m_Options.GetClTunedParametersFile().empty())
60 {
61 m_ClTunedParameters = armnn::IGpuAccTunedParameters::Create(m_Options.GetClTunedParametersMode(),
62 m_Options.GetClTuningLevel());
63 try
64 {
65 m_ClTunedParameters->Load(m_Options.GetClTunedParametersFile().c_str());
66 }
67 catch (std::exception& error)
68 {
69 // This is only a warning because the file won't exist the first time you are generating it.
70 ALOGW("ArmnnDevice: Failed to load CL tuned parameters file '%s': %s",
71 m_Options.GetClTunedParametersFile().c_str(), error.what());
72 }
73 runtimeOptions.m_GpuAccTunedParameters = m_ClTunedParameters;
74 }
75 }
76 catch (const armnn::ClRuntimeUnavailableException& error)
77 {
78 ALOGE("ArmnnDevice: Failed to setup CL runtime: %s. Device will be unavailable.", error.what());
79 }
80 catch (std::exception& error)
81 {
82 ALOGE("ArmnnDevice: Unknown exception: %s. Device will be unavailable.", error.what());
83 }
84 #endif
85 runtimeOptions.m_EnableGpuProfiling = m_Options.IsGpuProfilingEnabled();
86 m_Runtime = armnn::IRuntime::Create(runtimeOptions);
87
88 std::vector<armnn::BackendId> backends;
89
90 if (m_Runtime)
91 {
92 const armnn::BackendIdSet supportedDevices = m_Runtime->GetDeviceSpec().GetSupportedBackends();
93 for (auto &backend : m_Options.GetBackends())
94 {
95 if (std::find(supportedDevices.cbegin(), supportedDevices.cend(), backend) == supportedDevices.cend())
96 {
97 ALOGW("ArmnnDevice: Requested unknown backend %s", backend.Get().c_str());
98 }
99 else
100 {
101 if (m_Options.isAsyncModelExecutionEnabled() &&
102 armnn::HasCapability(armnn::BackendOptions::BackendOption{"AsyncExecution", false}, backend))
103 {
104 ALOGV("ArmnnDevice: ArmNN does not support AsyncExecution with the following backend: %s",
105 backend.Get().c_str());
106 }
107 else
108 {
109 backends.push_back(backend);
110 }
111 }
112 }
113 }
114
115 if (backends.empty())
116 {
117 // No known backend specified
118 throw armnn::InvalidArgumentException("ArmnnDevice: No known backend specified.");
119 }
120
121 m_Options.SetBackends(backends);
122 ALOGV("ArmnnDevice: Created device with the following backends: %s",
123 GetBackendString(m_Options).c_str());
124 }
125
126 } // namespace armnn_driver
127