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   for(int i=0; i<records.getNumRecords(); ++i) {
00046     int ID = records.getRecordWithLocalID(i)->getID();
00047     int proc = lindecomp.which_proc(ID);
00048     if (proc != myProc) {
00049       addItemsToCommMap(proc, 1, &ID, procs_to_shared_ids);
00050     }
00051   }
00052 }
00053 
00054 void set_shared_ids(MPI_Comm comm,
00055                     const snl_fei::RecordCollection& records,
00056                     fei::SharedIDs<int>& sharedIDs)
00057 {
00058   sharedIDs.getSharedIDs().clear();
00059   sharedIDs.getOwningProcs().clear();
00060 
00061   int numProcs = fei::numProcs(comm);
00062   if (numProcs < 2) return;
00063   int myProc = fei::localProc(comm);
00064 
00065   const std::map<int,int>& rmap = records.getGlobalToLocalMap();
00066   int local_rmap_size = rmap.size();
00067   int global_rmap_size = 0;
00068   fei::GlobalMax(comm, local_rmap_size, global_rmap_size);
00069   if (global_rmap_size == 0) return;
00070 
00071   std::map<int,int>::const_iterator highest = rmap.end();
00072   if (local_rmap_size > 0) --highest;
00073 
00074   int lowest_local_id = local_rmap_size>0 ? rmap.begin()->first : 0;
00075   int highest_local_id = local_rmap_size>0 ? highest->first : 0;
00076 
00077   int lowest_global_id = 0;
00078   int highest_global_id = 0;
00079 
00080   fei::GlobalMax(comm, highest_local_id, highest_global_id);
00081   fei::GlobalMin(comm, lowest_local_id, lowest_global_id);
00082 
00083   fei::LinearDecomposition<int> lindecomp(myProc,numProcs,
00084                                      lowest_global_id, highest_global_id);
00085 
00086   //Fill a CommMap (procs_to_shared_ids) that maps other procs to ids which we hold.
00087   //These are ids that appear locally, but which are *not* in our portion
00088   //of the linear-decomposition.
00089   fei::CommMap<int>::Type procs_to_shared_ids;
00090   copy_remotelyowned_ids_into_CommMap(myProc, lindecomp, records, procs_to_shared_ids);
00091 
00092   //Do a global-exchange where we send ids we share to procs that own them,
00093   //and receive IDs that we own from other procs that share them.
00094   fei::CommMap<int>::Type procs_to_owned_ids;
00095   fei::exchangeCommMapData<int>(comm, procs_to_shared_ids, procs_to_owned_ids);
00096 
00097   //transpose procs_to_owned_ids:
00098   fei::CommMap<int>::Type owned_ids_to_procs;
00099 
00100   fei::CommMap<int>::Type::iterator
00101     o_iter = procs_to_owned_ids.begin(), o_end = procs_to_owned_ids.end();
00102 
00103   for(; o_iter != o_end; ++o_iter) {
00104     int proc = o_iter->first;
00105     std::vector<int>& ids = o_iter->second;
00106     for(size_t i=0; i<ids.size(); ++i) {
00107       addItemsToCommMap(ids[i], 1, &proc, owned_ids_to_procs);
00108       if (records.getRecordWithID(ids[i]) != NULL) {
00109         addItemsToCommMap(ids[i], 1, &myProc, owned_ids_to_procs);
00110       }
00111     }
00112   }
00113 
00114   fei::CommMap<int>::Type procs_to_owned_ids_and_sharing_procs;
00115 
00116   for(o_iter=procs_to_owned_ids.begin(); o_iter!=procs_to_owned_ids.end(); ++o_iter) {
00117     int proc = o_iter->first;
00118     std::vector<int>& ids = o_iter->second;
00119     for(size_t i=0; i<ids.size(); ++i) {
00120       std::vector<int>& sharing_procs = owned_ids_to_procs[ids[i]];
00121       addItemsToCommMap(proc, 1, &ids[i], procs_to_owned_ids_and_sharing_procs, false);
00122       int num_sharing_procs = sharing_procs.size();
00123       addItemsToCommMap(proc, 1, &num_sharing_procs, procs_to_owned_ids_and_sharing_procs, false);
00124       addItemsToCommMap(proc, num_sharing_procs, &sharing_procs[0], procs_to_owned_ids_and_sharing_procs, false);
00125     }
00126   }
00127 
00128   fei::CommMap<int>::Type procs_to_shared_ids_and_sharing_procs;
00129   fei::exchangeCommMapData<int>(comm, procs_to_owned_ids_and_sharing_procs,
00130                                  procs_to_shared_ids_and_sharing_procs);
00131 
00132   copy_into_shared_ids(procs_to_owned_ids_and_sharing_procs, records, sharedIDs);
00133   copy_into_shared_ids(procs_to_shared_ids_and_sharing_procs, records, sharedIDs);
00134 }
00135 
00136 }//namespace fei
00137 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends