FEI Version of the Day
fei_set_shared_ids.cpp
00001 
00002 #include <fei_set_shared_ids.hpp>
00003 #include <fei_CommMap.hpp>
00004 #include <fei_CommUtils.hpp>
00005 #include <fei_TemplateUtils.hpp>
00006 #include <snl_fei_RecordCollection.hpp>
00007 #include <fei_SharedIDs.hpp>
00008 #include <fei_LinearDecomposition.hpp>
00009 
00010 namespace fei {
00011 
00012 void copy_into_shared_ids(const fei::CommMap<int>::Type& procs_to_ids_and_sharing_procs,
00013                           const snl_fei::RecordCollection& records,
00014                           fei::SharedIDs<int>& sharedIDs)
00015 {
00016   //Given a CommMap object which maps procs to packed vectors of ids and sharing
00017   //procs, and a RecordCollection of records that appear in the local subdomain:
00018   //Loop through the CommMap and for each id that exists in 'records', copy that
00019   //id along with the associated sharing procs into the sharedIDs object.
00020 
00021   fei::CommMap<int>::Type::const_iterator
00022     ip_iter = procs_to_ids_and_sharing_procs.begin(),
00023     ip_end = procs_to_ids_and_sharing_procs.end();
00024 
00025   for(; ip_iter != ip_end; ++ip_iter) {
00026     const std::vector<int>& ids_and_procs = ip_iter->second;
00027     size_t vsize = ids_and_procs.size();
00028     size_t offset = 0;
00029     while(offset < vsize) {
00030       int id = ids_and_procs[offset++];
00031       int num_procs = ids_and_procs[offset++];
00032       if (records.getRecordWithID(id) != NULL) {
00033         sharedIDs.addSharedID(id, num_procs, &ids_and_procs[offset]);
00034       }
00035       offset += num_procs;
00036     }
00037   }
00038 }
00039 
00040 void copy_remotelyowned_ids_into_CommMap(int myProc,
00041                                          const fei::LinearDecomposition<int>& lindecomp,
00042                                          const snl_fei::RecordCollection& records,
00043                                          fei::CommMap<int>::Type& procs_to_shared_ids)
00044 {
00045   typedef snl_fei::RecordCollection::map_type map_type;
00046   const map_type& rmap = records.getRecords();
00047 
00048   map_type::const_iterator
00049     r_iter = rmap.begin(), r_end = rmap.end();
00050 
00051   for(; r_iter!=r_end; ++r_iter) {
00052     int ID = r_iter->first;
00053     int proc = lindecomp.which_proc(ID);
00054     if (proc != myProc) {
00055       addItemsToCommMap(proc, 1, &ID, procs_to_shared_ids);
00056     }
00057   }
00058 }
00059 
00060 void set_shared_ids(MPI_Comm comm,
00061                     const snl_fei::RecordCollection& records,
00062                     fei::SharedIDs<int>& sharedIDs)
00063 {
00064   sharedIDs.getSharedIDs().clear();
00065   sharedIDs.getOwningProcs().clear();
00066 
00067   int numProcs = fei::numProcs(comm);
00068   if (numProcs < 2) return;
00069   int myProc = fei::localProc(comm);
00070 
00071   typedef snl_fei::RecordCollection::map_type map_type;
00072   const map_type& rmap = records.getRecords();
00073   int local_rmap_size = rmap.size();
00074   int global_rmap_size = 0;
00075   fei::GlobalMax(comm, local_rmap_size, global_rmap_size);
00076   if (global_rmap_size == 0) return;
00077 
00078   map_type::const_iterator highest = rmap.end();
00079   if (local_rmap_size > 0) --highest;
00080 
00081   int lowest_local_id = local_rmap_size>0 ? rmap.begin()->first : 0;
00082   int highest_local_id = local_rmap_size>0 ? highest->first : 0;
00083 
00084   int lowest_global_id = 0;
00085   int highest_global_id = 0;
00086 
00087   fei::GlobalMax(comm, highest_local_id, highest_global_id);
00088   fei::GlobalMin(comm, lowest_local_id, lowest_global_id);
00089 
00090   fei::LinearDecomposition<int> lindecomp(myProc,numProcs,
00091                                      lowest_global_id, highest_global_id);
00092 
00093   //Fill a CommMap (procs_to_shared_ids) that maps other procs to ids which we hold.
00094   //These are ids that appear locally, but which are *not* in our portion
00095   //of the linear-decomposition.
00096   fei::CommMap<int>::Type procs_to_shared_ids;
00097   copy_remotelyowned_ids_into_CommMap(myProc, lindecomp, records, procs_to_shared_ids);
00098 
00099   //Do a global-exchange where we send ids we share to procs that own them,
00100   //and receive IDs that we own from other procs that share them.
00101   fei::CommMap<int>::Type procs_to_owned_ids;
00102   fei::exchangeCommMapData<int>(comm, procs_to_shared_ids, procs_to_owned_ids);
00103 
00104   //transpose procs_to_owned_ids:
00105   fei::CommMap<int>::Type owned_ids_to_procs;
00106 
00107   fei::CommMap<int>::Type::iterator
00108     o_iter = procs_to_owned_ids.begin(), o_end = procs_to_owned_ids.end();
00109 
00110   for(; o_iter != o_end; ++o_iter) {
00111     int proc = o_iter->first;
00112     std::vector<int>& ids = o_iter->second;
00113     for(size_t i=0; i<ids.size(); ++i) {
00114       addItemsToCommMap(ids[i], 1, &proc, owned_ids_to_procs);
00115       if (records.getRecordWithID(ids[i]) != NULL) {
00116         addItemsToCommMap(ids[i], 1, &myProc, owned_ids_to_procs);
00117       }
00118     }
00119   }
00120 
00121   fei::CommMap<int>::Type procs_to_owned_ids_and_sharing_procs;
00122 
00123   for(o_iter=procs_to_owned_ids.begin(); o_iter!=procs_to_owned_ids.end(); ++o_iter) {
00124     int proc = o_iter->first;
00125     std::vector<int>& ids = o_iter->second;
00126     for(size_t i=0; i<ids.size(); ++i) {
00127       std::vector<int>& sharing_procs = owned_ids_to_procs[ids[i]];
00128       addItemsToCommMap(proc, 1, &ids[i], procs_to_owned_ids_and_sharing_procs, false);
00129       int num_sharing_procs = sharing_procs.size();
00130       addItemsToCommMap(proc, 1, &num_sharing_procs, procs_to_owned_ids_and_sharing_procs, false);
00131       addItemsToCommMap(proc, num_sharing_procs, &sharing_procs[0], procs_to_owned_ids_and_sharing_procs, false);
00132     }
00133   }
00134 
00135   fei::CommMap<int>::Type procs_to_shared_ids_and_sharing_procs;
00136   fei::exchangeCommMapData<int>(comm, procs_to_owned_ids_and_sharing_procs,
00137                                  procs_to_shared_ids_and_sharing_procs);
00138 
00139   copy_into_shared_ids(procs_to_owned_ids_and_sharing_procs, records, sharedIDs);
00140   copy_into_shared_ids(procs_to_shared_ids_and_sharing_procs, records, sharedIDs);
00141 }
00142 
00143 }//namespace fei
00144 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends