blob: 528d6f80d7737aa7a86a96370439ee4a28472f9d [file] [log] [blame]
Georgios Pinitasac4e8732017-07-05 17:02:25 +01001/*
2 * Copyright (c) 2017 ARM Limited.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +010024#include "AssetsLibrary.h"
Georgios Pinitasac4e8732017-07-05 17:02:25 +010025#include "Globals.h"
Moritz Pflanzerd58cec02017-07-18 15:44:21 +010026#include "NEON/Accessor.h"
Georgios Pinitasac4e8732017-07-05 17:02:25 +010027#include "PaddingCalculator.h"
Georgios Pinitasac4e8732017-07-05 17:02:25 +010028#include "TypePrinter.h"
29#include "Utils.h"
30#include "validation/Datasets.h"
31#include "validation/Helpers.h"
32#include "validation/Reference.h"
33#include "validation/Validation.h"
34
35#include "arm_compute/core/Helpers.h"
36#include "arm_compute/core/Types.h"
37#include "arm_compute/runtime/NEON/functions/NEDepthConcatenate.h"
38#include "arm_compute/runtime/Tensor.h"
39#include "arm_compute/runtime/TensorAllocator.h"
40
41#include "support/ToolchainSupport.h"
42
43#include "boost_wrapper.h"
44
45#include <algorithm>
46#include <memory>
47#include <random>
48#include <string>
49#include <vector>
50
51using namespace arm_compute;
52using namespace arm_compute::test;
Georgios Pinitasac4e8732017-07-05 17:02:25 +010053using namespace arm_compute::test::validation;
54
55namespace
56{
57/** Compute NEON depth concatenate layer function.
58 *
59 * @param[in] shapes List of shapes to concatenate
60 * @param[in] dt Datatype of tensors
61 * @param[in] fixed_point_position (Optional) Number of bits for the fractional part of fixed point numbers.
62 *
63 * @return Computed output tensor.
64 */
65Tensor compute_depth_concatenate_layer(const std::vector<TensorShape> &shapes, DataType dt, int fixed_point_position = 0)
66{
67 std::vector<std::unique_ptr<Tensor>> srcs{};
68 TensorShape dst_shape = calculate_depth_concatenate_shape(shapes);
69
70 // Create tensors
71 for(unsigned int i = 0; i < shapes.size(); ++i)
72 {
73 srcs.push_back(support::cpp14::make_unique<Tensor>());
74 srcs[i]->allocator()->init(TensorInfo(shapes[i], 1, dt, fixed_point_position));
75 }
76 Tensor dst = create_tensor<Tensor>(dst_shape, dt, 1, fixed_point_position);
77
78 // Create a vector of raw pointer
79 std::vector<ITensor *> srcs_raw{};
80 srcs_raw.resize(srcs.size());
81 std::transform(srcs.begin(), srcs.end(), srcs_raw.begin(), [](std::unique_ptr<Tensor> const & t)
82 {
83 return t.get();
84 });
85
86 // Create and configure function
87 NEDepthConcatenate depth_concat;
88 depth_concat.configure(srcs_raw, &dst);
89
90 // Allocate tensors
91 for(auto &t : srcs)
92 {
93 t->allocator()->allocate();
94 }
95 dst.allocator()->allocate();
96
97 for(const auto &t : srcs)
98 {
99 BOOST_TEST(!t->info()->is_resizable());
100 }
101 BOOST_TEST(!dst.info()->is_resizable());
102
103 // Fill tensors
104 for(unsigned int i = 0; i < srcs.size(); ++i)
105 {
Moritz Pflanzerd58cec02017-07-18 15:44:21 +0100106 library->fill_tensor_uniform(Accessor(*srcs[i]), i);
Georgios Pinitasac4e8732017-07-05 17:02:25 +0100107 }
108
109 // Compute function
110 depth_concat.run();
111
112 return dst;
113}
114} // namespace
115
116#ifndef DOXYGEN_SKIP_THIS
117BOOST_AUTO_TEST_SUITE(NEON)
118BOOST_AUTO_TEST_SUITE(DepthConcatenateLayer)
119
120BOOST_AUTO_TEST_SUITE(Float)
121BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
122BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * CNNFloatDataTypes(), shape, dt)
123{
124 // Create input shapes
125 std::vector<unsigned int> depths = { 4, 6, 11, 13 };
126 std::vector<TensorShape> shapes(depths.size(), shape);
127 for(unsigned int i = 0; i < shapes.size(); ++i)
128 {
129 shapes[i].set(2, depths[i]);
130 }
131
132 // Compute function
133 Tensor dst = compute_depth_concatenate_layer(shapes, dt);
134
135 // Compute reference
136 RawTensor ref_dst = Reference::compute_reference_depth_concatenate_layer(shapes, dt);
137
138 // Validate output
Moritz Pflanzerd58cec02017-07-18 15:44:21 +0100139 validate(Accessor(dst), ref_dst);
Georgios Pinitasac4e8732017-07-05 17:02:25 +0100140}
141
142BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
143BOOST_DATA_TEST_CASE(RunSmallPad, CNNFloatDataTypes(), dt)
144{
145 // Create input shapes
146 std::vector<TensorShape> shapes{ TensorShape(12u, 12u, 14u, 8u), TensorShape(14u, 14u, 12u, 8u), TensorShape(16u, 16u, 11u, 8u) };
147
148 // Compute function
149 Tensor dst = compute_depth_concatenate_layer(shapes, dt);
150
151 // Compute reference
152 RawTensor ref_dst = Reference::compute_reference_depth_concatenate_layer(shapes, dt);
153
154 // Validate output
Moritz Pflanzerd58cec02017-07-18 15:44:21 +0100155 validate(Accessor(dst), ref_dst);
Georgios Pinitasac4e8732017-07-05 17:02:25 +0100156}
157BOOST_AUTO_TEST_SUITE_END()
158
159BOOST_AUTO_TEST_SUITE(Quantized)
160BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
161BOOST_DATA_TEST_CASE(RunSmall, SmallShapes() * CNNFixedPointDataTypes() * boost::unit_test::data::xrange(3, 6, 1), shape, dt, fixed_point_position)
162{
163 // Create input shapes
164 std::vector<unsigned int> depths = { 4, 6, 11, 13 };
165 std::vector<TensorShape> shapes(depths.size(), shape);
166 for(unsigned int i = 0; i < shapes.size(); ++i)
167 {
168 shapes[i].set(2, depths[i]);
169 }
170
171 // Compute function
172 Tensor dst = compute_depth_concatenate_layer(shapes, dt, fixed_point_position);
173
174 // Compute reference
175 RawTensor ref_dst = Reference::compute_reference_depth_concatenate_layer(shapes, dt, fixed_point_position);
176
177 // Validate output
Moritz Pflanzerd58cec02017-07-18 15:44:21 +0100178 validate(Accessor(dst), ref_dst);
Georgios Pinitasac4e8732017-07-05 17:02:25 +0100179}
180
181BOOST_TEST_DECORATOR(*boost::unit_test::label("precommit"))
182BOOST_DATA_TEST_CASE(RunSmallPad, CNNFixedPointDataTypes() * boost::unit_test::data::xrange(3, 5, 1), dt, fixed_point_position)
183{
184 // Create input shapes
185 std::vector<TensorShape> shapes{ TensorShape(12u, 12u, 14u, 8u), TensorShape(14u, 14u, 12u, 8u), TensorShape(16u, 16u, 11u, 8u) };
186
187 // Compute function
188 Tensor dst = compute_depth_concatenate_layer(shapes, dt, fixed_point_position);
189
190 // Compute reference
191 RawTensor ref_dst = Reference::compute_reference_depth_concatenate_layer(shapes, dt, fixed_point_position);
192
193 // Validate output
Moritz Pflanzerd58cec02017-07-18 15:44:21 +0100194 validate(Accessor(dst), ref_dst);
Georgios Pinitasac4e8732017-07-05 17:02:25 +0100195}
196BOOST_AUTO_TEST_SUITE_END()
197
198BOOST_AUTO_TEST_SUITE_END()
199BOOST_AUTO_TEST_SUITE_END()
200#endif /* DOXYGEN_SKIP_THIS */