Loading [MathJax]/extensions/tex2jax.js
ug4
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
parallel_matrix_overlap_impl.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2010-2015: G-CSC, Goethe University Frankfurt
3 * Author: Martin Rupp, Sebastian Reiter
4 *
5 * This file is part of UG4.
6 *
7 * UG4 is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License version 3 (as published by the
9 * Free Software Foundation) with the following additional attribution
10 * requirements (according to LGPL/GPL v3 §7):
11 *
12 * (1) The following notice must be displayed in the Appropriate Legal Notices
13 * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 *
15 * (2) The following notice must be displayed at a prominent place in the
16 * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 *
18 * (3) The following bibliography is recommended for citation and must be
19 * preserved in all covered files:
20 * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 * parallel geometric multigrid solver on hierarchically distributed grids.
22 * Computing and visualization in science 16, 4 (2013), 151-164"
23 * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 * flexible software system for simulating pde based models on high performance
25 * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU Lesser General Public License for more details.
31 */
32
33#ifndef __H__LIB_ALGEBRA__PARALLELIZATION__PARALLEL_MATRIX_OVERLAP_IMPL__
34#define __H__LIB_ALGEBRA__PARALLELIZATION__PARALLEL_MATRIX_OVERLAP_IMPL__
35
36#include <vector>
37#include <set>
38#include <map>
39
41//#include "test_layout.h"
45#include "parallel_nodes.h"
46
47#include "row_sending_scheme.h"
48#include "new_layout_creator.h"
49
50namespace ug
51{
52
54
55// neuer algorithmus:
56// overlap 0
57// 1. slave-knoten verschicken ihre Zeile an den Master.
58// 2. Master nimmt diese entgegen, zeile wird f�r vorhandene Knoten addiert
59// 3. fertig.
60
61// overlap 1
62// 1. slave-knoten verschicken ihre Zeile an den Master.
63// /!\ werden verkn�pfungen zu anderen prozessoren verschickt, werden die prozessoren informiert
64// /!\ unter umst�nden wird so ein prozessor "von 2 seiten" informiert. dann muss es eine
65// 2. verschicke die matrixzeilen und benachrichtungen
66// 3. nehme matrixzeilen und benachrichtungen entgegen
67// 4. verarbeite benachrichtungen: erzeuge u.U. neue Master Knoten
68// 5. verarbeite matrixzeilen und erzeugt u.U. neue Knoten (Slave). Diese werden als "neu" markiert
69//
70// \param mat matrix to take values from
71// \param layout : for all interfaces I in layout, send matrix rows of nodes in I with com
72// \param create_new_nodes : if true, do not add nodes to masterOLLayout
73// \param masterOLLayout : for nodes which will be new on the other processors, add them to this layout
74// \param pids ... unclear if this is needed
75
76
77
78
79template<typename matrix_type>
81{
82private:
84 typedef std::map<int, BinaryBuffer> BufferMap;
85
87
88
89 matrix_type &m_mat;
90 matrix_type &m_newMat;
91
94
95 std::vector<IndexLayout> &m_vMasterLayouts;
96 std::vector<IndexLayout> &m_vSlaveLayouts;
98 //size_t m_overlapDepth; ///< overlap depth to be achieved
99
101
102public:
103 std::vector<size_t> m_overlapSize;
108private:
109
111
123 void communicate(const IndexLayout &sendingLayout, const IndexLayout &receivingLayout,
124 bool bCreateNewNodes,
125 IndexLayout &newSlavesLayout, IndexLayout &newMastersLayout,
126 std::set<int> &pids, bool bSet, size_t level)
127 {
128 PROFILE_FUNC_GROUP("algebra");
129
130 UG_DLOG(DBG_MATRIX_OVERLAP, 4, "\n\n*** GenerateOverlapClass::communicate ***\n\n")
132 {
133 UG_LOG("\n\nnew sending Layout:\n")
134 PrintLayout(sendingLayout);
135 UG_LOG("\n\nnew receiving Layout:\n")
136 PrintLayout(receivingLayout);
137 UG_LOG("\n\n");
138
139 UG_ASSERT(TestLayout(m_pc, m_com, sendingLayout, receivingLayout), "layout corrupted");
140 }
141
142 RowSendingScheme<matrix_type> rowSendingScheme(m_newMat, PN);
143
144 rowSendingScheme.set_create_new_nodes(bCreateNewNodes);
145 rowSendingScheme.issue_send(m_com, sendingLayout, receivingLayout);
146 m_com.communicate();
147
148 rowSendingScheme.process(receivingLayout);
149
150 if(bCreateNewNodes)
151 {
152 m_newMat.resize_and_keep_values(PN.local_size(), PN.local_size());
153 PN.add_new_layouts_to(newMastersLayout, newSlavesLayout);
154
155 AddLayout(m_totalMasterLayout, newMastersLayout);
156 AddLayout(m_totalSlaveLayout, newSlavesLayout);
157
159 {
160 UG_LOG("\n\nnew Master Layout:\n")
161 PrintLayout(newMastersLayout);
162 UG_LOG("\n\nnew Slave Layout:\n")
163 PrintLayout(newSlavesLayout);
164 UG_LOG("\n\n");
165
166 UG_ASSERT(TestLayout(m_pc, m_com, newMastersLayout, newSlavesLayout), "layout corrupted");
167 }
168
169
170 AddLayout(m_vMasterLayouts[level+1], newMastersLayout);
171 AddLayout(m_vSlaveLayouts[level+1], newSlavesLayout);
172 }
173 if(bSet)
174 rowSendingScheme.set_rows_in_matrix(m_newMat);
175 else
176 rowSendingScheme.add_rows_to_matrix(m_newMat);
177 }
178
179public:
180 // GenerateOverlap
181 //--------------------------------------------------
191 GenerateOverlapClass(matrix_type &mat, matrix_type &newMat,
192 IndexLayout &totalMasterLayout,
193 IndexLayout &totalSlaveLayout,
194 std::vector<IndexLayout> &vMasterLayouts,
195 std::vector<IndexLayout> &vSlaveLayouts,
196 ParallelNodes &pn) :
197 m_com(mat.layouts()->comm()), m_mat(mat), m_newMat(newMat),
198 m_totalMasterLayout(totalMasterLayout), m_totalSlaveLayout(totalSlaveLayout),
199 m_vMasterLayouts(vMasterLayouts), m_vSlaveLayouts(vSlaveLayouts),
200 PN(pn), m_pc(m_mat.layouts()->proc_comm())
201 {
202
203 }
204
206
210 {
211 PROFILE_FUNC_GROUP("algebra");
213 {
214 UG_DLOG(DBG_MATRIX_OVERLAP, 4, "GENERATE OVERLAP START\n");
215
216 UG_DLOG(DBG_MATRIX_OVERLAP, 4, "\n\nmatrix is " << m_mat.num_rows() << " x " << m_mat.num_cols() << "\n");
217 m_mat.print();
218
219 UG_LOG("\nmaster layout:\n");
220 PrintLayout(m_mat.layouts()->master());
221 UG_LOG("slave layout:\n");
222 PrintLayout(m_mat.layouts()->slave());
223 UG_LOG("\n\n");
224 }
225 UG_ASSERT(m_mat.num_rows() == m_mat.num_cols(), "atm only for square matrices");
226
227
228 const IndexLayout &masterLayout = m_mat.layouts()->master();
229 const IndexLayout &slaveLayout = m_mat.layouts()->slave();
230
232 {
233 PROFILE_BEGIN(calculate_TestLayout);
234 UG_ASSERT(TestLayout(m_pc, m_com, masterLayout, slaveLayout), "layout corrupted");
235 }
236
237
238 // generate global algebra indices
239 UG_DLOG(DBG_MATRIX_OVERLAP, 4, "generate " << m_mat.num_rows() << " m_globalIDs\n");
240 //GenerateGlobalAlgebraIDs(m_globalIDs, m_mat.num_rows(), masterLayout, slaveLayout);
241
242
244 {
245 for(size_t i=0; i<PN.local_size(); i++)
246 UG_DLOG(DBG_MATRIX_OVERLAP, 4, " " << i << ": global id " << PN.local_to_global(i) << "\n")
247 }
248
249
250 m_newMat.set_as_copy_of(m_mat);
251
252 // collect data
253 //-----------------
254
255 size_t maxOverlap = std::max(m_overlapDepthMaster, m_overlapDepthSlave);
256
257 std::vector<IndexLayout> masterOLLayouts, slaveOLLayouts;
258 masterOLLayouts.clear();
259 masterOLLayouts.resize(maxOverlap+1);
260 slaveOLLayouts.clear();
261 slaveOLLayouts.resize(maxOverlap+1);
262
263 std::vector<IndexLayout> backward_masterOLLayouts, backward_slaveOLLayouts;
264 backward_masterOLLayouts.clear();
265 backward_masterOLLayouts.resize(maxOverlap+1);
266 backward_slaveOLLayouts.clear();
267 backward_slaveOLLayouts.resize(maxOverlap+1);
268
269 // TODO: try to remove these pid numbers or reduce them by introducing receivePIDs, sendPIDs
270 // these are necessary because notifications can occur from a processor not in the current layout
271 std::set<int> pids;
272 for(IndexLayout::const_iterator iter = slaveLayout.begin(); iter != slaveLayout.end(); ++iter)
273 pids.insert(iter->first);
274 for(IndexLayout::const_iterator iter = masterLayout.begin(); iter != masterLayout.end(); ++iter)
275 pids.insert(iter->first);
276
277
278 //create_mark_map(masterLayout);
279 m_vMasterLayouts.resize(maxOverlap+1);
280 m_vSlaveLayouts.resize(maxOverlap+1);
281 AddLayout(m_vMasterLayouts[0], masterLayout);
282 AddLayout(m_vSlaveLayouts[0], slaveLayout);
283 m_overlapSize.clear();
284
285 for(size_t current_overlap=0; current_overlap <= maxOverlap; current_overlap++)
286 {
287 PROFILE_BEGIN(overlap_inner_loop);
288 m_overlapSize.push_back(m_newMat.num_rows());
289
291 {
292 UG_DLOG(DBG_MATRIX_OVERLAP, 4, "\n---------------------\ncurrentOL: " << current_overlap << "\n");
293 UG_DLOG(DBG_MATRIX_OVERLAP, 4, "---------------------\n\n");
294 }
295
296 if(current_overlap <= m_overlapDepthMaster)
297 {
298 UG_DLOG(DBG_MATRIX_OVERLAP, 4, "\n--FORWARDS--\n\n");
299 const IndexLayout *send_layout;
300 if(current_overlap == 0)
301 send_layout = &slaveLayout;
302 else
303 send_layout = &masterOLLayouts[current_overlap-1];
304
305 const IndexLayout *receive_layout;
306 if(current_overlap == 0)
307 receive_layout = &masterLayout;
308 else
309 receive_layout = &slaveOLLayouts[current_overlap-1];
310
311 if(current_overlap == m_overlapDepthMaster && m_masterDirichletLast)
312 {
313 PROFILE_BEGIN(calculate3_1a);
314 std::vector<IndexLayout::Element> vIndex;
315 CollectUniqueElements(vIndex, *receive_layout);
316 SetDirichletRow(m_newMat, vIndex);
317 }
318 else
319 {
320 PROFILE_BEGIN(calculate3_1b);
321 bool bCreateNewNodes = (current_overlap == m_overlapDepthMaster ? false : true);
322 communicate(*send_layout, *receive_layout, bCreateNewNodes,
323 slaveOLLayouts[current_overlap], masterOLLayouts[current_overlap], pids, false, current_overlap);
324 }
325 }
326
327 // backwards
328 if(current_overlap <= m_overlapDepthSlave)
329 {
330 UG_DLOG(DBG_MATRIX_OVERLAP, 4, "\n--BACKWARDS--\n\n");
331 const IndexLayout *backward_send_layout;
332 if(current_overlap == 0)
333 backward_send_layout = &masterLayout;
334 else
335 backward_send_layout = &backward_masterOLLayouts[current_overlap-1];
336
337 const IndexLayout *backward_receive_layout;
338 if(current_overlap == 0)
339 backward_receive_layout = &slaveLayout;
340 else
341 backward_receive_layout = &backward_slaveOLLayouts[current_overlap-1];
342
343 if(current_overlap == m_overlapDepthSlave && m_slaveDirichletLast)
344 {
345 PROFILE_BEGIN(calculate3_2a);
346 std::vector<IndexLayout::Element> vIndex;
347 CollectUniqueElements(vIndex, *backward_receive_layout);
348 SetDirichletRow(m_newMat, vIndex);
349 }
350 else
351 {
352 PROFILE_BEGIN(calculate3_2b);
353 bool bCreateNewNodes = (current_overlap == m_overlapDepthSlave ? false : true);
354 communicate(*backward_send_layout, *backward_receive_layout, bCreateNewNodes,
355 backward_slaveOLLayouts[current_overlap], backward_masterOLLayouts[current_overlap], pids, true, current_overlap+1);
356 }
357 }
358
359 // done!
360 }
361
362
363
367 spLayouts->master() = m_totalMasterLayout;
368 spLayouts->slave() = m_totalSlaveLayout;
369 spLayouts->proc_comm() = m_mat.layouts()->proc_comm();
370 spLayouts->comm() = m_mat.layouts()->comm();
371 m_newMat.set_layouts(spLayouts);
372 m_newMat.set_storage_type(m_mat.get_storage_mask());
373
375 {
376 UG_DLOG(DBG_MATRIX_OVERLAP, 4, "new matrix\n\n");
377 m_newMat.print();
378
379 UG_DLOG(DBG_MATRIX_OVERLAP, 4, "master OL Layout:\n");
380 PrintLayout(m_totalMasterLayout);
381 UG_DLOG(DBG_MATRIX_OVERLAP, 4, "slave OL Layout:\n");
382 PrintLayout(m_totalSlaveLayout);
383
384 UG_DLOG(DBG_MATRIX_OVERLAP, 4, "OL Layout:\n");
386 }
387
388 return true;
389 }
390
391};
392/*
393// TODO: one "bug" remains: dirichlet nodes, which have only connection to themselfs = 1.0, get afterwards 2.0 (because rows are not additive there)
394template<typename matrix_type>
395bool GenerateOverlap(const ParallelMatrix<matrix_type> &_mat, ParallelMatrix<matrix_type> &newMat,
396 IndexLayout &totalMasterLayout, IndexLayout &totalSlaveLayout, std::vector<IndexLayout> &vMasterLayouts, std::vector<IndexLayout> &vSlaveLayouts,
397 std::vector<size_t> &overlapSize,
398 size_t overlapDepth=1)
399{
400 PROFILE_FUNC_GROUP("algebra");
401 // pcl does not use const much
402 //UG_ASSERT(overlap_depth > 0, "overlap_depth has to be > 0");
403 ParallelMatrix<matrix_type> &mat = const_cast<ParallelMatrix<matrix_type> &> (_mat);
404
405 GenerateOverlapClass<ParallelMatrix<matrix_type> > c(mat, newMat, totalMasterLayout, totalSlaveLayout, vMasterLayouts, vSlaveLayouts);
406 c.m_overlapDepthMaster = overlapDepth;
407 c.m_overlapDepthSlave = overlapDepth;
408 c.m_masterDirichletLast = false;
409 c.m_slaveDirichletLast = false;
410 bool b = c.calculate();
411 overlapSize = c.m_overlapSize;
412 return b;
413}
414
415// TODO: one "bug" remains: dirichlet nodes, which have only connection to themselfs = 1.0, get afterwards 2.0 (because rows are not additive there)
416template<typename matrix_type>
417bool GenerateOverlap2(const ParallelMatrix<matrix_type> &_mat, ParallelMatrix<matrix_type> &newMat,
418 IndexLayout &totalMasterLayout, IndexLayout &totalSlaveLayout, std::vector<IndexLayout> &vMasterLayouts, std::vector<IndexLayout> &vSlaveLayouts,
419 size_t overlapDepthMaster, size_t overlapDepthSlave, bool masterDirichletLast, bool slaveDirichletLast)
420{
421 PROFILE_FUNC_GROUP("algebra");
422 // pcl does not use const much
423 //UG_ASSERT(overlap_depth > 0, "overlap_depth has to be > 0");
424 ParallelMatrix<matrix_type> &mat = const_cast<ParallelMatrix<matrix_type> &> (_mat);
425 ParallelNodes PN(mat.layouts(), mat.num_rows());
426
427 GenerateOverlapClass<ParallelMatrix<matrix_type> > c(mat, newMat, totalMasterLayout, totalSlaveLayout, vMasterLayouts, vSlaveLayouts,
428 PN);
429 c.m_overlapDepthMaster = overlapDepthMaster;
430 c.m_overlapDepthSlave = overlapDepthSlave;
431 c.m_masterDirichletLast = masterDirichletLast;
432 c.m_slaveDirichletLast = slaveDirichletLast;
433 return c.calculate();
434}*/
435
436// TODO: one "bug" remains: dirichlet nodes, which have only connection to themselfs = 1.0, get afterwards 2.0 (because rows are not additive there)
437template<typename matrix_type>
439{
440 PROFILE_FUNC_GROUP("algebra");
441 IndexLayout totalMasterLayout, totalSlaveLayout;
442 std::vector<IndexLayout> vMasterLayouts;
443 std::vector<IndexLayout> vSlaveLayouts;
444 // pcl does not use const much
445 //UG_ASSERT(overlap_depth > 0, "overlap_depth has to be > 0");
447 ParallelNodes PN(mat.layouts(), mat.num_rows());
449 mat, newMat, totalMasterLayout, totalSlaveLayout, vMasterLayouts, vSlaveLayouts, PN);
452 c.m_masterDirichletLast = false;
453 c.m_slaveDirichletLast = false;
454 bool b = c.calculate();
455 newMat.set_layouts(mat.layouts());
456 return b;
457}
458
459/*
460template<typename matrix_type>
461bool MakeFullRowsMatrix(const ParallelMatrix<matrix_type> &mat, ParallelMatrix<matrix_type> &newMat)
462{
463 // GenerateOverlap2(mat, newMat, totalMasterLayout, totalSlaveLayout, masterLayouts, slaveLayouts, 1, 0, true, true);
464 return true;
465}*/
466
467
468}
469#endif
Definition smart_pointer.h:296
Definition smart_pointer.h:108
Performs communication between interfaces on different processes.
Definition pcl_interface_communicator.h:68
You may add elements to this interface and iterate over them.
Definition pcl_communication_structs.h:207
Definition pcl_process_communicator.h:70
iterator end(size_t level=0)
returns the iterator to the last interface of the layout.
Definition pcl_communication_structs.h:492
iterator begin(size_t level=0)
returns the iterator to the first interface of the layout.
Definition pcl_communication_structs.h:486
InterfaceMap::const_iterator const_iterator
Definition pcl_communication_structs.h:477
Extends the HorizontalAlgebraLayouts by vertical layouts.
Definition algebra_layouts.h:121
Definition debug_id.h:94
Definition parallel_matrix_overlap_impl.h:81
std::vector< IndexLayout > & m_vSlaveLayouts
m_vSlaveLayout[i] is the slave layout from overlap i without others
Definition parallel_matrix_overlap_impl.h:96
pcl::InterfaceCommunicator< IndexLayout > & m_com
communicator
Definition parallel_matrix_overlap_impl.h:86
bool m_slaveDirichletLast
Definition parallel_matrix_overlap_impl.h:107
std::map< int, BinaryBuffer > BufferMap
Definition parallel_matrix_overlap_impl.h:84
matrix_type & m_newMat
the new to create matrix
Definition parallel_matrix_overlap_impl.h:90
const pcl::ProcessCommunicator & m_pc
Definition parallel_matrix_overlap_impl.h:100
IndexLayout::Interface Interface
Definition parallel_matrix_overlap_impl.h:83
matrix_type & m_mat
the original matrix (should be const)
Definition parallel_matrix_overlap_impl.h:89
std::vector< IndexLayout > & m_vMasterLayouts
m_vMasterLayout[i] is the master layout from overlap i without others
Definition parallel_matrix_overlap_impl.h:95
void communicate(const IndexLayout &sendingLayout, const IndexLayout &receivingLayout, bool bCreateNewNodes, IndexLayout &newSlavesLayout, IndexLayout &newMastersLayout, std::set< int > &pids, bool bSet, size_t level)
communicate
Definition parallel_matrix_overlap_impl.h:123
IndexLayout & m_totalSlaveLayout
layout combining all slave layouts from overlap 0 to overlap_depth-1
Definition parallel_matrix_overlap_impl.h:93
size_t m_overlapDepthSlave
Definition parallel_matrix_overlap_impl.h:105
size_t m_overlapDepthMaster
Definition parallel_matrix_overlap_impl.h:104
IndexLayout & m_totalMasterLayout
layout combining all master layouts from overlap 0 to overlap_depth-1
Definition parallel_matrix_overlap_impl.h:92
GenerateOverlapClass(matrix_type &mat, matrix_type &newMat, IndexLayout &totalMasterLayout, IndexLayout &totalSlaveLayout, std::vector< IndexLayout > &vMasterLayouts, std::vector< IndexLayout > &vSlaveLayouts, ParallelNodes &pn)
Generates a new matrix with overlap from another matrix.
Definition parallel_matrix_overlap_impl.h:191
bool m_masterDirichletLast
Definition parallel_matrix_overlap_impl.h:106
std::vector< size_t > m_overlapSize
Definition parallel_matrix_overlap_impl.h:103
ParallelNodes & PN
Definition parallel_matrix_overlap_impl.h:97
bool calculate()
calculate
Definition parallel_matrix_overlap_impl.h:209
Wrapper for sequential matrices to handle them in parallel.
Definition parallel_matrix.h:65
void set_layouts(ConstSmartPtr< AlgebraLayouts > layouts)
sets the algebra layouts
Definition parallel_matrix.h:97
ConstSmartPtr< AlgebraLayouts > layouts() const
returns the algebra layouts
Definition parallel_matrix.h:94
Definition parallel_nodes.h:112
size_t local_size() const
Definition parallel_nodes.h:273
const AlgebraID & local_to_global(size_t i) const
Definition parallel_nodes.h:278
void add_new_layouts_to(IndexLayout &newMasterLayout, IndexLayout &newSlaveLayout)
Definition parallel_nodes.cpp:382
Definition row_sending_scheme.h:47
void add_rows_to_matrix(matrix_type &mat)
Definition row_sending_scheme.h:147
void set_create_new_nodes(bool bCreateNewNodes)
Definition row_sending_scheme.h:65
void process(const IndexLayout &receiveLayout)
Definition row_sending_scheme.h:114
void set_rows_in_matrix(matrix_type &mat)
Definition row_sending_scheme.h:135
void issue_send(pcl::InterfaceCommunicator< IndexLayout > &communicator, const IndexLayout &sendLayout, const IndexLayout &receiveLayout)
Definition row_sending_scheme.h:83
void SetDirichletRow(TSparseMatrix &A, size_t i, size_t alpha)
Definition sparsematrix_util.h:796
#define UG_ASSERT(expr, msg)
Definition assert.h:70
#define UG_DLOG(__debugID__, level, msg)
Definition log.h:298
#define UG_LOG(msg)
Definition log.h:367
#define IF_DEBUG(__debugID__, level)
Definition log.h:303
the ug namespace
bool MakeConsistent(const ParallelMatrix< matrix_type > &_mat, ParallelMatrix< matrix_type > &newMat)
Definition parallel_matrix_overlap_impl.h:438
DebugID DBG_MATRIX_OVERLAP("Algebra.MatrixOverlap")
Definition parallel_matrix_overlap_impl.h:53
#define PROFILE_BEGIN(name)
Definition profiler.h:254
#define PROFILE_FUNC_GROUP(groups)
Definition profiler.h:258