FEI  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
fei_set_shared_ids.cpp
1 
2 #include <sstream>
3 #include <fei_set_shared_ids.hpp>
4 #include <fei_CommMap.hpp>
5 #include <fei_CommUtils.hpp>
6 #include <fei_TemplateUtils.hpp>
7 #include <snl_fei_RecordCollection.hpp>
8 #include <fei_SharedIDs.hpp>
9 #include <fei_LinearDecomposition.hpp>
10 
11 namespace fei {
12 
13 void copy_into_shared_ids(const fei::CommMap<int>::Type& procs_to_ids_and_sharing_procs,
14  const snl_fei::RecordCollection& records,
15  fei::SharedIDs<int>& sharedIDs)
16 {
17  //Given a CommMap object which maps procs to packed vectors of ids and sharing
18  //procs, and a RecordCollection of records that appear in the local subdomain:
19  //Loop through the CommMap and for each id that exists in 'records', copy that
20  //id along with the associated sharing procs into the sharedIDs object.
21 
23  ip_iter = procs_to_ids_and_sharing_procs.begin(),
24  ip_end = procs_to_ids_and_sharing_procs.end();
25 
26  for(; ip_iter != ip_end; ++ip_iter) {
27  const std::vector<int>& ids_and_procs = ip_iter->second;
28  size_t vsize = ids_and_procs.size();
29  size_t offset = 0;
30  while(offset < vsize) {
31  int id = ids_and_procs[offset++];
32  int num_procs = ids_and_procs[offset++];
33  if (records.getRecordWithID(id) != NULL) {
34  sharedIDs.addSharedID(id, num_procs, &ids_and_procs[offset]);
35  }
36  offset += num_procs;
37  }
38  }
39 }
40 
41 void copy_remotelyowned_ids_into_CommMap(int myProc,
42  const fei::LinearDecomposition<int>& lindecomp,
43  const snl_fei::RecordCollection& records,
44  fei::CommMap<int>::Type& procs_to_shared_ids)
45 {
46  for(size_t i=0; i<records.getNumRecords(); ++i) {
47  int ID = records.getRecordWithLocalID(i)->getID();
48  int proc = lindecomp.which_proc(ID);
49  if (proc != myProc) {
50  addItemsToCommMap(proc, 1, &ID, procs_to_shared_ids);
51  }
52  }
53 }
54 
55 void set_shared_ids(MPI_Comm comm,
56  const snl_fei::RecordCollection& records,
57  fei::SharedIDs<int>& sharedIDs,
58  int lowest_global_id, int highest_global_id)
59 {
60  sharedIDs.getSharedIDs().clear();
61  sharedIDs.getOwningProcs().clear();
62 
63  int numProcs = fei::numProcs(comm);
64  if (numProcs < 2) return;
65  int myProc = fei::localProc(comm);
66 
67  fei::LinearDecomposition<int> lindecomp(myProc,numProcs,
68  lowest_global_id, highest_global_id);
69 
70  //Fill a CommMap (procs_to_shared_ids) that maps other procs to ids which we
71  //have, but which are not in our portion of the linear decomposition.
72  fei::CommMap<int>::Type procs_to_shared_ids;
73  copy_remotelyowned_ids_into_CommMap(myProc, lindecomp, records, procs_to_shared_ids);
74 
75  //Do a global-exchange where we send those ids to procs that own them in the
76  //linear decomposition.
77  //And receive IDs in our portion of the linear decomposition from other procs
78  //that hold them.
79  fei::CommMap<int>::Type procs_to_owned_ids;
80  fei::exchangeCommMapData<int>(comm, procs_to_shared_ids, procs_to_owned_ids);
81 
82  //transpose procs_to_owned_ids:
83  fei::CommMap<int>::Type owned_ids_to_procs;
84 
86  o_iter = procs_to_owned_ids.begin(), o_end = procs_to_owned_ids.end();
87 
88  for(; o_iter != o_end; ++o_iter) {
89  int proc = o_iter->first;
90  std::vector<int>& ids = o_iter->second;
91  for(size_t i=0; i<ids.size(); ++i) {
92  addItemsToCommMap(ids[i], 1, &proc, owned_ids_to_procs);
93  if (records.getRecordWithID(ids[i]) != NULL) {
94  addItemsToCommMap(ids[i], 1, &myProc, owned_ids_to_procs);
95  }
96  }
97  }
98 
99  fei::CommMap<int>::Type procs_to_owned_ids_and_sharing_procs;
100 
101  for(o_iter=procs_to_owned_ids.begin(); o_iter!=procs_to_owned_ids.end(); ++o_iter) {
102  int proc = o_iter->first;
103  std::vector<int>& ids = o_iter->second;
104  for(size_t i=0; i<ids.size(); ++i) {
105  std::vector<int>& sharing_procs = owned_ids_to_procs[ids[i]];
106  int num_sharing_procs = sharing_procs.size();
107  if (num_sharing_procs > 1) {
108  addItemsToCommMap(proc, 1, &ids[i], procs_to_owned_ids_and_sharing_procs, false);
109  addItemsToCommMap(proc, 1, &num_sharing_procs, procs_to_owned_ids_and_sharing_procs, false);
110  addItemsToCommMap(proc, num_sharing_procs, &sharing_procs[0], procs_to_owned_ids_and_sharing_procs, false);
111  }
112  }
113  }
114 
115  fei::CommMap<int>::Type procs_to_shared_ids_and_sharing_procs;
116  fei::exchangeCommMapData<int>(comm, procs_to_owned_ids_and_sharing_procs,
117  procs_to_shared_ids_and_sharing_procs);
118 
119  copy_into_shared_ids(procs_to_owned_ids_and_sharing_procs, records, sharedIDs);
120  copy_into_shared_ids(procs_to_shared_ids_and_sharing_procs, records, sharedIDs);
121 }
122 
123 }//namespace fei
124 
void addItemsToCommMap(int proc, size_t numItems, const T *items, typename CommMap< T >::Type &comm_map, bool keep_sorted_and_unique=true)
Definition: fei_CommMap.hpp:32
std::vector< int > & getOwningProcs()
map_type & getSharedIDs()
void set_shared_ids(MPI_Comm comm, const snl_fei::RecordCollection &records, fei::SharedIDs< int > &sharedIDs, int lowest_global_id, int highest_global_id)
size_t getNumRecords() const
void addSharedID(const T &ID, size_t numSharingProcs, const int *sharingProcs)
int localProc(MPI_Comm comm)
fei::Record< int > * getRecordWithID(int ID)
int numProcs(MPI_Comm comm)