blob: dddc5aa8bc8ed533bb5a03fe9942453a98c53347 [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
Aron Virginas-Tarc9cc8042018-11-01 16:15:57 +000010#include <test/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
15#include <Filesystem.hpp>
16
Aron Virginas-Tar70104002018-10-24 15:33:28 +010017
18#include <boost/test/unit_test.hpp>
19
20BOOST_AUTO_TEST_SUITE(ClOptimizedNetwork)
21
22BOOST_AUTO_TEST_CASE(OptimizeValidateGpuDeviceSupportLayerNoFallback)
23{
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());
38 BOOST_CHECK(optNet);
39 // validate workloads
Aron Virginas-Tar5caf9072018-11-14 18:35:18 +000040 armnn::ClWorkloadFactory fact =
41 ClWorkloadFactoryHelper::GetFactory(ClWorkloadFactoryHelper::GetMemoryManager());
Aron Virginas-Tar70104002018-10-24 15:33:28 +010042 for (auto&& layer : static_cast<armnn::OptimizedNetwork*>(optNet.get())->GetGraph())
43 {
44 BOOST_CHECK(layer->GetBackendId() == armnn::Compute::GpuAcc);
45 BOOST_CHECK_NO_THROW(
Derek Lamberti94a88d22019-12-10 21:12:59 +000046 layer->CreateWorkload(fact));
Aron Virginas-Tar70104002018-10-24 15:33:28 +010047 }
48}
49
50BOOST_AUTO_TEST_CASE(FP16TurboModeTestOnGpuAcc)
51{
52 // Test to check when Fp16 Turbo mode set
53 // it converts the Fp32 network to Fp16 Network
54 // add Fp32ToFp16 conversion layer after the InputLayer
55 // add Fp16ToFp32 conversion layer after the OutputLayer
56 // checks the other layers if they are supported in Fp16
57 // if they are not put the conversion layers before and after
58 // if they are not supported in Fp16 use Fp32 instead
59 // if there are inverse conversion layers remove them with optimization
60 // at the moment FloorLayer is not supported in Fp16 so it rolls back to Fp32
61 // and inverse conversion layers are removed by the optimizer
62 armnn::Network net;
63
64 // Defines layers.
65 auto input = net.AddInputLayer(0, "input layer");
66 // ReLu1
67 armnn::ActivationDescriptor activation1Descriptor;
68 activation1Descriptor.m_Function = armnn::ActivationFunction::BoundedReLu;
69 activation1Descriptor.m_A = 1.f;
70 activation1Descriptor.m_B = -1.f;
71 auto activation = net.AddActivationLayer(activation1Descriptor, "activation layer");
72 auto output = net.AddOutputLayer(0, "output layer");
73
74 // Connects layers.
75 input->GetOutputSlot(0).Connect(activation->GetInputSlot(0));
76 activation->GetOutputSlot(0).Connect(output->GetInputSlot(0));
77
78 armnn::TensorShape shape({4});
79 armnn::TensorInfo info(shape, armnn::DataType::Float32);
80 input->GetOutputSlot(0).SetTensorInfo(info);
81 activation->GetOutputSlot(0).SetTensorInfo(info);
82
83 armnn::IRuntime::CreationOptions options;
84 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
85
86 std::vector<armnn::BackendId> backends = {armnn::Compute::GpuAcc};
87
88 armnn::OptimizerOptions optimizerOptions;
89 optimizerOptions.m_ReduceFp32ToFp16 = true;
90
91 armnn::IOptimizedNetworkPtr optimizedNet = armnn::Optimize(
92 net, backends, runtime->GetDeviceSpec(), optimizerOptions);
93
94 const armnn::Graph& graph = static_cast<armnn::OptimizedNetwork*>(optimizedNet.get())->GetGraph();
95
96 // Tests that all layers are present in the graph.
97 BOOST_TEST(graph.GetNumLayers() == 5);
98
99 // Tests that the vertices exist and have correct names.
100 BOOST_TEST(GraphHasNamedLayer(graph, "input layer"));
101 BOOST_TEST(GraphHasNamedLayer(graph, "convert_fp32_to_fp16-0-input layer"));
102 BOOST_TEST(GraphHasNamedLayer(graph, "activation layer"));
103 BOOST_TEST(GraphHasNamedLayer(graph, "convert_fp16_to_fp32-0-output layer"));
104 BOOST_TEST(GraphHasNamedLayer(graph, "output layer"));
105}
106
Sadik Armagan045f6be2020-09-10 13:37:32 +0100107BOOST_AUTO_TEST_CASE(FastMathEnabledTestOnGpuAcc)
108{
109 armnn::INetworkPtr net(armnn::INetwork::Create());
110
111 armnn::IConnectableLayer* input = net->AddInputLayer(0);
112 armnn::IConnectableLayer* output = net->AddOutputLayer(0);
113
114 input->GetOutputSlot(0).Connect(output->GetInputSlot(0));
115 input->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 1, 1, 4, 4 }, armnn::DataType::Float32));
116
117 armnn::IRuntime::CreationOptions options;
118 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
119
120 std::vector<armnn::BackendId> backends = {armnn::Compute::GpuAcc};
121 armnn::OptimizerOptions optimizerOptions;
122 armnn::BackendOptions modelOptions("GpuAcc", {{"FastMathEnabled", true}});
123 optimizerOptions.m_ModelOptions.push_back(modelOptions);
124
125 armnn::IOptimizedNetworkPtr optimizedNet = armnn::Optimize(
126 *net, backends, runtime->GetDeviceSpec(), optimizerOptions);
127
128 BOOST_CHECK(optimizedNet);
129
130 auto modelOptionsOut = static_cast<armnn::OptimizedNetwork*>(optimizedNet.get())->GetModelOptions();
131
132 BOOST_TEST(modelOptionsOut.size() == 1);
133 BOOST_TEST(modelOptionsOut[0].GetOption(0).GetName() == "FastMathEnabled");
134 BOOST_TEST(modelOptionsOut[0].GetOption(0).GetValue().AsBool() == true);
135}
136
Finn Williams40646322021-02-11 16:16:42 +0000137BOOST_AUTO_TEST_CASE(CheckMLGOTuningFile)
138{
139 class ClBackendContextTestClass : public armnn::ClBackendContext
140 {
141 public:
142 ClBackendContextTestClass(const armnn::IRuntime::CreationOptions &options) : ClBackendContext(options)
143 {}
144
145 bool call_reload_from_file()
146 {
147 return m_MLGOTuner.reload_from_file(m_MLGOTuningFile);
148 }
149 };
150
151 const std::string validText{
152 "<header>\n"
153 "gemm-version, [1,2,1]\n"
154 "ip-type,gpu\n"
155 "</header>\n"
156 "<heuristics-table>\n"
157 "0, g71 , 8, f32, best-performance, static, gemm-type, [m,n,k,n]\n"
158 "1, g71 , 8, f32, best-performance, static, gemm-config-reshaped-only-rhs, [m,n,k,n]\n"
159 "2, g71 , 8, f32, best-performance, static, gemm-config-reshaped, [m,n,k,n]\n"
160 "3, g71 , 8, qasymm8, best-performance, static, gemm-type, [m,n,k,n]\n"
161 "4, g71 , 8, qasymm8, best-performance, static, gemm-config-reshaped-only-rhs, [m,n,k,n]\n"
162 "5, g71 , 8, qasymm8, best-performance, static, gemm-config-native, [m,n,k,n]\n"
163 "</heuristics-table>\n"
164 "<heuristic, 0>\n"
165 "b , 0, var, r_mn, >=, num, 2., 1, 2\n"
166 "l , 1, gemm-type, reshaped\n"
167 "l , 2, gemm-type, reshaped-only-rhs\n"
168 "</heuristic>\n"
169 "<heuristic, 1>\n"
170 "l ,0,gemm-config-reshaped-only-rhs, [2, 4,4,4,1,1,0]\n"
171 "</heuristic>\n"
172 "<heuristic, 2>\n"
173 "l ,0,gemm-config-reshaped,[4,2,8,16,16,1,0,1,0]\n"
174 "</heuristic>\n"
175 "<heuristic, 3>\n"
176 "l , 0, gemm-type, native\n"
177 "</heuristic>\n"
178 "<heuristic, 4>\n"
179 "l ,0,gemm-config-reshaped-only-rhs, [2, 4,4,4,1,1,0]\n"
180 "</heuristic>\n"
181 "<heuristic, 5>\n"
182 "l ,0,gemm-config-native,[4,2,8]\n"
183 "</heuristic>\n"};
184
185 const std::string invalidText{"ʕノ•ᴥ•ʔノ ︵ ┻━┻"};
186
187 fs::path validFile = armnnUtils::Filesystem::NamedTempFile("validFile.mlgo");
188 fs::path invalidFile = armnnUtils::Filesystem::NamedTempFile("invalidFile.mlgo");
189
190 try
191 {
192 std::ofstream ofs1{validFile};
193 ofs1 << validText << std::endl;
194 ofs1.close();
195
196 std::ofstream ofs2{invalidFile};
197 ofs2 << invalidText << std::endl;
198 ofs2.close();
199 }
200 catch (std::exception &e)
201 {
202 std::cerr << "Unable to write to file at location [" << validFile.c_str() << "] : " << e.what() << std::endl;
203 BOOST_TEST(false);
204 }
205
206 armnn::IRuntime::CreationOptions creationOptions1;
207 armnn::BackendOptions validOptions
208 {
209 "GpuAcc",
210 {
211 {"MLGOTuningFilePath", validFile.c_str()}
212 }
213 };
214
215 creationOptions1.m_BackendOptions.emplace_back(validOptions);
216 ClBackendContextTestClass clBackendContext1(creationOptions1);
217 BOOST_TEST(clBackendContext1.call_reload_from_file());
218
219 armnn::BackendOptions invalidOptions
220 {
221 "GpuAcc",
222 {
223 {"MLGOTuningFilePath", invalidFile.c_str()}
224 }
225 };
226
227 armnn::IRuntime::CreationOptions creationOptions2;
228 creationOptions2.m_BackendOptions.emplace_back(invalidOptions);
229 ClBackendContextTestClass clBackendContext2(creationOptions2);
230 BOOST_TEST(clBackendContext2.call_reload_from_file() == false);
231
232 armnn::BackendOptions invalidPathOptions
233 {
234 "GpuAcc",
235 {
236 {"MLGOTuningFilePath", "not_a_real_file_path"}
237 }
238 };
239
240 armnn::IRuntime::CreationOptions creationOptions3;
241 creationOptions3.m_BackendOptions.emplace_back(invalidPathOptions);
242 ClBackendContextTestClass clBackendContext3(creationOptions3);
243 BOOST_TEST(clBackendContext3.call_reload_from_file() == false);
244}
245
Matthew Bentham39ef3e52020-01-20 10:09:09 +0000246BOOST_AUTO_TEST_SUITE_END();