@@ -65,45 +65,62 @@ bool is_in_box(const IndexType i, const IndexType bound)
6565 * Generates matrix data for a 2D stencil matrix. If restricted is set to true,
6666 * creates a 5-pt stencil, if it is false creates a 9-pt stencil.
6767 *
68- * If
69- * strong_scaling is set to true, creates the same problem size independent of
70- * the number of ranks, if it false the problem size grows with the number of
71- * ranks.
68+ * If `dim != [1 1]` then the matrix data is a subset of a larger matrix.
69+ * The total matrix is a discretization of `[0, dims[0]] x [0, dims[1]]`, and
70+ * each box is square. The position of the box defines the subset of the matrix.
71+ * The degrees of freedom are ordered box-wise and the boxes themselves are
72+ * ordered lexicographical. This means that the indices are with respect to the
73+ * larger matrix, i.e. they might not start with 0.
74+ *
75+ * @param dims The number of boxes in each dimension.
76+ * @param positions The position of this box with respect to each dimension.
77+ * @param target_local_size The desired size of the boxes. The actual size can
78+ * deviate from this to accommodate the square size of
79+ * the boxes.
80+ * @param restricted If true, a 5-pt stencil is used, else a 9-pt stencil.
81+ *
82+ * @return matrix data of a box using either 5-pt or 9-pt stencil.
7283 */
7384template <typename ValueType, typename IndexType>
7485gko::matrix_data<ValueType, IndexType> generate_2d_stencil_box (
75- std::array<int , 2 > dims, std::array<int , 2 > position ,
86+ std::array<int , 2 > dims, std::array<int , 2 > positions ,
7687 const gko::size_type target_local_size, bool restricted)
7788{
7889 auto num_boxes =
7990 std::accumulate (dims.begin (), dims.end (), 1 , std::multiplies<>{});
8091
81- const auto dp =
92+ const auto discretization_points =
8293 static_cast <IndexType>(closest_nth_root (target_local_size, 2 ));
83- const auto local_size = static_cast <gko::size_type>(dp * dp);
94+ const auto local_size = static_cast <gko::size_type>(discretization_points *
95+ discretization_points);
8496 const auto global_size = local_size * num_boxes;
8597 auto A_data = gko::matrix_data<ValueType, IndexType>(
8698 gko::dim<2 >{static_cast <gko::size_type>(global_size),
8799 static_cast <gko::size_type>(global_size)});
88100
89- auto global_offset = [&](const int px , const int py ) {
90- return static_cast <int >(local_size) * px +
91- static_cast <int >(local_size) * dims[0 ] * py ;
101+ auto global_offset = [&](const int position_x , const int position_y ) {
102+ return static_cast <int >(local_size) * position_x +
103+ static_cast <int >(local_size) * dims[0 ] * position_y ;
92104 };
93105
94- auto target_coords = [&](const IndexType i, const int coord) {
95- return is_in_box (i, dp) ? coord : i < 0 ? coord - 1 : coord + 1 ;
106+ auto target_position = [&](const IndexType i, const int position) {
107+ return is_in_box (i, discretization_points)
108+ ? position
109+ : (i < 0 ? position - 1 : position + 1 );
96110 };
97111
98112 auto target_local_idx = [&](const IndexType i) {
99- return is_in_box (i, dp) ? i : i < 0 ? dp + i : dp - i;
113+ return is_in_box (i, discretization_points)
114+ ? i
115+ : (i < 0 ? discretization_points + i
116+ : discretization_points - i);
100117 };
101118
102119 auto flat_idx = [&](const IndexType ix, IndexType iy) {
103- auto tcx = target_coords (ix, position [0 ]);
104- auto tcy = target_coords (iy, position [1 ]);
105- if (is_in_box (tcx , dims[0 ]) && is_in_box (tcy , dims[1 ])) {
106- return global_offset (tcx, tcy ) + target_local_idx (ix) +
120+ auto tpx = target_position (ix, positions [0 ]);
121+ auto tpy = target_position (iy, positions [1 ]);
122+ if (is_in_box (tpx , dims[0 ]) && is_in_box (tpy , dims[1 ])) {
123+ return global_offset (tpx, tpy ) + target_local_idx (ix) +
107124 target_local_idx (iy);
108125 } else {
109126 return static_cast <IndexType>(-1 );
@@ -127,8 +144,8 @@ gko::matrix_data<ValueType, IndexType> generate_2d_stencil_box(
127144 };
128145 const auto diag_value = static_cast <ValueType>(nnz_in_row () - 1 );
129146
130- for (IndexType i = 0 ; i < dp ; ++i) {
131- for (IndexType j = 0 ; j < dp ; ++j) {
147+ for (IndexType i = 0 ; i < discretization_points ; ++i) {
148+ for (IndexType j = 0 ; j < discretization_points ; ++j) {
132149 auto row = flat_idx (j, i);
133150 for (IndexType d_i : {-1 , 0 , 1 }) {
134151 for (IndexType d_j : {-1 , 0 , 1 }) {
@@ -156,50 +173,72 @@ gko::matrix_data<ValueType, IndexType> generate_2d_stencil_box(
156173
157174/* *
158175 * Generates matrix data for a 3D stencil matrix. If restricted is set to true,
159- * creates a 7-pt stencil, if it is false creates a 27-pt stencil. If
160- * strong_scaling is set to true, creates the same problem size independent of
161- * the number of ranks, if it false the problem size grows with the number of
162- * ranks.
176+ * creates a 7-pt stencil, if it is false creates a 27-pt stencil.
177+ *
178+ * If `dim != [1 1 1]` then the matrix data is a subset of a larger matrix.
179+ * The total matrix is a discretization of `[0, dims[0]] x [0, dims[1]] x [0,
180+ * dims[2]]`, and each box is a cube. The position of the box defines the subset
181+ * of the matrix. The degrees of freedom are ordered box-wise and the boxes
182+ * themselves are ordered lexicographical. This means that the indices are with
183+ * respect to the larger matrix, i.e. they might not start with 0.
184+ *
185+ * @param dims The number of boxes in each dimension.
186+ * @param positions The position of this box with respect to each dimension.
187+ * @param target_local_size The desired size of the boxes. The actual size can
188+ * deviate from this to accommodate the uniform size
189+ * of the boxes.
190+ * @param restricted If true, a 7-pt stencil is used, else a 27-pt stencil.
191+ *
192+ * @return matrix data of a box using either 7-pt or 27-pt stencil.
163193 */
164194template <typename ValueType, typename IndexType>
165195gko::matrix_data<ValueType, IndexType> generate_3d_stencil_box (
166- std::array<int , 3 > dims, std::array<int , 3 > position ,
196+ std::array<int , 3 > dims, std::array<int , 3 > positions ,
167197 const gko::size_type target_local_size, bool restricted)
168198{
169199 auto num_boxes =
170200 std::accumulate (dims.begin (), dims.end (), 1 , std::multiplies<>{});
171201
172- const auto dp =
202+ const auto discretization_points =
173203 static_cast <IndexType>(closest_nth_root (target_local_size, 3 ));
174- const auto local_size = static_cast <gko::size_type>(dp * dp * dp);
204+ const auto local_size = static_cast <gko::size_type>(
205+ discretization_points * discretization_points * discretization_points);
175206 const auto global_size = local_size * num_boxes;
176207 auto A_data = gko::matrix_data<ValueType, IndexType>(
177208 gko::dim<2 >{static_cast <gko::size_type>(global_size),
178209 static_cast <gko::size_type>(global_size)});
179210
180- auto global_offset = [&](const int cx, const int cy, const int cz) {
181- return cx * static_cast <int >(local_size) +
182- cy * static_cast <int >(local_size) * dims[0 ] +
183- cz * static_cast <int >(local_size) * dims[0 ] * dims[1 ];
211+ auto global_offset = [&](const int position_x, const int position_y,
212+ const int position_z) {
213+ return position_x * static_cast <int >(local_size) +
214+ position_y * static_cast <int >(local_size) * dims[0 ] +
215+ position_z * static_cast <int >(local_size) * dims[0 ] * dims[1 ];
184216 };
185217
186- auto target_coords = [&](const IndexType i, const int coord) {
187- return is_in_box (i, dp) ? coord : i < 0 ? coord - 1 : coord + 1 ;
218+ auto target_position = [&](const IndexType i, const int position) {
219+ return is_in_box (i, discretization_points)
220+ ? position
221+ : (i < 0 ? position - 1 : position + 1 );
188222 };
189223
190224 auto target_local_idx = [&](const IndexType i) {
191- return is_in_box (i, dp) ? i : i < 0 ? dp + i : dp - i;
225+ return is_in_box (i, discretization_points)
226+ ? i
227+ : (i < 0 ? discretization_points + i
228+ : discretization_points - i);
192229 };
193230
194231 auto flat_idx = [&](const IndexType ix, const IndexType iy,
195232 const IndexType iz) {
196- auto tcx = target_coords (ix, position[0 ]);
197- auto tcy = target_coords (iy, position[1 ]);
198- auto tcz = target_coords (iz, position[2 ]);
199- if (is_in_box (tcx, dims[0 ]) && is_in_box (tcy, dims[1 ]) &&
200- is_in_box (tcz, dims[2 ])) {
201- return global_offset (tcx, tcy, tcz) + target_local_idx (ix) +
202- target_local_idx (iy) * dp + target_local_idx (iz) * dp * dp;
233+ auto tpx = target_position (ix, positions[0 ]);
234+ auto tpy = target_position (iy, positions[1 ]);
235+ auto tpz = target_position (iz, positions[2 ]);
236+ if (is_in_box (tpx, dims[0 ]) && is_in_box (tpy, dims[1 ]) &&
237+ is_in_box (tpz, dims[2 ])) {
238+ return global_offset (tpx, tpy, tpz) + target_local_idx (ix) +
239+ target_local_idx (iy) * discretization_points +
240+ target_local_idx (iz) * discretization_points *
241+ discretization_points;
203242 } else {
204243 return static_cast <IndexType>(-1 );
205244 }
@@ -227,9 +266,9 @@ gko::matrix_data<ValueType, IndexType> generate_3d_stencil_box(
227266 };
228267 const auto diag_value = static_cast <ValueType>(nnz_in_row () - 1 );
229268
230- for (IndexType i = 0 ; i < dp ; ++i) {
231- for (IndexType j = 0 ; j < dp ; ++j) {
232- for (IndexType k = 0 ; k < dp ; ++k) {
269+ for (IndexType i = 0 ; i < discretization_points ; ++i) {
270+ for (IndexType j = 0 ; j < discretization_points ; ++j) {
271+ for (IndexType k = 0 ; k < discretization_points ; ++k) {
233272 auto row = flat_idx (k, j, i);
234273 for (IndexType d_i : {-1 , 0 , 1 }) {
235274 for (IndexType d_j : {-1 , 0 , 1 }) {
@@ -258,6 +297,17 @@ gko::matrix_data<ValueType, IndexType> generate_3d_stencil_box(
258297}
259298
260299
300+ /* *
301+ * Generates matrix data for the requested stencil.
302+ *
303+ * @see generate_2d_stencil_box, generate_3d_stencil_box
304+ *
305+ * @param stencil_name The name of the stencil.
306+ * @param target_local_size The desired size of the matrix. The actual size can
307+ * deviate from this to accommodate the uniform size
308+ * of the discretization.
309+ * @return matrix data using the requested stencil.
310+ */
261311template <typename ValueType, typename IndexType>
262312gko::matrix_data<ValueType, IndexType> generate_stencil (
263313 std::string stencil_name, const gko::size_type target_local_size)
@@ -284,6 +334,12 @@ gko::matrix_data<ValueType, IndexType> generate_stencil(
284334#if GINKGO_BUILD_MPI
285335
286336
337+ /* *
338+ * Generates matrix data for a given 2D stencil, where the position of this
339+ * block is given by it's MPI rank.
340+ *
341+ * @see generate_2d_stencil_box
342+ */
287343template <typename ValueType, typename IndexType>
288344gko::matrix_data<ValueType, IndexType> generate_2d_stencil (
289345 gko::experimental::mpi::communicator comm,
@@ -301,6 +357,12 @@ gko::matrix_data<ValueType, IndexType> generate_2d_stencil(
301357}
302358
303359
360+ /* *
361+ * Generates matrix data for a given 23 stencil, where the position of this
362+ * block is given by it's MPI rank.
363+ *
364+ * @see generate_3d_stencil_box
365+ */
304366template <typename ValueType, typename IndexType>
305367gko::matrix_data<ValueType, IndexType> generate_3d_stencil (
306368 gko::experimental::mpi::communicator comm,
@@ -321,10 +383,12 @@ gko::matrix_data<ValueType, IndexType> generate_3d_stencil(
321383
322384/* *
323385 * Generates matrix data for a 2D stencil matrix. If restricted is set to true,
324- * creates a 5-pt stencil, if it is false creates a 9-pt stencil. If
325- * strong_scaling is set to true, creates the same problemsize independent of
326- * the number of ranks, if it false the problem size grows with the number of
327- * ranks.
386+ * creates a 5-pt stencil, if it is false creates a 9-pt stencil.
387+ *
388+ * The degrees of freedom are ordered such that each MPI rank has at most two
389+ * neighbors.
390+ *
391+ * @see generate_2d_stencil_box
328392 */
329393template <typename ValueType, typename IndexType>
330394gko::matrix_data<ValueType, IndexType> generate_2d_stencil_with_optimal_comm (
@@ -385,10 +449,12 @@ gko::matrix_data<ValueType, IndexType> generate_2d_stencil_with_optimal_comm(
385449
386450/* *
387451 * Generates matrix data for a 3D stencil matrix. If restricted is set to true,
388- * creates a 7-pt stencil, if it is false creates a 27-pt stencil. If
389- * strong_scaling is set to true, creates the same problemsize independent of
390- * the number of ranks, if it false the problem size grows with the number of
391- * ranks.
452+ * creates a 7-pt stencil, if it is false creates a 27-pt stencil.
453+ *
454+ * The degrees of freedom are ordered such that each MPI rank has at most two
455+ * neighbors.
456+ *
457+ * @see generate_3d_stencil_box
392458 */
393459template <typename ValueType, typename IndexType>
394460gko::matrix_data<ValueType, IndexType> generate_3d_stencil_with_optimal_comm (
@@ -457,6 +523,13 @@ gko::matrix_data<ValueType, IndexType> generate_3d_stencil_with_optimal_comm(
457523}
458524
459525
526+ /* *
527+ * Generates matrix data for the requested stencil.
528+ *
529+ * @copydoc generate_stencil(const gko::size_type, bool)
530+ *
531+ * @param comm The MPI communicator to determine the rank.
532+ */
460533template <typename ValueType, typename IndexType>
461534gko::matrix_data<ValueType, IndexType> generate_stencil (
462535 std::string stencil_name, gko::experimental::mpi::communicator comm,
0 commit comments