blob: 9f58d9fefa86b30dc65c777272a971acf3c7de3b [file] [log] [blame]
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +01001/*
2 * Copyright (c) 2023 Arm Limited.
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25#include "ckw/KernelWriter.h"
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010026
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +010027#include "ckw/Error.h"
Viet-Hoa Doc8e16172023-06-27 14:09:46 +010028#include "ckw/TensorInfo.h"
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +010029#include "ckw/TensorOperand.h"
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010030
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +010031#include "src/Prototype.h"
32
33#include <sstream>
34
35namespace ckw
36{
37
38namespace
39{
40
41inline prototype::TensorInfo create_impl_tensor_info(const TensorInfo &info)
42{
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010043 return prototype::TensorInfo{info.shape(), info.data_type(), info.data_layout(), info.id()};
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +010044}
45
46} // namespace
47
48// =================================================================================================
49// Constructors and destructor
50// =================================================================================================
51
52KernelWriter::KernelWriter(Kernel &kernel)
53 : _kernel(&kernel),
54 _impl_attr(std::make_unique<prototype::GpuKernelWriterAttribute>()),
55 _impl(prototype::GpuKernelWriterFactory::create(_impl_attr.get(), kernel.impl()))
56{
57 _impl->set_IdSpace(1);
58}
59
60KernelWriter::~KernelWriter()
61{
62}
63
64// =================================================================================================
65// Scope management
66// =================================================================================================
67
68int32_t KernelWriter::id_space() const
69{
70 return _id_space;
71}
72
73KernelWriter &KernelWriter::id_space(int32_t id_space)
74{
75 CKW_ASSERT(id_space <= _max_id_space);
76
77 _id_space = id_space;
78 return *this;
79}
80
81int32_t KernelWriter::next_id_space()
82{
83 id_space(++_max_id_space);
84 return _id_space;
85}
86
87// =================================================================================================
88// Tensor and tile declaration
89// =================================================================================================
90
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010091TensorOperand &
92KernelWriter::declare_tensor_argument(const std::string &name, const TensorInfo &info, TensorStorageType storage_type)
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +010093{
94 const auto var_name = generate_variable_name(name);
95
96 _impl->declare_argument(var_name, create_impl_tensor_info(info));
97
Viet-Hoa Doc8e16172023-06-27 14:09:46 +010098 auto &operand = _kernel->register_operand(std::make_unique<TensorOperand>(var_name, info, storage_type));
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +010099
Viet-Hoa Doc8e16172023-06-27 14:09:46 +0100100 return operand;
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100101}
102
Nikolaj Jensen5ff48022023-06-27 14:13:24 +0100103TileOperand &KernelWriter::declare_tile_argument(const std::string &name, int32_t value)
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100104{
105 const auto var_name = generate_variable_name(name);
106
Viet-Hoa Doc8e16172023-06-27 14:09:46 +0100107 auto &operand = _kernel->register_operand(std::make_unique<TileOperand>(var_name, value));
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100108
Viet-Hoa Doc8e16172023-06-27 14:09:46 +0100109 return operand;
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100110}
111
Nikolaj Jensen5ff48022023-06-27 14:13:24 +0100112std::string KernelWriter::generate_variable_name(const std::string &name) const
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100113{
114 std::stringstream var_name;
115
116 var_name << "_" << _id_space << "_" << name;
117
118 return var_name.str();
119}
120
Viet-Hoa Doc8e16172023-06-27 14:09:46 +0100121TileOperand &KernelWriter::declare_tile_operand(std::unique_ptr<TileOperand> operand_ptr)
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100122{
Viet-Hoa Doc8e16172023-06-27 14:09:46 +0100123 auto &operand = _kernel->register_operand(std::move(operand_ptr));
124 const auto &name = operand.name();
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100125
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100126 if (!operand.is_constant())
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100127 {
Viet-Hoa Doc8e16172023-06-27 14:09:46 +0100128 const auto &info = operand.tile_info();
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100129
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100130 _impl->declare_tile(name, prototype::TileInfo(info.data_type(), info.width(), info.height()));
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100131 }
Jakub Sujake1c96e72023-07-31 13:36:58 +0100132 else
133 {
134 _impl->declare_const_tile(name, operand.value(), operand.data_type());
135 }
Viet-Hoa Doc8e16172023-06-27 14:09:46 +0100136
137 return operand;
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100138}
139
140// =================================================================================================
141// Load and store
142// =================================================================================================
143
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100144void KernelWriter::op_load(TileOperand &tile,
145 const TensorOperand &tensor,
146 const TensorTileSampler &sampler,
147 const TileOperand &dilation_y)
Jakub Sujake1c96e72023-07-31 13:36:58 +0100148{
149 prototype::TensorOperand impl_tensor(
150 tensor.name(),
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100151 prototype::GpuSampler{sampler.format(), prototype::to_gpu_tensor_storage(tensor.storage_type()),
152 sampler.address_mode_x(), sampler.address_mode_y(), sampler.address_mode_z()});
Jakub Sujake1c96e72023-07-31 13:36:58 +0100153
154 auto impl_x = sampler.x().create_impl_operand(_impl.get());
155 auto impl_y = sampler.y().create_impl_operand(_impl.get());
156 auto impl_z = sampler.z().create_impl_operand(_impl.get());
157 auto impl_b = sampler.b().create_impl_operand(_impl.get());
158
159 auto impl_dilation_y = dilation_y.create_impl_operand(_impl.get());
160
161 auto impl_dst = tile.create_impl_operand(_impl.get());
162
163 _impl->op_load_immediate(impl_tensor, impl_dst, impl_x, impl_y, impl_z, impl_b, impl_dilation_y);
164}
165
166void KernelWriter::op_load_indirect(TileOperand &tile, const TensorOperand &tensor, const TensorTileSampler &sampler)
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100167{
Viet-Hoa Doe1880f02023-06-28 10:25:35 +0100168 prototype::TensorOperand impl_tensor(
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100169 tensor.name(),
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100170 prototype::GpuSampler{sampler.format(), prototype::to_gpu_tensor_storage(tensor.storage_type()),
171 sampler.address_mode_x(), sampler.address_mode_y(), sampler.address_mode_z()});
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100172
173 auto impl_x = sampler.x().create_impl_operand(_impl.get());
174 auto impl_y = sampler.y().create_impl_operand(_impl.get());
175 auto impl_z = sampler.z().create_impl_operand(_impl.get());
176 auto impl_b = sampler.b().create_impl_operand(_impl.get());
177
178 auto impl_dst = tile.create_impl_operand(_impl.get());
179
Jakub Sujake1c96e72023-07-31 13:36:58 +0100180 _impl->op_load_indirect(impl_tensor, impl_dst, impl_x, impl_y, impl_z, impl_b);
181}
182
183void KernelWriter::util_get_indirect_buffer(TileOperand &tile,
184 const TensorOperand &tensor,
185 const TensorTileSampler &sampler,
186 const TileOperand &x,
187 const TileOperand &y,
188 const TileOperand &x_off,
189 const TileOperand &y_off)
190{
191 prototype::TensorOperand impl_tensor(
192 tensor.name(),
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100193 prototype::GpuSampler{sampler.format(), prototype::to_gpu_tensor_storage(tensor.storage_type()),
194 sampler.address_mode_x(), sampler.address_mode_y(), sampler.address_mode_z()});
Jakub Sujake1c96e72023-07-31 13:36:58 +0100195
196 auto impl_x = x.create_impl_operand(_impl.get());
197 auto impl_y = y.create_impl_operand(_impl.get());
198 auto impl_x_off = x_off.create_impl_operand(_impl.get());
199 auto impl_y_off = y_off.create_impl_operand(_impl.get());
200
201 auto impl_dst = tile.create_impl_operand(_impl.get());
202
203 _impl->util_get_indirect_buffer(impl_dst, impl_tensor, impl_x, impl_y, impl_x_off, impl_y_off);
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100204}
205
206void KernelWriter::op_store(TensorOperand &tensor, const TileOperand &tile, const TensorTileSampler &sampler)
207{
Viet-Hoa Doe1880f02023-06-28 10:25:35 +0100208 prototype::TensorOperand impl_tensor(
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100209 tensor.name(),
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100210 prototype::GpuSampler{sampler.format(), prototype::to_gpu_tensor_storage(tensor.storage_type()),
211 sampler.address_mode_x(), sampler.address_mode_y(), sampler.address_mode_z()});
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100212 auto impl_src = tile.create_impl_operand(_impl.get());
213 auto impl_x = sampler.x().create_impl_operand(_impl.get());
214 auto impl_y = sampler.y().create_impl_operand(_impl.get());
215 auto impl_z = sampler.z().create_impl_operand(_impl.get());
216 auto impl_b = sampler.b().create_impl_operand(_impl.get());
217
218 _impl->op_store_immediate(impl_tensor, impl_src, impl_x, impl_y, impl_z, impl_b);
219}
220
221// =================================================================================================
222// Data processing
223// =================================================================================================
224
Nikolaj Jensen5ff48022023-06-27 14:13:24 +0100225void KernelWriter::op_assign(const TileOperand &dst, const TileOperand &src)
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100226{
227 auto impl_dst = dst.create_impl_operand(_impl.get());
228 auto impl_src = src.create_impl_operand(_impl.get());
229
230 _impl->op_assign(impl_dst, impl_src);
231}
232
Nikolaj Jensen5ff48022023-06-27 14:13:24 +0100233void KernelWriter::op_cast_expression(const TileOperand &dst, const TileOperand &src, const ConvertPolicy policy)
234{
235 auto impl_dst = dst.create_impl_operand(_impl.get());
236 auto impl_src = src.create_impl_operand(_impl.get());
237
238 _impl->op_cast_expression(impl_dst, impl_src, policy);
239}
240
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100241void KernelWriter::op_binary_expression(const TileOperand &dst,
242 const TileOperand &lhs,
243 BinaryOp op,
244 const TileOperand &rhs)
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100245{
246 auto impl_lhs = lhs.create_impl_operand(_impl.get());
247 auto impl_rhs = rhs.create_impl_operand(_impl.get());
248 auto impl_dst = dst.create_impl_operand(_impl.get());
249
250 _impl->op_binary_expression(impl_dst, impl_lhs, op, impl_rhs);
251}
252
Nikolaj Jensen5ff48022023-06-27 14:13:24 +0100253void KernelWriter::op_unary_expression(const TileOperand &dst, UnaryOp op, const TileOperand &src)
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100254{
255 auto impl_dst = dst.create_impl_operand(_impl.get());
256 auto impl_src = src.create_impl_operand(_impl.get());
257
Nikolaj Jensen5ff48022023-06-27 14:13:24 +0100258 _impl->op_unary_expression(impl_dst, op, impl_src);
259}
260
261void KernelWriter::op_unary_elementwise_function(const TileOperand &dst, UnaryFunction opcode, const TileOperand &src)
262{
263 auto impl_dst = dst.create_impl_operand(_impl.get());
264 auto impl_src = src.create_impl_operand(_impl.get());
265
266 _impl->op_unary_elementwise_function(impl_dst, opcode, impl_src);
267}
268
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100269void KernelWriter::op_binary_elementwise_function(const TileOperand &dst,
270 BinaryFunction opcode,
271 const TileOperand &first,
272 const TileOperand &second)
Nikolaj Jensen5ff48022023-06-27 14:13:24 +0100273{
274 auto impl_dst = dst.create_impl_operand(_impl.get());
275 auto impl_first = first.create_impl_operand(_impl.get());
276 auto impl_second = second.create_impl_operand(_impl.get());
277
278 _impl->op_binary_elementwise_function(impl_dst, opcode, impl_first, impl_second);
279}
280
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100281void KernelWriter::op_ternary_elementwise_function(const TileOperand &dst,
282 TernaryFunction opcode,
283 const TileOperand &first,
284 const TileOperand &second,
285 const TileOperand &third)
Nikolaj Jensen5ff48022023-06-27 14:13:24 +0100286{
287 auto impl_dst = dst.create_impl_operand(_impl.get());
288 auto impl_first = first.create_impl_operand(_impl.get());
289 auto impl_second = second.create_impl_operand(_impl.get());
290 auto impl_third = third.create_impl_operand(_impl.get());
291
292 _impl->op_ternary_elementwise_function(impl_dst, opcode, impl_first, impl_second, impl_third);
293}
294
295void KernelWriter::op_if(const TileOperand &lhs, BinaryOp op, const TileOperand &rhs, const std::function<void()> &body)
296{
297 auto impl_lhs = lhs.create_impl_operand(_impl.get());
298 auto impl_rhs = rhs.create_impl_operand(_impl.get());
299
300 _impl->op_if_header(impl_lhs, op, impl_rhs);
301 _impl->compound_statement_begin();
302 body();
303 _impl->compound_statement_end();
304}
305
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100306void KernelWriter::op_else_if(const TileOperand &lhs,
307 BinaryOp op,
308 const TileOperand &rhs,
309 const std::function<void()> &body)
Nikolaj Jensen5ff48022023-06-27 14:13:24 +0100310{
311 auto impl_lhs = lhs.create_impl_operand(_impl.get());
312 auto impl_rhs = rhs.create_impl_operand(_impl.get());
313
314 _impl->op_else_if_header(impl_lhs, op, impl_rhs);
315 _impl->compound_statement_begin();
316 body();
317 _impl->compound_statement_end();
318}
319
320void KernelWriter::op_else(const std::function<void()> &body)
321{
322 _impl->op_else_header();
323 _impl->compound_statement_begin();
324 body();
325 _impl->compound_statement_end();
326}
327
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100328void KernelWriter::op_for_loop(const TileOperand &var_name,
329 BinaryOp cond_op,
330 const TileOperand &cond_value_name,
331 const TileOperand &update_var_name,
332 AssignmentOp update_op,
333 const TileOperand &update_value_name,
334 const std::function<void()> &body)
Nikolaj Jensen5ff48022023-06-27 14:13:24 +0100335{
336 auto impl_var_name = var_name.create_impl_operand(_impl.get());
337 auto impl_cond_value_name = cond_value_name.create_impl_operand(_impl.get());
Nikolaj Jensenfab6c212023-06-27 14:13:24 +0100338 auto impl_update_var_name = update_var_name.create_impl_operand(_impl.get());
Nikolaj Jensen5ff48022023-06-27 14:13:24 +0100339 auto impl_update_value_name = update_value_name.create_impl_operand(_impl.get());
340
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100341 _impl->op_for_loop_header(impl_var_name, cond_op, impl_cond_value_name, impl_update_var_name, update_op,
342 impl_update_value_name);
Nikolaj Jensen5ff48022023-06-27 14:13:24 +0100343 _impl->compound_statement_begin();
344 body();
345 _impl->compound_statement_end();
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100346}
347
348// =================================================================================================
349// Misc
350// =================================================================================================
351
Gunes Bayir91cb7332023-07-25 17:00:33 +0100352void KernelWriter::op_get_global_id(const TileOperand &dst, int32_t dim)
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100353{
354 _impl->op_get_global_id(prototype::Operand(dst.name()), dim);
355}
356
Nikolaj Jensen5ff48022023-06-27 14:13:24 +0100357void KernelWriter::op_return()
358{
359 _impl->op_return();
360}
361
Viet-Hoa Dobd4f6b92023-05-30 09:34:32 +0100362// =================================================================================================
363// Code generation
364// =================================================================================================
365
366std::string KernelWriter::generate_code()
367{
368 return prototype::generate_code(*_kernel->impl(), _kernel->name());
369}
370
371} // namespace ckw