15 #include <doctest/doctest.h> 22 template<
typename armnn::DataType DataType>
23 INetworkPtr CreateSplitterNetwork(
const TensorShape& inputShape,
24 const std::vector<TensorShape>& outputShapes,
25 unsigned int splitAxis,
26 unsigned int numSplit,
27 const float qScale = 1.0f,
28 const int32_t qOffset = 0)
30 using namespace armnn;
36 std::vector<unsigned int> splitterDimSizes(inputShape.GetNumDimensions());
39 for (
unsigned int i = 0; i < inputShape.GetNumDimensions(); ++i)
41 splitterDimSizes[i] = inputTensorInfo.GetShape()[i];
44 if (splitterDimSizes[splitAxis] % numSplit != 0)
46 throw ParseException(
"Number of splits must evenly divide the dimension");
48 splitterDimSizes[splitAxis] /= numSplit;
51 for (
unsigned int g = 0; g < numSplit; ++g)
54 for (
unsigned int dimIdx = 0; dimIdx < splitterDimSizes.size(); ++dimIdx)
56 splitDesc.
SetViewSize(g, dimIdx, splitterDimSizes[dimIdx]);
58 splitDesc.SetViewOriginCoord(g, splitAxis, splitterDimSizes[splitAxis] * g);
63 Connect(input, splitter, inputTensorInfo, 0, 0);
65 for (
unsigned int i = 0; i < outputShapes.size(); ++i)
68 IConnectableLayer* output = net->AddOutputLayer(armnn::numeric_cast<LayerBindingId>(i));
69 Connect(splitter, output, outputTensorInfo, i, 0);
75 template<armnn::DataType ArmnnType>
76 void Splitter1dEndToEnd(
const std::vector<BackendId>& backends)
78 using namespace armnn;
81 unsigned int splitAxis = 0;
82 unsigned int numSplit = 2;
84 const std::vector<TensorShape> outputShapes{{ 2 }, { 2 }};
87 INetworkPtr net = CreateSplitterNetwork<ArmnnType>(inputShape, outputShapes, splitAxis, numSplit);
92 std::vector<T> inputData{ 1, 2, 3, 4 };
94 std::vector<T> expectedOutput0{ 1, 2 };
95 std::vector<T> expectedOutput1{ 3, 4 };
97 std::map<int, std::vector<T>> inputTensorData = { { 0, inputData } };
98 std::map<int, std::vector<T>> expectedOutputData = { { 0, expectedOutput0 }, {1, expectedOutput1} };
100 EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
103 template<armnn::DataType ArmnnType>
104 void Splitter2dDim0EndToEnd(
const std::vector<BackendId>& backends)
106 using namespace armnn;
109 unsigned int splitAxis = 0;
110 unsigned int numSplit = 2;
112 const std::vector<TensorShape> outputShapes{{ 2, 3 }, { 2, 3 }};
115 INetworkPtr net = CreateSplitterNetwork<ArmnnType>(inputShape, outputShapes, splitAxis, numSplit);
120 std::vector<T> inputData{
129 std::vector<T> expectedOutput0{ 1, 2, 3, 4, 5, 6 };
130 std::vector<T> expectedOutput1{ 7, 8, 9, 10, 11, 12 };
132 std::map<int, std::vector<T>> inputTensorData = { { 0, inputData } };
133 std::map<int, std::vector<T>> expectedOutputData = { { 0, expectedOutput0 }, {1, expectedOutput1} };
135 EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
138 template<armnn::DataType ArmnnType>
139 void Splitter2dDim1EndToEnd(
const std::vector<BackendId>& backends)
141 using namespace armnn;
144 unsigned int splitAxis = 1;
145 unsigned int numSplit = 3;
147 const std::vector<TensorShape> outputShapes{{ 4, 1 }, { 4, 1 }, { 4, 1 }};
150 INetworkPtr net = CreateSplitterNetwork<ArmnnType>(inputShape, outputShapes, splitAxis, numSplit);
155 std::vector<T> inputData{
164 std::vector<T> expectedOutput0{ 1, 4, 7, 10 };
165 std::vector<T> expectedOutput1{ 2, 5, 8, 11 };
166 std::vector<T> expectedOutput2{ 3, 6, 9, 12 };
168 std::map<int, std::vector<T>> inputTensorData = { { 0, inputData } };
169 std::map<int, std::vector<T>> expectedOutputData = { { 0, expectedOutput0 },
170 { 1, expectedOutput1 },
171 { 2, expectedOutput2 } };
173 EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
176 template<armnn::DataType ArmnnType>
177 void Splitter3dDim0EndToEnd(
const std::vector<BackendId>& backends)
179 using namespace armnn;
182 unsigned int splitAxis = 0;
183 unsigned int numSplit = 2;
185 const std::vector<TensorShape> outputShapes{{ 1, 4, 3 }, { 1, 4, 3 }};
188 INetworkPtr net = CreateSplitterNetwork<ArmnnType>(inputShape, outputShapes, splitAxis, numSplit);
193 std::vector<T> inputData{
204 std::vector<T> expectedOutput0{
210 std::vector<T> expectedOutput1{
217 std::map<int, std::vector<T>> inputTensorData = { { 0, inputData } };
218 std::map<int, std::vector<T>> expectedOutputData = { { 0, expectedOutput0 },
219 { 1, expectedOutput1 } };
221 EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
224 template<armnn::DataType ArmnnType>
225 void Splitter3dDim1EndToEnd(
const std::vector<BackendId>& backends)
227 using namespace armnn;
230 unsigned int splitAxis = 1;
231 unsigned int numSplit = 2;
233 const std::vector<TensorShape> outputShapes{{ 2, 2, 3 }, { 2, 2, 3 }};
236 INetworkPtr net = CreateSplitterNetwork<ArmnnType>(inputShape, outputShapes, splitAxis, numSplit);
241 std::vector<T> inputData{
252 std::vector<T> expectedOutput0{
258 std::vector<T> expectedOutput1{
265 std::map<int, std::vector<T>> inputTensorData = { { 0, inputData } };
266 std::map<int, std::vector<T>> expectedOutputData = { { 0, expectedOutput0 },
267 { 1, expectedOutput1 } };
269 EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
272 template<armnn::DataType ArmnnType>
273 void Splitter3dDim2EndToEnd(
const std::vector<BackendId>& backends)
275 using namespace armnn;
278 unsigned int splitAxis = 2;
279 unsigned int numSplit = 3;
281 const std::vector<TensorShape> outputShapes{{ 2, 4, 1 }, { 2, 4, 1 }, { 2, 4, 1 }};
284 INetworkPtr net = CreateSplitterNetwork<ArmnnType>(inputShape, outputShapes, splitAxis, numSplit);
289 std::vector<T> inputData{
300 std::vector<T> expectedOutput0{ 1, 4, 7, 10, 13, 16, 19, 22 };
301 std::vector<T> expectedOutput1{ 2, 5, 8, 11, 14, 17, 20, 23 };
302 std::vector<T> expectedOutput2{ 3, 6, 9, 12, 15, 18, 21, 24 };
304 std::map<int, std::vector<T>> inputTensorData = { { 0, inputData } };
305 std::map<int, std::vector<T>> expectedOutputData = { { 0, expectedOutput0 },
306 { 1, expectedOutput1 },
307 { 2, expectedOutput2 } };
309 EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
312 template<armnn::DataType ArmnnType>
313 void Splitter4dDim0EndToEnd(
const std::vector<BackendId>& backends)
315 using namespace armnn;
318 unsigned int splitAxis = 0;
319 unsigned int numSplit = 2;
321 const std::vector<TensorShape> outputShapes{{ 2, 3, 2, 2 }, { 2, 3, 2, 2 }};
324 INetworkPtr net = CreateSplitterNetwork<ArmnnType>(inputShape, outputShapes, splitAxis, numSplit);
329 std::vector<T> inputData{
356 std::vector<T> expectedOutput0{
371 std::vector<T> expectedOutput1{
386 std::map<int, std::vector<T>> inputTensorData = {{ 0,inputData }};
387 std::map<int, std::vector<T>> expectedOutputData = {{ 0, expectedOutput0 }, { 1, expectedOutput1 }};
389 EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
392 template<armnn::DataType ArmnnType>
393 void Splitter4dDim1EndToEnd(
const std::vector<BackendId>& backends)
395 using namespace armnn;
398 unsigned int splitAxis = 1;
399 unsigned int numSplit = 2;
401 const std::vector<TensorShape> outputShapes{{ 2, 3, 2, 2 }, { 2, 3, 2, 2 }};
404 INetworkPtr net = CreateSplitterNetwork<ArmnnType>(inputShape, outputShapes, splitAxis, numSplit);
409 std::vector<T> inputData{
436 std::vector<T> expectedOutput0{
451 std::vector<T> expectedOutput1{
466 std::map<int, std::vector<T>> inputTensorData = {{ 0,inputData }};
467 std::map<int, std::vector<T>> expectedOutputData = {{ 0, expectedOutput0 }, { 1, expectedOutput1 }};
469 EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
472 template<armnn::DataType ArmnnType>
473 void Splitter4dDim2EndToEnd(
const std::vector<BackendId>& backends)
475 using namespace armnn;
478 unsigned int splitAxis = 2;
479 unsigned int numSplit = 2;
481 const std::vector<TensorShape> outputShapes{{ 2, 3, 2, 2 }, { 2, 3, 2, 2 }};
484 INetworkPtr net = CreateSplitterNetwork<ArmnnType>(inputShape, outputShapes, splitAxis, numSplit);
489 std::vector<T> inputData{
516 std::vector<T> expectedOutput0{
531 std::vector<T> expectedOutput1{
546 std::map<int, std::vector<T>> inputTensorData = {{ 0,inputData }};
547 std::map<int, std::vector<T>> expectedOutputData = {{ 0, expectedOutput0 }, { 1, expectedOutput1 }};
549 EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
552 template<armnn::DataType ArmnnType,
typename T = armnn::ResolveType<ArmnnType>>
553 void Splitter4dDim3EndToEnd(
const std::vector<BackendId>& backends)
555 using namespace armnn;
557 unsigned int splitAxis = 3;
558 unsigned int numSplit = 2;
560 const std::vector<TensorShape> outputShapes{{ 2, 3, 4, 1 }, { 2, 3, 4, 1 }};
563 INetworkPtr net = CreateSplitterNetwork<ArmnnType>(inputShape, outputShapes, splitAxis, numSplit);
568 std::vector<T> inputData{
595 std::vector<T> expectedOutput0{
604 std::vector<T> expectedOutput1{
613 std::map<int, std::vector<T>> inputTensorData = {{ 0,inputData }};
614 std::map<int, std::vector<T>> expectedOutputData = {{ 0, expectedOutput0 }, { 1, expectedOutput1 }};
616 EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(net), inputTensorData, expectedOutputData, backends);
A ViewsDescriptor for the SplitterLayer.
Interface for a layer that is connectable to other layers via InputSlots and OutputSlots.
typename ResolveTypeImpl< DT >::Type ResolveType
Copyright (c) 2021 ARM Limited and Contributors.
Status SetViewSize(uint32_t view, uint32_t coord, uint32_t value)
Set the size of the views.
void Connect(armnn::IConnectableLayer *from, armnn::IConnectableLayer *to, const armnn::TensorInfo &tensorInfo, unsigned int fromIndex, unsigned int toIndex)
std::unique_ptr< INetwork, void(*)(INetwork *network)> INetworkPtr
static INetworkPtr Create(NetworkOptions networkOptions={})