ug4
parallelization_util_impl.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014: G-CSC, Goethe University Frankfurt
3  * Author: 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 
34 #ifndef __H__LIB_ALGEBRA__PARALLELIZATION__PARALLELIZATION_UTIL_IMPL__
35 #define __H__LIB_ALGEBRA__PARALLELIZATION__PARALLELIZATION_UTIL_IMPL__
36 
37 #include <vector>
38 #include "common/error.h"
39 #include "parallelization_util.h"
40 
41 namespace ug{
42 
43 template <class TIndVec>
44 void GenerateGlobalConsecutiveIndices(TIndVec& indsOut, size_t numLocalInds,
45  const AlgebraLayouts& layouts)
46 {
47  typedef typename TIndVec::value_type index_t;
48 
50  indsOut.clear();
51  indsOut.resize(numLocalInds, 0);
52 
53 // count local unique indices. Ignore vmasters and hslaves.
54 // we're using uint64 here to stay compatible with mpi
55  uint64 numLocalUniqueInds = 0;
56  const index_t invalidIndex = -1;
57  SetLayoutValues(&indsOut, layouts.slave(), invalidIndex);
58  SetLayoutValues(&indsOut, layouts.vertical_master(), invalidIndex);
59 
60  for(size_t i = 0; i < numLocalInds; ++i){
61  if(indsOut[i] != invalidIndex){
62  ++numLocalUniqueInds;
63  }
64  }
65 
66 // we'll now gather the numbers of local unique indices on proces 0 and create
67 // an offset map for each process. This offset map will then be scattered to
68 // the separate processes again.
69  const pcl::ProcessCommunicator& procCom = layouts.proc_comm();
70  std::vector<uint64> p0_uniqueIndNumbers(procCom.size());
71 
72  procCom.gather(&numLocalUniqueInds, 1, PCL_DT_UNSIGNED_LONG_LONG,
73  &p0_uniqueIndNumbers.front(), 1, PCL_DT_UNSIGNED_LONG_LONG, 0);
74 
75  if(procCom.get_local_proc_id() == 0){
76  // convert the number of unique indices of each process to offsets
77  uint64 offset = 0;
78  for(size_t i = 0; i < p0_uniqueIndNumbers.size(); ++i){
79  size_t newOffset = offset + p0_uniqueIndNumbers[i];
80  p0_uniqueIndNumbers[i] = offset;
81  offset = newOffset;
82  }
83  }
84 
85  uint64 indOffset = 0;
86  procCom.scatter(&p0_uniqueIndNumbers.front(), 1, PCL_DT_UNSIGNED_LONG_LONG,
87  &indOffset, 1, PCL_DT_UNSIGNED_LONG_LONG, 0);
88 
89 // using the local offset we can now assign the local unique indices to indsOut
90  index_t newInd = static_cast<index_t>(indOffset);
91  for(size_t i = 0; i < numLocalInds; ++i){
92  if(indsOut[i] != invalidIndex){
93  indsOut[i] = newInd;
94  ++newInd;
95  }
96  }
97 
98 // finally we have to copy the unique indices from hmasters to hslaves and
99 // afterwards from vslaves to vmasters.
101  ComPol_VecCopy<TIndVec> compolCopy(&indsOut);
102 
103  icom.send_data(layouts.master(), compolCopy);
104  icom.receive_data(layouts.slave(), compolCopy);
105  icom.communicate();
106 
107 // Todo: This method is mainly used on surface-layouts.
108 // Currently a bug in those layouts prevents the execution of the following code
109 // which would be required for level-matrices.
110 // Since ghosts (pure v-masters) are ignored in surface-vectors and matrices,
111 // but pure v-slaves are considered, v-master and v-slave interfaces do not
112 // match. Fortunately they are not required for surface-index-generation.
113 // The following block should however be used as soon as those layouts are fixed.
114  // icom.send_data(layouts.vertical_slave(), compolCopy);
115  // icom.receive_data(layouts.vertical_master(), compolCopy);
116  // icom.communicate();
117 }
118 
119 
120 template <class TMatrix>
122  const TMatrix& mat,
123  std::vector<AlgebraID>* algebraIDs,
124  bool verbose)
125 {
126  const AlgebraLayouts& layouts = *mat.layouts();
127 
128  std::vector<AlgebraID> fallbackAlgebraIDs;
129  if(!algebraIDs) {
130  GenerateGlobalAlgebraIDs(layouts.comm(),
131  fallbackAlgebraIDs,
132  mat.num_rows(),
133  layouts.master(),
134  layouts.slave());
135  algebraIDs = &fallbackAlgebraIDs;
136  }
137 
138  struct IDByIndex {
139  IDByIndex (const std::vector<AlgebraID>* algIDs) : m_algIDs(*algIDs) {}
140  const AlgebraID& operator () (size_t idx) const {return m_algIDs[idx];}
141  const std::vector<AlgebraID>& m_algIDs;
142  };
143 
144  IDByIndex idByIndex(algebraIDs);
145 
146  bool ok = pcl::TestLayout<IndexLayout, AlgebraID> (
147  layouts.proc_comm(),
148  layouts.comm(),
149  layouts.master(),
150  layouts.slave(),
151  verbose,
152  idByIndex,
153  true);
154  UG_COND_THROW(!ok, "H-Master <-> H-Slave mismatch in matrix layout");
155 
156 // Global IDs do of course not match in overlap interfaces
157  ok = pcl::TestLayout<IndexLayout> (
158  layouts.proc_comm(),
159  layouts.comm(),
160  layouts.master_overlap(),
161  layouts.slave_overlap(),
162  verbose);
163  UG_COND_THROW(!ok, "H-Master-Overlap <-> H-Slave-Overlap mismatch in matrix layout");
164 }
165 
166 }// end of namespace
167 
168 #endif //__H__LIB_ALGEBRA__PARALLELIZATION__PARALLELIZATION_UTIL_IMPL__
location verbose
Definition: checkpoint_util.lua:128
Performs communication between interfaces on different processes.
Definition: pcl_interface_communicator.h:68
bool communicate(int tag=749345)
sends and receives the collected data.
Definition: pcl_interface_communicator_impl.hpp:409
void send_data(int targetProc, const Interface &interface, ICommunicationPolicy< TLayout > &commPol)
collects data that will be send during communicate.
Definition: pcl_interface_communicator_impl.hpp:80
void receive_data(int srcProc, const Interface &interface, ICommunicationPolicy< TLayout > &commPol)
registers a communication-policy to receive data on communicate.
Definition: pcl_interface_communicator_impl.hpp:188
Definition: pcl_process_communicator.h:70
void gather(const void *sendBuf, int sendCount, DataType sendType, void *recBuf, int recCount, DataType recType, int root) const
performs MPI_Gather on the processes of the communicator.
Definition: pcl_process_communicator.cpp:339
size_t size() const
returns the size of the communicator
Definition: pcl_process_communicator.cpp:71
void scatter(const void *sendBuf, int sendCount, DataType sendType, void *recBuf, int recCount, DataType recType, int root) const
performs MPI_Scatter on the processes of the communicator
Definition: pcl_process_communicator.cpp:392
int get_local_proc_id(int globalProcID=pcl::ProcRank()) const
returns the proc-id relative to this communicator
Definition: pcl_process_communicator.cpp:95
Extends the HorizontalAlgebraLayouts by vertical layouts.
Definition: algebra_layouts.h:121
const IndexLayout & vertical_master() const
Definition: algebra_layouts.h:133
Communication Policy to copy values of a vector.
Definition: communication_policies.h:88
const pcl::ProcessCommunicator & proc_comm() const
returns process communicator
Definition: algebra_layouts.h:68
const IndexLayout & master_overlap() const
Definition: algebra_layouts.h:62
const IndexLayout & slave() const
Definition: algebra_layouts.h:63
const IndexLayout & master() const
Definition: algebra_layouts.h:61
pcl::InterfaceCommunicator< IndexLayout > & comm() const
returns (non-const !!!) communicator
Definition: algebra_layouts.h:78
const IndexLayout & slave_overlap() const
Definition: algebra_layouts.h:64
void GenerateGlobalAlgebraIDs(pcl::InterfaceCommunicator< TLayout > &communicator, std::vector< AlgebraID > &idsOut, size_t numIDs, const TLayout &masterLayout, const TLayout &slaveLayout)
Generates a set of unique global algebra ids.
Definition: parallelization_util.h:81
void SetLayoutValues(TVector *pVec, const IndexLayout &layout, typename TVector::value_type val)
sets the values of a vector to a given number only on the layout indices
Definition: parallelization_util.h:315
#define PCL_DT_UNSIGNED_LONG_LONG
Definition: pcl_datatype.h:55
#define UG_COND_THROW(cond, msg)
UG_COND_THROW(cond, msg) : performs a UG_THROW(msg) if cond == true.
Definition: error.h:61
ugtypes::uint64_t uint64
Definition: types.h:117
#define PU_PROFILE_FUNC()
Definition: parallelization_util.h:48
the ug namespace
void GenerateGlobalConsecutiveIndices(TIndVec &indsOut, size_t numLocalInds, const AlgebraLayouts &layouts)
Generates a set of global consecutive indices.
Definition: parallelization_util_impl.h:44
void TestHorizontalAlgebraLayouts(const TMatrix &mat, std::vector< AlgebraID > *algebraIDs=NULL, bool verbose=false)
Tests layouts by matching master and slave interfaces and by comparing global id's.
Definition: parallelization_util_impl.h:121
T value_type
Definition: sparsematrix_interface.h:2
value_type & operator()(size_t r, size_t c)
this type is used to identify distributed objects.
Definition: algebra_id.h:46