38 uint32_t last_padding_dimension(
const PaddingList &padding)
40 int last_padding_dim = padding.size() - 1;
41 for (; last_padding_dim >= 0; --last_padding_dim)
43 if (padding[last_padding_dim].first > 0 || padding[last_padding_dim].second > 0)
48 return static_cast<uint32_t
>(last_padding_dim);
72 _pad_kernel = std::make_unique<NEPadLayerKernel>();
76 void NEPadLayer::configure_reflect_symmetric_mode(ITensor *
input, ITensor *output)
88 _slice_functions.resize(2 * _num_dimensions);
89 _slice_results.resize(2 * _num_dimensions);
90 _concat_functions.resize(_num_dimensions);
91 _concat_results.resize(_num_dimensions - 1);
93 Coordinates starts_before{};
94 Coordinates ends_before{};
95 Coordinates starts_after{};
96 Coordinates ends_after{};
97 Coordinates strides{};
98 ITensor *prev =
input;
99 for (uint32_t i = 0; i < _num_dimensions; ++i)
104 strides.set(i - 1, 1);
107 if (_padding[i].first > 0 || _padding[i].second > 0)
114 starts_before.set(i, _padding[i].first);
115 ends_before.set(i, 0);
116 starts_after.set(i,
input->info()->dimension(i) - 2);
117 ends_after.set(i,
input->info()->dimension(i) - _padding[i].second - 2);
122 starts_before.set(i, _padding[i].first - 1);
123 ends_before.set(i, -1);
124 starts_after.set(i,
input->info()->dimension(i) - 1);
125 ends_after.set(i,
input->info()->dimension(i) - _padding[i].second - 1);
131 const int32_t begin_mask_before = starts_before[i] < 0 ? ~0 : ~(1u << i);
132 const int32_t end_mask_before = ends_before[i] < 0 ? ~0 : ~(1u << i);
133 const int32_t begin_mask_after = starts_after[i] < 0 ? ~0 : ~(1u << i);
134 const int32_t end_mask_after = ends_after[i] < 0 ? ~0 : ~(1u << i);
137 std::vector<const ITensor *> concat_vector;
138 if (_padding[i].first > 0)
140 if (i < prev->
info()->num_dimensions())
142 _slice_functions[2 * i].configure(prev, &_slice_results[2 * i], starts_before, ends_before, strides,
143 begin_mask_before, end_mask_before);
144 concat_vector.emplace_back(&_slice_results[2 * i]);
149 concat_vector.push_back(prev);
152 concat_vector.push_back(prev);
153 if (_padding[i].second > 0)
155 if (i < prev->
info()->num_dimensions())
157 _slice_functions[2 * i + 1].configure(prev, &_slice_results[2 * i + 1], starts_after, ends_after,
158 strides, begin_mask_after, end_mask_after);
159 concat_vector.emplace_back(&_slice_results[2 * i + 1]);
164 concat_vector.push_back(prev);
168 ITensor *out = (i == _num_dimensions - 1) ? output : &_concat_results[i];
169 out->info()->set_quantization_info(output->info()->quantization_info());
170 for (
auto &v : concat_vector)
172 v->info()->set_quantization_info(
input->info()->quantization_info());
174 _concat_functions[i].configure(concat_vector, out, i);
175 if (i != _num_dimensions - 1)
177 _concat_results[i].allocator()->allocate();
181 _slice_results[2 * i].allocator()->allocate();
182 _slice_results[2 * i + 1].allocator()->allocate();
204 _num_dimensions = last_padding_dimension(padding) + 1;
205 if (_num_dimensions > 0)
211 configure_constant_mode(
input, output, padding, constant_value);
217 configure_reflect_symmetric_mode(
input, output);
256 for (uint32_t i = 0; i < padding.size(); ++i)
281 if (_num_dimensions > 0)
293 for (uint32_t i = 0; i < _num_dimensions; ++i)
295 if (_padding[i].first > 0 || _padding[i].second > 0)
297 if (_padding[i].first > 0 && _slice_results[2 * i].
info()->total_size() > 0)
299 _slice_functions[2 * i].run();
301 if (_padding[i].second > 0 && _slice_results[2 * i + 1].
info()->total_size() > 0)
303 _slice_functions[2 * i + 1].run();
305 _concat_functions[i].run();
316 _copy_function.
run();