blob: 6f6edc1bcfd4784bdb74f7fb71d5e4a000727068 [file] [log] [blame]
Usama Arif0681e3b2019-04-25 14:28:07 +01001/*
Michele Di Giorgiod9eaf612020-07-08 11:12:57 +01002 * Copyright (c) 2019-2020 Arm Limited.
Usama Arif0681e3b2019-04-25 14:28:07 +01003 *
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 */
Gian Marco Iodiceca1f4602019-07-16 15:46:48 +010024#include "activation_float_helpers.h"
Usama Arif0681e3b2019-04-25 14:28:07 +010025#include "helpers.h"
26
Gian Marco Iodice73cdaac2020-08-10 21:44:14 +010027/** Utility macro to access a vector with the scalar positions
28 *
29 * Supported cases are: Offset can only be of the same size of the OpenCL vector (2,3,4,8,16)
30 *
31 * @param[in] offset The offset within the vector. Offset can only be of the same size of the OpenCL vector (2,3,4,8,16)
32 * @param[in] n0 The number of consecutive columns to access. n0 + offset must be <= 16
33 * @param[in] x Vector to access
34 * @{
35 */
36#define SCALAR_ACCESS_STR(offset, n0, x) scalar_access_##offset##_##n0(x)
37#define SCALAR_ACCESS(offset, n0, x) SCALAR_ACCESS_STR(offset, n0, x)
38
39// offset == 0
40#define scalar_access_0_1(x) ((x).s0)
41#define scalar_access_0_2(x) ((x).s01)
42#define scalar_access_0_3(x) ((x).s012)
43#define scalar_access_0_4(x) ((x).s0123)
44#define scalar_access_0_8(x) ((x).s01234567)
45#define scalar_access_0_16(x) ((x).s0123456789ABCDEF)
46
47// offset == 1
48#define scalar_access_1_1(x) ((x).s1)
49#define scalar_access_1_2(x) ((x).s12)
50#define scalar_access_1_3(x) ((x).s123)
51#define scalar_access_1_4(x) ((x).s1234)
52#define scalar_access_1_8(x) ((x).s12345678)
53
54// offset == 2
55#define scalar_access_2_1(x) ((x).s2)
56#define scalar_access_2_2(x) ((x).s23)
57#define scalar_access_2_3(x) ((x).s234)
58#define scalar_access_2_4(x) ((x).s2345)
59#define scalar_access_2_8(x) ((x).s23456789)
60
61// offset == 3
62#define scalar_access_3_1(x) ((x).s3)
63#define scalar_access_3_2(x) ((x).s34)
64#define scalar_access_3_3(x) ((x).s345)
65#define scalar_access_3_4(x) ((x).s3456)
66#define scalar_access_3_8(x) ((x).s3456789A)
67
68// offset == 4
69#define scalar_access_4_1(x) ((x).s4)
70#define scalar_access_4_2(x) ((x).s45)
71#define scalar_access_4_3(x) ((x).s456)
72#define scalar_access_4_4(x) ((x).s4567)
73#define scalar_access_4_8(x) ((x).s456789AB)
74
75// offset == 8
76#define scalar_access_8_1(x) ((x).s8)
77#define scalar_access_8_2(x) ((x).s89)
78#define scalar_access_8_3(x) ((x).s89A)
79#define scalar_access_8_4(x) ((x).s89AB)
80#define scalar_access_8_8(x) ((x).s89ABCDEF)
81
82// offset == 12
83#define scalar_access_12_1(x) ((x).sC)
84#define scalar_access_12_2(x) ((x).sCD)
85#define scalar_access_12_3(x) ((x).sCDE)
86#define scalar_access_12_4(x) ((x).sCDEF)
87
88// offset == 16
89#define scalar_access_16_1(x) ((x).sF)
90
91/** Loads the rows from 0 to n-1 in the given variables (BASENAME0 to BASENAMEn-1) without allocating variables.
92 * @name LOAD_TENSOR_ROW_n
93 *
94 * @param[in] N0 The number of columns to load
95 * @param[in] DATA_TYPE The data type of variables
96 * @param[in] BASENAME The basename of the destination variables for the loaded rows
97 * @param[in] PTR The base pointer
98 * @param[in] COL_OFFSET The column vector offset. COL_OFFSET + N0 must be <= 16
99 * @param[in] STRIDE_Y The stride value in y-axis direction
100 * @param[in] Z The z-axis offset vector
101 * @{
102 */
103#define LOAD_TENSOR_ROW_0(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
104 ({})
105
106#define LOAD_TENSOR_ROW_1(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
107 SCALAR_ACCESS(COL_OFFSET, N0, BASENAME##0) = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + 0 * STRIDE_Y + Z##0));
108
109#define LOAD_TENSOR_ROW_2(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
110 LOAD_TENSOR_ROW_1(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
111 SCALAR_ACCESS(COL_OFFSET, N0, BASENAME##1) = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + 1 * STRIDE_Y + Z##1));
112
113#define LOAD_TENSOR_ROW_3(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
114 LOAD_TENSOR_ROW_2(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
115 SCALAR_ACCESS(COL_OFFSET, N0, BASENAME##2) = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + 2 * STRIDE_Y + Z##2));
116
117#define LOAD_TENSOR_ROW_4(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
118 LOAD_TENSOR_ROW_3(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
119 SCALAR_ACCESS(COL_OFFSET, N0, BASENAME##3) = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + 3 * STRIDE_Y + Z##3));
120
121#define LOAD_TENSOR_ROW_5(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
122 LOAD_TENSOR_ROW_4(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
123 SCALAR_ACCESS(COL_OFFSET, N0, BASENAME##4) = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + 4 * STRIDE_Y + Z##4));
124
125#define LOAD_TENSOR_ROW_6(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
126 LOAD_TENSOR_ROW_5(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
127 SCALAR_ACCESS(COL_OFFSET, N0, BASENAME##5) = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + 5 * STRIDE_Y + Z##5));
128
129#define LOAD_TENSOR_ROW_7(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
130 LOAD_TENSOR_ROW_6(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
131 SCALAR_ACCESS(COL_OFFSET, N0, BASENAME##6) = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + 6 * STRIDE_Y + Z##6));
132
133#define LOAD_TENSOR_ROW_8(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
134 LOAD_TENSOR_ROW_7(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
135 SCALAR_ACCESS(COL_OFFSET, N0, BASENAME##7) = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + 7 * STRIDE_Y + Z##7));
136
137#define LOAD_TENSOR_ROW_9(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
138 LOAD_TENSOR_ROW_8(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
139 SCALAR_ACCESS(COL_OFFSET, N0, BASENAME##8) = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + 8 * STRIDE_Y + Z##8));
140
141#define LOAD_TENSOR_ROW_10(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
142 LOAD_TENSOR_ROW_9(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
143 SCALAR_ACCESS(COL_OFFSET, N0, BASENAME##9) = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + 9 * STRIDE_Y + Z##9));
144
145#define LOAD_TENSOR_ROW_11(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
146 LOAD_TENSOR_ROW_10(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
147 SCALAR_ACCESS(COL_OFFSET, N0, BASENAME##A) = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + 10 * STRIDE_Y + Z##A));
148
149#define LOAD_TENSOR_ROW_12(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
150 LOAD_TENSOR_ROW_11(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
151 SCALAR_ACCESS(COL_OFFSET, N0, BASENAME##B) = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + 11 * STRIDE_Y + Z##B));
152
153#define LOAD_TENSOR_ROW_13(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
154 LOAD_TENSOR_ROW_12(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
155 SCALAR_ACCESS(COL_OFFSET, N0, BASENAME##C) = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + 12 * STRIDE_Y + Z##C));
156
157#define LOAD_TENSOR_ROW_14(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
158 LOAD_TENSOR_ROW_13(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
159 SCALAR_ACCESS(COL_OFFSET, N0, BASENAME##D) = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + 13 * STRIDE_Y + Z##D));
160
161#define LOAD_TENSOR_ROW_15(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
162 LOAD_TENSOR_ROW_14(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
163 SCALAR_ACCESS(COL_OFFSET, N0, BASENAME##E) = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + 14 * STRIDE_Y + Z##E));
164
165#define LOAD_TENSOR_ROW_16(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
166 LOAD_TENSOR_ROW_15(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) \
167 SCALAR_ACCESS(COL_OFFSET, N0, BASENAME##F) = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + 15 * STRIDE_Y + Z##F));
168/** @}*/ // end of group LOAD_TENSOR_ROW_n
169
170/** Load tensor (consecutive rows and columns) with Z offset.
171 * @name LOAD_TENSOR
172 *
173 * Supported cases are M0=1,2,3,...,16 and N0=1,2,3,4,8,16
174 * The data to load is expected to have consecutive names for each row.
175 * E.g., for M0=3, and BASENAME=c, the expected data is c0, c1 and c2.
176 * The Z offset is expected to have consecutive names.
177 * E.g., for M0=3, and Z=zin, the expected Z offsets are zin0, zin1 and zin2.
178 *
179 * @param[in] M0 The number of consecutive rows
180 * @param[in] N0 The number of consecutive columns
181 * @param[in] DATA_TYPE The data type of the target
182 * @param[in] BASENAME The basename of the result variables
183 * @param[in] PTR The base pointer for the data
184 * @param[in] COL_OFFSET The column vector offset. COL_OFFSET + N0 must be <= 16
185 * @param[in] STRIDE_Y The stride in y-axis direction
186 * @param[in] Z The z-axis offset vector
187 * @{
188 */
189#define LOAD_TENSOR_STR(M0, N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) LOAD_TENSOR_ROW_##M0(N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z)
190#define LOAD_TENSOR(M0, N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z) LOAD_TENSOR_STR(M0, N0, DATA_TYPE, BASENAME, PTR, COL_OFFSET, STRIDE_Y, Z)
191/** @} */ // end of group LOAD_TENSOR
192
193/** Load 2D tensor (consecutive rows and columns) with Z offset.
194 * @name LOAD_TENSOR_M0Xn
195 *
196 * @param[in] M0 The number of rows to load [0-16]
197 * @param[in] N0 The number of columns to load [0-16]
198 * @param[in] DATA_TYPE The data type of variables
199 * @param[in] BASENAME The basename of the destination variables for the loaded rows
200 * @param[in] PTR The base pointer
201 * @param[in] STRIDE_Y The stride value in y-axis direction
202 * @param[in] Z The z-axis offset vector
203 * @{
204 */
205#define LOAD_TENSOR_M0X0(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
206 ({})
207
208#define LOAD_TENSOR_M0X1(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
209 LOAD_TENSOR(M0, N0, DATA_TYPE, a, input_ptr, 0, src_stride_y, zin);
210
211#define LOAD_TENSOR_M0X2(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
212 LOAD_TENSOR(M0, N0, DATA_TYPE, a, input_ptr, 0, src_stride_y, zin);
213
214#define LOAD_TENSOR_M0X3(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
215 LOAD_TENSOR(M0, N0, DATA_TYPE, a, input_ptr, 0, src_stride_y, zin);
216
217#define LOAD_TENSOR_M0X4(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
218 LOAD_TENSOR(M0, N0, DATA_TYPE, a, input_ptr, 0, src_stride_y, zin);
219
220#define LOAD_TENSOR_M0X5(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
221 LOAD_TENSOR(M0, 4, DATA_TYPE, a, input_ptr, 0, src_stride_y, zin); \
222 LOAD_TENSOR(M0, 1, DATA_TYPE, a, input_ptr + 4 * sizeof(DATA_TYPE), 4, src_stride_y, zin);
223
224#define LOAD_TENSOR_M0X6(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
225 LOAD_TENSOR(M0, 4, DATA_TYPE, a, input_ptr, 0, src_stride_y, zin); \
226 LOAD_TENSOR(M0, 2, DATA_TYPE, a, input_ptr + 4 * sizeof(DATA_TYPE), 4, src_stride_y, zin);
227
228#define LOAD_TENSOR_M0X7(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
229 LOAD_TENSOR(M0, 4, DATA_TYPE, a, input_ptr, 0, src_stride_y, zin); \
230 LOAD_TENSOR(M0, 3, DATA_TYPE, a, input_ptr + 4 * sizeof(DATA_TYPE), 4, src_stride_y, zin);
231
232#define LOAD_TENSOR_M0X8(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
233 LOAD_TENSOR(M0, N0, DATA_TYPE, a, input_ptr, 0, src_stride_y, zin);
234
235#define LOAD_TENSOR_M0X9(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
236 LOAD_TENSOR(M0, 8, DATA_TYPE, a, input_ptr 0, src_stride_y, zin); \
237 LOAD_TENSOR(M0, 1, DATA_TYPE, a, input_ptr + 8 * sizeof(DATA_TYPE), 8, src_stride_y, zin);
238
239#define LOAD_TENSOR_M0X10(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
240 LOAD_TENSOR(M0, 8, DATA_TYPE, a, input_ptr, 0, src_stride_y, zin); \
241 LOAD_TENSOR(M0, 2, DATA_TYPE, a, input_ptr + 8 * sizeof(DATA_TYPE), 8, src_stride_y, zin);
242
243#define LOAD_TENSOR_M0X11(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
244 LOAD_TENSOR(M0, 8, DATA_TYPE, a, input_ptr, 0, src_stride_y, zin); \
245 LOAD_TENSOR(M0, 3, DATA_TYPE, a, input_ptr + 8 * sizeof(DATA_TYPE), 8, src_stride_y, zin);
246
247#define LOAD_TENSOR_M0X12(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
248 LOAD_TENSOR(M0, 8, DATA_TYPE, a, input_ptr, 0, src_stride_y, zin); \
249 LOAD_TENSOR(M0, 4, DATA_TYPE, a, input_ptr + 8 * sizeof(DATA_TYPE), 8, src_stride_y, zin);
250
251#define LOAD_TENSOR_M0X13(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
252 LOAD_TENSOR(M0, 8, DATA_TYPE, a, input_ptr, 0, src_stride_y, zin); \
253 LOAD_TENSOR(M0, 4, DATA_TYPE, a, input_ptr + 8 * sizeof(DATA_TYPE), 8, src_stride_y, zin); \
254 LOAD_TENSOR(M0, 1, DATA_TYPE, a, input_ptr + 12 * sizeof(DATA_TYPE), 12, src_stride_y, zin);
255
256#define LOAD_TENSOR_M0X14(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
257 LOAD_TENSOR(M0, 8, DATA_TYPE, a, input_ptr 0, src_stride_y, zin); \
258 LOAD_TENSOR(M0, 4, DATA_TYPE, a, input_ptr + 8 * sizeof(DATA_TYPE), 8, src_stride_y, zin); \
259 LOAD_TENSOR(M0, 2, DATA_TYPE, a, input_ptr + 12 * sizeof(DATA_TYPE), 12, src_stride_y, zin);
260
261#define LOAD_TENSOR_M0X15(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
262 LOAD_TENSOR(M0, 8, DATA_TYPE, a, input_ptr, 0, src_stride_y, zin); \
263 LOAD_TENSOR(M0, 4, DATA_TYPE, a, input_ptr + 8 * sizeof(DATA_TYPE), 8, src_stride_y, zin); \
264 LOAD_TENSOR(M0, 3, DATA_TYPE, a, input_ptr + 12 * sizeof(DATA_TYPE), 12, src_stride_y, zin);
265
266#define LOAD_TENSOR_M0X16(M0, N0, DATA_TYPE, a, input_ptr, src_stride_y, zin) \
267 LOAD_TENSOR(M0, N0, DATA_TYPE, a, input_ptr, 0, src_stride_y, zin);
268/** @}*/ // end of group LOAD_TENSOR_M0Xn
269
270/** Load 2D tensor (consecutive rows and columns) with Z offset.
271 * @name LOAD_TENSOR_M0XN0
272 *
273 * @param[in] M0 The number of consecutive rows [0-16]
274 * @param[in] N0 The number of consecutive columns [0-16]
275 * @param[in] DATA_TYPE The data type of the target
276 * @param[in] BASENAME The basename of the result variables
277 * @param[in] PTR The base pointer for the data
278 * @param[in] STRIDE_Y The stride in y-axis direction
279 * @param[in] Z The z-axis offset vector
280 * @{
281 */
282#define LOAD_TENSOR_M0XN0_STR(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) LOAD_TENSOR_M0X##N0(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z)
283#define LOAD_TENSOR_M0XN0(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) LOAD_TENSOR_M0XN0_STR(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z)
284
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +0000285/** Loads the rows from 0 to n-1 in the given variables (BASENAME0 to BASENAMEn-1).
286 * @name LOAD_ROW_n
287 *
Gian Marco Iodice73cdaac2020-08-10 21:44:14 +0100288 * @param[in] N0 The number of columns to load
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +0000289 * @param[in] DATA_TYPE The data type of variables
290 * @param[in] BASENAME The basename of the destination variables for the loaded rows
291 * @param[in] PTR The base pointer
292 * @param[in] OFFSET The offset within a row
293 * @param[in] STRIDE_Y The stride value in y-axis direction
294 * @param[in] Z The z-axis offset vector
295 * @{
296 */
Usama Arif0681e3b2019-04-25 14:28:07 +0100297#define LOAD_ROW_1(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
298 VEC_DATA_TYPE(DATA_TYPE, N0) \
299 BASENAME##0 = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + OFFSET + 0 * STRIDE_Y + Z##0));
300
301#define LOAD_ROW_2(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
302 LOAD_ROW_1(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
303 VEC_DATA_TYPE(DATA_TYPE, N0) \
304 BASENAME##1 = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + OFFSET + 1 * STRIDE_Y + Z##1));
305
306#define LOAD_ROW_3(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
307 LOAD_ROW_2(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
308 VEC_DATA_TYPE(DATA_TYPE, N0) \
309 BASENAME##2 = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + OFFSET + 2 * STRIDE_Y + Z##2));
310
311#define LOAD_ROW_4(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
312 LOAD_ROW_3(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
313 VEC_DATA_TYPE(DATA_TYPE, N0) \
314 BASENAME##3 = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + OFFSET + 3 * STRIDE_Y + Z##3));
315
316#define LOAD_ROW_5(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
317 LOAD_ROW_4(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
318 VEC_DATA_TYPE(DATA_TYPE, N0) \
319 BASENAME##4 = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + OFFSET + 4 * STRIDE_Y + Z##4));
320
321#define LOAD_ROW_6(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
322 LOAD_ROW_5(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
323 VEC_DATA_TYPE(DATA_TYPE, N0) \
324 BASENAME##5 = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + OFFSET + 5 * STRIDE_Y + Z##5));
325
326#define LOAD_ROW_7(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
327 LOAD_ROW_6(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
328 VEC_DATA_TYPE(DATA_TYPE, N0) \
329 BASENAME##6 = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + OFFSET + 6 * STRIDE_Y + Z##6));
330
331#define LOAD_ROW_8(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
332 LOAD_ROW_7(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
333 VEC_DATA_TYPE(DATA_TYPE, N0) \
334 BASENAME##7 = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + OFFSET + 7 * STRIDE_Y + Z##7));
335
336#define LOAD_ROW_9(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
337 LOAD_ROW_8(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
338 VEC_DATA_TYPE(DATA_TYPE, N0) \
339 BASENAME##8 = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + OFFSET + 8 * STRIDE_Y + Z##8));
340
341#define LOAD_ROW_10(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
342 LOAD_ROW_9(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
343 VEC_DATA_TYPE(DATA_TYPE, N0) \
344 BASENAME##9 = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + OFFSET + 9 * STRIDE_Y + Z##9));
345
346#define LOAD_ROW_11(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
347 LOAD_ROW_10(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
348 VEC_DATA_TYPE(DATA_TYPE, N0) \
349 BASENAME##A = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + OFFSET + 10 * STRIDE_Y + Z##A));
350
351#define LOAD_ROW_12(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
352 LOAD_ROW_11(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
353 VEC_DATA_TYPE(DATA_TYPE, N0) \
354 BASENAME##B = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + OFFSET + 11 * STRIDE_Y + Z##B));
355
356#define LOAD_ROW_13(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
357 LOAD_ROW_12(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
358 VEC_DATA_TYPE(DATA_TYPE, N0) \
359 BASENAME##C = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + OFFSET + 12 * STRIDE_Y + Z##C));
360
361#define LOAD_ROW_14(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
362 LOAD_ROW_13(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
363 VEC_DATA_TYPE(DATA_TYPE, N0) \
364 BASENAME##D = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + OFFSET + 13 * STRIDE_Y + Z##D));
365
366#define LOAD_ROW_15(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
367 LOAD_ROW_14(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
368 VEC_DATA_TYPE(DATA_TYPE, N0) \
369 BASENAME##E = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + OFFSET + 14 * STRIDE_Y + Z##E));
370
371#define LOAD_ROW_16(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
372 LOAD_ROW_15(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) \
373 VEC_DATA_TYPE(DATA_TYPE, N0) \
374 BASENAME##F = VLOAD(N0)(0, (__global DATA_TYPE *)(PTR + OFFSET + 15 * STRIDE_Y + Z##F));
375
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +0000376/** @}*/ // end of group LOAD_ROW_n
Usama Arif0681e3b2019-04-25 14:28:07 +0100377
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +0000378/** Load Blocks (consecutive rows and columns) with Z offset.
379 * @name LOAD_BLOCK
380 *
381 * Supported cases are M0=1,2,3,...,16 and N0=1,2,3,4,8,16
382 * The data to load is expected to have consecutive names for each row.
383 * E.g., for M0=3, and BASENAME=c, the expected data is c0, c1 and c2.
384 * The Z offset is expected to have consecutive names.
385 * E.g., for M0=3, and Z=zin, the expected Z offsets are zin0, zin1 and zin2.
386 *
387 * @param[in] M0 The number of consecutive rows
388 * @param[in] N0 The number of consecutive columns
389 * @param[in] DATA_TYPE The data type of the target
390 * @param[in] BASENAME The basename of the result variables
391 * @param[in] PTR The base pointer for the data
392 * @param[in] OFFSET The offset within a row
393 * @param[in] STRIDE_Y The stride in y-axis direction
394 * @param[in] Z The z-axis offset vector
395 * @{
396 */
397#define LOAD_BLOCK_STR(M0, N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) LOAD_ROW_##M0(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z)
398#define LOAD_BLOCK(M0, N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z) LOAD_BLOCK_STR(M0, N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y, Z)
399/** @} */ // end of group LOAD_BLOCK
400
Gian Marco Iodicee3a849a2020-06-10 17:59:30 +0100401/** Loads the rows from 0 to n-1 in the given variables (BASENAME0 to BASENAMEn-1).
402 * @name LOAD_TEXTURE2D_ROW_n
403 *
404 * @param[in] N0 The number of pixels to read
405 * @param[in] DATA_TYPE The data type of variables
406 * @param[in] BASENAME The basename of the destination variables for the loaded rows
407 * @param[in] IMG The 2D OpenCL image object
408 * @param[in] X_COORD The x coordinate for the top-left pixel
409 * @param[in] Y_COORD The y coordinate for the top-left pixel
410 * @param[in] X_STEP_ROW The incremental step row for the x coordinate (in pixels)
411 * @param[in] Y_STEP_ROW The incremental step row for the y coordinate (in pixels)
412 * @{
413 */
414#define LOAD_TEXTURE2D_ROW_1(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
415 BASENAME##0 = READ_IMAGE2D(DATA_TYPE, N0, IMG, (X_COORD + 0 * X_STEP_ROW), (Y_COORD + 0 * Y_STEP_ROW))
416
417#define LOAD_TEXTURE2D_ROW_2(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
418 LOAD_TEXTURE2D_ROW_1(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
419 BASENAME##1 = READ_IMAGE2D(DATA_TYPE, N0, IMG, (X_COORD + 1 * X_STEP_ROW), (Y_COORD + 1 * Y_STEP_ROW))
420
421#define LOAD_TEXTURE2D_ROW_3(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
422 LOAD_TEXTURE2D_ROW_2(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
423 BASENAME##2 = READ_IMAGE2D(DATA_TYPE, N0, IMG, (X_COORD + 2 * X_STEP_ROW), (Y_COORD + 2 * Y_STEP_ROW))
424
425#define LOAD_TEXTURE2D_ROW_4(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
426 LOAD_TEXTURE2D_ROW_3(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
427 BASENAME##3 = READ_IMAGE2D(DATA_TYPE, N0, IMG, (X_COORD + 3 * X_STEP_ROW), (Y_COORD + 3 * Y_STEP_ROW))
428
429#define LOAD_TEXTURE2D_ROW_5(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
430 LOAD_TEXTURE2D_ROW_4(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
431 BASENAME##4 = READ_IMAGE2D(DATA_TYPE, N0, IMG, (X_COORD + 4 * X_STEP_ROW), (Y_COORD + 4 * Y_STEP_ROW))
432
433#define LOAD_TEXTURE2D_ROW_6(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
434 LOAD_TEXTURE2D_ROW_5(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
435 BASENAME##5 = READ_IMAGE2D(DATA_TYPE, N0, IMG, (X_COORD + 5 * X_STEP_ROW), (Y_COORD + 5 * Y_STEP_ROW))
436
437#define LOAD_TEXTURE2D_ROW_7(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
438 LOAD_TEXTURE2D_ROW_6(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
439 BASENAME##6 = READ_IMAGE2D(DATA_TYPE, N0, IMG, (X_COORD + 6 * X_STEP_ROW), (Y_COORD + 6 * Y_STEP_ROW))
440
441#define LOAD_TEXTURE2D_ROW_8(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
442 LOAD_TEXTURE2D_ROW_7(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
443 BASENAME##7 = READ_IMAGE2D(DATA_TYPE, N0, IMG, (X_COORD + 7 * X_STEP_ROW), (Y_COORD + 7 * Y_STEP_ROW))
444
445#define LOAD_TEXTURE2D_ROW_9(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
446 LOAD_TEXTURE2D_ROW_8(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
447 BASENAME##8 = READ_IMAGE2D(DATA_TYPE, N0, IMG, (X_COORD + 8 * X_STEP_ROW), (Y_COORD + 8 * Y_STEP_ROW))
448
449#define LOAD_TEXTURE2D_ROW_10(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
450 LOAD_TEXTURE2D_ROW_9(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
451 BASENAME##9 = READ_IMAGE2D(DATA_TYPE, N0, IMG, (X_COORD + 9 * X_STEP_ROW), (Y_COORD + 9 * Y_STEP_ROW))
452
453#define LOAD_TEXTURE2D_ROW_11(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
454 LOAD_TEXTURE2D_ROW_10(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
455 BASENAME##A = READ_IMAGE2D(DATA_TYPE, N0, IMG, (X_COORD + 10 * X_STEP_ROW), (Y_COORD + 10 * Y_STEP_ROW))
456
457#define LOAD_TEXTURE2D_ROW_12(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
458 LOAD_TEXTURE2D_ROW_11(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
459 BASENAME##B = READ_IMAGE2D(DATA_TYPE, N0, IMG, (X_COORD + 11 * X_STEP_ROW), (Y_COORD + 11 * Y_STEP_ROW))
460
461#define LOAD_TEXTURE2D_ROW_13(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
462 LOAD_TEXTURE2D_ROW_12(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
463 BASENAME##C = READ_IMAGE2D(DATA_TYPE, N0, IMG, (X_COORD + 12 * X_STEP_ROW), (Y_COORD + 12 * Y_STEP_ROW))
464
465#define LOAD_TEXTURE2D_ROW_14(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
466 LOAD_TEXTURE2D_ROW_13(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
467 BASENAME##D = READ_IMAGE2D(DATA_TYPE, N0, IMG, (X_COORD + 13 * X_STEP_ROW), (Y_COORD + 13 * Y_STEP_ROW))
468
469#define LOAD_TEXTURE2D_ROW_15(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
470 LOAD_TEXTURE2D_ROW_14(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
471 BASENAME##E = READ_IMAGE2D(DATA_TYPE, N0, IMG, (X_COORD + 14 * X_STEP_ROW), (Y_COORD + 14 * Y_STEP_ROW))
472
473#define LOAD_TEXTURE2D_ROW_16(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
474 LOAD_TEXTURE2D_ROW_15(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) \
475 BASENAME##F = READ_IMAGE2D(DATA_TYPE, N0, IMG, (X_COORD + 15 * X_STEP_ROW), (Y_COORD + 15 * Y_STEP_ROW))
476/** @} */ // end of group LOAD_TEXTURE2D_ROW_n
477
478/** Load a 2D texture in unit of pixel. A pixel is made of 4 floating point values
479 * @name LOAD_TEXTURE2D
480 *
481 * Supported cases are M0=1,2,3,...,16 and N0=1
482 * The data to load is expected to have consecutive names for each row.
483 * E.g., for M0=3, and BASENAME=c, the expected data is c0, c1 and c2.
484 *
485 * @param[in] M0 The number of consecutive rows
486 * @param[in] N0 The number of consecutive pixels. Only 1, 2 and 4 are supported
487 * @param[in] DATA_TYPE The data type of the target
488 * @param[in] BASENAME The basename of the result variables
489 * @param[in] IMG The 2D OpenCL image object
490 * @param[in] X_COORD The x coordinate for the top-left pixel
491 * @param[in] Y_COORD The y coordinate for the top-left pixel
492 * @param[in] X_STEP_ROW The incremental step row for the x coordinate (in pixels)
493 * @param[in] Y_STEP_ROW The incremental step row for the y coordinate (in pixels)
494 * @{
495 */
496#define LOAD_TEXTURE2D_STR(M0, N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) LOAD_TEXTURE2D_ROW_##M0(N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW)
497#define LOAD_TEXTURE2D(M0, N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW) LOAD_TEXTURE2D_STR(M0, N0, DATA_TYPE, BASENAME, IMG, X_COORD, Y_COORD, X_STEP_ROW, Y_STEP_ROW)
498/** @} */ // end of group LOAD_TEXTURE2D
499
Michele Di Giorgiob54ba282020-01-14 15:31:55 +0000500/** Loads the elements from 0 to n-1 in the given variables (BASENAME0 to BASENAMEn-1).
501 * @name LOAD_ELEMENT_n
502 *
503 * @param[in] N0 The number of rows to load
504 * @param[in] DATA_TYPE The data type of variables
505 * @param[in] BASENAME The basename of the destination variables for the loaded rows
506 * @param[in] PTR The base pointer
507 * @param[in] OFFSET The offset within a row
508 * @param[in] STRIDE_Y The stride value in y-axis direction
509 * @{
510 */
511#define LOAD_ELEMENT_1(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
512 VEC_DATA_TYPE(DATA_TYPE, N0) \
513 BASENAME##0 = *((__global DATA_TYPE *)(PTR + OFFSET + 0 * STRIDE_Y));
514
515#define LOAD_ELEMENT_2(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
516 LOAD_ELEMENT_1(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
517 VEC_DATA_TYPE(DATA_TYPE, N0) \
518 BASENAME##1 = *((__global DATA_TYPE *)(PTR + OFFSET + 1 * STRIDE_Y));
519
520#define LOAD_ELEMENT_3(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
521 LOAD_ELEMENT_2(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
522 VEC_DATA_TYPE(DATA_TYPE, N0) \
523 BASENAME##2 = *((__global DATA_TYPE *)(PTR + OFFSET + 2 * STRIDE_Y));
524
525#define LOAD_ELEMENT_4(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
526 LOAD_ELEMENT_3(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
527 VEC_DATA_TYPE(DATA_TYPE, N0) \
528 BASENAME##3 = *((__global DATA_TYPE *)(PTR + OFFSET + 3 * STRIDE_Y));
529
530#define LOAD_ELEMENT_5(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
531 LOAD_ELEMENT_4(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
532 VEC_DATA_TYPE(DATA_TYPE, N0) \
533 BASENAME##4 = *((__global DATA_TYPE *)(PTR + OFFSET + 4 * STRIDE_Y));
534
535#define LOAD_ELEMENT_6(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
536 LOAD_ELEMENT_5(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
537 VEC_DATA_TYPE(DATA_TYPE, N0) \
538 BASENAME##5 = *((__global DATA_TYPE *)(PTR + OFFSET + 5 * STRIDE_Y));
539
540#define LOAD_ELEMENT_7(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
541 LOAD_ELEMENT_6(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
542 VEC_DATA_TYPE(DATA_TYPE, N0) \
543 BASENAME##6 = *((__global DATA_TYPE *)(PTR + OFFSET + 6 * STRIDE_Y));
544
545#define LOAD_ELEMENT_8(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
546 LOAD_ELEMENT_7(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
547 VEC_DATA_TYPE(DATA_TYPE, N0) \
548 BASENAME##7 = *((__global DATA_TYPE *)(PTR + OFFSET + 7 * STRIDE_Y));
549
550#define LOAD_ELEMENT_9(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
551 LOAD_ELEMENT_8(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
552 VEC_DATA_TYPE(DATA_TYPE, N0) \
553 BASENAME##8 = *((__global DATA_TYPE *)(PTR + OFFSET + 8 * STRIDE_Y));
554
555#define LOAD_ELEMENT_10(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
556 LOAD_ELEMENT_9(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
557 VEC_DATA_TYPE(DATA_TYPE, N0) \
558 BASENAME##9 = *((__global DATA_TYPE *)(PTR + OFFSET + 9 * STRIDE_Y));
559
560#define LOAD_ELEMENT_11(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
561 LOAD_ELEMENT_10(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
562 VEC_DATA_TYPE(DATA_TYPE, N0) \
563 BASENAME##A = *((__global DATA_TYPE *)(PTR + OFFSET + 10 * STRIDE_Y));
564
565#define LOAD_ELEMENT_12(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
566 LOAD_ELEMENT_11(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
567 VEC_DATA_TYPE(DATA_TYPE, N0) \
568 BASENAME##B = *((__global DATA_TYPE *)(PTR + OFFSET + 11 * STRIDE_Y));
569
570#define LOAD_ELEMENT_13(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
571 LOAD_ELEMENT_12(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
572 VEC_DATA_TYPE(DATA_TYPE, N0) \
573 BASENAME##C = *((__global DATA_TYPE *)(PTR + OFFSET + 12 * STRIDE_Y));
574
575#define LOAD_ELEMENT_14(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
576 LOAD_ELEMENT_13(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
577 VEC_DATA_TYPE(DATA_TYPE, N0) \
578 BASENAME##D = *((__global DATA_TYPE *)(PTR + OFFSET + 13 * STRIDE_Y));
579
580#define LOAD_ELEMENT_15(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
581 LOAD_ELEMENT_14(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
582 VEC_DATA_TYPE(DATA_TYPE, N0) \
583 BASENAME##E = *((__global DATA_TYPE *)(PTR + OFFSET + 14 * STRIDE_Y));
584
585#define LOAD_ELEMENT_16(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
586 LOAD_ELEMENT_15(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) \
587 VEC_DATA_TYPE(DATA_TYPE, N0) \
588 BASENAME##F = *((__global DATA_TYPE *)(PTR + OFFSET + 15 * STRIDE_Y));
589
590/** @}*/ // end of group LOAD_ELEMENT_n
591
592/** Load Scalar as Vector (consecutive elements).
593 * @name LOAD_SCALAR_AS_VECTOR
594 *
595 * Supported cases are M0=1,2,3,...,16 and N0=1,2,3,4,8,16
596 * The data to load is expected to have consecutive names for each row.
597 * E.g., for M0=3, and BASENAME=c, the expected data is c0, c1 and c2.
598 *
599 * @param[in] M0 The number of consecutive rows
600 * @param[in] N0 The number of consecutive columns
601 * @param[in] DATA_TYPE The data type of the target
602 * @param[in] BASENAME The basename of the result variables
603 * @param[in] PTR The base pointer for the data
604 * @param[in] OFFSET The offset within a row
605 * @param[in] STRIDE_Y The stride in y-axis direction
606 * @{
607 */
608#define LOAD_SCALAR_AS_VECTOR_STR(M0, N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) LOAD_ELEMENT_##M0(N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y)
609#define LOAD_SCALAR_AS_VECTOR(M0, N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y) LOAD_SCALAR_AS_VECTOR_STR(M0, N0, DATA_TYPE, BASENAME, PTR, OFFSET, STRIDE_Y)
610/** @} */ // end of group LOAD_SCALAR_AS_VECTOR
611
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +0000612/** Basic macros to calculate Z offset values from Z0 to Zn-1
613 * @name CALCULATE_Z_OFFSET_n
614 *
615 * @param[in] M0 The number of offset values to calculate
616 * @param[in] DATA_TYPE The data type of the results
617 * @param[in] Z The basename of the result variables
618 * @param[in] Y The work-itme ID of y-axis
619 * @param[in] HEIGHT_GEMM3D The height of GEMM3D
620 * @param[in] DEPTH_GEMM3D The depth of GEMM3D
621 * @param[in] CROSS_PLANE_PAD The padding required for plane changes accross the z-dimension
622 * @param[in] STRIDE_Y The stride value in y-axis direction
623 *
624 * @{
625 */
Usama Arif0681e3b2019-04-25 14:28:07 +0100626#define CALCULATE_Z_OFFSET_1(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) \
Gian Marco Iodice43a129e2019-05-14 10:14:08 +0100627 Z##0 = (0 + (DATA_TYPE)(Y * (DATA_TYPE)M0)) / (DATA_TYPE)HEIGHT_GEMM3D; \
628 Z##0 = min((DATA_TYPE)(DEPTH_GEMM3D - 1), Z##0); \
Usama Arif0681e3b2019-04-25 14:28:07 +0100629 Z##0 *= (CROSS_PLANE_PAD * STRIDE_Y);
630
631#define CALCULATE_Z_OFFSET_2(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) \
632 CALCULATE_Z_OFFSET_1(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) \
Gian Marco Iodice43a129e2019-05-14 10:14:08 +0100633 Z##1 = (1 + (DATA_TYPE)(Y * (DATA_TYPE)M0)) / (DATA_TYPE)HEIGHT_GEMM3D; \
634 Z##1 = min((DATA_TYPE)(DEPTH_GEMM3D - 1), Z##1); \
Usama Arif0681e3b2019-04-25 14:28:07 +0100635 Z##1 *= (CROSS_PLANE_PAD * STRIDE_Y);
636
637#define CALCULATE_Z_OFFSET_3(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) \
638 CALCULATE_Z_OFFSET_2(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) \
Gian Marco Iodice43a129e2019-05-14 10:14:08 +0100639 Z##2 = (2 + (DATA_TYPE)(Y * (DATA_TYPE)M0)) / (DATA_TYPE)HEIGHT_GEMM3D; \
640 Z##2 = min((DATA_TYPE)(DEPTH_GEMM3D - 1), Z##2); \
Usama Arif0681e3b2019-04-25 14:28:07 +0100641 Z##2 *= (CROSS_PLANE_PAD * STRIDE_Y);
642
643#define CALCULATE_Z_OFFSET_4(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) \
644 CALCULATE_Z_OFFSET_3(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) \
Gian Marco Iodice43a129e2019-05-14 10:14:08 +0100645 Z##3 = (3 + (DATA_TYPE)(Y * (DATA_TYPE)M0)) / (DATA_TYPE)HEIGHT_GEMM3D; \
646 Z##3 = min((DATA_TYPE)(DEPTH_GEMM3D - 1), Z##3); \
Usama Arif0681e3b2019-04-25 14:28:07 +0100647 Z##3 *= (CROSS_PLANE_PAD * STRIDE_Y);
648
649#define CALCULATE_Z_OFFSET_5(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) \
650 CALCULATE_Z_OFFSET_4(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) \
Gian Marco Iodice43a129e2019-05-14 10:14:08 +0100651 Z##4 = (4 + (DATA_TYPE)(Y * (DATA_TYPE)M0)) / (DATA_TYPE)HEIGHT_GEMM3D; \
652 Z##4 = min((DATA_TYPE)(DEPTH_GEMM3D - 1), Z##4); \
Usama Arif0681e3b2019-04-25 14:28:07 +0100653 Z##4 *= (CROSS_PLANE_PAD * STRIDE_Y);
654
655#define CALCULATE_Z_OFFSET_6(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) \
656 CALCULATE_Z_OFFSET_5(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) \
Gian Marco Iodice43a129e2019-05-14 10:14:08 +0100657 Z##5 = (5 + (DATA_TYPE)(Y * (DATA_TYPE)M0)) / (DATA_TYPE)HEIGHT_GEMM3D; \
658 Z##5 = min((DATA_TYPE)(DEPTH_GEMM3D - 1), Z##5); \
Usama Arif0681e3b2019-04-25 14:28:07 +0100659 Z##5 *= (CROSS_PLANE_PAD * STRIDE_Y);
660
661#define CALCULATE_Z_OFFSET_7(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) \
662 CALCULATE_Z_OFFSET_6(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) \
Gian Marco Iodice43a129e2019-05-14 10:14:08 +0100663 Z##6 = (6 + (DATA_TYPE)(Y * (DATA_TYPE)M0)) / (DATA_TYPE)HEIGHT_GEMM3D; \
664 Z##6 = min((DATA_TYPE)(DEPTH_GEMM3D - 1), Z##6); \
Usama Arif0681e3b2019-04-25 14:28:07 +0100665 Z##6 *= (CROSS_PLANE_PAD * STRIDE_Y);
666
667#define CALCULATE_Z_OFFSET_8(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) \
668 CALCULATE_Z_OFFSET_7(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) \
Gian Marco Iodice43a129e2019-05-14 10:14:08 +0100669 Z##7 = (7 + (DATA_TYPE)(Y * (DATA_TYPE)M0)) / (DATA_TYPE)HEIGHT_GEMM3D; \
670 Z##7 = min((DATA_TYPE)(DEPTH_GEMM3D - 1), Z##7); \
Usama Arif0681e3b2019-04-25 14:28:07 +0100671 Z##7 *= (CROSS_PLANE_PAD * STRIDE_Y);
672
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +0000673/** @} */ // end of group CALCULATE_Z_OFFSET_n
Usama Arif0681e3b2019-04-25 14:28:07 +0100674
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +0000675/** Calculate Z offset values from Z0 to Zn-1
676 * @name CALCULATE_Z_OFFSET
677 *
678 * The Z offsets are expected to have consecutive names.
679 * E.g., for M0=3 and Z=zin, the expected names of Z offsets are zin1, zin2, zin3.
680 * Note that, CROSS_PLANE_PAD (cross plain padding) is required to take into account
681 * the possible cross plane paddings in case of the plance changes across the z-dimension.
682 *
683 * <!--
684 * | |
685 * | plane0 |
686 * | |
687 * |__________________|
688 * |******************|
689 * | cross_plane_pad |
690 * |******************|
691 * | |
692 * | plane1 |
693 * | |
694 * |__________________|
695 * -->
696 *
697 * @param[in] M0 The number of offset values to calculate
698 * @param[in] DATA_TYPE The data type of the results
699 * @param[in] Z The basename of the result variables
700 * @param[in] Y The work-itme ID of y-axis
701 * @param[in] HEIGHT_GEMM3D The height of GEMM3D
702 * @param[in] DEPTH_GEMM3D The depth of GEMM3D
703 * @param[in] CROSS_PLANE_PAD The padding required for plane changes accross the z-dimension
704 * @param[in] STRIDE_Y The stride value in y-axis direction
705 * @{
706 */
707#define CALCULATE_Z_OFFSET_STR(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) CALCULATE_Z_OFFSET_##M0(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y)
708#define CALCULATE_Z_OFFSET(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y) CALCULATE_Z_OFFSET_STR(M0, DATA_TYPE, Z, Y, HEIGHT_GEMM3D, DEPTH_GEMM3D, CROSS_PLANE_PAD, STRIDE_Y)
709/** @} */ // end of group CALCULATE_Z_OFFSET
710
711/** Store the 0 to (n-1)th rows of the given variables
712 * @name STORE_ROW_n
713 *
SiCong Li3a501662020-06-26 10:02:06 +0100714 * @param[in] N0 The width of the passed in vector. Supported: 1, 2, 3, 4, 8, 16
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +0000715 * @param[in] DATA_TYPE The data type of the vectors
716 * @param[in] BASENAME The basename of the variables
717 * @param[in] PTR The base pointer
718 * @param[in] STRIDE_Y The stride value in y-axis direction
719 * @param[in] Z The offset in z-axis direction
720 * @{
721 */
Usama Arif0681e3b2019-04-25 14:28:07 +0100722#define STORE_ROW_1(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
723 VSTORE(N0) \
724 (BASENAME##0, 0, (__global DATA_TYPE *)(PTR + 0 * STRIDE_Y + Z##0));
725
726#define STORE_ROW_2(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
727 STORE_ROW_1(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
728 VSTORE(N0) \
729 (BASENAME##1, 0, (__global DATA_TYPE *)(PTR + 1 * STRIDE_Y + Z##1));
730
731#define STORE_ROW_3(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
732 STORE_ROW_2(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
733 VSTORE(N0) \
734 (BASENAME##2, 0, (__global DATA_TYPE *)(PTR + 2 * STRIDE_Y + Z##2));
735
736#define STORE_ROW_4(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
737 STORE_ROW_3(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
738 VSTORE(N0) \
739 (BASENAME##3, 0, (__global DATA_TYPE *)(PTR + 3 * STRIDE_Y + Z##3));
740
741#define STORE_ROW_5(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
742 STORE_ROW_4(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
743 VSTORE(N0) \
744 (BASENAME##4, 0, (__global DATA_TYPE *)(PTR + 4 * STRIDE_Y + Z##4));
745
746#define STORE_ROW_6(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
747 STORE_ROW_5(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
748 VSTORE(N0) \
749 (BASENAME##5, 0, (__global DATA_TYPE *)(PTR + 5 * STRIDE_Y + Z##5));
750
751#define STORE_ROW_7(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
752 STORE_ROW_6(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
753 VSTORE(N0) \
754 (BASENAME##6, 0, (__global DATA_TYPE *)(PTR + 6 * STRIDE_Y + Z##6));
755
756#define STORE_ROW_8(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
757 STORE_ROW_7(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
758 VSTORE(N0) \
759 (BASENAME##7, 0, (__global DATA_TYPE *)(PTR + 7 * STRIDE_Y + Z##7));
760
761#define STORE_ROW_9(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
762 STORE_ROW_8(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
763 VSTORE(N0) \
764 (BASENAME##8, 0, (__global DATA_TYPE *)(PTR + 8 * STRIDE_Y + Z##8));
765
766#define STORE_ROW_10(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
767 STORE_ROW_9(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
768 VSTORE(N0) \
769 (BASENAME##9, 0, (__global DATA_TYPE *)(PTR + 9 * STRIDE_Y + Z##9));
770
771#define STORE_ROW_11(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
772 STORE_ROW_10(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
773 VSTORE(N0) \
774 (BASENAME##A, 0, (__global DATA_TYPE *)(PTR + 10 * STRIDE_Y + Z##A));
775
776#define STORE_ROW_12(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
777 STORE_ROW_11(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
778 VSTORE(N0) \
779 (BASENAME##B, 0, (__global DATA_TYPE *)(PTR + 11 * STRIDE_Y + Z##B));
780
781#define STORE_ROW_13(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
782 STORE_ROW_12(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
783 VSTORE(N0) \
784 (BASENAME##C, 0, (__global DATA_TYPE *)(PTR + 12 * STRIDE_Y + Z##C));
785
786#define STORE_ROW_14(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
787 STORE_ROW_13(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
788 VSTORE(N0) \
789 (BASENAME##D, 0, (__global DATA_TYPE *)(PTR + 13 * STRIDE_Y + Z##D));
790
791#define STORE_ROW_15(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
792 STORE_ROW_14(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
793 VSTORE(N0) \
794 (BASENAME##E, 0, (__global DATA_TYPE *)(PTR + 14 * STRIDE_Y + Z##E));
795
796#define STORE_ROW_16(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
797 STORE_ROW_15(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
798 VSTORE(N0) \
799 (BASENAME##F, 0, (__global DATA_TYPE *)(PTR + 15 * STRIDE_Y + Z##F));
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +0000800/** @} */ // end of groupd STORE_ROW_n
Usama Arif0681e3b2019-04-25 14:28:07 +0100801
SiCong Li3a501662020-06-26 10:02:06 +0100802/** Partially store the 0 to (n-1)th rows of the given variables
803 * @name STORE_ROW_PARTIAL_n
804 * Within each row, store the lower @p STORE_N0 elements of vectors of width @p N0
805 *
806 * @note in case @p STORE_N0 != 1, 2, 3, 4, 8, 16, extra vstore(s) will be invoked, thus incurring small performance penalty.
807 *
808 * @param[in] N0 The width of the passed in vector. Supported: 1, 2, 3, 4, 8, 16
809 * @param[in] STORE_N0 The **lower** size of the vectors to store. Supported: [1-16 and <= @p N0
810 * @param[in] DATA_TYPE The data type of the vectors
811 * @param[in] BASENAME The basename of the variables
812 * @param[in] PTR The base pointer
813 * @param[in] STRIDE_Y The stride value in y-axis direction
814 * @param[in] Z The offset in z-axis direction
815 * @{
816 */
817#define STORE_ROW_PARTIAL_1(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
818 VSTORE_PARTIAL(N0, STORE_N0) \
819 (BASENAME##0, 0, (__global DATA_TYPE *)(PTR + 0 * STRIDE_Y + Z##0));
820
821#define STORE_ROW_PARTIAL_2(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
822 STORE_ROW_PARTIAL_1(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
823 VSTORE_PARTIAL(N0, STORE_N0) \
824 (BASENAME##1, 0, (__global DATA_TYPE *)(PTR + 1 * STRIDE_Y + Z##1));
825
826#define STORE_ROW_PARTIAL_3(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
827 STORE_ROW_PARTIAL_2(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
828 VSTORE_PARTIAL(N0, STORE_N0) \
829 (BASENAME##2, 0, (__global DATA_TYPE *)(PTR + 2 * STRIDE_Y + Z##2));
830
831#define STORE_ROW_PARTIAL_4(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
832 STORE_ROW_PARTIAL_3(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
833 VSTORE_PARTIAL(N0, STORE_N0) \
834 (BASENAME##3, 0, (__global DATA_TYPE *)(PTR + 3 * STRIDE_Y + Z##3));
835
836#define STORE_ROW_PARTIAL_5(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
837 STORE_ROW_PARTIAL_4(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
838 VSTORE_PARTIAL(N0, STORE_N0) \
839 (BASENAME##4, 0, (__global DATA_TYPE *)(PTR + 4 * STRIDE_Y + Z##4));
840
841#define STORE_ROW_PARTIAL_6(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
842 STORE_ROW_PARTIAL_5(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
843 VSTORE_PARTIAL(N0, STORE_N0) \
844 (BASENAME##5, 0, (__global DATA_TYPE *)(PTR + 5 * STRIDE_Y + Z##5));
845
846#define STORE_ROW_PARTIAL_7(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
847 STORE_ROW_PARTIAL_6(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
848 VSTORE_PARTIAL(N0, STORE_N0) \
849 (BASENAME##6, 0, (__global DATA_TYPE *)(PTR + 6 * STRIDE_Y + Z##6));
850
851#define STORE_ROW_PARTIAL_8(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
852 STORE_ROW_PARTIAL_7(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
853 VSTORE_PARTIAL(N0, STORE_N0) \
854 (BASENAME##7, 0, (__global DATA_TYPE *)(PTR + 7 * STRIDE_Y + Z##7));
855
856#define STORE_ROW_PARTIAL_9(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
857 STORE_ROW_PARTIAL_8(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
858 VSTORE_PARTIAL(N0, STORE_N0) \
859 (BASENAME##8, 0, (__global DATA_TYPE *)(PTR + 8 * STRIDE_Y + Z##8));
860
861#define STORE_ROW_PARTIAL_10(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
862 STORE_ROW_PARTIAL_9(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
863 VSTORE_PARTIAL(N0, STORE_N0) \
864 (BASENAME##9, 0, (__global DATA_TYPE *)(PTR + 9 * STRIDE_Y + Z##9));
865
866#define STORE_ROW_PARTIAL_11(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
867 STORE_ROW_PARTIAL_10(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
868 VSTORE_PARTIAL(N0, STORE_N0) \
869 (BASENAME##A, 0, (__global DATA_TYPE *)(PTR + 10 * STRIDE_Y + Z##A));
870
871#define STORE_ROW_PARTIAL_12(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
872 STORE_ROW_PARTIAL_11(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
873 VSTORE_PARTIAL(N0, STORE_N0) \
874 (BASENAME##B, 0, (__global DATA_TYPE *)(PTR + 11 * STRIDE_Y + Z##B));
875
876#define STORE_ROW_PARTIAL_13(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
877 STORE_ROW_PARTIAL_12(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
878 VSTORE_PARTIAL(N0, STORE_N0) \
879 (BASENAME##C, 0, (__global DATA_TYPE *)(PTR + 12 * STRIDE_Y + Z##C));
880
881#define STORE_ROW_PARTIAL_14(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
882 STORE_ROW_PARTIAL_13(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
883 VSTORE_PARTIAL(N0, STORE_N0) \
884 (BASENAME##D, 0, (__global DATA_TYPE *)(PTR + 13 * STRIDE_Y + Z##D));
885
886#define STORE_ROW_PARTIAL_15(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
887 STORE_ROW_PARTIAL_14(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
888 VSTORE_PARTIAL(N0, STORE_N0) \
889 (BASENAME##E, 0, (__global DATA_TYPE *)(PTR + 14 * STRIDE_Y + Z##E));
890
891#define STORE_ROW_PARTIAL_16(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
892 STORE_ROW_PARTIAL_15(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
893 VSTORE_PARTIAL(N0, STORE_N0) \
894 (BASENAME##F, 0, (__global DATA_TYPE *)(PTR + 15 * STRIDE_Y + Z##F));
895/** @} */ // end of groupd STORE_ROW_PARTIAL_n
896
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +0000897/** Convert and store the 0th to (n-1)th rows of the given variables
898 * @name CONVERT_STORE_ROW_n
899 *
900 * @param[in] N0 The size of the vectors
901 * @param[in] DATA_TYPE The data type of the vectors
902 * @param[in] BASENAME The basename of the variables
903 * @param[in] PTR The base pointer
904 * @param[in] STRIDE_Y The stride value in y-axis direction
905 * @param[in] Z The offset in z-axis direction
906 * @{
907 */
Gian Marco Iodice43a129e2019-05-14 10:14:08 +0100908#define CONVERT_STORE_ROW_1(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
909 VSTORE(N0) \
910 (CONVERT_SAT((BASENAME##0), VEC_DATA_TYPE(DATA_TYPE, N0)), 0, (__global DATA_TYPE *)(PTR + 0 * STRIDE_Y + Z##0));
911
912#define CONVERT_STORE_ROW_2(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
913 CONVERT_STORE_ROW_1(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
914 VSTORE(N0) \
915 (CONVERT_SAT((BASENAME##1), VEC_DATA_TYPE(DATA_TYPE, N0)), 0, (__global DATA_TYPE *)(PTR + 1 * STRIDE_Y + Z##1));
916
917#define CONVERT_STORE_ROW_3(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
918 CONVERT_STORE_ROW_2(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
919 VSTORE(N0) \
920 (CONVERT_SAT((BASENAME##2), VEC_DATA_TYPE(DATA_TYPE, N0)), 0, (__global DATA_TYPE *)(PTR + 2 * STRIDE_Y + Z##2));
921
922#define CONVERT_STORE_ROW_4(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
923 CONVERT_STORE_ROW_3(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
924 VSTORE(N0) \
925 (CONVERT_SAT((BASENAME##3), VEC_DATA_TYPE(DATA_TYPE, N0)), 0, (__global DATA_TYPE *)(PTR + 3 * STRIDE_Y + Z##3));
926
927#define CONVERT_STORE_ROW_5(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
928 CONVERT_STORE_ROW_4(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
929 VSTORE(N0) \
930 (CONVERT_SAT((BASENAME##4), VEC_DATA_TYPE(DATA_TYPE, N0)), 0, (__global DATA_TYPE *)(PTR + 4 * STRIDE_Y + Z##4));
931
932#define CONVERT_STORE_ROW_6(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
933 CONVERT_STORE_ROW_5(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
934 VSTORE(N0) \
935 (CONVERT_SAT((BASENAME##5), VEC_DATA_TYPE(DATA_TYPE, N0)), 0, (__global DATA_TYPE *)(PTR + 5 * STRIDE_Y + Z##5));
936
937#define CONVERT_STORE_ROW_7(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
938 CONVERT_STORE_ROW_6(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
939 VSTORE(N0) \
940 (CONVERT_SAT((BASENAME##6), VEC_DATA_TYPE(DATA_TYPE, N0)), 0, (__global DATA_TYPE *)(PTR + 6 * STRIDE_Y + Z##6));
941
942#define CONVERT_STORE_ROW_8(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
943 CONVERT_STORE_ROW_7(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
944 VSTORE(N0) \
945 (CONVERT_SAT((BASENAME##7), VEC_DATA_TYPE(DATA_TYPE, N0)), 0, (__global DATA_TYPE *)(PTR + 7 * STRIDE_Y + Z##7));
946
947#define CONVERT_STORE_ROW_9(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
948 CONVERT_STORE_ROW_8(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
949 VSTORE(N0) \
950 (CONVERT_SAT((BASENAME##8), VEC_DATA_TYPE(DATA_TYPE, N0)), 0, (__global DATA_TYPE *)(PTR + 8 * STRIDE_Y + Z##8));
951
952#define CONVERT_STORE_ROW_10(N0, DATA, BASENAME, PTR, STRIDE_Y, Z) \
953 CONVERT_STORE_ROW_9(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
954 VSTORE(N0) \
955 (CONVERT_SAT((BASENAME##9), VEC_DATA_TYPE(DATA_TYPE, N0)), 0, (__global DATA_TYPE *)(PTR + 9 * STRIDE_Y + Z##9));
956
957#define CONVERT_STORE_ROW_11(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
958 CONVERT_STORE_ROW_10(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
959 VSTORE(N0) \
960 (CONVERT_SAT((BASENAME##A), VEC_DATA_TYPE(DATA_TYPE, N0)), 0, (__global DATA_TYPE *)(PTR + 10 * STRIDE_Y + Z##A));
961
962#define CONVERT_STORE_ROW_12(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
963 CONVERT_STORE_ROW_11(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
964 VSTORE(N0) \
965 (CONVERT_SAT((BASENAME##B), VEC_DATA_TYPE(DATA_TYPE, N0)), 0, (__global DATA_TYPE *)(PTR + 11 * STRIDE_Y + Z##B));
966
967#define CONVERT_STORE_ROW_13(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
968 CONVERT_STORE_ROW_12(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
969 VSTORE(N0) \
970 (CONVERT_SAT((BASENAME##C), VEC_DATA_TYPE(DATA_TYPE, N0)), 0, (__global DATA_TYPE *)(PTR + 12 * STRIDE_Y + Z##C));
971
972#define CONVERT_STORE_ROW_14(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
973 CONVERT_STORE_ROW_13(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
974 VSTORE(N0) \
975 (CONVERT_SAT((BASENAME##D), VEC_DATA_TYPE(DATA_TYPE, N0)), 0, (__global DATA_TYPE *)(PTR + 13 * STRIDE_Y + Z##D));
976
977#define CONVERT_STORE_ROW_15(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
978 CONVERT_STORE_ROW_14(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
979 VSTORE(N0) \
980 (CONVERT_SAT((BASENAME##E), VEC_DATA_TYPE(DATA_TYPE, N0)), 0, (__global DATA_TYPE *)(PTR + 14 * STRIDE_Y + Z##E));
981
982#define CONVERT_STORE_ROW_16(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
983 CONVERT_STORE_ROW_15(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) \
984 VSTORE(N0) \
985 (CONVERT_SAT((BASENAME##F), VEC_DATA_TYPE(DATA_TYPE, N0)), 0, (__global DATA_TYPE *)(PTR + 15 * STRIDE_Y + Z##F));
986
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +0000987/** @} */ // end of groupd CONVERT_STORE_ROW_n
988
989/** Store a block of the given size M0xN0
990 * @name STORE_BLOCK
991 *
992 * Supported cases are M0=1,2,3,...,16 and N0=2,3,4,8,16.
993 * The data to store is expected to have consecutive names for each row.
994 * E.g., for M0=3 and basename=c, the expected names are c0, c1 and c2.
995 * The Z offset is expected to have consecutive names.
996 * E.g., for M0=3 and Z=zin, the expected z offset names are zin0, zin1 and zin2.
997 *
998 * @param[in] M0 The number of rows to store
999 * @param[in] N0 The size of each vector
1000 * @param[in] DATA_TYPE The data type of the vectors
1001 * @param[in] BASENAME The basename of the variables
1002 * @param[in] PTR The base pointer
1003 * @param[in] STRIDE_Y The stride value in y-axis direction
1004 * @param[in] Z The offset in z-axis direction
1005 * @{
1006 */
Usama Arif0681e3b2019-04-25 14:28:07 +01001007#define STORE_BLOCK_STR(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) STORE_ROW_##M0(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z)
Usama Arif0681e3b2019-04-25 14:28:07 +01001008#define STORE_BLOCK(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) STORE_BLOCK_STR(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z)
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001009/** @} */ // end of group STORE_BLOCK
Usama Arif0681e3b2019-04-25 14:28:07 +01001010
SiCong Li3a501662020-06-26 10:02:06 +01001011/** Partially store a block of the given size STORE_M0xSTORE_N0
1012 * @name STORE_BLOCK_PARTIAL
1013 *
1014 * @note The vector width @p N0 is also required for correct partial storing behaviour.
1015 * @note in case @p STORE_N0 != 1, 2, 3, 4, 8, 16, extra vstore(s) will be invoked, thus incurring small performance penalty.
1016 *
1017 * The data to store is expected to have consecutive names for each row.
1018 * E.g., for STORE_M0=3 and basename=c, the expected names are c0, c1 and c2.
1019 * The Z offset is expected to have consecutive names.
1020 * E.g., for STORE_M0=3 and Z=zin, the expected z offset names are zin0, zin1 and zin2.
1021 *
1022 * @param[in] STORE_M0 The number of rows to store. Supported: 1-16
1023 * @param[in] STORE_N0 The lower number of elements of vectors to store. Supported: 1-16 and <= @p N0
1024 * @param[in] N0 The size of each vector. Supported: 1, 2, 3, 4, 8, 16
1025 * @param[in] DATA_TYPE The data type of the vectors
1026 * @param[in] BASENAME The basename of the variables
1027 * @param[in] PTR The base pointer
1028 * @param[in] STRIDE_Y The stride value in y-axis direction
1029 * @param[in] Z The offset in z-axis direction
1030 * @{
1031 */
1032#define STORE_BLOCK_PARTIAL_STR(STORE_M0, STORE_N0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) STORE_ROW_PARTIAL_##STORE_M0(N0, STORE_N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z)
1033#define STORE_BLOCK_PARTIAL(STORE_M0, STORE_N0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) STORE_BLOCK_PARTIAL_STR(STORE_M0, STORE_N0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z)
1034/** Store a block that can be partial in both x and y dimensions
1035 *
1036 * @note in cases @p PARTIAL_STORE_N0 != 1, 2, 3, 4, 8, 16, extra vstore(s) will be invoked, thus incurring small performance penalty.
1037 *
1038 * The data to store is expected to have consecutive names for each row.
1039 * E.g., for M0=3 and basename=c, the expected names are c0, c1 and c2.
1040 * The Z offset is expected to have consecutive names.
1041 * E.g., for M0=3 and Z=zin, the expected z offset names are zin0, zin1 and zin2.
1042 *
1043 * @param[in] M0 The number of rows to store, for non-partial blocks. Supported: 1-16
1044 * @param[in] N0 The size of each vector, for non-partial blocks. Supported: 1, 2, 3, 4, 8, 16
1045 * @param[in] DATA_TYPE The data type of the vectors
1046 * @param[in] BASENAME The basename of the variables
1047 * @param[in] PTR The base pointer
1048 * @param[in] STRIDE_Y The stride value in y-axis direction
1049 * @param[in] Z The offset in z-axis direction
1050 * @param[in] PARTIAL_STORE_M0 The partial size in y, for partial blocks. Supported range: [1, @p M0)
1051 * @param[in] PARTIAL_STORE_N0 The partial size in x, for partial blocks. Supported range: [1, @p N0)
SiCong Li3a501662020-06-26 10:02:06 +01001052 * @param[in] N Total number of columns. Used to detect if current block is at the boundary in x.
Gian Marco Iodice088d63a2020-08-11 14:14:06 +01001053 * @param[in] PARTIAL_COND_Y Condition on the y axis to perform the partial store Y. True to use PARTIAL_STORE_M0 rather than M0.
1054 * @param[in] PARTIAL_COND_X Condition on the x axis to perform the partial store X. True to use PARTIAL_STORE_N0 rather than N0.
SiCong Li3a501662020-06-26 10:02:06 +01001055 */
Gian Marco Iodice088d63a2020-08-11 14:14:06 +01001056#define STORE_BLOCK_PARTIAL_IN_X_AND_Y(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z, PARTIAL_STORE_M0, PARTIAL_STORE_N0, N, PARTIAL_COND_Y, PARTIAL_COND_X) \
1057 if(!(PARTIAL_COND_X) && !(PARTIAL_COND_Y)) \
1058 { \
1059 STORE_BLOCK_PARTIAL(M0, N0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z); \
1060 } \
1061 else if((PARTIAL_COND_Y) && !(PARTIAL_COND_X)) \
1062 { \
1063 STORE_BLOCK_PARTIAL(PARTIAL_STORE_M0, N0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z); \
1064 } \
1065 else if(!(PARTIAL_COND_Y) && (PARTIAL_COND_X)) \
1066 { \
1067 STORE_BLOCK_PARTIAL(M0, PARTIAL_STORE_N0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z); \
1068 } \
1069 else \
1070 { \
1071 STORE_BLOCK_PARTIAL(PARTIAL_STORE_M0, PARTIAL_STORE_N0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z); \
SiCong Li3a501662020-06-26 10:02:06 +01001072 }
1073/** Store a block that can only be partial in x but not y.
1074 *
1075 * @note in case @p N0 or @p PARTIAL_STORE_N0 != 1, 2, 3, 4, 8, 16, extra vstore(s) will be invoked, thus incurring small performance penalty.
1076 *
1077 * The data to store is expected to have consecutive names for each row.
1078 * E.g., for M0=3 and basename=c, the expected names are c0, c1 and c2.
1079 * The Z offset is expected to have consecutive names.
1080 * E.g., for M0=3 and Z=zin, the expected z offset names are zin0, zin1 and zin2.
1081 *
1082 * @param[in] M0 The number of rows to store, for non-partial blocks. Supported: 1-16
1083 * @param[in] N0 The size of each vector, for non-partial blocks. Supported: 1, 2, 3, 4, 8, 16
1084 * @param[in] DATA_TYPE The data type of the vectors
1085 * @param[in] BASENAME The basename of the variables
1086 * @param[in] PTR The base pointer
1087 * @param[in] STRIDE_Y The stride value in y-axis direction
1088 * @param[in] Z The offset in z-axis direction
1089 * @param[in] PARTIAL_STORE_N0 The partial size in x, for partial blocks. Supported range: [1, @p N0)
1090 * @param[in] N Total number of columns. Used to detect if current block is at the boundary in x.
Gian Marco Iodice088d63a2020-08-11 14:14:06 +01001091 * @param[in] PARTIAL_COND_X Condition on the x axis to perform the partial store X. True to use PARTIAL_STORE_N0 rather than N0.
SiCong Li3a501662020-06-26 10:02:06 +01001092 */
Gian Marco Iodice088d63a2020-08-11 14:14:06 +01001093#define STORE_BLOCK_PARTIAL_IN_X(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z, PARTIAL_STORE_N0, N, PARTIAL_COND_X) \
1094 if(!(PARTIAL_COND_X)) \
1095 { \
1096 STORE_BLOCK_PARTIAL(M0, N0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z); \
1097 } \
1098 else \
1099 { \
1100 STORE_BLOCK_PARTIAL(M0, PARTIAL_STORE_N0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z); \
SiCong Li3a501662020-06-26 10:02:06 +01001101 }
1102/** Store a block that can only be partial in y but not x.
1103 *
1104 * @note in case @p N0 or @p PARTIAL_STORE_N0 != 1, 2, 3, 4, 8, 16, extra vstore(s) will be invoked, thus incurring small performance penalty.
1105 *
1106 * The data to store is expected to have consecutive names for each row.
1107 * E.g., for M0=3 and basename=c, the expected names are c0, c1 and c2.
1108 * The Z offset is expected to have consecutive names.
1109 * E.g., for M0=3 and Z=zin, the expected z offset names are zin0, zin1 and zin2.
1110 *
1111 * @param[in] M0 The number of rows to store, for non-partial blocks. Supported: 1-16
1112 * @param[in] N0 The size of each vector, for non-partial blocks. Supported: 1, 2, 3, 4, 8, 16
1113 * @param[in] DATA_TYPE The data type of the vectors
1114 * @param[in] BASENAME The basename of the variables
1115 * @param[in] PTR The base pointer
1116 * @param[in] STRIDE_Y The stride value in y-axis direction
1117 * @param[in] Z The offset in z-axis direction
1118 * @param[in] PARTIAL_STORE_M0 The partial size in y, for partial blocks. Supported range: [1, @p M0)
Gian Marco Iodice088d63a2020-08-11 14:14:06 +01001119 * @param[in] PARTIAL_COND_Y Condition on the y axis to perform the partial store Y. True to use PARTIAL_STORE_M0 rather than M0.
SiCong Li3a501662020-06-26 10:02:06 +01001120 */
Gian Marco Iodice088d63a2020-08-11 14:14:06 +01001121#define STORE_BLOCK_PARTIAL_IN_Y(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z, PARTIAL_STORE_M0, PARTIAL_COND_Y) \
1122 if(!(PARTIAL_COND_Y)) \
1123 { \
1124 STORE_BLOCK_PARTIAL(M0, N0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z); \
1125 } \
1126 else \
1127 { \
1128 STORE_BLOCK_PARTIAL(PARTIAL_STORE_M0, N0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z); \
SiCong Li3a501662020-06-26 10:02:06 +01001129 }
1130/** @} */ // end of group STORE_BLOCK_PARTIAL
1131
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001132/** Convert and store a block of the given size M0xN0
1133 * @name CONVERT_STORE_BLOCK
1134 *
1135 * Supported cases are M0=1,2,3,...,16 and N0=2,3,4,8,16.
1136 * The data to store is expected to have consecutive names for each row.
1137 * E.g., for M0=3 and basename=c, the expected names are c0, c1 and c2.
1138 * The Z offset is expected to have consecutive names.
1139 * E.g., for M0=3 and Z=zin, the expected z offset names are zin0, zin1 and zin2.
1140 *
1141 * @param[in] M0 The number of rows to store
1142 * @param[in] N0 The size of each vector
1143 * @param[in] DATA_TYPE The data type of the vectors
1144 * @param[in] BASENAME The basename of the variables
1145 * @param[in] PTR The base pointer
1146 * @param[in] STRIDE_Y The stride value in y-axis direction
1147 * @param[in] Z The offset in z-axis direction
1148 * @{
Gian Marco Iodice43a129e2019-05-14 10:14:08 +01001149 */
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001150#define CONVERT_STORE_BLOCK_STR(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) CONVERT_STORE_ROW_##M0(N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z)
Gian Marco Iodice43a129e2019-05-14 10:14:08 +01001151#define CONVERT_STORE_BLOCK(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z) CONVERT_STORE_BLOCK_STR(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z)
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001152/** @} */ // end of group CONVERT_STORE_BLOCK
Gian Marco Iodice43a129e2019-05-14 10:14:08 +01001153
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001154/** Scale the rows in the given variables (BASENAME0 to BASENAMEn-1)
1155 * @name SCALE_ROW_n
1156 *
1157 * @param[in] DATA_TYPE The data type of the variables
1158 * @param[in] BASENAME The basename of the variables
1159 * @param[in] SCALE The scale factor
1160 * @{
1161 */
Usama Arif0681e3b2019-04-25 14:28:07 +01001162#define SCALE_ROW_1(DATA_TYPE, BASENAME, SCALE) \
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001163 BASENAME##0 *= (DATA_TYPE)SCALE;
Usama Arif0681e3b2019-04-25 14:28:07 +01001164
1165#define SCALE_ROW_2(DATA_TYPE, BASENAME, SCALE) \
1166 SCALE_ROW_1(DATA_TYPE, BASENAME, SCALE) \
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001167 BASENAME##1 *= (DATA_TYPE)SCALE;
Usama Arif0681e3b2019-04-25 14:28:07 +01001168
1169#define SCALE_ROW_3(DATA_TYPE, BASENAME, SCALE) \
1170 SCALE_ROW_2(DATA_TYPE, BASENAME, SCALE) \
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001171 BASENAME##2 *= (DATA_TYPE)SCALE;
Usama Arif0681e3b2019-04-25 14:28:07 +01001172
1173#define SCALE_ROW_4(DATA_TYPE, BASENAME, SCALE) \
1174 SCALE_ROW_3(DATA_TYPE, BASENAME, SCALE) \
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001175 BASENAME##3 *= (DATA_TYPE)SCALE;
Usama Arif0681e3b2019-04-25 14:28:07 +01001176
1177#define SCALE_ROW_5(DATA_TYPE, BASENAME, SCALE) \
1178 SCALE_ROW_4(DATA_TYPE, BASENAME, SCALE) \
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001179 BASENAME##4 *= (DATA_TYPE)SCALE;
Usama Arif0681e3b2019-04-25 14:28:07 +01001180
1181#define SCALE_ROW_6(DATA_TYPE, BASENAME, SCALE) \
1182 SCALE_ROW_5(DATA_TYPE, BASENAME, SCALE) \
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001183 BASENAME##5 *= (DATA_TYPE)SCALE;
Usama Arif0681e3b2019-04-25 14:28:07 +01001184
1185#define SCALE_ROW_7(DATA_TYPE, BASENAME, SCALE) \
1186 SCALE_ROW_6(DATA_TYPE, BASENAME, SCALE) \
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001187 BASENAME##6 *= (DATA_TYPE)SCALE;
Usama Arif0681e3b2019-04-25 14:28:07 +01001188
1189#define SCALE_ROW_8(DATA_TYPE, BASENAME, SCALE) \
1190 SCALE_ROW_7(DATA_TYPE, BASENAME, SCALE) \
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001191 BASENAME##7 *= (DATA_TYPE)SCALE;
Usama Arif0681e3b2019-04-25 14:28:07 +01001192
1193#define SCALE_ROW_9(DATA_TYPE, BASENAME, SCALE) \
1194 SCALE_ROW_8(DATA_TYPE, BASENAME, SCALE) \
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001195 BASENAME##8 *= (DATA_TYPE)SCALE;
Usama Arif0681e3b2019-04-25 14:28:07 +01001196
1197#define SCALE_ROW_10(DATA_TYPE, BASENAME, SCALE) \
1198 SCALE_ROW_9(DATA_TYPE, BASENAME, SCALE) \
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001199 BASENAME##9 *= (DATA_TYPE)SCALE;
Usama Arif0681e3b2019-04-25 14:28:07 +01001200
1201#define SCALE_ROW_11(DATA_TYPE, BASENAME, SCALE) \
1202 SCALE_ROW_10(DATA_TYPE, BASENAME, SCALE) \
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001203 BASENAME##A *= (DATA_TYPE)SCALE;
Usama Arif0681e3b2019-04-25 14:28:07 +01001204
1205#define SCALE_ROW_12(DATA_TYPE, BASENAME, SCALE) \
1206 SCALE_ROW_11(DATA_TYPE, BASENAME, SCALE) \
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001207 BASENAME##B *= (DATA_TYPE)SCALE;
Usama Arif0681e3b2019-04-25 14:28:07 +01001208
1209#define SCALE_ROW_13(DATA_TYPE, BASENAME, SCALE) \
1210 SCALE_ROW_12(DATA_TYPE, BASENAME, SCALE) \
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001211 BASENAME##C *= (DATA_TYPE)SCALE;
Usama Arif0681e3b2019-04-25 14:28:07 +01001212
1213#define SCALE_ROW_14(DATA_TYPE, BASENAME, SCALE) \
1214 SCALE_ROW_13(DATA_TYPE, BASENAME, SCALE) \
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001215 BASENAME##D *= (DATA_TYPE)SCALE;
Usama Arif0681e3b2019-04-25 14:28:07 +01001216
1217#define SCALE_ROW_15(DATA_TYPE, BASENAME, SCALE) \
1218 SCALE_ROW_14(DATA_TYPE, BASENAME, SCALE) \
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001219 BASENAME##E *= (DATA_TYPE)SCALE;
Usama Arif0681e3b2019-04-25 14:28:07 +01001220
1221#define SCALE_ROW_16(DATA_TYPE, BASENAME, SCALE) \
1222 SCALE_ROW_15(DATA_TYPE, BASENAME, SCALE) \
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001223 BASENAME##F *= (DATA_TYPE)SCALE;
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001224/** @} */ // end of group SCALE_ROW_n
Usama Arif0681e3b2019-04-25 14:28:07 +01001225
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001226/** Scale elements stored in a block (BASENAME)
1227 * @name SCALE_BLOCK
1228 *
1229 * Supported cases are N=1,2,3,...,16
1230 *
1231 * @param[in] N The number of rows in the block
1232 * @param[in] DATA_TYPE The data type of the block
1233 * @param[in] BASENAME The basename of the block
1234 * @param[in] SCALE The scale factor
1235 * @{
Usama Arif0681e3b2019-04-25 14:28:07 +01001236 */
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001237#define SCALE_BLOCK_STR(N, DATA_TYPE, BASENAME, SCALE) SCALE_ROW_##N(DATA_TYPE, BASENAME, SCALE)
Usama Arif0681e3b2019-04-25 14:28:07 +01001238#define SCALE_BLOCK(N, DATA_TYPE, BASENAME, SCALE) SCALE_BLOCK_STR(N, DATA_TYPE, BASENAME, SCALE)
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001239/** @} */ // end of group SCALE_BLOCK
Gian Marco Iodice43a129e2019-05-14 10:14:08 +01001240
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001241/** Create a new vector containing the values at the given index for a set of given vectors
1242 * @name COLUMN_VECTORn
1243 *
1244 * @param[in] IDX_COL The index value
1245 * @param[in] BASENAME The basename of the destination vectors
1246 * @param[in] X The basename of the source vectors
Michele Di Giorgiof9179d32019-11-27 16:17:30 +00001247 * @param[in] TYPE The data type of the destination vectors
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001248 * @{
1249 */
Michele Di Giorgiof9179d32019-11-27 16:17:30 +00001250#define COLUMN_VECTOR1(IDX_COL, BASENAME, X, TYPE) \
1251 TYPE BASENAME##IDX_COL = (TYPE)((X##0).s##IDX_COL);
1252#define COLUMN_VECTOR2(IDX_COL, BASENAME, X, TYPE) \
1253 VEC_DATA_TYPE(TYPE, 2) \
1254 BASENAME##IDX_COL = (VEC_DATA_TYPE(TYPE, 2))((X##0).s##IDX_COL, (X##1).s##IDX_COL);
1255#define COLUMN_VECTOR3(IDX_COL, BASENAME, X, TYPE) \
1256 VEC_DATA_TYPE(TYPE, 3) \
1257 BASENAME##IDX_COL = (VEC_DATA_TYPE(TYPE, 3))((X##0).s##IDX_COL, (X##1).s##IDX_COL, (X##2).s##IDX_COL);
1258#define COLUMN_VECTOR4(IDX_COL, BASENAME, X, TYPE) \
1259 VEC_DATA_TYPE(TYPE, 4) \
1260 BASENAME##IDX_COL = (VEC_DATA_TYPE(TYPE, 4))((X##0).s##IDX_COL, (X##1).s##IDX_COL, (X##2).s##IDX_COL, (X##3).s##IDX_COL);
1261#define COLUMN_VECTOR8(IDX_COL, BASENAME, X, TYPE) \
1262 VEC_DATA_TYPE(TYPE, 8) \
1263 BASENAME##IDX_COL = (VEC_DATA_TYPE(TYPE, 8))((X##0).s##IDX_COL, (X##1).s##IDX_COL, (X##2).s##IDX_COL, (X##3).s##IDX_COL, (X##4).s##IDX_COL, (X##5).s##IDX_COL, (X##6).s##IDX_COL, (X##7).s##IDX_COL);
1264#define COLUMN_VECTOR16(IDX_COL, BASENAME, X, TYPE) \
1265 VEC_DATA_TYPE(TYPE, 16) \
1266 BASENAME##IDX_COL = (VEC_DATA_TYPE(TYPE, 16))((X##0).s##IDX_COL, (X##1).s##IDX_COL, (X##2).s##IDX_COL, (X##3).s##IDX_COL, (X##4).s##IDX_COL, (X##5).s##IDX_COL, (X##6).s##IDX_COL, (X##7).s##IDX_COL, (X##8).s##IDX_COL, (X##9).s##IDX_COL, (X##A).s##IDX_COL, (X##B).s##IDX_COL, (X##C).s##IDX_COL, (X##D).s##IDX_COL, (X##E).s##IDX_COL, (X##F).s##IDX_COL);
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001267/** @} */ // end of group COLUMN_VECTORn
Gian Marco Iodice43a129e2019-05-14 10:14:08 +01001268
Gian Marco Iodice061eefd2020-04-23 13:40:00 +01001269/** Create a new vector containing the values at the given index. Utility macros for transposing a colum-vector
1270 * @name COLUMN_VECTOR_SCALARn
1271 *
1272 * @param[in] IDX_COL The index value
1273 * @param[in] BASENAME The basename of the destination vectors
1274 * @param[in] X The basename of the source vectors
1275 * @param[in] TYPE The data type of the destination vectors
1276 * @{
1277 */
1278#define COLUMN_VECTOR_SCALAR1(IDX_COL, BASENAME, X, TYPE) \
1279 TYPE BASENAME##IDX_COL = (TYPE)((X##0));
1280#define COLUMN_VECTOR_SCALAR2(IDX_COL, BASENAME, X, TYPE) \
1281 VEC_DATA_TYPE(TYPE, 2) \
1282 BASENAME##IDX_COL = (VEC_DATA_TYPE(TYPE, 2))((X##0), (X##1));
1283#define COLUMN_VECTOR_SCALAR3(IDX_COL, BASENAME, X, TYPE) \
1284 VEC_DATA_TYPE(TYPE, 3) \
1285 BASENAME##IDX_COL = (VEC_DATA_TYPE(TYPE, 3))((X##0), (X##1), (X##2));
1286#define COLUMN_VECTOR_SCALAR4(IDX_COL, BASENAME, X, TYPE) \
1287 VEC_DATA_TYPE(TYPE, 4) \
1288 BASENAME##IDX_COL = (VEC_DATA_TYPE(TYPE, 4))((X##0), (X##1), (X##2), (X##3));
1289#define COLUMN_VECTOR_SCALAR8(IDX_COL, BASENAME, X, TYPE) \
1290 VEC_DATA_TYPE(TYPE, 8) \
1291 BASENAME##IDX_COL = (VEC_DATA_TYPE(TYPE, 8))((X##0), (X##1), (X##2), (X##3), (X##4), (X##5), (X##6), (X##7));
1292#define COLUMN_VECTOR_SCALAR16(IDX_COL, BASENAME, X, TYPE) \
1293 VEC_DATA_TYPE(TYPE, 16) \
1294 BASENAME##IDX_COL = (VEC_DATA_TYPE(TYPE, 16))((X##0), (X##1), (X##2), (X##3), (X##4), (X##5), (X##6), (X##7), (X##8), (X##9), (X##A), (X##B), (X##C), (X##D), (X##E), (X##F));
1295/** @} */ // end of group COLUMN_VECTORn
1296
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001297/** Create transposed vectors of the given vectors
1298 * @name TRANSPOSE_K0Xn
1299 *
1300 * @param[in] K0 The size of the source vectors
1301 * @param[in] BASENAME The basename of transposed vectors
1302 * @param[in] B The basename of source vectors for transposition
Michele Di Giorgiof9179d32019-11-27 16:17:30 +00001303 * @param[in] TYPE The data type of the transposed vectors
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001304 * @{
1305 */
Michele Di Giorgiof9179d32019-11-27 16:17:30 +00001306#define TRANSPOSE_K0X1(K0, BASENAME, B, TYPE) \
Gian Marco Iodice061eefd2020-04-23 13:40:00 +01001307 COLUMN_VECTOR_SCALAR(K0, 0, BASENAME, B, TYPE);
Michele Di Giorgiof9179d32019-11-27 16:17:30 +00001308#define TRANSPOSE_K0X2(K0, BASENAME, B, TYPE) \
Gian Marco Iodice061eefd2020-04-23 13:40:00 +01001309 COLUMN_VECTOR(K0, 0, BASENAME, B, TYPE); \
Michele Di Giorgiof9179d32019-11-27 16:17:30 +00001310 COLUMN_VECTOR(K0, 1, BASENAME, B, TYPE);
1311#define TRANSPOSE_K0X3(K0, BASENAME, B, TYPE) \
1312 TRANSPOSE_K0X2(K0, BASENAME, B, TYPE); \
1313 COLUMN_VECTOR(K0, 2, BASENAME, B, TYPE);
1314#define TRANSPOSE_K0X4(K0, BASENAME, B, TYPE) \
1315 TRANSPOSE_K0X3(K0, BASENAME, B, TYPE); \
1316 COLUMN_VECTOR(K0, 3, BASENAME, B, TYPE);
1317#define TRANSPOSE_K0X8(K0, BASENAME, B, TYPE) \
1318 TRANSPOSE_K0X4(K0, BASENAME, B, TYPE); \
1319 COLUMN_VECTOR(K0, 4, BASENAME, B, TYPE); \
1320 COLUMN_VECTOR(K0, 5, BASENAME, B, TYPE); \
1321 COLUMN_VECTOR(K0, 6, BASENAME, B, TYPE); \
1322 COLUMN_VECTOR(K0, 7, BASENAME, B, TYPE);
1323#define TRANSPOSE_K0X16(K0, BASENAME, B, TYPE) \
1324 TRANSPOSE_K0X8(K0, BASENAME, B, TYPE); \
1325 COLUMN_VECTOR(K0, 8, BASENAME, B, TYPE); \
1326 COLUMN_VECTOR(K0, 9, BASENAME, B, TYPE); \
1327 COLUMN_VECTOR(K0, A, BASENAME, B, TYPE); \
1328 COLUMN_VECTOR(K0, B, BASENAME, B, TYPE); \
1329 COLUMN_VECTOR(K0, C, BASENAME, B, TYPE); \
1330 COLUMN_VECTOR(K0, D, BASENAME, B, TYPE); \
1331 COLUMN_VECTOR(K0, E, BASENAME, B, TYPE); \
1332 COLUMN_VECTOR(K0, F, BASENAME, B, TYPE);
Gian Marco Iodice43a129e2019-05-14 10:14:08 +01001333
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001334/** @} */ // end of group TRANSPOSE_K0Xn
1335
1336/** Create column vectors to contain the values at the given index for a set of given vectors
1337 *
1338 * @param[in] K0 The number of source vectors
1339 * @param[in] IDX_COL The index value
1340 * @param[in] BASENAME The basename of the destination vectors
1341 * @param[in] B The basename of the source vectors
Michele Di Giorgiof9179d32019-11-27 16:17:30 +00001342 * @param[in] TYPE The data type of the destination vectors
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001343 */
Michele Di Giorgiof9179d32019-11-27 16:17:30 +00001344#define COLUMN_VECTOR(K0, IDX_COL, BASENAME, B, TYPE) \
1345 CONCAT(COLUMN_VECTOR, K0) \
1346 (IDX_COL, BASENAME, B, TYPE);
Gian Marco Iodice43a129e2019-05-14 10:14:08 +01001347
Gian Marco Iodice061eefd2020-04-23 13:40:00 +01001348/** Create column vectors to contain the values at the given index. Utility macro for transposing a column-vector
1349 *
1350 * @param[in] K0 The number of source vectors
1351 * @param[in] IDX_COL The index value
1352 * @param[in] BASENAME The basename of the destination vectors
1353 * @param[in] B The basename of the source vectors
1354 * @param[in] TYPE The data type of the destination vectors
1355 */
1356#define COLUMN_VECTOR_SCALAR(K0, IDX_COL, BASENAME, B, TYPE) \
1357 CONCAT(COLUMN_VECTOR_SCALAR, K0) \
1358 (IDX_COL, BASENAME, B, TYPE);
1359
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001360/** Create transposed vectors form the given source vectors
1361 *
1362 * @param[in] K0 The size of source vectors
1363 * @param[in] N0 The number of source vectors
1364 * @param[in] BASENAME The basename of transposed vectors
1365 * @param[in] B The basename of source vectors for transposition
Michele Di Giorgiof9179d32019-11-27 16:17:30 +00001366 * @param[in] TYPE The data type of the transposed vectors
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001367 *
1368 */
Michele Di Giorgiof9179d32019-11-27 16:17:30 +00001369#define TRANSPOSE_K0XN0(K0, N0, BASENAME, B, TYPE) \
1370 CONCAT(TRANSPOSE_K0X, N0) \
1371 (K0, BASENAME, B, TYPE);
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001372
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001373/** Add the variables (BIAS0 to BIASn-1) to the others (BASENAME0 to BASENAMEn-1)
1374 * @name ADD_ROW_n
1375 *
1376 * @param[in] BASENAME The basename of the destination variables
1377 * @param[in] BIAS The basename of the added variables
1378 * @{
1379 */
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001380#define ADD_ROW_1(BASENAME, BIAS) \
1381 BASENAME##0 += BIAS##0;
1382
1383#define ADD_ROW_2(BASENAME, BIAS) \
1384 ADD_ROW_1(BASENAME, BIAS) \
1385 BASENAME##1 += BIAS##1;
1386
1387#define ADD_ROW_3(BASENAME, BIAS) \
1388 ADD_ROW_2(BASENAME, BIAS) \
1389 BASENAME##2 += BIAS##2;
1390
1391#define ADD_ROW_4(BASENAME, BIAS) \
1392 ADD_ROW_3(BASENAME, BIAS) \
1393 BASENAME##3 += BIAS##3;
1394
1395#define ADD_ROW_5(BASENAME, BIAS) \
1396 ADD_ROW_4(BASENAME, BIAS) \
1397 BASENAME##4 += BIAS##4;
1398
1399#define ADD_ROW_6(BASENAME, BIAS) \
1400 ADD_ROW_5(BASENAME, BIAS) \
1401 BASENAME##5 += BIAS##5;
1402
1403#define ADD_ROW_7(BASENAME, BIAS) \
1404 ADD_ROW_6(BASENAME, BIAS) \
1405 BASENAME##6 += BIAS##6;
1406
1407#define ADD_ROW_8(BASENAME, BIAS) \
1408 ADD_ROW_7(BASENAME, BIAS) \
1409 BASENAME##7 += BIAS##7;
1410
1411#define ADD_ROW_9(BASENAME, BIAS) \
1412 ADD_ROW_8(BASENAME, BIAS) \
1413 BASENAME##8 += BIAS##8;
1414
1415#define ADD_ROW_10(BASENAME, BIAS) \
1416 ADD_ROW_9(BASENAME, BIAS) \
1417 BASENAME##9 += BIAS##9;
1418
1419#define ADD_ROW_11(BASENAME, BIAS) \
1420 ADD_ROW_10(BASENAME, BIAS) \
1421 BASENAME##A += BIAS##A;
1422
1423#define ADD_ROW_12(BASENAME, BIAS) \
1424 ADD_ROW_11(BASENAME, BIAS) \
1425 BASENAME##B += BIAS##B;
1426
1427#define ADD_ROW_13(BASENAME, BIAS) \
1428 ADD_ROW_12(BASENAME, BIAS) \
1429 BASENAME##C += BIAS##C;
1430
1431#define ADD_ROW_14(BASENAME, BIAS) \
1432 ADD_ROW_13(BASENAME, BIAS) \
1433 BASENAME##D += BIAS##D;
1434
1435#define ADD_ROW_15(BASENAME, BIAS) \
1436 ADD_ROW_14(BASENAME, BIAS) \
1437 BASENAME##E += BIAS##E;
1438
1439#define ADD_ROW_16(BASENAME, BIAS) \
1440 ADD_ROW_15(BASENAME, BIAS) \
1441 BASENAME##F += BIAS##F;
1442
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001443/** @} */ // end of group ADD_ROW_n
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001444
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001445/** Add the block (BIAS) to another block (BASENAME)
1446 * @name ADD_BLOCK
1447 *
1448 * Supported cases are N=1,2,3,...,16
1449 *
1450 * @param[in] N The number of vectors in the block
1451 * @param[in] BASENAME The basename of the destination variables
1452 * @param[in] BIAS The basename of the added variables
1453 * @{
1454 */
1455#define ADD_BLOCK_STR(N, BASENAME, BIAS) ADD_ROW_##N(BASENAME, BIAS)
1456#define ADD_BLOCK(N, BASENAME, BIAS) ADD_BLOCK_STR(N, BASENAME, BIAS)
1457/** @} */ // end of group ADD_BLOCK
1458
1459/** Broadcast (add single value) to the each element of the destination variables
1460 * @name ADD_ROW_BROADCAST_n
1461 *
1462 * @param[in] BASENAME The basename of the destination variables
1463 * @param[in] BIAS The variable containing the value to add
1464 * @{
1465 */
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001466#define ADD_ROW_BROADCAST_1(BASENAME, BIAS) \
1467 BASENAME##0 += BIAS;
1468
1469#define ADD_ROW_BROADCAST_2(BASENAME, BIAS) \
1470 ADD_ROW_BROADCAST_1(BASENAME, BIAS) \
1471 BASENAME##1 += BIAS;
1472
1473#define ADD_ROW_BROADCAST_3(BASENAME, BIAS) \
1474 ADD_ROW_BROADCAST_2(BASENAME, BIAS) \
1475 BASENAME##2 += BIAS;
1476
1477#define ADD_ROW_BROADCAST_4(BASENAME, BIAS) \
1478 ADD_ROW_BROADCAST_3(BASENAME, BIAS) \
1479 BASENAME##3 += BIAS;
1480
1481#define ADD_ROW_BROADCAST_5(BASENAME, BIAS) \
1482 ADD_ROW_BROADCAST_4(BASENAME, BIAS) \
1483 BASENAME##4 += BIAS;
1484
1485#define ADD_ROW_BROADCAST_6(BASENAME, BIAS) \
1486 ADD_ROW_BROADCAST_5(BASENAME, BIAS) \
1487 BASENAME##5 += BIAS;
1488
1489#define ADD_ROW_BROADCAST_7(BASENAME, BIAS) \
1490 ADD_ROW_BROADCAST_6(BASENAME, BIAS) \
1491 BASENAME##6 += BIAS;
1492
1493#define ADD_ROW_BROADCAST_8(BASENAME, BIAS) \
1494 ADD_ROW_BROADCAST_7(BASENAME, BIAS) \
1495 BASENAME##7 += BIAS;
1496
1497#define ADD_ROW_BROADCAST_9(BASENAME, BIAS) \
1498 ADD_ROW_BROADCAST_8(BASENAME, BIAS) \
1499 BASENAME##8 += BIAS;
1500
1501#define ADD_ROW_BROADCAST_10(BASENAME, BIAS) \
1502 ADD_ROW_BROADCAST_9(BASENAME, BIAS) \
1503 BASENAME##9 += BIAS;
1504
1505#define ADD_ROW_BROADCAST_11(BASENAME, BIAS) \
1506 ADD_ROW_BROADCAST_10(BASENAME, BIAS) \
1507 BASENAME##A += BIAS;
1508
1509#define ADD_ROW_BROADCAST_12(BASENAME, BIAS) \
1510 ADD_ROW_BROADCAST_11(BASENAME, BIAS) \
1511 BASENAME##B += BIAS;
1512
1513#define ADD_ROW_BROADCAST_13(BASENAME, BIAS) \
1514 ADD_ROW_BROADCAST_12(BASENAME, BIAS) \
1515 BASENAME##C += BIAS;
1516
1517#define ADD_ROW_BROADCAST_14(BASENAME, BIAS) \
1518 ADD_ROW_BROADCAST_13(BASENAME, BIAS) \
1519 BASENAME##D += BIAS;
1520
1521#define ADD_ROW_BROADCAST_15(BASENAME, BIAS) \
1522 ADD_ROW_BROADCAST_14(BASENAME, BIAS) \
1523 BASENAME##E += BIAS;
1524
1525#define ADD_ROW_BROADCAST_16(BASENAME, BIAS) \
1526 ADD_ROW_BROADCAST_15(BASENAME, BIAS) \
1527 BASENAME##F += BIAS;
1528
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001529/** Broadcast (add a value) to the each element of the destination block (BASENAME)
1530 * @name ADD_BLOCK_BROADCAST
1531 *
1532 * Supported cases are N=1,2,3,...,16.
1533 *
1534 * @param[in] N The number of vectors in the block
1535 * @param[in] BASENAME The basename of the destination variables
1536 * @param[in] BIAS The variable containing the value to add
1537 * @{
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001538 */
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001539#define ADD_BLOCK_BROADCAST_STR(N, BASENAME, BIAS) ADD_ROW_BROADCAST_##N(BASENAME, BIAS)
Georgios Pinitasb0f342e2019-05-21 13:32:43 +01001540#define ADD_BLOCK_BROADCAST(N, BASENAME, BIAS) ADD_BLOCK_BROADCAST_STR(N, BASENAME, BIAS)
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001541/** @} */ // end of group ADD_BLOCK_BROADCAST
Gian Marco Iodiceca1f4602019-07-16 15:46:48 +01001542
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001543/** Apply activation to the given variables
1544 * @name ACTIVATION_ROW_n
1545 *
1546 * @param[in] ACTIVATION_TYPE The type of the activation
1547 * @param[in] DATA_TYPE The data type of the vectors
1548 * @param[in] BASENAME The basename of the variables
1549 * @param[in] A_VAL Additional value required by the activation
1550 * @param[in] B_VAL Additional value required by the activation
1551 * @{
1552 */
Gian Marco Iodiceca1f4602019-07-16 15:46:48 +01001553#define ACTIVATION_ROW_1(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1554 BASENAME##0 = ACTIVATION(ACTIVATION_TYPE, DATA_TYPE, BASENAME##0, A_VAL, B_VAL);
1555
1556#define ACTIVATION_ROW_2(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1557 ACTIVATION_ROW_1(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1558 BASENAME##1 = ACTIVATION(ACTIVATION_TYPE, DATA_TYPE, BASENAME##1, A_VAL, B_VAL);
1559
1560#define ACTIVATION_ROW_3(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1561 ACTIVATION_ROW_2(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1562 BASENAME##2 = ACTIVATION(ACTIVATION_TYPE, DATA_TYPE, BASENAME##2, A_VAL, B_VAL);
1563
1564#define ACTIVATION_ROW_4(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1565 ACTIVATION_ROW_3(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1566 BASENAME##3 = ACTIVATION(ACTIVATION_TYPE, DATA_TYPE, BASENAME##3, A_VAL, B_VAL);
1567
1568#define ACTIVATION_ROW_5(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1569 ACTIVATION_ROW_4(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1570 BASENAME##4 = ACTIVATION(ACTIVATION_TYPE, DATA_TYPE, BASENAME##4, A_VAL, B_VAL);
1571
1572#define ACTIVATION_ROW_6(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1573 ACTIVATION_ROW_5(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1574 BASENAME##5 = ACTIVATION(ACTIVATION_TYPE, DATA_TYPE, BASENAME##5, A_VAL, B_VAL);
1575
1576#define ACTIVATION_ROW_7(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1577 ACTIVATION_ROW_6(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1578 BASENAME##6 = ACTIVATION(ACTIVATION_TYPE, DATA_TYPE, BASENAME##6, A_VAL, B_VAL);
1579
1580#define ACTIVATION_ROW_8(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1581 ACTIVATION_ROW_7(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1582 BASENAME##7 = ACTIVATION(ACTIVATION_TYPE, DATA_TYPE, BASENAME##7, A_VAL, B_VAL);
1583
1584#define ACTIVATION_ROW_9(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1585 ACTIVATION_ROW_8(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1586 BASENAME##8 = ACTIVATION(ACTIVATION_TYPE, DATA_TYPE, BASENAME##8, A_VAL, B_VAL);
1587
1588#define ACTIVATION_ROW_10(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1589 ACTIVATION_ROW_9(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1590 BASENAME##9 = ACTIVATION(ACTIVATION_TYPE, DATA_TYPE, BASENAME##9, A_VAL, B_VAL);
1591
1592#define ACTIVATION_ROW_11(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1593 ACTIVATION_ROW_10(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1594 BASENAME##A = ACTIVATION(ACTIVATION_TYPE, DATA_TYPE, BASENAME##A, A_VAL, B_VAL);
1595
1596#define ACTIVATION_ROW_12(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1597 ACTIVATION_ROW_11(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1598 BASENAME##B = ACTIVATION(ACTIVATION_TYPE, DATA_TYPE, BASENAME##B, A_VAL, B_VAL);
1599
1600#define ACTIVATION_ROW_13(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1601 ACTIVATION_ROW_12(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1602 BASENAME##C = ACTIVATION(ACTIVATION_TYPE, DATA_TYPE, BASENAME##C, A_VAL, B_VAL);
1603
1604#define ACTIVATION_ROW_14(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1605 ACTIVATION_ROW_13(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1606 BASENAME##D = ACTIVATION(ACTIVATION_TYPE, DATA_TYPE, BASENAME##D, A_VAL, B_VAL);
1607
1608#define ACTIVATION_ROW_15(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1609 ACTIVATION_ROW_14(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1610 BASENAME##E = ACTIVATION(ACTIVATION_TYPE, DATA_TYPE, BASENAME##E, A_VAL, B_VAL);
1611
1612#define ACTIVATION_ROW_16(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1613 ACTIVATION_ROW_15(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) \
1614 BASENAME##F = ACTIVATION(ACTIVATION_TYPE, DATA_TYPE, BASENAME##F, A_VAL, B_VAL);
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001615/** @} */ // end of group ACTIVATION_ROW_n
Gian Marco Iodiceca1f4602019-07-16 15:46:48 +01001616
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001617/** Apply activation to a block (BASENAME)
1618 * @name ACTIVATION_BLOCK
1619 *
1620 * Supported cases are N=1,2,3,...,16.
1621 *
1622 * @param[in] N The number of vectors in the block
1623 * @param[in] ACTIVATION_TYPE The type of the activation
1624 * @param[in] DATA_TYPE The data type of the vectors
1625 * @param[in] BASENAME The basename of the variables
1626 * @param[in] A_VAL Additional value required by the activation
1627 * @param[in] B_VAL Additional value required by the activation
1628 * @{
Gian Marco Iodiceca1f4602019-07-16 15:46:48 +01001629 */
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001630#define ACTIVATION_BLOCK_STR(N, ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) ACTIVATION_ROW_##N(ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL)
Gian Marco Iodice0c17aa22019-09-27 09:23:15 +01001631#define ACTIVATION_BLOCK(N, ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL) ACTIVATION_BLOCK_STR(N, ACTIVATION_TYPE, DATA_TYPE, BASENAME, A_VAL, B_VAL)
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001632/** @} */ // end of group ACTIVATION_BLOCK
Gian Marco Iodice0c17aa22019-09-27 09:23:15 +01001633
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001634/** Apply convert_<data_type> to the given variables
1635 * @name CONVERT_ROW_n
1636 *
1637 * @param[in] N The size of the vectors
1638 * @param[in] DATA_TYPE The data type of the vectors
1639 * @param[in] BASENAME_SRC The basename of the source variables
1640 * @param[in] BASENAME_DST The basename of the destination variables
1641 */
Gian Marco Iodice0c17aa22019-09-27 09:23:15 +01001642#define CONVERT_ROW_1(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1643 VEC_DATA_TYPE(DATA_TYPE, N) \
1644 BASENAME_DST##0 = CONVERT(BASENAME_SRC##0, VEC_DATA_TYPE(DATA_TYPE, N));
1645
1646#define CONVERT_ROW_2(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1647 CONVERT_ROW_1(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1648 VEC_DATA_TYPE(DATA_TYPE, N) \
1649 BASENAME_DST##1 = CONVERT(BASENAME_SRC##1, VEC_DATA_TYPE(DATA_TYPE, N));
1650
1651#define CONVERT_ROW_3(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1652 CONVERT_ROW_2(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1653 VEC_DATA_TYPE(DATA_TYPE, N) \
1654 BASENAME_DST##2 = CONVERT(BASENAME_SRC##2, VEC_DATA_TYPE(DATA_TYPE, N));
1655
1656#define CONVERT_ROW_4(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1657 CONVERT_ROW_3(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1658 VEC_DATA_TYPE(DATA_TYPE, N) \
1659 BASENAME_DST##3 = CONVERT(BASENAME_SRC##3, VEC_DATA_TYPE(DATA_TYPE, N));
1660
1661#define CONVERT_ROW_5(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1662 CONVERT_ROW_4(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1663 VEC_DATA_TYPE(DATA_TYPE, N) \
1664 BASENAME_DST##4 = CONVERT(BASENAME_SRC##4, VEC_DATA_TYPE(DATA_TYPE, N));
1665
1666#define CONVERT_ROW_6(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1667 CONVERT_ROW_5(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1668 VEC_DATA_TYPE(DATA_TYPE, N) \
1669 BASENAME_DST##5 = CONVERT(BASENAME_SRC##5, VEC_DATA_TYPE(DATA_TYPE, N));
1670
1671#define CONVERT_ROW_7(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1672 CONVERT_ROW_6(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1673 VEC_DATA_TYPE(DATA_TYPE, N) \
1674 BASENAME_DST##6 = CONVERT(BASENAME_SRC##6, VEC_DATA_TYPE(DATA_TYPE, N));
1675
1676#define CONVERT_ROW_8(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1677 CONVERT_ROW_7(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1678 VEC_DATA_TYPE(DATA_TYPE, N) \
1679 BASENAME_DST##7 = CONVERT(BASENAME_SRC##7, VEC_DATA_TYPE(DATA_TYPE, N));
1680
1681#define CONVERT_ROW_9(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1682 CONVERT_ROW_8(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1683 VEC_DATA_TYPE(DATA_TYPE, N) \
1684 BASENAME_DST##8 = CONVERT(BASENAME_SRC##8, VEC_DATA_TYPE(DATA_TYPE, N));
1685
1686#define CONVERT_ROW_10(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1687 CONVERT_ROW_9(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1688 VEC_DATA_TYPE(DATA_TYPE, N) \
1689 BASENAME_DST##9 = CONVERT(BASENAME_SRC##9, VEC_DATA_TYPE(DATA_TYPE, N));
1690
1691#define CONVERT_ROW_11(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1692 CONVERT_ROW_10(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1693 VEC_DATA_TYPE(DATA_TYPE, N) \
1694 BASENAME_DST##A = CONVERT(BASENAME_SRC##A, VEC_DATA_TYPE(DATA_TYPE, N));
1695
1696#define CONVERT_ROW_12(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1697 CONVERT_ROW_11(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1698 VEC_DATA_TYPE(DATA_TYPE, N) \
1699 BASENAME_DST##B = CONVERT(BASENAME_SRC##B, VEC_DATA_TYPE(DATA_TYPE, N));
1700
1701#define CONVERT_ROW_13(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1702 CONVERT_ROW_12(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1703 VEC_DATA_TYPE(DATA_TYPE, N) \
1704 BASENAME_DST##C = CONVERT(BASENAME_SRC##C, VEC_DATA_TYPE(DATA_TYPE, N));
1705
1706#define CONVERT_ROW_14(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1707 CONVERT_ROW_13(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1708 VEC_DATA_TYPE(DATA_TYPE, N) \
1709 BASENAME_DST##D = CONVERT(BASENAME_SRC##D, VEC_DATA_TYPE(DATA_TYPE, N));
1710
1711#define CONVERT_ROW_15(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1712 CONVERT_ROW_14(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1713 VEC_DATA_TYPE(DATA_TYPE, N) \
1714 BASENAME_DST##E = CONVERT(BASENAME_SRC##E, VEC_DATA_TYPE(DATA_TYPE, N));
1715
1716#define CONVERT_ROW_16(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1717 CONVERT_ROW_15(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) \
1718 VEC_DATA_TYPE(DATA_TYPE, N) \
1719 BASENAME_DST##F = CONVERT(BASENAME_SRC##F, VEC_DATA_TYPE(DATA_TYPE, N));
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001720/** @} */ // end of group CONVERT_ROW_n
Gian Marco Iodice0c17aa22019-09-27 09:23:15 +01001721
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001722/** Apply convert_<data_type> to a block (BASENAME_SRC) and save to another block (BASENAME_DST)
1723 * @name CONVERT_BLOCK
1724 *
1725 * Supported cases N=1,2,3,...,16.
1726 *
1727 * @param[in] M The number of vectors to convert
1728 * @param[in] N The size of the vectors
1729 * @param[in] DATA_TYPE The data type of the vectors
1730 * @param[in] BASENAME_SRC The basename of the source variables
1731 * @param[in] BASENAME_DST The basename of the destination variables
Gian Marco Iodice0c17aa22019-09-27 09:23:15 +01001732 */
Sang-Hoon Park11b0b8a2019-11-05 13:29:19 +00001733#define CONVERT_BLOCK_STR(M, N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) CONVERT_ROW_##M(N, DATA_TYPE, BASENAME_SRC, BASENAME_DST)
1734#define CONVERT_BLOCK(M, N, DATA_TYPE, BASENAME_SRC, BASENAME_DST) CONVERT_BLOCK_STR(M, N, DATA_TYPE, BASENAME_SRC, BASENAME_DST)
SiCong Li3a501662020-06-26 10:02:06 +01001735/** @} */ // end of group CONVERT_BLOCK
1736
1737#if defined(PARTIAL_STORE_M0) && defined(PARTIAL_STORE_N0)
1738
SiCong Li406a13f2020-07-15 12:09:58 +01001739/** Boundary-aware GEMM block store
SiCong Li3a501662020-06-26 10:02:06 +01001740 * @name STORE_BLOCK_BOUNDARY_AWARE
SiCong Li406a13f2020-07-15 12:09:58 +01001741 * This macro assumes the following schemes to achieve boundary-awareness:
1742 * - Overlapping load in Y axis from lhs tensor. This implies lhs has no padding along y dim.
1743 * - Non-Overlapping(normal) load from rhs tensor. This imples rhs can have paddings.
1744 * - Overlapping load in Y axis from bias tensor. This implies rhs has no padding along y dim.
1745 * The macro then ensures that the dst tensor can be stored without any paddings in both x and y dim.
SiCong Li3a501662020-06-26 10:02:06 +01001746 *
SiCong Li406a13f2020-07-15 12:09:58 +01001747 * In the y dimension, we place the partial blocks **at the beginning** while in the x dimension, we place the partial
1748 * blocks **at the end**.
SiCong Li3a501662020-06-26 10:02:06 +01001749 * Say, the dst tensor is of shape MxN and we have M0 and N0 as the block size, this is how we define "partial blocks"/
1750 * "boundary block" (we use the 2 terms "partial blocks" and "boundary blocks" interchangeably) and its various parameters:
1751 *
1752 * *--x--> x == 0 x == 1
1753 * | |<------------------------------N-------------------------->|
1754 * y |<--------------N0------------->|<----PARTIAL_STORE_N0----->|
1755 * | -------------#############################################################
SiCong Li406a13f2020-07-15 12:09:58 +01001756 * * | | |...............................|...........................|
1757 * y == 0 | PAR_..._M0 |......Boundary block in y......|.Boundary block in x and y.|
1758 * | | |...............................|...........................|
SiCong Li3a501662020-06-26 10:02:06 +01001759 * M --#############################################################
SiCong Li406a13f2020-07-15 12:09:58 +01001760 * | | | |...........................|
1761 * y == 1 | M0 | Non-boundary block |....Boundary block in x....|
1762 * | | | |...........................|
SiCong Li3a501662020-06-26 10:02:06 +01001763 * |------------#############################################################
1764 *
1765 * Then @p PARTIAL_STORE_M0 = M % M0 and @p PARTIAL_STORE_N0 = N % N0
1766 *
1767 * @note in cases @p PARTIAL_STORE_N0 != 1, 2, 3, 4, 8, 16, extra vstore(s) will be invoked, thus incurring small performance penalty.
1768 *
SiCong Li3a501662020-06-26 10:02:06 +01001769 * It automatically detects if a giving M,N,M0,N0 combination can yield partial blocks in either X and Y dimension,
1770 * and select corresponding store methods such that the boundary detection logic is only added when needed.
1771 *
1772 * The data to store is expected to have consecutive names for each row.
1773 * E.g., for M0=3 and basename=c, the expected names are c0, c1 and c2.
1774 * The Z offset is expected to have consecutive names.
1775 * E.g., for M0=3 and Z=zin, the expected z offset names are zin0, zin1 and zin2.
1776 *
1777 * @param[in] M0 The number of rows to store, for non-partial blocks. Supported: 1-16
1778 * @param[in] N0 The size of each vector, for non-partial blocks. Supported: 1, 2, 3, 4, 8, 16
1779 * @param[in] DATA_TYPE The data type of the vectors
1780 * @param[in] BASENAME The basename of the variables
1781 * @param[in] PTR The base pointer
1782 * @param[in] STRIDE_Y The stride value in y-axis direction
1783 * @param[in] Z The offset in z-axis direction
1784 * @param[in] PARTIAL_STORE_M0 The partial size in y, for partial blocks. Supported: [0, @p M0)
1785 * @param[in] PARTIAL_STORE_N0 The partial size in x, for partial blocks. Supported: [0, @p N0)
SiCong Li3a501662020-06-26 10:02:06 +01001786 * @param[in] N Total number of columns. Used to detect if current block is at the boundary in x.
Gian Marco Iodice088d63a2020-08-11 14:14:06 +01001787 * @param[in] PARTIAL_COND_Y Condition on the y axis to perform the partial store Y. True to use PARTIAL_STORE_M0 rather than M0.
1788 * @param[in] PARTIAL_COND_X Condition on the x axis to perform the partial store X. True to use PARTIAL_STORE_N0 rather than N0.
SiCong Li3a501662020-06-26 10:02:06 +01001789 * @{
1790 */
1791#if PARTIAL_STORE_M0 == 0 && PARTIAL_STORE_N0 == 0
1792// Case1: No partial blocks in either x or y
Gian Marco Iodice088d63a2020-08-11 14:14:06 +01001793#define STORE_BLOCK_BOUNDARY_AWARE(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z, PARTIAL_STORE_M0, PARTIAL_STORE_N0, N, PARTIAL_COND_Y, PARTIAL_COND_X) \
SiCong Li3a501662020-06-26 10:02:06 +01001794 STORE_BLOCK(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z)
1795
1796#elif PARTIAL_STORE_M0 > 0 && PARTIAL_STORE_N0 == 0
1797// Case2: Partial blocks in y
Gian Marco Iodice088d63a2020-08-11 14:14:06 +01001798#define STORE_BLOCK_BOUNDARY_AWARE(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z, PARTIAL_STORE_M0, PARTIAL_STORE_N0, N, PARTIAL_COND_Y, PARTIAL_COND_X) \
1799 STORE_BLOCK_PARTIAL_IN_Y(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z, PARTIAL_STORE_M0, PARTIAL_COND_Y)
SiCong Li3a501662020-06-26 10:02:06 +01001800
1801#elif PARTIAL_STORE_M0 == 0 && PARTIAL_STORE_N0 > 0
1802// Case3: Partial blocks in x
Gian Marco Iodice088d63a2020-08-11 14:14:06 +01001803#define STORE_BLOCK_BOUNDARY_AWARE(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z, PARTIAL_STORE_M0, PARTIAL_STORE_N0, N, PARTIAL_COND_Y, PARTIAL_COND_X) \
1804 STORE_BLOCK_PARTIAL_IN_X(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z, PARTIAL_STORE_N0, N, PARTIAL_COND_X)
SiCong Li3a501662020-06-26 10:02:06 +01001805
1806#else // PARTIAL_STORE_M0 == 0 && PARTIAL_STORE_N0 == 0
1807// Case4: Partial blocks in both x and y
Gian Marco Iodice088d63a2020-08-11 14:14:06 +01001808#define STORE_BLOCK_BOUNDARY_AWARE(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z, PARTIAL_STORE_M0, PARTIAL_STORE_N0, N, PARTIAL_COND_Y, PARTIAL_COND_X) \
1809 STORE_BLOCK_PARTIAL_IN_X_AND_Y(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z, PARTIAL_STORE_M0, PARTIAL_STORE_N0, N, PARTIAL_COND_Y, PARTIAL_COND_X)
SiCong Li3a501662020-06-26 10:02:06 +01001810
1811#endif // PARTIAL_STORE_M0 == 0 && PARTIAL_STORE_N0 == 0
1812
1813#else // defined(PARTIAL_STORE_M0) && defined(PARTIAL_STORE_N0)
1814
Gian Marco Iodice088d63a2020-08-11 14:14:06 +01001815#define STORE_BLOCK_BOUNDARY_AWARE(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z, PARTIAL_STORE_M0, PARTIAL_STORE_N0, N, PARTIAL_COND_Y, PARTIAL_COND_X) \
SiCong Li3a501662020-06-26 10:02:06 +01001816 STORE_BLOCK(M0, N0, DATA_TYPE, BASENAME, PTR, STRIDE_Y, Z)
1817
1818#endif // defined(PARTIAL_STORE_M0) && defined(PARTIAL_STORE_N0)
SiCong Li406a13f2020-07-15 12:09:58 +01001819/** @} */ // end of group STORE_BLOCK_BOUNDARY_AWARE
1820
1821#if defined(PARTIAL_STORE_M0)
1822/** Compute the start m0 row (LHS, BIAS and DST) in a boundary-aware way so as to avoid padding
1823 * @name COMPUTE_M0_START_ROW
1824 * If there're any partial blocks in y dimension, they are placed at the beginning of the rows.
1825 * This shift amount is added to all rows such that the partial block (at the beginning) overlaps with the subsequent
1826 * blocks in the y dimension to avoid any padding.
1827 * EG: M0=4, PARTIAL_STORE_M0=1:
1828 * | Non-overlapping | +M0_ROW_SHIFT (Overlapping)
1829 * block 0 (partial)| start row = 0 | start row = 0
1830 * block 1 (full) | start row = 4 | start row = 1
1831 * block 2 (full) | start row = 8 | start row = 5
1832 *
1833 * @param[in] y Global id of current block in y.
1834 * @param[in] M0 The number of rows to store, for non-partial blocks. Supported: 1-16
1835 * @param[in] PARTIAL_STORE_M0 The partial size in y, for partial blocks. Supported: [0, @p M0)
1836 * @{
1837 */
1838#define COMPUTE_M0_START_ROW(y, M0, PARTIAL_STORE_M0) \
1839 ((uint)(max(0, (int)(y * M0) - (int)((M0 - PARTIAL_STORE_M0) % M0))))
1840#else // defined(PARTIAL_STORE_M0)
1841#define COMPUTE_M0_START_ROW(y, M0, PARTIAL_STORE_M0) \
1842 ((uint)(y * M0))
1843#endif // defined(PARTIAL_STORE_M0)
Gian Marco Iodice088d63a2020-08-11 14:14:06 +01001844/** @} */ // end of group COMPUTE_M0_START_ROW