blob: 7500560c91da49ede01b70506f47c2b55dc7f840 [file] [log] [blame]
Gian Marco Iodice5d016812022-11-17 11:03:39 +00001/*
2 * Copyright (c) 2022 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 */
24#include "IndirectConv2dAddressPrecalculation.h"
25
26#include "arm_compute/core/Types.h"
27
28#include "tests/validation/Helpers.h"
29
30namespace arm_compute
31{
32namespace test
33{
34namespace validation
35{
36namespace reference
37{
38SimpleTensor<int32_t> indirect_conv2d_addr_precalculation(const TensorShape &shape_conv_src, const TensorShape &shape_conv_wei, const TensorShape &shape_conv_dst, const TensorShape &shape_dst,
39 const PadStrideInfo &conv_info)
40{
41 SimpleTensor<int32_t> out{ shape_dst, DataType::S32 };
42
43 constexpr unsigned int width_idx = 1;
44 constexpr unsigned int heigh_idx = 2;
45
46 const int src_conv_width = static_cast<int32_t>(shape_conv_src[width_idx]); // NHWC
47 const int src_conv_height = static_cast<int32_t>(shape_conv_src[heigh_idx]); // NHWC
48 const int dst_conv_width = static_cast<int32_t>(shape_conv_dst[width_idx]); // NHWC
49 const int wei_conv_width = static_cast<int32_t>(shape_conv_wei[width_idx]); // NHWC
50 const int wei_conv_height = static_cast<int32_t>(shape_conv_wei[heigh_idx]); // NHWC
51 const int dst_width = static_cast<int32_t>(shape_dst[0]);
52 const int dst_height = static_cast<int32_t>(shape_dst[1]);
53 const int dst_batch = static_cast<int32_t>(shape_dst[2]);
54 const int ks = wei_conv_width * wei_conv_height;
55 const int stride_x = static_cast<int32_t>(conv_info.stride().first);
56 const int stride_y = static_cast<int32_t>(conv_info.stride().second);
57 const int pad_left = static_cast<int32_t>(conv_info.pad_left());
58 const int pad_top = static_cast<int32_t>(conv_info.pad_top());
59
60 const int m0 = dst_width / ks;
61
62 for(int z = 0; z < dst_batch; ++z)
63 {
64 for(int y = 0; y < dst_height; ++y)
65 {
66 const int mout = y * m0;
67 for(int ki = 0; ki < ks; ++ki)
68 {
69 const int xk = ki % wei_conv_width;
70 const int yk = ki / wei_conv_width;
71 for(int mi = 0; mi < m0; ++mi)
72 {
73 int xi = ((mout + mi) % dst_conv_width) * stride_x;
74 int yi = ((mout + mi) / dst_conv_width) * stride_y;
75 xi -= pad_left;
76 yi -= pad_top;
77 const int x_s = xi + xk;
78 const int y_s = yi + yk;
79 int my = x_s + y_s * src_conv_width;
80 my = my + z * src_conv_width * src_conv_height;
81 my = x_s >= 0 ? my : -1;
82 my = x_s < src_conv_width ? my : -1;
83 my = y_s >= 0 ? my : -1;
84 my = y_s < src_conv_height ? my : -1;
85
86 const unsigned int addr_out = mi + ki * m0 + y * (dst_width) + z * (dst_width * dst_height);
Gian Marco Iodice76335eb2022-11-17 11:03:39 +000087 out[addr_out] = my;
Gian Marco Iodice5d016812022-11-17 11:03:39 +000088 }
89 }
90 }
91 }
92
93 return out;
94}
95} // namespace reference
96} // namespace validation
97} // namespace test
98} // namespace arm_compute