blob: 7e8064fc7641cc00acedc47c9f8dec051448a3e4 [file] [log] [blame]
Aron Virginas-Tar70104002018-10-24 15:33:28 +01001//
Mike Kelly3ec30772023-03-08 13:47:17 +00002// Copyright © 2017-2023 Arm Ltd and Contributors. All rights reserved.
Aron Virginas-Tar70104002018-10-24 15:33:28 +01003// SPDX-License-Identifier: MIT
4//
5
Sadik Armagan1625efc2021-06-10 18:24:34 +01006#include <doctest/doctest.h>
Colm Donelana98e79a2022-12-06 21:32:29 +00007#include <Graph.hpp>
8#include <armnn/BackendId.hpp>
9#include <armnn/Descriptors.hpp>
10#include <armnn/INetwork.hpp>
11#include <armnn/IRuntime.hpp>
12#include <armnn/Tensor.hpp>
13#include <armnn/Types.hpp>
14#include <GraphUtils.hpp>
15#include <reference/RefWorkloadFactory.hpp>
16#include <memory>
17#include <vector>
Aron Virginas-Tar70104002018-10-24 15:33:28 +010018
Sadik Armagan1625efc2021-06-10 18:24:34 +010019TEST_SUITE("RefOptimizedNetwork")
20{
21TEST_CASE("OptimizeValidateCpuRefWorkloads")
Aron Virginas-Tar70104002018-10-24 15:33:28 +010022{
23 const armnn::TensorInfo desc({3, 5}, armnn::DataType::Float32);
24
Kevin Mayd92a6e42021-02-04 10:27:41 +000025 // build up the structure of the network
26 armnn::INetworkPtr net(armnn::INetwork::Create());
Aron Virginas-Tar70104002018-10-24 15:33:28 +010027
28 armnn::NormalizationDescriptor nmDesc;
29 armnn::ActivationDescriptor acDesc;
30
31 // in
32 // |
33 // nm
34 // / |
35 // ac |
36 // \ |
37 // ml
38 // |
39 // sm
40 // |
41 // ot
Kevin Mayd92a6e42021-02-04 10:27:41 +000042 armnn::IConnectableLayer* layer = net->AddInputLayer(0, "in");
Aron Virginas-Tar70104002018-10-24 15:33:28 +010043 layer->GetOutputSlot(0).SetTensorInfo(desc);
44
Kevin Mayd92a6e42021-02-04 10:27:41 +000045 armnn::IConnectableLayer* const normLayer = net->AddNormalizationLayer(nmDesc, "nm");
Aron Virginas-Tar70104002018-10-24 15:33:28 +010046
47 layer->GetOutputSlot(0).Connect(normLayer->GetInputSlot(0));
48 normLayer->GetOutputSlot(0).SetTensorInfo(desc);
49
Kevin Mayd92a6e42021-02-04 10:27:41 +000050 layer = net->AddActivationLayer(acDesc, "ac");
Aron Virginas-Tar70104002018-10-24 15:33:28 +010051
52 normLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0));
53 layer->GetOutputSlot(0).SetTensorInfo(desc);
54
55 armnn::IConnectableLayer* prevLayer = layer;
Mike Kelly3ec30772023-03-08 13:47:17 +000056 layer = net->AddElementwiseBinaryLayer(armnn::BinaryOperation::Mul, "ml");
Aron Virginas-Tar70104002018-10-24 15:33:28 +010057
58 prevLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0));
59 normLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1));
60 layer->GetOutputSlot(0).SetTensorInfo(desc);
61
62 prevLayer = layer;
63 armnn::SoftmaxDescriptor softmaxDescriptor;
Kevin Mayd92a6e42021-02-04 10:27:41 +000064 layer = net->AddSoftmaxLayer(softmaxDescriptor, "sm");
Aron Virginas-Tar70104002018-10-24 15:33:28 +010065
66 prevLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0));
67 layer->GetOutputSlot(0).SetTensorInfo(desc);
68
69 prevLayer = layer;
Kevin Mayd92a6e42021-02-04 10:27:41 +000070 layer = net->AddOutputLayer(0, "ot");
Aron Virginas-Tar70104002018-10-24 15:33:28 +010071
72 prevLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0));
73
74 armnn::IRuntime::CreationOptions options;
75 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
76
77 std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef };
Kevin Mayd92a6e42021-02-04 10:27:41 +000078 armnn::IOptimizedNetworkPtr optNet = armnn::Optimize(*net, backends, runtime->GetDeviceSpec());
Francis Murtagh3d2b4b22021-02-15 18:23:17 +000079 armnn::Graph& graph = GetGraphForTesting(optNet.get());
80 graph.AllocateDynamicBuffers();
Sadik Armagan1625efc2021-06-10 18:24:34 +010081 CHECK(optNet);
Aron Virginas-Tar70104002018-10-24 15:33:28 +010082
83 // Validates workloads.
84 armnn::RefWorkloadFactory fact;
Francis Murtagh3d2b4b22021-02-15 18:23:17 +000085 for (auto&& layer : graph)
Aron Virginas-Tar70104002018-10-24 15:33:28 +010086 {
Sadik Armagan1625efc2021-06-10 18:24:34 +010087 CHECK_NOTHROW(layer->CreateWorkload(fact));
Aron Virginas-Tar70104002018-10-24 15:33:28 +010088 }
89}
90
Sadik Armagan1625efc2021-06-10 18:24:34 +010091TEST_CASE("OptimizeValidateWorkloadsCpuRefPermuteLayer")
Aron Virginas-Tar70104002018-10-24 15:33:28 +010092{
93 // Create runtime in which test will run
94 armnn::IRuntime::CreationOptions options;
95 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
96
97 std::vector<armnn::BackendId> backends = {armnn::Compute::CpuRef};
98
99 // build up the structure of the network
100 armnn::INetworkPtr net(armnn::INetwork::Create());
101
102 armnn::IConnectableLayer* input = net->AddInputLayer(0);
103
104 armnn::PermuteDescriptor descriptor({0, 2, 3, 1});
105 armnn::IConnectableLayer* permute = net->AddPermuteLayer(descriptor);
106
107 armnn::IConnectableLayer* output = net->AddOutputLayer(0);
108
109 input->GetOutputSlot(0).Connect(permute->GetInputSlot(0));
110 permute->GetOutputSlot(0).Connect(output->GetInputSlot(0));
111
112 input->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 1, 1, 4, 4 }, armnn::DataType::Float32));
113 permute->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 1, 4, 1, 4 }, armnn::DataType::Float32));
114
115 // optimize the network
116 armnn::IOptimizedNetworkPtr optNet = armnn::Optimize(*net, backends, runtime->GetDeviceSpec());
117
Francis Murtagh3d2b4b22021-02-15 18:23:17 +0000118 armnn::Graph& graph = GetGraphForTesting(optNet.get());
119 graph.AllocateDynamicBuffers();
120
121 for (auto&& layer : graph)
Aron Virginas-Tar70104002018-10-24 15:33:28 +0100122 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100123 CHECK(layer->GetBackendId() == armnn::Compute::CpuRef);
Aron Virginas-Tar70104002018-10-24 15:33:28 +0100124 }
125}
126
Sadik Armagan1625efc2021-06-10 18:24:34 +0100127TEST_CASE("OptimizeValidateWorkloadsCpuRefMeanLayer")
Aron Virginas-Tar70104002018-10-24 15:33:28 +0100128{
129 // Create runtime in which test will run
130 armnn::IRuntime::CreationOptions options;
131 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
132
133 std::vector<armnn::BackendId> backends = {armnn::Compute::CpuRef};
134
135 // build up the structure of the network
136 armnn::INetworkPtr net(armnn::INetwork::Create());
137
138 armnn::IConnectableLayer* input = net->AddInputLayer(0);
139
140 armnn::MeanDescriptor descriptor({ 0, 1 }, false);
141 armnn::IConnectableLayer* meanLayer = net->AddMeanLayer(descriptor);
142
143 armnn::IConnectableLayer* output = net->AddOutputLayer(0);
144
145 input->GetOutputSlot(0).Connect(meanLayer->GetInputSlot(0));
146 meanLayer->GetOutputSlot(0).Connect(output->GetInputSlot(0));
147
148 input->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 4, 3, 2 }, armnn::DataType::Float32));
149 meanLayer->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 2 }, armnn::DataType::Float32));
150
151 // optimize the network
152 armnn::IOptimizedNetworkPtr optNet = armnn::Optimize(*net, backends, runtime->GetDeviceSpec());
Francis Murtagh3d2b4b22021-02-15 18:23:17 +0000153 armnn::Graph& graph = GetGraphForTesting(optNet.get());
154 graph.AllocateDynamicBuffers();
155 for (auto&& layer : graph)
Aron Virginas-Tar70104002018-10-24 15:33:28 +0100156 {
Sadik Armagan1625efc2021-06-10 18:24:34 +0100157 CHECK(layer->GetBackendId() == armnn::Compute::CpuRef);
Aron Virginas-Tar70104002018-10-24 15:33:28 +0100158 }
159}
160
Sadik Armagan1625efc2021-06-10 18:24:34 +0100161TEST_CASE("DebugTestOnCpuRef")
keidav01738c2e62018-12-11 16:14:20 +0000162{
Kevin Mayd92a6e42021-02-04 10:27:41 +0000163 // build up the structure of the network
164 armnn::INetworkPtr net(armnn::INetwork::Create());
keidav01738c2e62018-12-11 16:14:20 +0000165
166 armnn::ActivationDescriptor activation1Descriptor;
167 activation1Descriptor.m_Function = armnn::ActivationFunction::BoundedReLu;
168 activation1Descriptor.m_A = 1.f;
169 activation1Descriptor.m_B = -1.f;
170
171 // Defines layers.
Kevin Mayd92a6e42021-02-04 10:27:41 +0000172 auto input = net->AddInputLayer(0, "InputLayer");
173 auto activation = net->AddActivationLayer(activation1Descriptor, "ActivationLayer");
174 auto output = net->AddOutputLayer(0, "OutputLayer");
keidav01738c2e62018-12-11 16:14:20 +0000175
176 // Connects layers.
177 input->GetOutputSlot(0).Connect(activation->GetInputSlot(0));
178 activation->GetOutputSlot(0).Connect(output->GetInputSlot(0));
179
180 armnn::TensorShape shape({4});
181 armnn::TensorInfo info(shape, armnn::DataType::Float32);
182 input->GetOutputSlot(0).SetTensorInfo(info);
183 activation->GetOutputSlot(0).SetTensorInfo(info);
184
185 armnn::IRuntime::CreationOptions options;
186 armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
187
188 std::vector<armnn::BackendId> backends = {armnn::Compute::CpuRef};
189
190 armnn::OptimizerOptions optimizerOptions;
191 optimizerOptions.m_Debug = true;
192
Kevin Mayd92a6e42021-02-04 10:27:41 +0000193 armnn::IOptimizedNetworkPtr optimizedNet = armnn::Optimize(*net, backends, runtime->GetDeviceSpec(),
keidav01738c2e62018-12-11 16:14:20 +0000194 optimizerOptions);
195
Francis Murtagh3d2b4b22021-02-15 18:23:17 +0000196 armnn::Graph& graph = GetGraphForTesting(optimizedNet.get());
197 graph.AllocateDynamicBuffers();
198
keidav01738c2e62018-12-11 16:14:20 +0000199 // Tests that all layers are present in the graph.
Sadik Armagan1625efc2021-06-10 18:24:34 +0100200 CHECK(graph.GetNumLayers() == 5);
keidav01738c2e62018-12-11 16:14:20 +0000201
202 // Tests that the vertices exist and have correct names.
Sadik Armagan1625efc2021-06-10 18:24:34 +0100203 CHECK(GraphHasNamedLayer(graph, "InputLayer"));
204 CHECK(GraphHasNamedLayer(graph, "DebugLayerAfterInputLayer_0"));
205 CHECK(GraphHasNamedLayer(graph, "ActivationLayer"));
206 CHECK(GraphHasNamedLayer(graph, "DebugLayerAfterActivationLayer_0"));
207 CHECK(GraphHasNamedLayer(graph, "OutputLayer"));
keidav01738c2e62018-12-11 16:14:20 +0000208}
209
Sadik Armagan1625efc2021-06-10 18:24:34 +0100210}