blob: cf17eae208f4905d96f0f9d4983c167d49b2b967 [file] [log] [blame]
Aron Virginas-Tar70104002018-10-24 15:33:28 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// 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>
14
Rob Hughes9542f902021-07-14 09:48:54 +010015#include <armnnUtils/Filesystem.hpp>
Finn Williams40646322021-02-11 16:16:42 +000016
Sadik Armagan1625efc2021-06-10 18:24:34 +010017#include <doctest/doctest.h>
Aron Virginas-Tar70104002018-10-24 15:33:28 +010018
Sadik Armagan1625efc2021-06-10 18:24:34 +010019TEST_SUITE("ClOptimizedNetwork")
20{
21TEST_CASE("OptimizeValidateGpuDeviceSupportLayerNoFallback")
Aron Virginas-Tar70104002018-10-24 15:33:28 +010022{
23 // build up the structure of the network
24 armnn::INetworkPtr net(armnn::INetwork::Create());
25
26 armnn::IConnectableLayer* input = net->AddInputLayer(0);
27 armnn::IConnectableLayer* output = net->AddOutputLayer(0);
28
29 input->GetOutputSlot(0).Connect(output->GetInputSlot(0));
30 input->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 1, 1, 4, 4 }, armnn::DataType::Float32));
31
32 armnn::IRuntime::CreationOptions options;
33 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
34
35 std::vector<armnn::BackendId> backends = { armnn::Compute::GpuAcc };
36 armnn::IOptimizedNetworkPtr optNet = armnn::Optimize(*net, backends, runtime->GetDeviceSpec());
Sadik Armagan1625efc2021-06-10 18:24:34 +010037 CHECK(optNet);
Aron Virginas-Tar70104002018-10-24 15:33:28 +010038 // validate workloads
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +000039 armnn::ClWorkloadFactory fact =
40 ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
Francis Murtagh3d2b4b22021-02-15 18:23:17 +000041
42 const armnn::Graph& theGraph = GetGraphForTesting(optNet.get());
43 for (auto&& layer : theGraph)
Aron Virginas-Tar70104002018-10-24 15:33:28 +010044 {
Sadik Armagan1625efc2021-06-10 18:24:34 +010045 CHECK(layer->GetBackendId() == armnn::Compute::GpuAcc);
46 CHECK_NOTHROW(
Derek Lamberti94a88d22019-12-10 21:12:59 +000047 layer->CreateWorkload(fact));
Aron Virginas-Tar70104002018-10-24 15:33:28 +010048 }
49}
50
Sadik Armagan1625efc2021-06-10 18:24:34 +010051TEST_CASE("FP16TurboModeTestOnGpuAcc")
Aron Virginas-Tar70104002018-10-24 15:33:28 +010052{
53 // Test to check when Fp16 Turbo mode set
54 // it converts the Fp32 network to Fp16 Network
55 // add Fp32ToFp16 conversion layer after the InputLayer
56 // add Fp16ToFp32 conversion layer after the OutputLayer
57 // checks the other layers if they are supported in Fp16
58 // if they are not put the conversion layers before and after
59 // if they are not supported in Fp16 use Fp32 instead
60 // if there are inverse conversion layers remove them with optimization
61 // at the moment FloorLayer is not supported in Fp16 so it rolls back to Fp32
62 // and inverse conversion layers are removed by the optimizer
Francis Murtagh3d2b4b22021-02-15 18:23:17 +000063 armnn::INetworkPtr net(armnn::INetwork::Create());
Aron Virginas-Tar70104002018-10-24 15:33:28 +010064
65 // Defines layers.
Francis Murtagh3d2b4b22021-02-15 18:23:17 +000066 auto input = net->AddInputLayer(0, "input layer");
Aron Virginas-Tar70104002018-10-24 15:33:28 +010067 // ReLu1
68 armnn::ActivationDescriptor activation1Descriptor;
69 activation1Descriptor.m_Function = armnn::ActivationFunction::BoundedReLu;
70 activation1Descriptor.m_A = 1.f;
71 activation1Descriptor.m_B = -1.f;
Francis Murtagh3d2b4b22021-02-15 18:23:17 +000072 auto activation = net->AddActivationLayer(activation1Descriptor, "activation layer");
73 auto output = net->AddOutputLayer(0, "output layer");
Aron Virginas-Tar70104002018-10-24 15:33:28 +010074
75 // Connects layers.
76 input->GetOutputSlot(0).Connect(activation->GetInputSlot(0));
77 activation->GetOutputSlot(0).Connect(output->GetInputSlot(0));
78
79 armnn::TensorShape shape({4});
80 armnn::TensorInfo info(shape, armnn::DataType::Float32);
81 input->GetOutputSlot(0).SetTensorInfo(info);
82 activation->GetOutputSlot(0).SetTensorInfo(info);
83
84 armnn::IRuntime::CreationOptions options;
85 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
86
87 std::vector<armnn::BackendId> backends = {armnn::Compute::GpuAcc};
88
89 armnn::OptimizerOptions optimizerOptions;
90 optimizerOptions.m_ReduceFp32ToFp16 = true;
91
92 armnn::IOptimizedNetworkPtr optimizedNet = armnn::Optimize(
Francis Murtagh3d2b4b22021-02-15 18:23:17 +000093 *net, backends, runtime->GetDeviceSpec(), optimizerOptions);
Aron Virginas-Tar70104002018-10-24 15:33:28 +010094
Francis Murtagh3d2b4b22021-02-15 18:23:17 +000095 const armnn::Graph& graph = GetGraphForTesting(optimizedNet.get());
Aron Virginas-Tar70104002018-10-24 15:33:28 +010096
97 // Tests that all layers are present in the graph.
Sadik Armagan1625efc2021-06-10 18:24:34 +010098 CHECK(graph.GetNumLayers() == 5);
Aron Virginas-Tar70104002018-10-24 15:33:28 +010099
100 // Tests that the vertices exist and have correct names.
Sadik Armagan1625efc2021-06-10 18:24:34 +0100101 CHECK(GraphHasNamedLayer(graph, "input layer"));
102 CHECK(GraphHasNamedLayer(graph, "convert_fp32_to_fp16-0-input layer"));
103 CHECK(GraphHasNamedLayer(graph, "activation layer"));
104 CHECK(GraphHasNamedLayer(graph, "convert_fp16_to_fp32-0-output layer"));
105 CHECK(GraphHasNamedLayer(graph, "output layer"));
Aron Virginas-Tar70104002018-10-24 15:33:28 +0100106}
107
Sadik Armagan1625efc2021-06-10 18:24:34 +0100108TEST_CASE("FastMathEnabledTestOnGpuAcc")
Sadik Armagan045f6be2020-09-10 13:37:32 +0100109{
110 armnn::INetworkPtr net(armnn::INetwork::Create());
111
112 armnn::IConnectableLayer* input = net->AddInputLayer(0);
113 armnn::IConnectableLayer* output = net->AddOutputLayer(0);
114
115 input->GetOutputSlot(0).Connect(output->GetInputSlot(0));
116 input->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 1, 1, 4, 4 }, armnn::DataType::Float32));
117
118 armnn::IRuntime::CreationOptions options;
119 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
120
121 std::vector<armnn::BackendId> backends = {armnn::Compute::GpuAcc};
122 armnn::OptimizerOptions optimizerOptions;
123 armnn::BackendOptions modelOptions("GpuAcc", {{"FastMathEnabled", true}});
124 optimizerOptions.m_ModelOptions.push_back(modelOptions);
125
126 armnn::IOptimizedNetworkPtr optimizedNet = armnn::Optimize(
127 *net, backends, runtime->GetDeviceSpec(), optimizerOptions);
128
Sadik Armagan1625efc2021-06-10 18:24:34 +0100129 CHECK(optimizedNet);
Sadik Armagan045f6be2020-09-10 13:37:32 +0100130
Francis Murtagh3d2b4b22021-02-15 18:23:17 +0000131 auto modelOptionsOut = GetModelOptionsForTesting(optimizedNet.get());
Sadik Armagan045f6be2020-09-10 13:37:32 +0100132
James Conroya0f8b152022-06-21 11:31:47 +0000133 CHECK(modelOptionsOut.size() == 1);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100134 CHECK(modelOptionsOut[0].GetOption(0).GetName() == "FastMathEnabled");
135 CHECK(modelOptionsOut[0].GetOption(0).GetValue().AsBool() == true);
Sadik Armagan045f6be2020-09-10 13:37:32 +0100136}
137
Sadik Armagan1625efc2021-06-10 18:24:34 +0100138TEST_CASE("CheckMLGOTuningFile")
Finn Williams40646322021-02-11 16:16:42 +0000139{
140 class ClBackendContextTestClass : public armnn::ClBackendContext
141 {
142 public:
143 ClBackendContextTestClass(const armnn::IRuntime::CreationOptions &options) : ClBackendContext(options)
144 {}
145
146 bool call_reload_from_file()
147 {
148 return m_MLGOTuner.reload_from_file(m_MLGOTuningFile);
149 }
150 };
151
152 const std::string validText{
153 "<header>\n"
154 "gemm-version, [1,2,1]\n"
155 "ip-type,gpu\n"
156 "</header>\n"
157 "<heuristics-table>\n"
158 "0, g71 , 8, f32, best-performance, static, gemm-type, [m,n,k,n]\n"
159 "1, g71 , 8, f32, best-performance, static, gemm-config-reshaped-only-rhs, [m,n,k,n]\n"
160 "2, g71 , 8, f32, best-performance, static, gemm-config-reshaped, [m,n,k,n]\n"
161 "3, g71 , 8, qasymm8, best-performance, static, gemm-type, [m,n,k,n]\n"
162 "4, g71 , 8, qasymm8, best-performance, static, gemm-config-reshaped-only-rhs, [m,n,k,n]\n"
163 "5, g71 , 8, qasymm8, best-performance, static, gemm-config-native, [m,n,k,n]\n"
164 "</heuristics-table>\n"
165 "<heuristic, 0>\n"
166 "b , 0, var, r_mn, >=, num, 2., 1, 2\n"
167 "l , 1, gemm-type, reshaped\n"
168 "l , 2, gemm-type, reshaped-only-rhs\n"
169 "</heuristic>\n"
170 "<heuristic, 1>\n"
171 "l ,0,gemm-config-reshaped-only-rhs, [2, 4,4,4,1,1,0]\n"
172 "</heuristic>\n"
173 "<heuristic, 2>\n"
174 "l ,0,gemm-config-reshaped,[4,2,8,16,16,1,0,1,0]\n"
175 "</heuristic>\n"
176 "<heuristic, 3>\n"
177 "l , 0, gemm-type, native\n"
178 "</heuristic>\n"
179 "<heuristic, 4>\n"
180 "l ,0,gemm-config-reshaped-only-rhs, [2, 4,4,4,1,1,0]\n"
181 "</heuristic>\n"
182 "<heuristic, 5>\n"
183 "l ,0,gemm-config-native,[4,2,8]\n"
184 "</heuristic>\n"};
185
186 const std::string invalidText{"ʕノ•ᴥ•ʔノ ︵ ┻━┻"};
187
188 fs::path validFile = armnnUtils::Filesystem::NamedTempFile("validFile.mlgo");
189 fs::path invalidFile = armnnUtils::Filesystem::NamedTempFile("invalidFile.mlgo");
190
191 try
192 {
193 std::ofstream ofs1{validFile};
194 ofs1 << validText << std::endl;
195 ofs1.close();
196
197 std::ofstream ofs2{invalidFile};
198 ofs2 << invalidText << std::endl;
199 ofs2.close();
200 }
201 catch (std::exception &e)
202 {
203 std::cerr << "Unable to write to file at location [" << validFile.c_str() << "] : " << e.what() << std::endl;
Sadik Armagan1625efc2021-06-10 18:24:34 +0100204 CHECK(false);
Finn Williams40646322021-02-11 16:16:42 +0000205 }
206
207 armnn::IRuntime::CreationOptions creationOptions1;
208 armnn::BackendOptions validOptions
209 {
210 "GpuAcc",
211 {
212 {"MLGOTuningFilePath", validFile.c_str()}
213 }
214 };
215
216 creationOptions1.m_BackendOptions.emplace_back(validOptions);
217 ClBackendContextTestClass clBackendContext1(creationOptions1);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100218 CHECK(clBackendContext1.call_reload_from_file());
Finn Williams40646322021-02-11 16:16:42 +0000219
220 armnn::BackendOptions invalidOptions
221 {
222 "GpuAcc",
223 {
224 {"MLGOTuningFilePath", invalidFile.c_str()}
225 }
226 };
227
228 armnn::IRuntime::CreationOptions creationOptions2;
229 creationOptions2.m_BackendOptions.emplace_back(invalidOptions);
230 ClBackendContextTestClass clBackendContext2(creationOptions2);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100231 CHECK(clBackendContext2.call_reload_from_file() == false);
Finn Williams40646322021-02-11 16:16:42 +0000232
233 armnn::BackendOptions invalidPathOptions
234 {
235 "GpuAcc",
236 {
237 {"MLGOTuningFilePath", "not_a_real_file_path"}
238 }
239 };
240
241 armnn::IRuntime::CreationOptions creationOptions3;
242 creationOptions3.m_BackendOptions.emplace_back(invalidPathOptions);
243 ClBackendContextTestClass clBackendContext3(creationOptions3);
Sadik Armagan1625efc2021-06-10 18:24:34 +0100244 CHECK(clBackendContext3.call_reload_from_file() == false);
Finn Williams40646322021-02-11 16:16:42 +0000245}
246
Sadik Armagan1625efc2021-06-10 18:24:34 +0100247}