StencilStream v3.0.0
SYCL-based Stencil Simulation Framework Targeting FPGAs
Loading...
Searching...
No Matches
Grid.hpp
Go to the documentation of this file.
1/*
2 * Copyright © 2020-2024 Jan-Oliver Opdenhövel, Paderborn Center for Parallel Computing, Paderborn
3 * University
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6 * associated documentation files (the “Software”), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
8 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in all copies or
12 * substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 */
20#pragma once
21#include "../AccessorSubscript.hpp"
22#include "../Concepts.hpp"
23
24namespace stencil {
25namespace monotile {
26
58template <class Cell, uindex_t word_size = 64> class Grid {
59 private:
60 static constexpr uindex_t word_length =
61 std::lcm(sizeof(Padded<Cell>), word_size) / sizeof(Padded<Cell>);
62 using IOWord = std::array<Padded<Cell>, word_length>;
63
64 public:
70 static constexpr uindex_t dimensions = 2;
71
79 Grid(uindex_t grid_width, uindex_t grid_height)
80 : tile_buffer(sycl::range<1>(n_cells_to_n_words(grid_width * grid_height, word_length))),
81 grid_width(grid_width), grid_height(grid_height) {}
82
89 Grid(sycl::range<2> range)
90 : tile_buffer(sycl::range<1>(n_cells_to_n_words(range[0] * range[1], word_length))),
91 grid_width(range[0]), grid_height(range[1]) {}
92
101 Grid(sycl::buffer<Cell, 2> buffer)
102 : tile_buffer(1), grid_width(buffer.get_range()[0]), grid_height(buffer.get_range()[1]) {
103 tile_buffer = sycl::range<1>(n_cells_to_n_words(grid_width * grid_height, word_length));
104 copy_from_buffer(buffer);
105 }
106
116 Grid(Grid const &other_grid)
117 : tile_buffer(other_grid.tile_buffer), grid_width(other_grid.grid_width),
118 grid_height(other_grid.grid_height) {}
119
123 Grid make_similar() const { return Grid(grid_width, grid_height); }
124
128 uindex_t get_grid_width() const { return grid_width; }
129
133 uindex_t get_grid_height() const { return grid_height; }
134
144 template <sycl::access::mode access_mode = sycl::access::mode::read_write> class GridAccessor {
145 private:
146 using accessor_t = sycl::host_accessor<IOWord, 1, access_mode>;
147
148 public:
153
158 : ac(grid.tile_buffer), grid_width(grid.get_grid_width()),
159 grid_height(grid.get_grid_height()) {}
160
165
174
181 Cell const &operator[](sycl::id<2> id)
182 requires(access_mode == sycl::access::mode::read)
183 {
184 uindex_t word_i = (id[0] * grid_height + id[1]) / word_length;
185 uindex_t cell_i = (id[0] * grid_height + id[1]) % word_length;
186 return ac[word_i][cell_i].value;
187 }
188
195 Cell &operator[](sycl::id<2> id)
196 requires(access_mode != sycl::access::mode::read)
197 {
198 uindex_t word_i = (id[0] * grid_height + id[1]) / word_length;
199 uindex_t cell_i = (id[0] * grid_height + id[1]) % word_length;
200 return ac[word_i][cell_i].value;
201 }
202
203 private:
204 accessor_t ac;
205 uindex_t grid_width, grid_height;
206 };
207
218 void copy_from_buffer(sycl::buffer<Cell, 2> input_buffer) {
219 uindex_t width = this->get_grid_width();
220 uindex_t height = this->get_grid_height();
221
222 if (input_buffer.get_range() != sycl::range<2>(width, height)) {
223 throw std::range_error("The target buffer has not the same size as the grid");
224 }
225
226 sycl::host_accessor in_ac(input_buffer, sycl::read_only);
228 for (uindex_t c = 0; c < width; c++) {
229 for (uindex_t r = 0; r < height; r++) {
230 tile_ac[c][r] = in_ac[c][r];
231 }
232 }
233 }
234
244 void copy_to_buffer(sycl::buffer<Cell, 2> output_buffer) {
245 uindex_t width = this->get_grid_width();
246 uindex_t height = this->get_grid_height();
247
248 if (output_buffer.get_range() != sycl::range<2>(width, height)) {
249 throw std::range_error("The target buffer has not the same size as the grid");
250 }
251
253 sycl::host_accessor out_ac(output_buffer, sycl::write_only);
254 for (uindex_t c = 0; c < width; c++) {
255 for (uindex_t r = 0; r < height; r++) {
256 out_ac[c][r] = in_ac[c][r];
257 }
258 }
259 }
260
277 template <typename in_pipe> sycl::event submit_read(sycl::queue queue) {
278 return queue.submit([&](sycl::handler &cgh) {
279 sycl::accessor ac(tile_buffer, cgh, sycl::read_only);
280 uindex_t n_cells = grid_width * grid_height;
281
282 cgh.single_task([=]() {
283 IOWord cache;
284
285 uindex_t word_i = 0;
286 uindex_t cell_i = word_length;
287 for (uindex_t i = 0; i < n_cells; i++) {
288 if (cell_i == word_length) {
289 cache = ac[word_i];
290 word_i++;
291 cell_i = 0;
292 }
293 in_pipe::write(cache[cell_i].value);
294 cell_i++;
295 }
296 });
297 });
298 }
299
317 template <typename out_pipe> sycl::event submit_write(sycl::queue queue) {
318 return queue.submit([&](sycl::handler &cgh) {
319 sycl::accessor ac(tile_buffer, cgh, sycl::write_only);
320 uindex_t n_cells = grid_width * grid_height;
321
322 cgh.single_task([=]() {
323 IOWord cache;
324
325 uindex_t word_i = 0;
326 uindex_t cell_i = 0;
327 for (uindex_t i = 0; i < n_cells; i++) {
328 cache[cell_i].value = out_pipe::read();
329 cell_i++;
330 if (cell_i == word_length || i == n_cells - 1) {
331 ac[word_i] = cache;
332 cell_i = 0;
333 word_i++;
334 }
335 }
336 });
337 });
338 }
339
340 private:
341 sycl::buffer<IOWord, 1> tile_buffer;
342 uindex_t grid_width, grid_height;
343};
344} // namespace monotile
345} // namespace stencil
T value
Definition Helpers.hpp:0
A helper class to support the double-subscript idiom for GridAccessors.
Definition AccessorSubscript.hpp:49
An accessor for the monotile grid.
Definition Grid.hpp:144
GridAccessor(Grid &grid)
Create a new accessor to the given grid.
Definition Grid.hpp:157
Cell const & operator[](sycl::id< 2 > id)
Access a cell of the grid.
Definition Grid.hpp:181
BaseSubscript operator[](uindex_t i)
Access/Dereference the first dimension.
Definition Grid.hpp:173
static constexpr uindex_t dimensions
The number of dimensions of the underlying grid.
Definition Grid.hpp:152
Cell & operator[](sycl::id< 2 > id)
Access a cell of the grid.
Definition Grid.hpp:195
AccessorSubscript< Cell, GridAccessor, access_mode > BaseSubscript
Shorthand for the used subscript type.
Definition Grid.hpp:164
A grid class for the monotile architecture.
Definition Grid.hpp:58
sycl::event submit_read(sycl::queue queue)
Submit a kernel that sends the contents of the grid into a pipe.
Definition Grid.hpp:277
static constexpr uindex_t dimensions
The number of dimensions of the grid.
Definition Grid.hpp:70
Grid(sycl::range< 2 > range)
Create a new, uninitialized grid with the given dimensions.
Definition Grid.hpp:89
void copy_from_buffer(sycl::buffer< Cell, 2 > input_buffer)
Copy the contents of the SYCL buffer into the grid.
Definition Grid.hpp:218
Grid make_similar() const
Create an new, uninitialized grid with the same size as the current one.
Definition Grid.hpp:123
Grid(sycl::buffer< Cell, 2 > buffer)
Create a new grid with the same size and contents as the given SYCL buffer.
Definition Grid.hpp:101
uindex_t get_grid_width() const
Return the width, or number of columns, of the grid.
Definition Grid.hpp:128
Grid(uindex_t grid_width, uindex_t grid_height)
Create a new, uninitialized grid with the given dimensions.
Definition Grid.hpp:79
uindex_t get_grid_height() const
Return the height, or number of rows, of the grid.
Definition Grid.hpp:133
void copy_to_buffer(sycl::buffer< Cell, 2 > output_buffer)
Copy the contents of the grid into the SYCL buffer.
Definition Grid.hpp:244
Grid(Grid const &other_grid)
Create a new reference to the given grid.
Definition Grid.hpp:116
sycl::event submit_write(sycl::queue queue)
Submit a kernel that receives cells from the pipe and writes them to the grid.
Definition Grid.hpp:317
Definition AccessorSubscript.hpp:24
BOOST_PP_CAT(BOOST_PP_CAT(uint, STENCIL_INDEX_WIDTH), _t) uindex_t
An unsigned integer of configurable width.
Definition Index.hpp:42
constexpr uindex_t n_cells_to_n_words(uindex_t n_cells, uindex_t word_length)
Compute the number of words necessary to store a given number of cells.
Definition Helpers.hpp:34
A container with padding to the next power of two.
Definition Helpers.hpp:45