Mercurial > fem-fenics-eugenio
comparison src/PETSc_factory.cc @ 268:61830a4f9ab9
Improve formatting
author | Eugenio Gianniti <eugenio.gianniti@mail.polimi.it> |
---|---|
date | Thu, 14 Aug 2014 12:26:55 +0200 |
parents | 8fe68d94ab76 |
children |
comparison
equal
deleted
inserted
replaced
267:53039ac90368 | 268:61830a4f9ab9 |
---|---|
19 #ifdef LATEST_DOLFIN | 19 #ifdef LATEST_DOLFIN |
20 #include <boost/mpi.hpp> | 20 #include <boost/mpi.hpp> |
21 #include <boost/serialization/vector.hpp> | 21 #include <boost/serialization/vector.hpp> |
22 #endif | 22 #endif |
23 | 23 |
24 femfenics_base_factory const& | 24 femfenics_base_factory const & |
25 PETSc_factory::instance (void) | 25 PETSc_factory::instance (void) |
26 { | 26 { |
27 static PETSc_factory const theinstance; | 27 static PETSc_factory const theinstance; |
28 return theinstance; | 28 return theinstance; |
29 } | 29 } |
30 | 30 |
31 octave_value | 31 octave_value |
32 PETSc_factory::matrix (dolfin::Matrix const& A) const | 32 PETSc_factory::matrix (dolfin::Matrix const & A) const |
33 { | 33 { |
34 octave_value retval; | 34 octave_value retval; |
35 | 35 |
36 unsigned const size = | 36 unsigned const size = |
37 #ifdef LATEST_DOLFIN | 37 #ifdef LATEST_DOLFIN |
38 dolfin::MPI::size (MPI_COMM_WORLD); | 38 dolfin::MPI::size (MPI_COMM_WORLD); |
39 #else | 39 #else |
40 dolfin::MPI::num_processes (); | 40 dolfin::MPI::num_processes (); |
41 #endif | 41 #endif |
42 | 42 |
43 if (size > 1) | 43 if (size > 1) |
44 retval = do_matrix_parallel (A); | 44 { retval = do_matrix_parallel (A); } |
45 else | 45 else |
46 retval = do_matrix_serial (A); | 46 { retval = do_matrix_serial (A); } |
47 | 47 |
48 return retval; | 48 return retval; |
49 } | 49 } |
50 | 50 |
51 octave_value | 51 octave_value |
52 PETSc_factory::vector (dolfin::Vector const& b) const | 52 PETSc_factory::vector (dolfin::Vector const & b) const |
53 { | 53 { |
54 octave_value retval; | 54 octave_value retval; |
55 | 55 |
56 unsigned const size = | 56 unsigned const size = |
57 #ifdef LATEST_DOLFIN | 57 #ifdef LATEST_DOLFIN |
58 dolfin::MPI::size (MPI_COMM_WORLD); | 58 dolfin::MPI::size (MPI_COMM_WORLD); |
59 #else | 59 #else |
60 dolfin::MPI::num_processes (); | 60 dolfin::MPI::num_processes (); |
61 #endif | 61 #endif |
62 | 62 |
63 if (size > 1) | 63 if (size > 1) |
64 retval = do_vector_parallel (b); | 64 { retval = do_vector_parallel (b); } |
65 else | 65 else |
66 retval = do_vector_serial (b); | 66 { retval = do_vector_serial (b); } |
67 | 67 |
68 return retval; | 68 return retval; |
69 } | 69 } |
70 | 70 |
71 void | 71 void |
72 PETSc_factory::add_to_arrays (Array <octave_idx_type> & ridx, | 72 PETSc_factory::add_to_arrays (Array <octave_idx_type> & ridx, |
73 Array <octave_idx_type> & cidx, | 73 Array <octave_idx_type> & cidx, |
74 Array <double> & values, | 74 Array <double> & values, |
75 std::vector <std::size_t> const& row, | 75 std::vector <std::size_t> const & row, |
76 std::vector <std::size_t> const& col, | 76 std::vector <std::size_t> const & col, |
77 std::vector <double> const& val) | 77 std::vector <double> const & val) |
78 { | 78 { |
79 octave_idx_type pos = cidx.numel (); | 79 octave_idx_type pos = cidx.numel (); |
80 | 80 |
81 dim_vector dims = cidx.dims (); | 81 dim_vector dims = cidx.dims (); |
82 if (dims(1) == 1) | 82 if (dims(1) == 1) |
83 dims(0) += col.size (); | 83 { dims(0) += col.size (); } |
84 else | 84 else |
85 dims(1) += col.size (); | 85 { dims(1) += col.size (); } |
86 ridx.resize (dims, 0); | 86 ridx.resize (dims, 0); |
87 cidx.resize (dims, 0); | 87 cidx.resize (dims, 0); |
88 values.resize (dims, 0); | 88 values.resize (dims, 0); |
89 | 89 |
90 std::vector <std::size_t>::const_iterator rit = row.begin (), | 90 std::vector <std::size_t>::const_iterator rit = row.begin (), |
91 cit = col.begin (); | 91 cit = col.begin (); |
92 std::vector <double>::const_iterator vit = val.begin (); | 92 std::vector <double>::const_iterator vit = val.begin (); |
93 | 93 |
94 while (cit != col.end ()) | 94 while (cit != col.end ()) |
95 { | 95 { |
96 ridx(pos) = *rit; | 96 ridx(pos) = *rit; |
97 cidx(pos) = *cit; | 97 cidx(pos) = *cit; |
98 values(pos) = *vit; | 98 values(pos) = *vit; |
99 | 99 |
100 ++rit; | 100 ++rit; |
101 ++cit; | 101 ++cit; |
102 ++vit; | 102 ++vit; |
103 ++pos; | 103 ++pos; |
104 } | 104 } |
105 | 105 |
106 return; | 106 return; |
107 } | 107 } |
108 | 108 |
109 octave_value | 109 octave_value |
110 PETSc_factory::do_matrix_serial (dolfin::Matrix const& A) const | 110 PETSc_factory::do_matrix_serial (dolfin::Matrix const & A) const |
111 { | 111 { |
112 octave_value retval; | 112 octave_value retval; |
113 | 113 |
114 std::size_t nr = A.size (0), nc = A.size (1); | 114 std::size_t nr = A.size (0), nc = A.size (1); |
115 | 115 |
116 dim_vector dims (0, 1); | 116 dim_vector dims (0, 1); |
117 Array <octave_idx_type> | 117 Array <octave_idx_type> ridx (dims, 0), cidx (dims, 0); |
118 ridx (dims, 0), | 118 Array<double> data (dims, 0); |
119 cidx (dims, 0); | 119 |
120 Array<double> data (dims, 0); | 120 for (std::size_t i = 0; i < nr; ++i) |
121 | 121 { |
122 for (std::size_t i = 0; i < nr; ++i) | 122 std::vector <double> data_tmp; |
123 { | 123 std::vector <std::size_t> cidx_tmp; |
124 std::vector <double> data_tmp; | 124 A.getrow (i, cidx_tmp, data_tmp); |
125 std::vector <std::size_t> cidx_tmp; | 125 std::vector <std::size_t> ridx_tmp (cidx_tmp.size (), i); |
126 A.getrow (i, cidx_tmp, data_tmp); | 126 add_to_arrays (ridx, cidx, data, ridx_tmp, cidx_tmp, data_tmp); |
127 std::vector <std::size_t> ridx_tmp (cidx_tmp.size (), i); | 127 } |
128 add_to_arrays (ridx, cidx, data, ridx_tmp, cidx_tmp, data_tmp); | 128 |
129 } | 129 SparseMatrix sm (data, ridx, cidx, nr, nc); |
130 | 130 retval = sm; |
131 SparseMatrix sm (data, ridx, cidx, nr, nc); | 131 |
132 retval = sm; | 132 return retval; |
133 | 133 } |
134 return retval; | 134 |
135 } | 135 octave_value |
136 | 136 PETSc_factory::do_matrix_parallel (dolfin::Matrix const & A) const |
137 octave_value | 137 { |
138 PETSc_factory::do_matrix_parallel (dolfin::Matrix const& A) const | 138 octave_value retval; |
139 { | 139 |
140 octave_value retval; | 140 std::vector <std::size_t> rows, cols; |
141 | 141 std::vector <double> vals; |
142 std::vector <std::size_t> rows, cols; | 142 std::size_t const nrows = A.size (0), ncols = A.size (1); |
143 std::vector <double> vals; | 143 |
144 std::size_t const nrows = A.size (0), ncols = A.size (1); | 144 std::pair <std::size_t, std::size_t> const range = A.local_range (0); |
145 | 145 for (std::size_t i = range.first; i < range.second; ++i) |
146 std::pair <std::size_t, std::size_t> const range = A.local_range (0); | 146 { |
147 for (std::size_t i = range.first; i < range.second; ++i) | 147 std::vector <std::size_t> cols_tmp; |
148 { | 148 std::vector <double> vals_tmp; |
149 std::vector <std::size_t> cols_tmp; | 149 A.getrow (i, cols_tmp, vals_tmp); |
150 std::vector <double> vals_tmp; | 150 cols.insert (cols.end (), cols_tmp.begin (), cols_tmp.end ()); |
151 A.getrow (i, cols_tmp, vals_tmp); | 151 vals.insert (vals.end (), vals_tmp.begin (), vals_tmp.end ()); |
152 cols.insert (cols.end (), cols_tmp.begin (), cols_tmp.end ()); | 152 for (std::size_t j = 0; j < cols_tmp.size (); ++j) |
153 vals.insert (vals.end (), vals_tmp.begin (), vals_tmp.end ()); | 153 { rows.push_back (i); } |
154 for (std::size_t j = 0; j < cols_tmp.size (); ++j) | 154 } |
155 rows.push_back (i); | 155 |
156 } | 156 boost::mpi::communicator world; |
157 | 157 |
158 boost::mpi::communicator world; | 158 unsigned const size = world.size (); |
159 | 159 unsigned const rank = world.rank (); |
160 unsigned const size = world.size (); | 160 |
161 unsigned const rank = world.rank (); | 161 for (unsigned p = 1; p < size; ++p) |
162 | 162 { |
163 for (unsigned p = 1; p < size; ++p) | 163 if (rank == p) |
164 { | 164 { |
165 if (rank == p) | 165 unsigned const tag = 3 * (p - 1); |
166 { | 166 world.send (0, tag, rows); |
167 unsigned const tag = 3*(p-1); | 167 world.send (0, tag + 1, cols); |
168 world.send (0, tag, rows); | 168 world.send (0, tag + 2, vals); |
169 world.send (0, tag+1, cols); | 169 } |
170 world.send (0, tag+2, vals); | 170 } |
171 } | 171 |
172 } | 172 if (rank == 0) |
173 | 173 { |
174 if (rank == 0) | 174 dim_vector dims (0, 1); |
175 { | 175 Array <octave_idx_type> ridx (dims, 0), cidx (dims, 0); |
176 dim_vector dims (0, 1); | 176 Array <double> data (dims, 0); |
177 Array <octave_idx_type> ridx (dims, 0), cidx (dims, 0); | 177 add_to_arrays (ridx, cidx, data, rows, cols, vals); |
178 Array <double> data (dims, 0); | 178 |
179 add_to_arrays (ridx, cidx, data, rows, cols, vals); | 179 for (unsigned p = 1; p < size; ++p) |
180 | 180 { |
181 for (unsigned p = 1; p < size; ++p) | 181 std::vector <double> new_vals; |
182 { | 182 std::vector <std::size_t> new_rows, new_cols; |
183 std::vector <double> new_vals; | 183 unsigned const tag = 3 * (p - 1); |
184 std::vector <std::size_t> new_rows, new_cols; | 184 |
185 unsigned const tag = 3*(p-1); | 185 world.recv (p, tag, new_rows); |
186 | 186 world.recv (p, tag + 1, new_cols); |
187 world.recv (p, tag, new_rows); | 187 world.recv (p, tag + 2, new_vals); |
188 world.recv (p, tag+1, new_cols); | 188 |
189 world.recv (p, tag+2, new_vals); | 189 add_to_arrays (ridx, cidx, data, new_rows, new_cols, new_vals); |
190 | 190 } |
191 add_to_arrays (ridx, cidx, data, new_rows, new_cols, new_vals); | 191 |
192 } | 192 SparseMatrix sm (data, ridx, cidx, nrows, ncols); |
193 | 193 retval = sm; |
194 SparseMatrix sm (data, ridx, cidx, nrows, ncols); | 194 } |
195 retval = sm; | 195 else |
196 } | 196 // Return an identity matrix just to avoid warnings or errors |
197 else | 197 { |
198 // Return an identity matrix just to avoid warnings or errors | 198 dim_vector dims (nrows, 1); |
199 { | 199 Array <octave_idx_type> ridx (dims), cidx (dims); |
200 dim_vector dims (nrows, 1); | 200 Array <double> data (dims, 1); |
201 Array <octave_idx_type> ridx (dims), cidx (dims); | 201 |
202 Array <double> data (dims, 1); | 202 for (std::size_t i = 0; i < nrows; ++i) |
203 | 203 { |
204 for (std::size_t i = 0; i < nrows; ++i) | 204 ridx.xelem (i) = i; |
205 { | 205 cidx.xelem (i) = i; |
206 ridx.xelem (i) = i; | 206 } |
207 cidx.xelem (i) = i; | 207 |
208 } | 208 SparseMatrix sm (data, ridx, cidx, nrows, ncols); |
209 | 209 retval = sm; |
210 SparseMatrix sm (data, ridx, cidx, nrows, ncols); | 210 } |
211 retval = sm; | 211 |
212 } | 212 return retval; |
213 | 213 } |
214 return retval; | 214 |
215 } | 215 octave_value |
216 | 216 PETSc_factory::do_vector_serial (dolfin::Vector const & b) const |
217 octave_value | 217 { |
218 PETSc_factory::do_vector_serial (dolfin::Vector const& b) const | 218 octave_value retval; |
219 { | 219 |
220 octave_value retval; | 220 dim_vector dims; |
221 | 221 dims.resize (2); |
222 dim_vector dims; | 222 dims(0) = b.size (); |
223 dims.resize (2); | 223 dims(1) = 1; |
224 dims(0) = b.size (); | 224 Array <double> myb (dims); |
225 dims(1) = 1; | 225 |
226 Array <double> myb (dims); | 226 for (std::size_t i = 0; i < b.size (); ++i) |
227 | 227 { myb.xelem (i) = b[i]; } |
228 for (std::size_t i = 0; i < b.size (); ++i) | 228 |
229 myb.xelem (i) = b[i]; | 229 retval = myb; |
230 | 230 |
231 retval = myb; | 231 return retval; |
232 | 232 } |
233 return retval; | 233 |
234 } | 234 octave_value |
235 | 235 PETSc_factory::do_vector_parallel (dolfin::Vector const & b) const |
236 octave_value | 236 { |
237 PETSc_factory::do_vector_parallel (dolfin::Vector const& b) const | 237 octave_value retval; |
238 { | 238 |
239 octave_value retval; | 239 std::size_t const length = b.size (); |
240 | 240 dim_vector dims (length, 1); |
241 std::size_t const length = b.size (); | 241 Array <double> vec (dims, 0); |
242 dim_vector dims (length, 1); | 242 |
243 Array <double> vec (dims, 0); | 243 std::vector <double> entries; |
244 | 244 b.gather_on_zero (entries); |
245 std::vector <double> entries; | 245 |
246 b.gather_on_zero (entries); | 246 #ifdef LATEST_DOLFIN |
247 | 247 if (dolfin::MPI::rank (MPI_COMM_WORLD) == 0) |
248 #ifdef LATEST_DOLFIN | |
249 if (dolfin::MPI::rank (MPI_COMM_WORLD) == 0) | |
250 #else | 248 #else |
251 if (dolfin::MPI::process_number () == 0) | 249 if (dolfin::MPI::process_number () == 0) |
252 #endif | 250 #endif |
253 for (std::size_t i = 0; i < length; ++i) | 251 for (std::size_t i = 0; i < length; ++i) |
254 vec.xelem (i) = entries[i]; | 252 { vec.xelem (i) = entries[i]; } |
255 | 253 |
256 // On nodes other than zero, return an all zero vector of the right length | 254 // On nodes other than zero, return an all zero vector of the right length |
257 retval = vec; | 255 retval = vec; |
258 | 256 |
259 return retval; | 257 return retval; |
260 } | 258 } |