StencilStream v3.0.0
SYCL-based Stencil Simulation Framework Targeting FPGAs
Loading...
Searching...
No Matches
StencilUpdate.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
6 * of this software and associated documentation files (the “Software”), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23#pragma once
24#include "../Concepts.hpp"
25#include "../Stencil.hpp"
26#include "Grid.hpp"
27#include <chrono>
28
29namespace stencil {
30namespace cpu {
31
40template <concepts::TransitionFunction F> class StencilUpdate {
41 private:
42 using Cell = F::Cell;
43
44 public:
47
51 struct Params {
58
62 Cell halo_value = Cell();
63
71
76
80 sycl::device device = sycl::device();
81
91 bool blocking = false;
92 };
93
97 StencilUpdate(Params params) : params(params), n_processed_cells(0), walltime(0.0) {}
98
110 GridImpl swap_grid_a = source_grid.make_similar();
111 GridImpl swap_grid_b = source_grid.make_similar();
112 GridImpl *pass_source = &source_grid;
113 GridImpl *pass_target = &swap_grid_b;
114
115 sycl::queue queue(params.device);
116 auto walltime_start = std::chrono::high_resolution_clock::now();
117
118 for (uindex_t i_iter = 0; i_iter < params.n_iterations; i_iter++) {
119 for (uindex_t i_subiter = 0; i_subiter < F::n_subiterations; i_subiter++) {
120 run_iter(queue, pass_source, pass_target, params.iteration_offset + i_iter,
121 i_subiter);
122 if (i_iter == 0 && i_subiter == 0) {
123 pass_source = &swap_grid_b;
124 pass_target = &swap_grid_a;
125 } else {
126 std::swap(pass_source, pass_target);
127 }
128 }
129 }
130
131 if (params.blocking) {
132 queue.wait();
133 }
134
135 auto walltime_end = std::chrono::high_resolution_clock::now();
136 std::chrono::duration<double> walltime = walltime_end - walltime_start;
137 this->walltime += walltime.count();
138 n_processed_cells +=
139 params.n_iterations * source_grid.get_grid_width() * source_grid.get_grid_height();
140
141 return *pass_source;
142 }
143
149 Params &get_params() { return params; }
150
158 uindex_t get_n_processed_cells() const { return n_processed_cells; }
159
166 double get_walltime() const { return walltime; }
167
168 private:
185 void run_iter(sycl::queue queue, GridImpl *pass_source, GridImpl *pass_target, uindex_t i_iter,
186 uindex_t i_subiter) {
187 using TDV = typename F::TimeDependentValue;
188 using StencilImpl = Stencil<Cell, F::stencil_radius, TDV>;
189
190 queue.submit([&](sycl::handler &cgh) {
191 sycl::accessor source_ac(pass_source->get_buffer(), cgh, sycl::read_only);
192 sycl::accessor target_ac(pass_target->get_buffer(), cgh, sycl::write_only);
193 index_t grid_width = source_ac.get_range()[0];
194 index_t grid_height = source_ac.get_range()[1];
195 index_t stencil_radius = index_t(F::stencil_radius);
196 Cell halo_value = params.halo_value;
197 F transition_function = params.transition_function;
198 TDV tdv = transition_function.get_time_dependent_value(i_iter);
199
200 auto kernel = [=](sycl::id<2> id) {
201 StencilImpl stencil(ID(id[0], id[1]), UID(grid_width, grid_height), i_iter,
202 i_subiter, tdv);
203
204 for (index_t rel_c = -stencil_radius; rel_c <= stencil_radius; rel_c++) {
205 for (index_t rel_r = -stencil_radius; rel_r <= stencil_radius; rel_r++) {
206 index_t c = rel_c + id[0];
207 index_t r = rel_r + id[1];
208 bool within_grid = c >= 0 && r >= 0 && c < grid_width && r < grid_height;
209 stencil[ID(rel_c, rel_r)] = (within_grid) ? source_ac[c][r] : halo_value;
210 }
211 }
212
213 target_ac[id] = transition_function(stencil);
214 };
215
216 cgh.parallel_for(source_ac.get_range(), kernel);
217 });
218 }
219
220 Params params;
221 uindex_t n_processed_cells;
222 double walltime;
223};
224} // namespace cpu
225} // namespace stencil
The stencil buffer.
Definition Stencil.hpp:48
A grid class for the CPU backend.
Definition Grid.hpp:51
Grid make_similar() const
Create an new, uninitialized grid with the same size as the current one.
Definition Grid.hpp:169
uindex_t get_grid_height() const
Return the height, or number of rows, of the grid.
Definition Grid.hpp:164
uindex_t get_grid_width() const
Return the width, or number of columns, of the grid.
Definition Grid.hpp:159
A grid updater that applies an iterative stencil code to a grid.
Definition StencilUpdate.hpp:40
StencilUpdate(Params params)
Create a new stencil updater object.
Definition StencilUpdate.hpp:97
uindex_t get_n_processed_cells() const
Return the accumulated total number of cells processed by this updater.
Definition StencilUpdate.hpp:158
Grid< Cell > GridImpl
Shorthand for the used and supported grid type.
Definition StencilUpdate.hpp:46
Params & get_params()
Return a reference to the parameters.
Definition StencilUpdate.hpp:149
double get_walltime() const
Return the accumulated runtime of the updater, measured from the host side.
Definition StencilUpdate.hpp:166
GridImpl operator()(GridImpl &source_grid)
Compute a new grid based on the source grid, using the configured transition function.
Definition StencilUpdate.hpp:109
Definition AccessorSubscript.hpp:24
GenericID< uindex_t > UID
An unsigned, two-dimensional index.
Definition GenericID.hpp:80
BOOST_PP_CAT(BOOST_PP_CAT(uint, STENCIL_INDEX_WIDTH), _t) uindex_t
An unsigned integer of configurable width.
Definition Index.hpp:42
GenericID< index_t > ID
A signed, two-dimensional index.
Definition GenericID.hpp:75
BOOST_PP_CAT(BOOST_PP_CAT(int, STENCIL_INDEX_WIDTH), _t) index_t
A signed integer of configurable width.
Definition Index.hpp:56
Parameters for the stencil updater.
Definition StencilUpdate.hpp:51
uindex_t iteration_offset
The iteration index offset.
Definition StencilUpdate.hpp:70
Cell halo_value
The cell value to present for cells outside of the grid.
Definition StencilUpdate.hpp:62
bool blocking
Should the stencil updater block until completion, or return immediately after all kernels have been ...
Definition StencilUpdate.hpp:91
uindex_t n_iterations
The number of iterations to compute.
Definition StencilUpdate.hpp:75
sycl::device device
The device to use for computations.
Definition StencilUpdate.hpp:80
F transition_function
An instance of the transition function type.
Definition StencilUpdate.hpp:57