xref: /aosp_15_r20/external/armnn/src/backends/neon/test/NeonOptimizedNetworkTests.cpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
2 // Copyright © 2017, 2023 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 
6 #include "NeonWorkloadFactoryHelper.hpp"
7 
8 #include <Graph.hpp>
9 #include <Network.hpp>
10 
11 #include <neon/NeonWorkloadFactory.hpp>
12 
13 #include <doctest/doctest.h>
14 
15 TEST_SUITE("NeonOptimizedNetwork")
16 {
17 TEST_CASE("OptimizeValidateCpuAccDeviceSupportLayerNoFallback")
18 {
19     // build up the structure of the network
20     armnn::INetworkPtr net(armnn::INetwork::Create());
21 
22     armnn::IConnectableLayer* input  = net->AddInputLayer(0);
23     armnn::IConnectableLayer* output = net->AddOutputLayer(0);
24 
25     input->GetOutputSlot(0).Connect(output->GetInputSlot(0));
26     input->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 1, 1, 4, 4 }, armnn::DataType::Float32));
27 
28     armnn::IRuntime::CreationOptions options;
29     armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
30 
31     std::vector<armnn::BackendId> backends = { armnn::Compute::CpuAcc };
32     armnn::IOptimizedNetworkPtr optNet = armnn::Optimize(*net, backends, runtime->GetDeviceSpec());
33     CHECK(optNet);
34     // validate workloads
35     armnn::NeonWorkloadFactory fact =
36         NeonWorkloadFactoryHelper::GetFactory(NeonWorkloadFactoryHelper::GetMemoryManager());
37 
38     armnn::Graph& graph = GetGraphForTesting(optNet.get());
39     for (auto&& layer : graph)
40     {
41         CHECK(layer->GetBackendId() == armnn::Compute::CpuAcc);
42         CHECK_NOTHROW(
43             layer->CreateWorkload(fact));
44     }
45 }
46 
47 TEST_CASE("OptimizeValidateDeviceNonSupportLayerNoFallback")
48 {
49     // build up the structure of the network
50     armnn::INetworkPtr net(armnn::INetwork::Create());
51 
52     armnn::IConnectableLayer* input = net->AddInputLayer(0);
53 
54     // This layer configuration isn't supported by CpuAcc and isn't allowed to fall back, so Optimize will return null.
55     armnn::NormalizationDescriptor descriptor;
56     armnn::IConnectableLayer* normalize = net->AddNormalizationLayer(descriptor);
57 
58     armnn::IConnectableLayer* output = net->AddOutputLayer(0);
59 
60     input->GetOutputSlot(0).Connect(normalize->GetInputSlot(0));
61     normalize->GetOutputSlot(0).Connect(output->GetInputSlot(0));
62 
63     input->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 1, 1, 4, 4 }, armnn::DataType::Float32));
64     normalize->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 1, 1, 4, 4 }, armnn::DataType::Float32));
65 
66     armnn::IRuntime::CreationOptions options;
67     armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
68 
69     std::vector<armnn::BackendId> backends = { armnn::Compute::CpuAcc };
70     std::vector<std::string> errMessages;
71 
72     try
73     {
74         Optimize(*net, backends, runtime->GetDeviceSpec(),
75                  armnn::OptimizerOptionsOpaque(), errMessages);
76         FAIL("Should have thrown an exception.");
77     }
78     catch (const armnn::InvalidArgumentException& e)
79     {
80         // Different exceptions are thrown on different backends
81     }
82     CHECK(errMessages.size() > 0);
83 }
84 
85 TEST_CASE("FastMathEnabledTestOnCpuAcc")
86 {
87     armnn::INetworkPtr net(armnn::INetwork::Create());
88 
89     armnn::IConnectableLayer* input  = net->AddInputLayer(0);
90     armnn::IConnectableLayer* output = net->AddOutputLayer(0);
91 
92     input->GetOutputSlot(0).Connect(output->GetInputSlot(0));
93     input->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 1, 1, 4, 4 }, armnn::DataType::Float32));
94 
95     armnn::IRuntime::CreationOptions options;
96     armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
97 
98     std::vector<armnn::BackendId> backends = {armnn::Compute::CpuAcc};
99     armnn::OptimizerOptionsOpaque optimizerOptions;
100     armnn::BackendOptions modelOptions("CpuAcc", {{"FastMathEnabled", true}});
101     optimizerOptions.AddModelOption(modelOptions);
102 
103     armnn::IOptimizedNetworkPtr optimizedNet = armnn::Optimize(
104     *net, backends, runtime->GetDeviceSpec(), optimizerOptions);
105 
106     CHECK(optimizedNet);
107 
108     auto modelOptionsOut = GetModelOptionsForTesting(optimizedNet.get());
109 
110     CHECK(modelOptionsOut.size() == 2); // FastMathEnabled and the Global to hold the import export values.
111     CHECK(modelOptionsOut[0].GetOption(0).GetName() == "FastMathEnabled");
112     CHECK(modelOptionsOut[0].GetOption(0).GetValue().AsBool() == true);
113 }
114 
115 TEST_CASE("NumberOfThreadsTestOnCpuAcc")
116 {
117     armnn::INetworkPtr net(armnn::INetwork::Create());
118 
119     armnn::IConnectableLayer* input  = net->AddInputLayer(0);
120     armnn::IConnectableLayer* output = net->AddOutputLayer(0);
121 
122     input->GetOutputSlot(0).Connect(output->GetInputSlot(0));
123     input->GetOutputSlot(0).SetTensorInfo(armnn::TensorInfo({ 1, 1, 4, 4 }, armnn::DataType::Float32));
124 
125     armnn::IRuntime::CreationOptions options;
126     armnn::IRuntimePtr runtime(armnn::IRuntime::Create(options));
127 
128     unsigned int numberOfThreads = 2;
129 
130     std::vector<armnn::BackendId> backends = {armnn::Compute::CpuAcc};
131     armnn::OptimizerOptionsOpaque optimizerOptions;
132     armnn::BackendOptions modelOptions("CpuAcc", {{"NumberOfThreads", numberOfThreads}});
133     optimizerOptions.AddModelOption(modelOptions);
134 
135     armnn::IOptimizedNetworkPtr optimizedNet = armnn::Optimize(
136             *net, backends, runtime->GetDeviceSpec(), optimizerOptions);
137 
138     CHECK(optimizedNet);
139     std::unique_ptr<armnn::Graph> graphPtr;
140     armnn::OptimizedNetworkImpl impl(std::move(graphPtr), optimizerOptions.GetModelOptions());
141 
142     auto modelOptionsOut = impl.GetModelOptions();
143 
144     CHECK(modelOptionsOut.size() == 1);
145     CHECK(modelOptionsOut[0].GetOption(0).GetName() == "NumberOfThreads");
146     CHECK(modelOptionsOut[0].GetOption(0).GetValue().AsUnsignedInt() == numberOfThreads);
147 }
148 
149 }