ArmNN
 22.02
ValidatorStrategyTests.cpp File Reference
#include <backendsCommon/memoryOptimizerStrategyLibrary/strategies/StrategyValidator.hpp>
#include <doctest/doctest.h>
#include <vector>

Go to the source code of this file.

Functions

 TEST_SUITE ("MemoryOptimizerStrategyValidatorTestSuite")
 

Function Documentation

◆ TEST_SUITE()

TEST_SUITE ( "MemoryOptimizerStrategyValidatorTestSuite"  )

Definition at line 13 of file ValidatorStrategyTests.cpp.

References MemBin::m_MemBlocks, MemBin::m_MemSize, armnn::MultiAxisPacking, armnn::Optimize(), StrategyValidator::SetStrategy(), and armnn::SingleAxisPacking.

14 {
15 
16 // TestMemoryOptimizerStrategy: Create a MemBin and put all blocks in it so the can overlap.
17 class TestMemoryOptimizerStrategy : public IMemoryOptimizerStrategy
18 {
19 public:
20  TestMemoryOptimizerStrategy(MemBlockStrategyType type)
21  : m_Name(std::string("testMemoryOptimizerStrategy"))
22  , m_MemBlockStrategyType(type) {}
23 
24  std::string GetName() const override
25  {
26  return m_Name;
27  }
28 
30  {
31  return m_MemBlockStrategyType;
32  }
33 
34  std::vector<MemBin> Optimize(std::vector<MemBlock>& memBlocks) override
35  {
36  std::vector<MemBin> memBins;
37  memBins.reserve(memBlocks.size());
38 
39  MemBin memBin;
40  memBin.m_MemBlocks.reserve(memBlocks.size());
41  memBin.m_MemSize = 0;
42  for (auto& memBlock : memBlocks)
43  {
44 
45  memBin.m_MemSize = memBin.m_MemSize + memBlock.m_MemSize;
46  memBin.m_MemBlocks.push_back(memBlock);
47  }
48  memBins.push_back(memBin);
49 
50  return memBins;
51  }
52 
53 private:
54  std::string m_Name;
55  MemBlockStrategyType m_MemBlockStrategyType;
56 };
57 
58 TEST_CASE("MemoryOptimizerStrategyValidatorTestOverlapX")
59 {
60  // create a few memory blocks
61  MemBlock memBlock0(0, 5, 20, 0, 0);
62  MemBlock memBlock1(6, 10, 10, 0, 1);
63  MemBlock memBlock2(11, 15, 15, 0, 2);
64  MemBlock memBlock3(16, 20, 20, 0, 3);
65  MemBlock memBlock4(21, 25, 5, 0, 4);
66 
67  std::vector<MemBlock> memBlocks;
68  memBlocks.reserve(5);
69  memBlocks.push_back(memBlock0);
70  memBlocks.push_back(memBlock1);
71  memBlocks.push_back(memBlock2);
72  memBlocks.push_back(memBlock3);
73  memBlocks.push_back(memBlock4);
74 
75  // Optimize the memory blocks with TestMemoryOptimizerStrategySingle
76  TestMemoryOptimizerStrategy testMemoryOptimizerStrategySingle(MemBlockStrategyType::SingleAxisPacking);
77  auto ptr = std::make_shared<TestMemoryOptimizerStrategy>(testMemoryOptimizerStrategySingle);
78  StrategyValidator validator;
79  validator.SetStrategy(ptr);
80  // SingleAxisPacking can overlap on X axis.
81  CHECK_NOTHROW(validator.Optimize(memBlocks));
82 
83  // Optimize the memory blocks with TestMemoryOptimizerStrategyMulti
84  TestMemoryOptimizerStrategy testMemoryOptimizerStrategyMulti(MemBlockStrategyType::MultiAxisPacking);
85  auto ptrMulti = std::make_shared<TestMemoryOptimizerStrategy>(testMemoryOptimizerStrategyMulti);
86  StrategyValidator validatorMulti;
87  validatorMulti.SetStrategy(ptrMulti);
88  // MultiAxisPacking can overlap on X axis.
89  CHECK_NOTHROW(validatorMulti.Optimize(memBlocks));
90 }
91 
92 TEST_CASE("MemoryOptimizerStrategyValidatorTestOverlapXAndY")
93 {
94  // create a few memory blocks
95  MemBlock memBlock0(0, 5, 20, 0, 0);
96  MemBlock memBlock1(0, 10, 10, 0, 1);
97  MemBlock memBlock2(0, 15, 15, 0, 2);
98  MemBlock memBlock3(0, 20, 20, 0, 3);
99  MemBlock memBlock4(0, 25, 5, 0, 4);
100 
101  std::vector<MemBlock> memBlocks;
102  memBlocks.reserve(5);
103  memBlocks.push_back(memBlock0);
104  memBlocks.push_back(memBlock1);
105  memBlocks.push_back(memBlock2);
106  memBlocks.push_back(memBlock3);
107  memBlocks.push_back(memBlock4);
108 
109  // Optimize the memory blocks with TestMemoryOptimizerStrategySingle
110  TestMemoryOptimizerStrategy testMemoryOptimizerStrategySingle(MemBlockStrategyType::SingleAxisPacking);
111  auto ptr = std::make_shared<TestMemoryOptimizerStrategy>(testMemoryOptimizerStrategySingle);
112  StrategyValidator validator;
113  validator.SetStrategy(ptr);
114  // SingleAxisPacking cannot overlap on both X and Y axis.
115  CHECK_THROWS(validator.Optimize(memBlocks));
116 
117  // Optimize the memory blocks with TestMemoryOptimizerStrategyMulti
118  TestMemoryOptimizerStrategy testMemoryOptimizerStrategyMulti(MemBlockStrategyType::MultiAxisPacking);
119  auto ptrMulti = std::make_shared<TestMemoryOptimizerStrategy>(testMemoryOptimizerStrategyMulti);
120  StrategyValidator validatorMulti;
121  validatorMulti.SetStrategy(ptrMulti);
122  // MultiAxisPacking cannot overlap on both X and Y axis.
123  CHECK_THROWS(validatorMulti.Optimize(memBlocks));
124 }
125 
126 TEST_CASE("MemoryOptimizerStrategyValidatorTestOverlapY")
127 {
128  // create a few memory blocks
129  MemBlock memBlock0(0, 2, 20, 0, 0);
130  MemBlock memBlock1(0, 3, 10, 21, 1);
131  MemBlock memBlock2(0, 5, 15, 37, 2);
132  MemBlock memBlock3(0, 6, 20, 58, 3);
133  MemBlock memBlock4(0, 8, 5, 79, 4);
134 
135  std::vector<MemBlock> memBlocks;
136  memBlocks.reserve(5);
137  memBlocks.push_back(memBlock0);
138  memBlocks.push_back(memBlock1);
139  memBlocks.push_back(memBlock2);
140  memBlocks.push_back(memBlock3);
141  memBlocks.push_back(memBlock4);
142 
143  // Optimize the memory blocks with TestMemoryOptimizerStrategySingle
144  TestMemoryOptimizerStrategy testMemoryOptimizerStrategySingle(MemBlockStrategyType::SingleAxisPacking);
145  auto ptr = std::make_shared<TestMemoryOptimizerStrategy>(testMemoryOptimizerStrategySingle);
146  StrategyValidator validator;
147  validator.SetStrategy(ptr);
148  // SingleAxisPacking cannot overlap on Y axis
149  CHECK_THROWS(validator.Optimize(memBlocks));
150 
151  // Optimize the memory blocks with TestMemoryOptimizerStrategyMulti
152  TestMemoryOptimizerStrategy testMemoryOptimizerStrategyMulti(MemBlockStrategyType::MultiAxisPacking);
153  auto ptrMulti = std::make_shared<TestMemoryOptimizerStrategy>(testMemoryOptimizerStrategyMulti);
154  StrategyValidator validatorMulti;
155  validatorMulti.SetStrategy(ptrMulti);
156  // MultiAxisPacking can overlap on Y axis
157  CHECK_NOTHROW(validatorMulti.Optimize(memBlocks));
158 }
159 
160 // TestMemoryOptimizerStrategyDuplicate: Create a MemBin and put all blocks in it duplicating each so validator
161 // can check
162 class TestMemoryOptimizerStrategyDuplicate : public TestMemoryOptimizerStrategy
163 {
164 public:
165  TestMemoryOptimizerStrategyDuplicate(MemBlockStrategyType type)
166  : TestMemoryOptimizerStrategy(type)
167  {}
168 
169  std::vector<MemBin> Optimize(std::vector<MemBlock>& memBlocks) override
170  {
171  std::vector<MemBin> memBins;
172  memBins.reserve(memBlocks.size());
173 
174  MemBin memBin;
175  memBin.m_MemBlocks.reserve(memBlocks.size());
176  for (auto& memBlock : memBlocks)
177  {
178  memBin.m_MemSize = memBin.m_MemSize + memBlock.m_MemSize;
179  memBin.m_MemBlocks.push_back(memBlock);
180  // Put block in twice so it gets found twice
181  memBin.m_MemBlocks.push_back(memBlock);
182  }
183  memBins.push_back(memBin);
184 
185  return memBins;
186  }
187 };
188 
189 TEST_CASE("MemoryOptimizerStrategyValidatorTestDuplicateBlocks")
190 {
191  // create a few memory blocks
192  MemBlock memBlock0(0, 2, 20, 0, 0);
193  MemBlock memBlock1(2, 3, 10, 20, 1);
194  MemBlock memBlock2(3, 5, 15, 30, 2);
195  MemBlock memBlock3(5, 6, 20, 50, 3);
196  MemBlock memBlock4(7, 8, 5, 70, 4);
197 
198  std::vector<MemBlock> memBlocks;
199  memBlocks.reserve(5);
200  memBlocks.push_back(memBlock0);
201  memBlocks.push_back(memBlock1);
202  memBlocks.push_back(memBlock2);
203  memBlocks.push_back(memBlock3);
204  memBlocks.push_back(memBlock4);
205 
206  // Optimize the memory blocks with TestMemoryOptimizerStrategySingle
207  // Duplicate strategy is invalid as same block is found twice
208  TestMemoryOptimizerStrategyDuplicate testMemoryOptimizerStrategySingle(MemBlockStrategyType::SingleAxisPacking);
209  auto ptr = std::make_shared<TestMemoryOptimizerStrategyDuplicate>(testMemoryOptimizerStrategySingle);
210  StrategyValidator validator;
211  validator.SetStrategy(ptr);
212  CHECK_THROWS(validator.Optimize(memBlocks));
213 
214  // Optimize the memory blocks with TestMemoryOptimizerStrategyMulti
215  TestMemoryOptimizerStrategyDuplicate testMemoryOptimizerStrategyMulti(MemBlockStrategyType::MultiAxisPacking);
216  auto ptrMulti = std::make_shared<TestMemoryOptimizerStrategyDuplicate>(testMemoryOptimizerStrategyMulti);
217  StrategyValidator validatorMulti;
218  validatorMulti.SetStrategy(ptrMulti);
219  CHECK_THROWS(validatorMulti.Optimize(memBlocks));
220 }
221 
222 // TestMemoryOptimizerStrategySkip: Create a MemBin and put all blocks in it skipping every other block so validator
223 // can check
224 class TestMemoryOptimizerStrategySkip : public TestMemoryOptimizerStrategy
225 {
226 public:
227  TestMemoryOptimizerStrategySkip(MemBlockStrategyType type)
228  : TestMemoryOptimizerStrategy(type)
229  {}
230 
231  std::vector<MemBin> Optimize(std::vector<MemBlock>& memBlocks) override
232  {
233  std::vector<MemBin> memBins;
234  memBins.reserve(memBlocks.size());
235 
236  MemBin memBin;
237  memBin.m_MemBlocks.reserve(memBlocks.size());
238  for (unsigned int i = 0; i < memBlocks.size()-1; i+=2)
239  {
240  auto memBlock = memBlocks[i];
241  memBin.m_MemSize = memBin.m_MemSize + memBlock.m_MemSize;
242  memBin.m_MemBlocks.push_back(memBlock);
243  }
244  memBins.push_back(memBin);
245 
246  return memBins;
247  }
248 };
249 
250 TEST_CASE("MemoryOptimizerStrategyValidatorTestSkipBlocks")
251 {
252  // create a few memory blocks
253  MemBlock memBlock0(0, 2, 20, 0, 0);
254  MemBlock memBlock1(2, 3, 10, 20, 1);
255  MemBlock memBlock2(3, 5, 15, 30, 2);
256  MemBlock memBlock3(5, 6, 20, 50, 3);
257  MemBlock memBlock4(7, 8, 5, 70, 4);
258 
259  std::vector<MemBlock> memBlocks;
260  memBlocks.reserve(5);
261  memBlocks.push_back(memBlock0);
262  memBlocks.push_back(memBlock1);
263  memBlocks.push_back(memBlock2);
264  memBlocks.push_back(memBlock3);
265  memBlocks.push_back(memBlock4);
266 
267  // Optimize the memory blocks with TestMemoryOptimizerStrategySingle
268  // Skip strategy is invalid as every second block is not found
269  TestMemoryOptimizerStrategySkip testMemoryOptimizerStrategySingle(MemBlockStrategyType::SingleAxisPacking);
270  auto ptr = std::make_shared<TestMemoryOptimizerStrategySkip>(testMemoryOptimizerStrategySingle);
271  StrategyValidator validator;
272  validator.SetStrategy(ptr);
273  CHECK_THROWS(validator.Optimize(memBlocks));
274 
275  // Optimize the memory blocks with TestMemoryOptimizerStrategyMulti
276  TestMemoryOptimizerStrategySkip testMemoryOptimizerStrategyMulti(MemBlockStrategyType::MultiAxisPacking);
277  auto ptrMulti = std::make_shared<TestMemoryOptimizerStrategySkip>(testMemoryOptimizerStrategyMulti);
278  StrategyValidator validatorMulti;
279  validatorMulti.SetStrategy(ptrMulti);
280  CHECK_THROWS(validatorMulti.Optimize(memBlocks));
281 }
282 
283 }
std::vector< MemBlock > m_MemBlocks
IOptimizedNetworkPtr Optimize(const INetwork &network, const std::vector< BackendId > &backendPreferences, const IDeviceSpec &deviceSpec, const OptimizerOptions &options=OptimizerOptions(), Optional< std::vector< std::string > &> messages=EmptyOptional())
Create an optimized version of the network.
Definition: Network.cpp:1680
void SetStrategy(std::shared_ptr< IMemoryOptimizerStrategy > strategy)
virtual MemBlockStrategyType GetMemBlockStrategyType() const =0
MemBlockStrategyType
Definition: Types.hpp:226
virtual std::vector< MemBin > Optimize(std::vector< MemBlock > &memBlocks)=0
virtual std::string GetName() const =0