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(size_t 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                     int lowest_global_id, int highest_global_id)
00058 {
00059   sharedIDs.getSharedIDs().clear();
00060   sharedIDs.getOwningProcs().clear();
00061 
00062   int numProcs = fei::numProcs(comm);
00063   if (numProcs < 2) return;
00064   int myProc = fei::localProc(comm);
00065 
00066   fei::LinearDecomposition<int> lindecomp(myProc,numProcs,
00067                                      lowest_global_id, highest_global_id);
00068 
00069   //Fill a CommMap (procs_to_shared_ids) that maps other procs to ids which we hold.
00070   //These are ids that appear locally, but which are *not* in our portion
00071   //of the linear-decomposition.
00072   fei::CommMap<int>::Type procs_to_shared_ids;
00073   copy_remotelyowned_ids_into_CommMap(myProc, lindecomp, records, procs_to_shared_ids);
00074 
00075   //Do a global-exchange where we send ids we share to procs that own them,
00076   //and receive IDs that we own from other procs that share them.
00077   fei::CommMap<int>::Type procs_to_owned_ids;
00078   fei::exchangeCommMapData<int>(comm, procs_to_shared_ids, procs_to_owned_ids);
00079 
00080   //transpose procs_to_owned_ids:
00081   fei::CommMap<int>::Type owned_ids_to_procs;
00082 
00083   fei::CommMap<int>::Type::iterator
00084     o_iter = procs_to_owned_ids.begin(), o_end = procs_to_owned_ids.end();
00085 
00086   for(; o_iter != o_end; ++o_iter) {
00087     int proc = o_iter->first;
00088     std::vector<int>& ids = o_iter->second;
00089     for(size_t i=0; i<ids.size(); ++i) {
00090       addItemsToCommMap(ids[i], 1, &proc, owned_ids_to_procs);
00091       if (records.getRecordWithID(ids[i]) != NULL) {
00092         addItemsToCommMap(ids[i], 1, &myProc, owned_ids_to_procs);
00093       }
00094     }
00095   }
00096 
00097   fei::CommMap<int>::Type procs_to_owned_ids_and_sharing_procs;
00098 
00099   for(o_iter=procs_to_owned_ids.begin(); o_iter!=procs_to_owned_ids.end(); ++o_iter) {
00100     int proc = o_iter->first;
00101     std::vector<int>& ids = o_iter->second;
00102     for(size_t i=0; i<ids.size(); ++i) {
00103       std::vector<int>& sharing_procs = owned_ids_to_procs[ids[i]];
00104       addItemsToCommMap(proc, 1, &ids[i], procs_to_owned_ids_and_sharing_procs, false);
00105       int num_sharing_procs = sharing_procs.size();
00106       addItemsToCommMap(proc, 1, &num_sharing_procs, procs_to_owned_ids_and_sharing_procs, false);
00107       addItemsToCommMap(proc, num_sharing_procs, &sharing_procs[0], procs_to_owned_ids_and_sharing_procs, false);
00108     }
00109   }
00110 
00111   fei::CommMap<int>::Type procs_to_shared_ids_and_sharing_procs;
00112   fei::exchangeCommMapData<int>(comm, procs_to_owned_ids_and_sharing_procs,
00113                                  procs_to_shared_ids_and_sharing_procs);
00114 
00115   copy_into_shared_ids(procs_to_owned_ids_and_sharing_procs, records, sharedIDs);
00116   copy_into_shared_ids(procs_to_shared_ids_and_sharing_procs, records, sharedIDs);
00117 }
00118 
00119 }//namespace fei
00120 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends