Brick Library 0.1
Performance-portable stencil datalayout & codegen
bricksetup.h
Go to the documentation of this file.
1
6#ifndef BRICK_SETUP_H
7#define BRICK_SETUP_H
8
9#include <vector>
10#include <typeinfo>
11#include <initializer_list>
12#include <algorithm>
13#include "brick.h"
14
15struct RunningTag {
16};
17struct StopTag {
18};
19
20template<unsigned select>
21struct TagSelect {
22 static constexpr RunningTag value = RunningTag();
23};
24
25template<>
26struct TagSelect<0> {
27 static constexpr StopTag value = StopTag();
28};
29
30template<unsigned dims, unsigned d>
31inline void
32init_fill(const std::vector<long> &stride, unsigned *adjlist, unsigned *grid_ptr, unsigned *low, unsigned *high,
33 RunningTag t) {
34 unsigned str = static_power<3, d - 1>::value;
35 init_fill<dims, d - 1>(stride, adjlist, grid_ptr - stride[d - 1], low, high, TagSelect<d - 1>::value);
36 init_fill<dims, d - 1>(stride, adjlist + str, grid_ptr, low, high, TagSelect<d - 1>::value);
37 init_fill<dims, d - 1>(stride, adjlist + str * 2, grid_ptr + stride[d - 1], low, high, TagSelect<d - 1>::value);
38}
39
40template<unsigned dims, unsigned d>
41inline void
42init_fill(const std::vector<long> &stride, unsigned *adjlist, unsigned *grid_ptr, unsigned *low, unsigned *high,
43 StopTag t) {
44 if (grid_ptr >= low && grid_ptr < high)
45 *adjlist = *grid_ptr;
46 else
47 *adjlist = 0;
48}
49
50template<unsigned dims, unsigned d>
51inline void
52init_iter(const std::vector<long> &dimlist, const std::vector<long> &stride, BrickInfo<dims> &bInfo, unsigned *grid_ptr,
53 unsigned *low, unsigned *high, RunningTag t) {
54 if (dims == d) {
55#pragma omp parallel for
56 for (long s = 0; s < dimlist[dims - d]; ++s)
57 init_iter<dims, d - 1>(dimlist, stride, bInfo, grid_ptr + s * stride[dims - d], low, high,
59 } else {
60 for (long s = 0; s < dimlist[dims - d]; ++s)
61 init_iter<dims, d - 1>(dimlist, stride, bInfo, grid_ptr + s * stride[dims - d], low, high,
63 }
64}
65
66template<unsigned dims, unsigned d>
67inline void
68init_iter(const std::vector<long> &dimlist, const std::vector<long> &stride, BrickInfo<dims> &bInfo, unsigned *grid_ptr,
69 unsigned *low, unsigned *high, StopTag t) {
70 init_fill<dims, dims>(stride, bInfo.adj[*grid_ptr], grid_ptr, low, high, RunningTag());
71}
72
73template<unsigned dims>
74BrickInfo<dims> init_grid(unsigned *&grid_ptr, const std::vector<long> &dimlist) {
75 long size = 1;
76 std::vector<long> stride;
77 for (const auto a: dimlist) {
78 stride.push_back(size);
79 size *= a;
80 }
81 grid_ptr = (unsigned *) malloc(size * sizeof(unsigned));
82 for (unsigned pos = 0; pos < size; ++pos)
83 grid_ptr[pos] = pos;
84
85 BrickInfo<dims> bInfo(size);
86
87 init_iter<dims, dims>(dimlist, stride, bInfo, grid_ptr, grid_ptr, grid_ptr + size, RunningTag());
88
89 return bInfo;
90}
91
92template<unsigned dims, unsigned d, typename F, typename A>
93inline void fill(const std::vector<long> &tile, const std::vector<long> &stride, bElem *arr, A a, F f, RunningTag t) {
94 for (long s = 0; s < tile[d - 1]; ++s)
95 fill<dims, d - 1>(tile, stride, arr + s * stride[d - 1], a[s], f, TagSelect<d - 1>::value);
96}
97
98template<unsigned dims, unsigned d, typename F, typename A>
99inline void fill(const std::vector<long> &tile, const std::vector<long> &stride, bElem *arr, A &a, F f, StopTag t) {
100 f(a, arr);
101}
102
103template<unsigned dims, unsigned d, typename T, typename F>
104inline void iter(const std::vector<long> &dimlist, const std::vector<long> &tile,
105 const std::vector<long> &strideA, const std::vector<long> &strideB,
106 const std::vector<long> &padding, const std::vector<long> &ghost,
107 T &brick, bElem *arr, unsigned *grid_ptr, F f, RunningTag t) {
108 constexpr unsigned dimp = d - 1;
109 if (dims == d) {
110#pragma omp parallel for
111 for (long s = ghost[dimp] / tile[dimp]; s < (dimlist[dimp] + ghost[dimp]) / tile[dimp]; ++s)
112 iter<dims, d - 1>(dimlist, tile, strideA, strideB, padding, ghost, brick,
113 arr + (padding[dimp] + s * tile[dimp]) * strideA[dimp],
114 grid_ptr + s * strideB[dimp], f, TagSelect<dimp>::value);
115 } else {
116 for (long s = ghost[dimp] / tile[dimp]; s < (dimlist[dimp] + ghost[dimp]) / tile[dimp]; ++s)
117 iter<dims, d - 1>(dimlist, tile, strideA, strideB, padding, ghost, brick,
118 arr + (padding[dimp] + s * tile[dimp]) * strideA[dimp],
119 grid_ptr + s * strideB[dimp], f, TagSelect<dimp>::value);
120 }
121}
122
123template<unsigned dims, unsigned d, typename T, typename F>
124inline void iter(const std::vector<long> &dimlist, const std::vector<long> &tile,
125 const std::vector<long> &strideA, const std::vector<long> &strideB,
126 const std::vector<long> &padding, const std::vector<long> &ghost,
127 T &brick, bElem *arr, unsigned *grid_ptr, F f, StopTag t) {
128 fill<dims, dims>(tile, strideA, arr, brick[*grid_ptr], f, RunningTag());
129}
130
131/*
132 * Iterate elements side by side in brick and arrays.
133 *
134 * dimlist: the internal regions, iterated
135 * padding: the padding necessary for arrays, skipped
136 * ghost: the padding for both, skipped
137 * f: F (&bElem, *bElem) -> void
138 */
139template<unsigned dims, typename F, typename T, unsigned ... BDims>
140inline void
141iter_grid(const std::vector<long> &dimlist, const std::vector<long> &padding, const std::vector<long> &ghost,
142 bElem *arr, unsigned *grid_ptr, Brick<Dim<BDims...>, T> &brick, F f) {
143 std::vector<long> strideA;
144 std::vector<long> strideB;
145 std::vector<long> tile = {BDims...};
146 // Arrays are contiguous first
147 std::reverse(tile.begin(), tile.end());
148
149 long sizeA = 1;
150 long sizeB = 1;
151 for (long a = 0; a < dimlist.size(); ++a) {
152 strideA.push_back(sizeA);
153 strideB.push_back(sizeB);
154 sizeA *= (dimlist[a] + 2 * (padding[a] + ghost[a]));
155 sizeB *= ((dimlist[a] + 2 * ghost[a]) / tile[a]);
156 }
157
158 iter<dims, dims>(dimlist, tile, strideA, strideB, padding, ghost, brick, arr, grid_ptr, f, RunningTag());
159}
160
172template<unsigned dims, typename T>
173inline void
174copyToBrick(const std::vector<long> &dimlist, const std::vector<long> &padding, const std::vector<long> &ghost,
175 bElem *arr, unsigned *grid_ptr, T &brick) {
176 auto f = [](bElem &brick, bElem *arr) -> void {
177 brick = *arr;
178 };
179
180 iter_grid<dims>(dimlist, padding, ghost, arr, grid_ptr, brick, f);
181}
182
194template<unsigned dims, typename T>
195inline void copyToBrick(const std::vector<long> &dimlist, bElem *arr, unsigned *grid_ptr, T &brick) {
196 std::vector<long> padding(dimlist.size(), 0);
197 std::vector<long> ghost(dimlist.size(), 0);
198
199 copyToBrick<dims>(dimlist, padding, ghost, arr, grid_ptr, brick);
200}
201
213template<unsigned dims, typename T>
214inline void copyFromBrick(const std::vector<long> &dimlist, const std::vector<long> &padding,
215 const std::vector<long> &ghost, bElem *arr, unsigned *grid_ptr, T &brick) {
216 auto f = [](bElem &brick, bElem *arr) -> void {
217 *arr = brick;
218 };
219
220 iter_grid<dims>(dimlist, padding, ghost, arr, grid_ptr, brick, f);
221}
222
223#endif
Main header for bricks.
void copyToBrick(const std::vector< long > &dimlist, const std::vector< long > &padding, const std::vector< long > &ghost, bElem *arr, unsigned *grid_ptr, T &brick)
Copy values from an array to bricks.
Definition: bricksetup.h:174
void init_fill(const std::vector< long > &stride, unsigned *adjlist, unsigned *grid_ptr, unsigned *low, unsigned *high, RunningTag t)
Definition: bricksetup.h:32
void iter(const std::vector< long > &dimlist, const std::vector< long > &tile, const std::vector< long > &strideA, const std::vector< long > &strideB, const std::vector< long > &padding, const std::vector< long > &ghost, T &brick, bElem *arr, unsigned *grid_ptr, F f, RunningTag t)
Definition: bricksetup.h:104
void iter_grid(const std::vector< long > &dimlist, const std::vector< long > &padding, const std::vector< long > &ghost, bElem *arr, unsigned *grid_ptr, Brick< Dim< BDims... >, T > &brick, F f)
Definition: bricksetup.h:141
void fill(const std::vector< long > &tile, const std::vector< long > &stride, bElem *arr, A a, F f, RunningTag t)
Definition: bricksetup.h:93
BrickInfo< dims > init_grid(unsigned *&grid_ptr, const std::vector< long > &dimlist)
Definition: bricksetup.h:74
void copyFromBrick(const std::vector< long > &dimlist, const std::vector< long > &padding, const std::vector< long > &ghost, bElem *arr, unsigned *grid_ptr, T &brick)
Copy values from bricks to an array.
Definition: bricksetup.h:214
void init_iter(const std::vector< long > &dimlist, const std::vector< long > &stride, BrickInfo< dims > &bInfo, unsigned *grid_ptr, unsigned *low, unsigned *high, RunningTag t)
Definition: bricksetup.h:52
Metadata related to bricks.
Definition: brick.h:97
adjlist adj
Adjacency list.
Definition: brick.h:101
Generic base template, see Brick< Dim< BDims... >, Dim< Folds... > >
Definition: brick.h:340
Empty template to specify an n-D list.
Definition: brick.h:131
Definition: bricksetup.h:15
Definition: bricksetup.h:17
Definition: bricksetup.h:21
static constexpr RunningTag value
Definition: bricksetup.h:22
Compute Statically compute exponentials.
Definition: brick.h:35
#define bElem
Basic datatype for all brick elements.
Definition: vecscatter.h:13
#define brick(...)
Inject stencil code for brick datalayout.
Definition: vecscatter.h:62
#define tile(...)
Inject stencil code for tiling here.
Definition: vecscatter.h:27