blob: 9d721c08ed5c71d60e751c8b6f314895e4d7f745 [file] [log] [blame]
Aron Virginas-Tar70104002018-10-24 15:33:28 +01001//
John Mcloughlinc5ee0d72023-03-24 12:07:25 +00002// Copyright © 2017, 2023 Arm Ltd. All rights reserved.
Aron Virginas-Tar70104002018-10-24 15:33:28 +01003// SPDX-License-Identifier: MIT
4//
5
Aron Virginas-Tar56055192018-11-12 18:10:43 +00006#include "ClWorkloadFactoryHelper.hpp"
7
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +00008#include <Network.hpp>
Aron Virginas-Tar70104002018-10-24 15:33:28 +01009
Sadik Armagana097d2a2021-11-24 15:47:28 +000010#include <GraphUtils.hpp>
Aron Virginas-Tar70104002018-10-24 15:33:28 +010011
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000012#include <cl/ClWorkloadFactory.hpp>
Finn Williams40646322021-02-11 16:16:42 +000013#include <cl/ClBackendContext.hpp>
Ryan OSheab4c49342023-07-25 14:28:27 +010014#include <arm_compute/core/CL/CLKernelLibrary.h>
Finn Williams40646322021-02-11 16:16:42 +000015
Rob Hughes9542f902021-07-14 09:48:54 +010016#include <armnnUtils/Filesystem.hpp>
Finn Williams40646322021-02-11 16:16:42 +000017
Sadik Armagan1625efc2021-06-10 18:24:34 +010018#include <doctest/doctest.h>
Aron Virginas-Tar70104002018-10-24 15:33:28 +010019
Sadik Armagan1625efc2021-06-10 18:24:34 +010020TEST_SUITE("ClOptimizedNetwork")
21{
22TEST_CASE("OptimizeValidateGpuDeviceSupportLayerNoFallback")
Aron Virginas-Tar70104002018-10-24 15:33:28 +010023{
24 // build up the structure of the network
25 armnn::INetworkPtr net(armnn::INetwork::Create());
26
27 armnn::IConnectableLayer* input = net->AddInputLayer(0);
28 armnn::IConnectableLayer* output = net->AddOutputLayer(0);
29
30 input->GetOutputSlot(0).Connect(output->GetInputSlot(0));
31 input->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 1, 1, 4, 4 }, armnn::DataType::Float32));
32
33 armnn::IRuntime::CreationOptions options;
34 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
35
36 std::vector<armnn::BackendId> backends = { armnn::Compute::GpuAcc };
37 armnn::IOptimizedNetworkPtr optNet = armnn::Optimize(*net, backends, runtime->GetDeviceSpec());
Sadik Armagan1625efc2021-06-10 18:24:34 +010038 CHECK(optNet);
Aron Virginas-Tar70104002018-10-24 15:33:28 +010039 // validate workloads
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +000040 armnn::ClWorkloadFactory fact =
41 ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
Francis Murtagh3d2b4b22021-02-15 18:23:17 +000042
43 const armnn::Graph& theGraph = GetGraphForTesting(optNet.get());
44 for (auto&& layer : theGraph)
Aron Virginas-Tar70104002018-10-24 15:33:28 +010045 {
Sadik Armagan1625efc2021-06-10 18:24:34 +010046 CHECK(layer->GetBackendId() == armnn::Compute::GpuAcc);
47 CHECK_NOTHROW(
Derek Lamberti94a88d22019-12-10 21:12:59 +000048 layer->CreateWorkload(fact));
Aron Virginas-Tar70104002018-10-24 15:33:28 +010049 }
50}
51
Sadik Armagan1625efc2021-06-10 18:24:34 +010052TEST_CASE("FP16TurboModeTestOnGpuAcc")
Aron Virginas-Tar70104002018-10-24 15:33:28 +010053{
54 // Test to check when Fp16 Turbo mode set
55 // it converts the Fp32 network to Fp16 Network
56 // add Fp32ToFp16 conversion layer after the InputLayer
57 // add Fp16ToFp32 conversion layer after the OutputLayer
58 // checks the other layers if they are supported in Fp16
59 // if they are not put the conversion layers before and after
60 // if they are not supported in Fp16 use Fp32 instead
61 // if there are inverse conversion layers remove them with optimization
62 // at the moment FloorLayer is not supported in Fp16 so it rolls back to Fp32
63 // and inverse conversion layers are removed by the optimizer
Francis Murtagh3d2b4b22021-02-15 18:23:17 +000064 armnn::INetworkPtr net(armnn::INetwork::Create());
Aron Virginas-Tar70104002018-10-24 15:33:28 +010065
66 // Defines layers.
Francis Murtagh3d2b4b22021-02-15 18:23:17 +000067 auto input = net->AddInputLayer(0, "input layer");
Aron Virginas-Tar70104002018-10-24 15:33:28 +010068 // ReLu1
69 armnn::ActivationDescriptor activation1Descriptor;
70 activation1Descriptor.m_Function = armnn::ActivationFunction::BoundedReLu;
71 activation1Descriptor.m_A = 1.f;
72 activation1Descriptor.m_B = -1.f;
Francis Murtagh3d2b4b22021-02-15 18:23:17 +000073 auto activation = net->AddActivationLayer(activation1Descriptor, "activation layer");
74 auto output = net->AddOutputLayer(0, "output layer");
Aron Virginas-Tar70104002018-10-24 15:33:28 +010075
76 // Connects layers.
77 input->GetOutputSlot(0).Connect(activation->GetInputSlot(0));
78 activation->GetOutputSlot(0).Connect(output->GetInputSlot(0));
79
80 armnn::TensorShape shape({4});
81 armnn::TensorInfo info(shape, armnn::DataType::Float32);
82 input->GetOutputSlot(0).SetTensorInfo(info);
83 activation->GetOutputSlot(0).SetTensorInfo(info);
84
85 armnn::IRuntime::CreationOptions options;
86 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
87
88 std::vector<armnn::BackendId> backends = {armnn::Compute::GpuAcc};
89
John Mcloughlinc5ee0d72023-03-24 12:07:25 +000090 armnn::OptimizerOptionsOpaque optimizerOptions;
91 optimizerOptions.SetReduceFp32ToFp16(true);
Aron Virginas-Tar70104002018-10-24 15:33:28 +010092
93 armnn::IOptimizedNetworkPtr optimizedNet = armnn::Optimize(
Francis Murtagh3d2b4b22021-02-15 18:23:17 +000094 *net, backends, runtime->GetDeviceSpec(), optimizerOptions);
Aron Virginas-Tar70104002018-10-24 15:33:28 +010095
Francis Murtagh3d2b4b22021-02-15 18:23:17 +000096 const armnn::Graph& graph = GetGraphForTesting(optimizedNet.get());
Aron Virginas-Tar70104002018-10-24 15:33:28 +010097
Ryan OSheab4c49342023-07-25 14:28:27 +010098 if(arm_compute::CLKernelLibrary::get().fp16_supported())
99 {
100 // Tests that all layers are present in the graph.
101 CHECK(graph.GetNumLayers() == 5);
Aron Virginas-Tar70104002018-10-24 15:33:28 +0100102
Ryan OSheab4c49342023-07-25 14:28:27 +0100103 // Tests that the vertices exist and have correct names.
104 CHECK(GraphHasNamedLayer(graph, "input layer"));
105 CHECK(GraphHasNamedLayer(graph, "convert_fp32_to_fp16-0-input layer"));
106 CHECK(GraphHasNamedLayer(graph, "activation layer"));
107 CHECK(GraphHasNamedLayer(graph, "convert_fp16_to_fp32-0-output layer"));
108 CHECK(GraphHasNamedLayer(graph, "output layer"));
109 }
110 else
111 {
112 // Tests that all layers except for conversion layers are present in the graph.
113 CHECK(graph.GetNumLayers() == 3);
114
115 // Tests that the vertices exist and have correct names.
116 CHECK(GraphHasNamedLayer(graph, "input layer"));
117 CHECK(GraphHasNamedLayer(graph, "activation layer"));
118 CHECK(GraphHasNamedLayer(graph, "output layer"));
119 }
Aron Virginas-Tar70104002018-10-24 15:33:28 +0100120}
121
Sadik Armagan1625efc2021-06-10 18:24:34 +0100122TEST_CASE("FastMathEnabledTestOnGpuAcc")
Sadik Armagan045f6be2020-09-10 13:37:32 +0100123{
124 armnn::INetworkPtr net(armnn::INetwork::Create());
125
126 armnn::IConnectableLayer* input = net->AddInputLayer(0);
127 armnn::IConnectableLayer* output = net->AddOutputLayer(0);
128
129 input->GetOutputSlot(0).Connect(output->GetInputSlot(0));
130 input->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 1, 1, 4, 4 }, armnn::DataType::Float32));
131
132 armnn::IRuntime::CreationOptions options;
133 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
134
135 std::vector<armnn::BackendId> backends = {armnn::Compute::GpuAcc};
John Mcloughlinc5ee0d72023-03-24 12:07:25 +0000136 armnn::OptimizerOptionsOpaque optimizerOptions;
Sadik Armagan045f6be2020-09-10 13:37:32 +0100137 armnn::BackendOptions modelOptions("GpuAcc", {{"FastMathEnabled", true}});
John Mcloughlinc5ee0d72023-03-24 12:07:25 +0000138 optimizerOptions.AddModelOption(modelOptions);
Sadik Armagan045f6be2020-09-10 13:37:32 +0100139
140 armnn::IOptimizedNetworkPtr optimizedNet = armnn::Optimize(
141 *net, backends, runtime->GetDeviceSpec(), optimizerOptions);
142
Sadik Armagan1625efc2021-06-10 18:24:34 +0100143 CHECK(optimizedNet);
Sadik Armagan045f6be2020-09-10 13:37:32 +0100144
Francis Murtagh3d2b4b22021-02-15 18:23:17 +0000145 auto modelOptionsOut = GetModelOptionsForTesting(optimizedNet.get());
Sadik Armagan045f6be2020-09-10 13:37:32 +0100146
Francis Murtagh626bd902022-06-21 13:16:23 +0000147 CHECK(modelOptionsOut.size() == 2); // FastMathEnabled and the Global to hold the import export values.
Sadik Armagan1625efc2021-06-10 18:24:34 +0100148 CHECK(modelOptionsOut[0].GetOption(0).GetName() == "FastMathEnabled");
149 CHECK(modelOptionsOut[0].GetOption(0).GetValue().AsBool() == true);
Sadik Armagan045f6be2020-09-10 13:37:32 +0100150}
151
Sadik Armagan1625efc2021-06-10 18:24:34 +0100152TEST_CASE("CheckMLGOTuningFile")
Finn Williams40646322021-02-11 16:16:42 +0000153{
154 class ClBackendContextTestClass : public armnn::ClBackendContext
155 {
156 public:
157 ClBackendContextTestClass(const armnn::IRuntime::CreationOptions &options) : ClBackendContext(options)
158 {}
159
160 bool call_reload_from_file()
161 {
162 return m_MLGOTuner.reload_from_file(m_MLGOTuningFile);
163 }
164 };
165
166 const std::string validText{
167 "<header>\n"
168 "gemm-version, [1,2,1]\n"
169 "ip-type,gpu\n"
170 "</header>\n"
171 "<heuristics-table>\n"
172 "0, g71 , 8, f32, best-performance, static, gemm-type, [m,n,k,n]\n"
173 "1, g71 , 8, f32, best-performance, static, gemm-config-reshaped-only-rhs, [m,n,k,n]\n"
174 "2, g71 , 8, f32, best-performance, static, gemm-config-reshaped, [m,n,k,n]\n"
175 "3, g71 , 8, qasymm8, best-performance, static, gemm-type, [m,n,k,n]\n"
176 "4, g71 , 8, qasymm8, best-performance, static, gemm-config-reshaped-only-rhs, [m,n,k,n]\n"
177 "5, g71 , 8, qasymm8, best-performance, static, gemm-config-native, [m,n,k,n]\n"
178 "</heuristics-table>\n"
179 "<heuristic, 0>\n"
180 "b , 0, var, r_mn, >=, num, 2., 1, 2\n"
181 "l , 1, gemm-type, reshaped\n"
182 "l , 2, gemm-type, reshaped-only-rhs\n"
183 "</heuristic>\n"
184 "<heuristic, 1>\n"
185 "l ,0,gemm-config-reshaped-only-rhs, [2, 4,4,4,1,1,0]\n"
186 "</heuristic>\n"
187 "<heuristic, 2>\n"
188 "l ,0,gemm-config-reshaped,[4,2,8,16,16,1,0,1,0]\n"
189 "</heuristic>\n"
190 "<heuristic, 3>\n"
191 "l , 0, gemm-type, native\n"
192 "</heuristic>\n"
193 "<heuristic, 4>\n"
194 "l ,0,gemm-config-reshaped-only-rhs, [2, 4,4,4,1,1,0]\n"
195 "</heuristic>\n"
196 "<heuristic, 5>\n"
197 "l ,0,gemm-config-native,[4,2,8]\n"
198 "</heuristic>\n"};
199
200 const std::string invalidText{"ʕノ•ᴥ•ʔノ ︵ ┻━┻"};
201
202 fs::path validFile = armnnUtils::Filesystem::NamedTempFile("validFile.mlgo");
203 fs::path invalidFile = armnnUtils::Filesystem::NamedTempFile("invalidFile.mlgo");
204
205 try
206 {
207 std::ofstream ofs1{validFile};
208 ofs1 << validText << std::endl;
209 ofs1.close();
210
211 std::ofstream ofs2{invalidFile};
212 ofs2 << invalidText << std::endl;
213 ofs2.close();
214 }
215 catch (std::exception &e)
216 {
217 std::cerr << "Unable to write to file at location [" << validFile.c_str() << "] : " << e.what() << std::endl;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100218 CHECK(false);
Finn Williams40646322021-02-11 16:16:42 +0000219 }
220
221 armnn::IRuntime::CreationOptions creationOptions1;
222 armnn::BackendOptions validOptions
223 {
224 "GpuAcc",
225 {
226 {"MLGOTuningFilePath", validFile.c_str()}
227 }
228 };
229
230 creationOptions1.m_BackendOptions.emplace_back(validOptions);
231 ClBackendContextTestClass clBackendContext1(creationOptions1);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100232 CHECK(clBackendContext1.call_reload_from_file());
Finn Williams40646322021-02-11 16:16:42 +0000233
234 armnn::BackendOptions invalidOptions
235 {
236 "GpuAcc",
237 {
238 {"MLGOTuningFilePath", invalidFile.c_str()}
239 }
240 };
241
242 armnn::IRuntime::CreationOptions creationOptions2;
243 creationOptions2.m_BackendOptions.emplace_back(invalidOptions);
244 ClBackendContextTestClass clBackendContext2(creationOptions2);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100245 CHECK(clBackendContext2.call_reload_from_file() == false);
Finn Williams40646322021-02-11 16:16:42 +0000246
247 armnn::BackendOptions invalidPathOptions
248 {
249 "GpuAcc",
250 {
251 {"MLGOTuningFilePath", "not_a_real_file_path"}
252 }
253 };
254
255 armnn::IRuntime::CreationOptions creationOptions3;
256 creationOptions3.m_BackendOptions.emplace_back(invalidPathOptions);
257 ClBackendContextTestClass clBackendContext3(creationOptions3);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100258 CHECK(clBackendContext3.call_reload_from_file() == false);
Finn Williams40646322021-02-11 16:16:42 +0000259}
260
Sadik Armagan1625efc2021-06-10 18:24:34 +0100261}