21#include <nonius/nonius.h++>
23#include <arm_compute/core/Types.h>
24#include <arm_compute/runtime/NEON/NEScheduler.h>
25#include <arm_compute/runtime/NEON/NEFunctions.h>
45TensorInfo make_info(uint32_t N)
48 return TensorInfo{shape, 1, DataType::F32};
51template <enum Layout> TensorInfo make_info(uint32_t N, uint32_t C, uint32_t H, uint32_t W);
53template <> TensorInfo make_info<NCHW>(uint32_t N, uint32_t C, uint32_t H, uint32_t W)
56 TensorInfo
info{shape, 1, DataType::F32};
57 info.set_data_layout(DataLayout::NCHW);
61template <> TensorInfo make_info<NHWC>(uint32_t N, uint32_t C, uint32_t H, uint32_t W)
64 TensorInfo
info{shape, 1, DataType::F32};
65 info.set_data_layout(DataLayout::NHWC);
69inline void check(
const Status &status)
73 std::cerr << status.error_description() << std::endl;
74 throw std::runtime_error{
"ERROR"};
78inline bool is_odd(uint32_t n) {
return (n % 2 != 0) ? true :
false; }
127 uint32_t vertical_stride;
128 uint32_t horizontal_stride;
131 std::string fused_act;
133 uint32_t top_padding;
134 uint32_t bottom_padding;
135 uint32_t left_padding;
136 uint32_t right_padding;
138 Configuration(nonius::chronometer
meter)
140 ifm_N =
meter.param<BATCH>();
141 ifm_C =
meter.param<IFM_C>();
142 ifm_H =
meter.param<IFM_H>();
143 ifm_W =
meter.param<IFM_W>();
145 ofm_N =
meter.param<BATCH>();
146 ofm_C =
meter.param<OFM_C>();
147 ofm_H =
meter.param<OFM_H>();
148 ofm_W =
meter.param<OFM_W>();
150 ker_N =
meter.param<OFM_C>();
151 ker_C =
meter.param<IFM_C>();
152 ker_H =
meter.param<KER_H>();
153 ker_W =
meter.param<KER_W>();
155 vertical_stride =
meter.param<STRIDE_H>();
156 horizontal_stride =
meter.param<STRIDE_W>();
158 padding =
meter.param<PADDING>();
159 fused_act =
meter.param<FUSED_ACT>();
161 assert((ifm_H - ker_H) % vertical_stride == 0);
162 assert((ifm_W - ker_H) % horizontal_stride == 0);
164 uint32_t
const effective_ofm_H = (ifm_H - ker_H) / vertical_stride + 1;
165 uint32_t
const effective_ofm_W = (ifm_W - ker_H) / horizontal_stride + 1;
167 assert(ofm_H >= effective_ofm_H);
168 assert(ofm_W >= effective_ofm_W);
170 uint32_t
const pad_H = ofm_H - effective_ofm_H;
171 uint32_t
const pad_W = ofm_W - effective_ofm_W;
173 top_padding = pad_H / 2;
174 bottom_padding = pad_H / 2;
175 left_padding = pad_W / 2;
176 right_padding = pad_W / 2;
184 template <Layout L> TensorInfo src_info()
const
186 return make_info<L>(ifm_N, ifm_C, ifm_H, ifm_W);
188 template <Layout L> TensorInfo dst_info()
const
190 return make_info<L>(ofm_N, ofm_C, ofm_H, ofm_W);
192 template <Layout L> TensorInfo ker_info()
const
194 return make_info<L>(ker_N, ker_C, ker_H, ker_W);
196 TensorInfo bias_info(
void)
const {
return make_info(ker_N); }
198 PadStrideInfo pad_stride_info(
void)
const
200 return PadStrideInfo{horizontal_stride,
206 DimensionRoundingType::FLOOR};
218inline nonius::benchmark_registry &local_benchmark_registry()
220 static nonius::benchmark_registry registry;
226#define NONIUS_LOCAL_BENCHMARK(name, ...) \
229 static ::nonius::benchmark_registrar \
230 NONIUS_DETAIL_UNIQUE_NAME(benchmark_registrar)(local_benchmark_registry(), name, __VA_ARGS__); \
234 NEDirectConvolutionLayer conv;
252 p.pad_stride_info()));
256 meter.measure([&](
int) {
272 meter.measure([&](
int) { conv.run(); });
276 NEDirectConvolutionLayer conv;
294 p.pad_stride_info()));
298 meter.measure([&](
int) {
314 meter.measure([&](
int) { conv.run(); });
318 NEGEMMConvolutionLayer conv;
336 p.pad_stride_info()));
340 meter.measure([&](
int) {
356 meter.measure([&](
int) { conv.run(); });
360 NEGEMMConvolutionLayer
conv;
378 p.pad_stride_info()));
382 meter.measure([&](
int) {
402 NEWinogradConvolutionLayer conv;
420 p.pad_stride_info()));
424 meter.measure([&](
int) {
440 meter.measure([&](
int) { conv.run(); });
444 NEWinogradConvolutionLayer
conv;
462 p.pad_stride_info()));
466 meter.measure([&](
int) {
487 return local_benchmark_registry();
volatile const char info[]
::nncc::core::ADT::tensor::Shape TensorShape
void conv(const nncc::core::ADT::feature::Shape &out_shape, nncc::core::ADT::feature::Accessor< OutputDType > &out_data, const nncc::core::ADT::feature::Shape &in_shape, const nncc::core::ADT::feature::Reader< InputDType > &in_data, const nncc::core::ADT::kernel::Shape &ker_shape, const nncc::core::ADT::kernel::Reader< KernelDType > &ker_data, const PadInfo &pad_info, const StrideInfo &stride_info)