ViennaCL - The Vienna Computing Library: examples/tutorial/bandwidth-reduction.cpp Source File

ViennaCL - The Vienna Computing Library 1.7.1 Free open-source GPU-accelerated linear algebra and solver library. |

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bandwidth-reduction.cpp
Go to the documentation of this file.
1 /* =========================================================================
2 Copyright (c) 2010-2016, Institute for Microelectronics,
3 Institute for Analysis and Scientific Computing,
4 TU Wien.
5 Portions of this software are copyright by UChicago Argonne, LLC.
6
7 -----------------
8 ViennaCL - The Vienna Computing Library
9 -----------------
10
11 Project Head: Karl Rupp rupp@iue.tuwien.ac.at
12
13 (A list of authors and contributors can be found in the PDF manual)
14
15 License: MIT (X11), see file LICENSE in the base directory
16 ============================================================================= */
17
27 #include <iostream>
28 #include <fstream>
29 #include <string>
30 #include <algorithm>
31 #include <map>
32 #include <vector>
33 #include <deque>
34 #include <cmath>
35
36 #include "viennacl/misc/bandwidth_reduction.hpp"
37
38
49 inline std::vector< std::map<int, double> > reorder_matrix(std::vector< std::map<int, double> > const & matrix, std::vector<int> const & r)
50 {
51 std::vector< std::map<int, double> > matrix2(r.size());
52
53 for (std::size_t i = 0; i < r.size(); i++)
54 for (std::map<int, double>::const_iterator it = matrix[i].begin(); it != matrix[i].end(); it++)
55 matrix2[static_cast<std::size_t>(r[i])][r[static_cast<std::size_t>(it->first)]] = it->second;
56
57 return matrix2;
58 }
59
64 inline int calc_bw(std::vector< std::map<int, double> > const & matrix)
65 {
66 int bw = 0;
67
68 for (std::size_t i = 0; i < matrix.size(); i++)
69 {
70 int min_index = static_cast<int>(matrix.size());
71 int max_index = 0;
72 for (std::map<int, double>::const_iterator it = matrix[i].begin(); it != matrix[i].end(); it++)
73 {
74 if (it->first > max_index)
75 max_index = it->first;
76 if (it->first < min_index)
77 min_index = it->first;
78 }
79
80 if (max_index > min_index) //row isn't empty
81 bw = std::max(bw, max_index - min_index);
82 }
83
84 return bw;
85 }
86
91 template<typename IndexT>
92 int calc_reordered_bw(std::vector< std::map<int, double> > const & matrix, std::vector<IndexT> const & r)
93 {
94 int bw = 0;
95
96 for (std::size_t i = 0; i < r.size(); i++)
97 {
98 int min_index = static_cast<int>(matrix.size());
99 int max_index = 0;
100 for (std::map<int, double>::const_iterator it = matrix[i].begin(); it != matrix[i].end(); it++)
101 {
102 std::size_t col_idx = static_cast<std::size_t>(it->first);
103 if (r[col_idx] > max_index)
104 max_index = r[col_idx];
105 if (r[col_idx] < min_index)
106 min_index = r[col_idx];
107 }
108 if (max_index > min_index)
109 bw = std::max(bw, max_index - min_index);
110 }
111
112 return bw;
113 }
114
121 inline std::vector<int> generate_random_reordering(std::size_t n)
122 {
123 std::vector<int> r(n);
124 int tmp;
125
126 for (std::size_t i = 0; i < n; i++)
127 r[i] = static_cast<int>(i);
128
129 for (std::size_t i = 0; i < n - 1; i++)
130 {
131 std::size_t j = i + static_cast<std::size_t>((static_cast<double>(rand()) / static_cast<double>(RAND_MAX)) * static_cast<double>(n - 1 - i));
132 if (j != i)
133 {
134 tmp = r[i];
135 r[i] = r[j];
136 r[j] = tmp;
137 }
138 }
139
140 return r;
141 }
142
152 inline std::vector< std::map<int, double> > gen_3d_mesh_matrix(std::size_t l, std::size_t m, std::size_t n, bool tri)
153 {
154 std::vector< std::map<int, double> > matrix;
155 std::size_t s = l * m * n;
156 std::size_t ind;
157 std::size_t ind1;
158 std::size_t ind2;
159
160 matrix.resize(s);
161 for (std::size_t i = 0; i < l; i++)
162 {
163 for (std::size_t j = 0; j < m; j++)
164 {
165 for (std::size_t k = 0; k < n; k++)
166 {
167 ind = i + l * j + l * m * k;
168
169 matrix[ind][static_cast<int>(ind)] = 1.0;
170
171 if (i > 0)
172 {
173 ind2 = ind - 1;
174 matrix[ind][static_cast<int>(ind2)] = 1.0;
175 matrix[ind2][static_cast<int>(ind)] = 1.0;
176 }
177 if (j > 0)
178 {
179 ind2 = ind - l;
180 matrix[ind][static_cast<int>(ind2)] = 1.0;
181 matrix[ind2][static_cast<int>(ind)] = 1.0;
182 }
183 if (k > 0)
184 {
185 ind2 = ind - l * m;
186 matrix[ind][static_cast<int>(ind2)] = 1.0;
187 matrix[ind2][static_cast<int>(ind)] = 1.0;
188 }
189
190 if (tri)
191 {
192 if (i < l - 1 && j < m - 1)
193 {
194 if ((i + j + k) % 2 == 0)
195 {
196 ind1 = ind;
197 ind2 = ind + 1 + l;
198 }
199 else
200 {
201 ind1 = ind + 1;
202 ind2 = ind + l;
203 }
204 matrix[ind1][static_cast<int>(ind2)] = 1.0;
205 matrix[ind2][static_cast<int>(ind1)] = 1.0;
206 }
207 if (i < l - 1 && k < n - 1)
208 {
209 if ((i + j + k) % 2 == 0)
210 {
211 ind1 = ind;
212 ind2 = ind + 1 + l * m;
213 }
214 else
215 {
216 ind1 = ind + 1;
217 ind2 = ind + l * m;
218 }
219 matrix[ind1][static_cast<int>(ind2)] = 1.0;
220 matrix[ind2][static_cast<int>(ind1)] = 1.0;
221 }
222 if (j < m - 1 && k < n - 1)
223 {
224 if ((i + j + k) % 2 == 0)
225 {
226 ind1 = ind;
227 ind2 = ind + l + l * m;
228 }
229 else
230 {
231 ind1 = ind + l;
232 ind2 = ind + l * m;
233 }
234 matrix[ind1][static_cast<int>(ind2)] = 1.0;
235 matrix[ind2][static_cast<int>(ind1)] = 1.0;
236 }
237 }
238 }
239 }
240 }
241
242 return matrix;
243 }
244
245
252 int main(int, char **)
253 {
254 srand(42);
255 std::cout << "-- Generating matrix --" << std::endl;
256 std::size_t dof_per_dim = 64; //number of grid points per coordinate direction
257 std::size_t n = dof_per_dim * dof_per_dim * dof_per_dim; //total number of unknowns
258 std::vector< std::map<int, double> > matrix = gen_3d_mesh_matrix(dof_per_dim, dof_per_dim, dof_per_dim, false); //If last parameter is 'true', a tetrahedral grid instead of a hexahedral grid is used.
259
263 std::vector<int> r = generate_random_reordering(n);
264 std::vector< std::map<int, double> > matrix2 = reorder_matrix(matrix, r);
265
266
270 std::cout << " * Unknowns: " << n << std::endl;
271 std::cout << " * Initial bandwidth: " << calc_bw(matrix) << std::endl;
272 std::cout << " * Randomly reordered bandwidth: " << calc_bw(matrix2) << std::endl;
273
277 std::cout << "-- Cuthill-McKee algorithm --" << std::endl;
278 r = viennacl::reorder(matrix2, viennacl::cuthill_mckee_tag());
279 r = viennacl::reorder(matrix2, viennacl::cuthill_mckee_tag());
280 std::cout << " * Reordered bandwidth: " << calc_reordered_bw(matrix2, r) << std::endl;
281
285 std::cout << "-- Advanced Cuthill-McKee algorithm --" << std::endl;
286 double a = 0.0;
287 std::size_t gmax = 1;
288 r = viennacl::reorder(matrix2, viennacl::advanced_cuthill_mckee_tag(a, gmax));
289 std::cout << " * Reordered bandwidth: " << calc_reordered_bw(matrix2, r) << std::endl;
290
294 std::cout << "-- Gibbs-Poole-Stockmeyer algorithm --" << std::endl;
295 r = viennacl::reorder(matrix2, viennacl::gibbs_poole_stockmeyer_tag());
296 std::cout << " * Reordered bandwidth: " << calc_reordered_bw(matrix2, r) << std::endl;
297
301 std::cout << "!!!! TUTORIAL COMPLETED SUCCESSFULLY !!!!" << std::endl;
302
303 return EXIT_SUCCESS;
304 }
viennacl::reorder
std::vector< IndexT > reorder(std::vector< std::map< IndexT, ValueT > > const &matrix, cuthill_mckee_tag)
Function for the calculation of a node number permutation to reduce the bandwidth of an incidence mat...
Definition: cuthill_mckee.hpp:367
main
int main()
Definition: bisect.cpp:91
bandwidth_reduction.hpp
Convenience include for bandwidth reduction algorithms such as Cuthill-McKee or Gibbs-Poole-Stockmeye...
viennacl::linalg::detail::max
T max(const T &lhs, const T &rhs)
Maximum.
Definition: util.hpp:59
viennacl::gibbs_poole_stockmeyer_tag
Tag class for identifying the Gibbs-Poole-Stockmeyer algorithm for reducing the bandwidth of a sparse...
Definition: gibbs_poole_stockmeyer.hpp:133
viennacl::detail::calc_reordered_bw
IndexT calc_reordered_bw(std::vector< std::map< IndexT, ValueT > > const &matrix, std::vector< bool > &dof_assigned_to_node, std::vector< IndexT > const &permutation)
Definition: cuthill_mckee.hpp:47
viennacl::advanced_cuthill_mckee_tag
Tag for the advanced Cuthill-McKee algorithm (i.e. running the 'standard' Cuthill-McKee algorithm for...
Definition: cuthill_mckee.hpp:429
viennacl::cuthill_mckee_tag
A tag class for selecting the Cuthill-McKee algorithm for reducing the bandwidth of a sparse matrix...
Definition: cuthill_mckee.hpp:350