1*89c4ff92SAndroid Build Coastguard Worker //
2*89c4ff92SAndroid Build Coastguard Worker // Copyright © 2022-2023 Arm Ltd and Contributors. All rights reserved.
3*89c4ff92SAndroid Build Coastguard Worker // SPDX-License-Identifier: MIT
4*89c4ff92SAndroid Build Coastguard Worker //
5*89c4ff92SAndroid Build Coastguard Worker
6*89c4ff92SAndroid Build Coastguard Worker #include "ExecuteNetworkParams.hpp"
7*89c4ff92SAndroid Build Coastguard Worker
8*89c4ff92SAndroid Build Coastguard Worker #include "NetworkExecutionUtils/NetworkExecutionUtils.hpp"
9*89c4ff92SAndroid Build Coastguard Worker #include <armnn/Logging.hpp>
10*89c4ff92SAndroid Build Coastguard Worker
11*89c4ff92SAndroid Build Coastguard Worker #include <fmt/format.h>
12*89c4ff92SAndroid Build Coastguard Worker #include <armnnUtils/Filesystem.hpp>
13*89c4ff92SAndroid Build Coastguard Worker
CheckClTuningParameter(const int & tuningLevel,const std::string & tuningPath,const std::vector<armnn::BackendId> computeDevices)14*89c4ff92SAndroid Build Coastguard Worker void CheckClTuningParameter(const int& tuningLevel,
15*89c4ff92SAndroid Build Coastguard Worker const std::string& tuningPath,
16*89c4ff92SAndroid Build Coastguard Worker const std::vector<armnn::BackendId> computeDevices)
17*89c4ff92SAndroid Build Coastguard Worker {
18*89c4ff92SAndroid Build Coastguard Worker if (!tuningPath.empty())
19*89c4ff92SAndroid Build Coastguard Worker {
20*89c4ff92SAndroid Build Coastguard Worker if (tuningLevel == 0)
21*89c4ff92SAndroid Build Coastguard Worker {
22*89c4ff92SAndroid Build Coastguard Worker ARMNN_LOG(info) << "Using cl tuning file: " << tuningPath << "\n";
23*89c4ff92SAndroid Build Coastguard Worker if (!ValidatePath(tuningPath, true))
24*89c4ff92SAndroid Build Coastguard Worker {
25*89c4ff92SAndroid Build Coastguard Worker throw armnn::InvalidArgumentException("The tuning path is not valid");
26*89c4ff92SAndroid Build Coastguard Worker }
27*89c4ff92SAndroid Build Coastguard Worker }
28*89c4ff92SAndroid Build Coastguard Worker else if ((1 <= tuningLevel) && (tuningLevel <= 3))
29*89c4ff92SAndroid Build Coastguard Worker {
30*89c4ff92SAndroid Build Coastguard Worker ARMNN_LOG(info) << "Starting execution to generate a cl tuning file: " << tuningPath << "\n"
31*89c4ff92SAndroid Build Coastguard Worker << "Tuning level in use: " << tuningLevel << "\n";
32*89c4ff92SAndroid Build Coastguard Worker }
33*89c4ff92SAndroid Build Coastguard Worker else if ((0 < tuningLevel) || (tuningLevel > 3))
34*89c4ff92SAndroid Build Coastguard Worker {
35*89c4ff92SAndroid Build Coastguard Worker throw armnn::InvalidArgumentException(fmt::format("The tuning level {} is not valid.",
36*89c4ff92SAndroid Build Coastguard Worker tuningLevel));
37*89c4ff92SAndroid Build Coastguard Worker }
38*89c4ff92SAndroid Build Coastguard Worker
39*89c4ff92SAndroid Build Coastguard Worker // Ensure that a GpuAcc is enabled. Otherwise no tuning data are used or genereted
40*89c4ff92SAndroid Build Coastguard Worker // Only warn if it's not enabled
41*89c4ff92SAndroid Build Coastguard Worker auto it = std::find(computeDevices.begin(), computeDevices.end(), "GpuAcc");
42*89c4ff92SAndroid Build Coastguard Worker if (it == computeDevices.end())
43*89c4ff92SAndroid Build Coastguard Worker {
44*89c4ff92SAndroid Build Coastguard Worker ARMNN_LOG(warning) << "To use Cl Tuning the compute device GpuAcc needs to be active.";
45*89c4ff92SAndroid Build Coastguard Worker }
46*89c4ff92SAndroid Build Coastguard Worker }
47*89c4ff92SAndroid Build Coastguard Worker }
48*89c4ff92SAndroid Build Coastguard Worker
ValidateParams()49*89c4ff92SAndroid Build Coastguard Worker void ExecuteNetworkParams::ValidateParams()
50*89c4ff92SAndroid Build Coastguard Worker {
51*89c4ff92SAndroid Build Coastguard Worker if (m_DynamicBackendsPath == "")
52*89c4ff92SAndroid Build Coastguard Worker {
53*89c4ff92SAndroid Build Coastguard Worker // Check compute devices are valid unless they are dynamically loaded at runtime
54*89c4ff92SAndroid Build Coastguard Worker std::string invalidBackends;
55*89c4ff92SAndroid Build Coastguard Worker if (!CheckRequestedBackendsAreValid(m_ComputeDevices, armnn::Optional<std::string&>(invalidBackends)))
56*89c4ff92SAndroid Build Coastguard Worker {
57*89c4ff92SAndroid Build Coastguard Worker ARMNN_LOG(fatal) << "The list of preferred devices contains invalid backend IDs: "
58*89c4ff92SAndroid Build Coastguard Worker << invalidBackends;
59*89c4ff92SAndroid Build Coastguard Worker }
60*89c4ff92SAndroid Build Coastguard Worker }
61*89c4ff92SAndroid Build Coastguard Worker CheckClTuningParameter(m_TuningLevel, m_TuningPath, m_ComputeDevices);
62*89c4ff92SAndroid Build Coastguard Worker
63*89c4ff92SAndroid Build Coastguard Worker if (m_EnableBf16TurboMode && !m_EnableFastMath)
64*89c4ff92SAndroid Build Coastguard Worker {
65*89c4ff92SAndroid Build Coastguard Worker throw armnn::InvalidArgumentException("To use BF16 please use --enable-fast-math. ");
66*89c4ff92SAndroid Build Coastguard Worker }
67*89c4ff92SAndroid Build Coastguard Worker
68*89c4ff92SAndroid Build Coastguard Worker // Check input tensor shapes
69*89c4ff92SAndroid Build Coastguard Worker if ((m_InputTensorShapes.size() != 0) &&
70*89c4ff92SAndroid Build Coastguard Worker (m_InputTensorShapes.size() != m_InputNames.size()))
71*89c4ff92SAndroid Build Coastguard Worker {
72*89c4ff92SAndroid Build Coastguard Worker throw armnn::InvalidArgumentException("input-name and input-tensor-shape must have "
73*89c4ff92SAndroid Build Coastguard Worker "the same amount of elements. ");
74*89c4ff92SAndroid Build Coastguard Worker }
75*89c4ff92SAndroid Build Coastguard Worker
76*89c4ff92SAndroid Build Coastguard Worker if (m_InputTensorDataFilePaths.size() != 0)
77*89c4ff92SAndroid Build Coastguard Worker {
78*89c4ff92SAndroid Build Coastguard Worker if (!ValidatePaths(m_InputTensorDataFilePaths, true))
79*89c4ff92SAndroid Build Coastguard Worker {
80*89c4ff92SAndroid Build Coastguard Worker throw armnn::InvalidArgumentException("One or more input data file paths are not valid.");
81*89c4ff92SAndroid Build Coastguard Worker }
82*89c4ff92SAndroid Build Coastguard Worker
83*89c4ff92SAndroid Build Coastguard Worker if (m_InputTensorDataFilePaths.size() < m_InputNames.size())
84*89c4ff92SAndroid Build Coastguard Worker {
85*89c4ff92SAndroid Build Coastguard Worker throw armnn::InvalidArgumentException(
86*89c4ff92SAndroid Build Coastguard Worker fmt::format("According to the number of input names the user provided the network has {} "
87*89c4ff92SAndroid Build Coastguard Worker "inputs. But only {} input-tensor-data file paths were provided. Each input of the "
88*89c4ff92SAndroid Build Coastguard Worker "model is expected to be stored in it's own file.",
89*89c4ff92SAndroid Build Coastguard Worker m_InputNames.size(),
90*89c4ff92SAndroid Build Coastguard Worker m_InputTensorDataFilePaths.size()));
91*89c4ff92SAndroid Build Coastguard Worker }
92*89c4ff92SAndroid Build Coastguard Worker }
93*89c4ff92SAndroid Build Coastguard Worker
94*89c4ff92SAndroid Build Coastguard Worker // Check that threshold time is not less than zero
95*89c4ff92SAndroid Build Coastguard Worker if (m_ThresholdTime < 0)
96*89c4ff92SAndroid Build Coastguard Worker {
97*89c4ff92SAndroid Build Coastguard Worker throw armnn::InvalidArgumentException("Threshold time supplied as a command line argument is less than zero.");
98*89c4ff92SAndroid Build Coastguard Worker }
99*89c4ff92SAndroid Build Coastguard Worker
100*89c4ff92SAndroid Build Coastguard Worker // Warn if ExecuteNetwork will generate dummy input data
101*89c4ff92SAndroid Build Coastguard Worker if (m_GenerateTensorData)
102*89c4ff92SAndroid Build Coastguard Worker {
103*89c4ff92SAndroid Build Coastguard Worker ARMNN_LOG(warning) << "No input files provided, input tensors will be filled with 0s.";
104*89c4ff92SAndroid Build Coastguard Worker }
105*89c4ff92SAndroid Build Coastguard Worker
106*89c4ff92SAndroid Build Coastguard Worker if (m_AllowExpandedDims && m_InferOutputShape)
107*89c4ff92SAndroid Build Coastguard Worker {
108*89c4ff92SAndroid Build Coastguard Worker throw armnn::InvalidArgumentException("infer-output-shape and allow-expanded-dims cannot be used together.");
109*89c4ff92SAndroid Build Coastguard Worker }
110*89c4ff92SAndroid Build Coastguard Worker }
111*89c4ff92SAndroid Build Coastguard Worker
112*89c4ff92SAndroid Build Coastguard Worker #if defined(ARMNN_TFLITE_DELEGATE)
113*89c4ff92SAndroid Build Coastguard Worker /**
114*89c4ff92SAndroid Build Coastguard Worker * A utility method that populates a DelegateOptions object from this ExecuteNetworkParams.
115*89c4ff92SAndroid Build Coastguard Worker *
116*89c4ff92SAndroid Build Coastguard Worker * @return a populated armnnDelegate::DelegateOptions object.
117*89c4ff92SAndroid Build Coastguard Worker */
ToDelegateOptions() const118*89c4ff92SAndroid Build Coastguard Worker armnnDelegate::DelegateOptions ExecuteNetworkParams::ToDelegateOptions() const
119*89c4ff92SAndroid Build Coastguard Worker {
120*89c4ff92SAndroid Build Coastguard Worker armnnDelegate::DelegateOptions delegateOptions(m_ComputeDevices);
121*89c4ff92SAndroid Build Coastguard Worker delegateOptions.SetDynamicBackendsPath(m_DynamicBackendsPath);
122*89c4ff92SAndroid Build Coastguard Worker delegateOptions.SetGpuProfilingState(m_EnableProfiling);
123*89c4ff92SAndroid Build Coastguard Worker delegateOptions.SetInternalProfilingParams(m_EnableProfiling, armnn::ProfilingDetailsMethod::DetailsWithEvents);
124*89c4ff92SAndroid Build Coastguard Worker
125*89c4ff92SAndroid Build Coastguard Worker // GPU Backend options first.
126*89c4ff92SAndroid Build Coastguard Worker {
127*89c4ff92SAndroid Build Coastguard Worker armnn::BackendOptions gpuOption("GpuAcc", {{"TuningLevel", m_TuningLevel}});
128*89c4ff92SAndroid Build Coastguard Worker delegateOptions.AddBackendOption(gpuOption);
129*89c4ff92SAndroid Build Coastguard Worker }
130*89c4ff92SAndroid Build Coastguard Worker {
131*89c4ff92SAndroid Build Coastguard Worker armnn::BackendOptions gpuOption("GpuAcc", {{"TuningFile", m_TuningPath.c_str()}});
132*89c4ff92SAndroid Build Coastguard Worker delegateOptions.AddBackendOption(gpuOption);
133*89c4ff92SAndroid Build Coastguard Worker }
134*89c4ff92SAndroid Build Coastguard Worker {
135*89c4ff92SAndroid Build Coastguard Worker armnn::BackendOptions gpuOption("GpuAcc", {{"KernelProfilingEnabled", m_EnableProfiling}});
136*89c4ff92SAndroid Build Coastguard Worker delegateOptions.AddBackendOption(gpuOption);
137*89c4ff92SAndroid Build Coastguard Worker }
138*89c4ff92SAndroid Build Coastguard Worker
139*89c4ff92SAndroid Build Coastguard Worker // Optimizer options next.
140*89c4ff92SAndroid Build Coastguard Worker armnn::OptimizerOptionsOpaque optimizerOptions;
141*89c4ff92SAndroid Build Coastguard Worker optimizerOptions.SetReduceFp32ToFp16(m_EnableFp16TurboMode);
142*89c4ff92SAndroid Build Coastguard Worker optimizerOptions.SetDebugEnabled(m_PrintIntermediate);
143*89c4ff92SAndroid Build Coastguard Worker optimizerOptions.SetDebugToFileEnabled(m_PrintIntermediateOutputsToFile);
144*89c4ff92SAndroid Build Coastguard Worker optimizerOptions.SetProfilingEnabled(m_EnableProfiling);
145*89c4ff92SAndroid Build Coastguard Worker optimizerOptions.SetShapeInferenceMethod(armnn::ShapeInferenceMethod::ValidateOnly);
146*89c4ff92SAndroid Build Coastguard Worker if (m_InferOutputShape)
147*89c4ff92SAndroid Build Coastguard Worker {
148*89c4ff92SAndroid Build Coastguard Worker optimizerOptions.SetShapeInferenceMethod(armnn::ShapeInferenceMethod::InferAndValidate);
149*89c4ff92SAndroid Build Coastguard Worker armnn::BackendOptions networkOption("ShapeInferenceMethod",
150*89c4ff92SAndroid Build Coastguard Worker {
151*89c4ff92SAndroid Build Coastguard Worker {"InferAndValidate", true}
152*89c4ff92SAndroid Build Coastguard Worker });
153*89c4ff92SAndroid Build Coastguard Worker optimizerOptions.AddModelOption(networkOption);
154*89c4ff92SAndroid Build Coastguard Worker }
155*89c4ff92SAndroid Build Coastguard Worker
156*89c4ff92SAndroid Build Coastguard Worker {
157*89c4ff92SAndroid Build Coastguard Worker armnn::BackendOptions option("GpuAcc", {{"FastMathEnabled", m_EnableFastMath}});
158*89c4ff92SAndroid Build Coastguard Worker optimizerOptions.AddModelOption(option);
159*89c4ff92SAndroid Build Coastguard Worker }
160*89c4ff92SAndroid Build Coastguard Worker {
161*89c4ff92SAndroid Build Coastguard Worker armnn::BackendOptions option("GpuAcc", {{"CachedNetworkFilePath", m_CachedNetworkFilePath}});
162*89c4ff92SAndroid Build Coastguard Worker optimizerOptions.AddModelOption(option);
163*89c4ff92SAndroid Build Coastguard Worker }
164*89c4ff92SAndroid Build Coastguard Worker {
165*89c4ff92SAndroid Build Coastguard Worker armnn::BackendOptions option("GpuAcc", {{"MLGOTuningFilePath", m_MLGOTuningFilePath}});
166*89c4ff92SAndroid Build Coastguard Worker optimizerOptions.AddModelOption(option);
167*89c4ff92SAndroid Build Coastguard Worker }
168*89c4ff92SAndroid Build Coastguard Worker
169*89c4ff92SAndroid Build Coastguard Worker armnn::BackendOptions cpuAcc("CpuAcc",
170*89c4ff92SAndroid Build Coastguard Worker {
171*89c4ff92SAndroid Build Coastguard Worker { "FastMathEnabled", m_EnableFastMath },
172*89c4ff92SAndroid Build Coastguard Worker { "NumberOfThreads", m_NumberOfThreads }
173*89c4ff92SAndroid Build Coastguard Worker });
174*89c4ff92SAndroid Build Coastguard Worker optimizerOptions.AddModelOption(cpuAcc);
175*89c4ff92SAndroid Build Coastguard Worker if (m_AllowExpandedDims)
176*89c4ff92SAndroid Build Coastguard Worker {
177*89c4ff92SAndroid Build Coastguard Worker armnn::BackendOptions networkOption("AllowExpandedDims",
178*89c4ff92SAndroid Build Coastguard Worker {
179*89c4ff92SAndroid Build Coastguard Worker {"AllowExpandedDims", true}
180*89c4ff92SAndroid Build Coastguard Worker });
181*89c4ff92SAndroid Build Coastguard Worker optimizerOptions.AddModelOption(networkOption);
182*89c4ff92SAndroid Build Coastguard Worker }
183*89c4ff92SAndroid Build Coastguard Worker delegateOptions.SetOptimizerOptions(optimizerOptions);
184*89c4ff92SAndroid Build Coastguard Worker return delegateOptions;
185*89c4ff92SAndroid Build Coastguard Worker }
186*89c4ff92SAndroid Build Coastguard Worker
187*89c4ff92SAndroid Build Coastguard Worker #endif
188