moab
|
00001 00017 #ifndef MOAB_PARALLEL_COMM_HPP 00018 #define MOAB_PARALLEL_COMM_HPP 00019 00020 #include "moab/Forward.hpp" 00021 #include "moab/Interface.hpp" 00022 #include "moab/Range.hpp" 00023 #include "moab/ProcConfig.hpp" 00024 #include <map> 00025 #include <set> 00026 #include <vector> 00027 #include <iostream> 00028 #include <fstream> 00029 #include <assert.h> 00030 #include <stdlib.h> 00031 #include "math.h" 00032 #include "moab/TupleList.hpp" 00033 00034 namespace moab { 00035 00036 class SequenceManager; 00037 class Error; 00038 template <typename KeyType, typename ValType, ValType NullVal> class RangeMap; 00039 typedef RangeMap<EntityHandle, EntityHandle, 0> HandleMap; 00040 class ParallelMergeMesh; 00041 class DebugOutput; 00042 class SharedSetData; 00043 00044 #define MAX_SHARING_PROCS 64 00045 00053 class ParallelComm 00054 { 00055 public: 00056 00057 friend class ParallelMergeMesh; 00058 00059 // ================================== 00060 // \section CONSTRUCTORS/DESTRUCTORS/PCOMM MANAGEMENT 00061 // ================================== 00062 00064 ParallelComm(Interface *impl, 00065 MPI_Comm comm, 00066 int* pcomm_id_out = 0); 00067 00069 ParallelComm(Interface *impl, 00070 std::vector<unsigned char> &tmp_buff, 00071 MPI_Comm comm, 00072 int* pcomm_id_out = 0); 00073 00075 int get_id() const { return pcommID; } 00076 00078 static ParallelComm *get_pcomm(Interface *impl, const int index); 00079 00083 static ParallelComm *get_pcomm( Interface* impl, 00084 EntityHandle partitioning, 00085 const MPI_Comm* comm = 0 ); 00086 00087 static ErrorCode get_all_pcomm( Interface* impl, 00088 std::vector<ParallelComm*>& list ); 00089 00091 ~ParallelComm(); 00092 00093 static unsigned char PROC_SHARED, PROC_OWNER; 00094 00095 // ================================== 00096 // \section GLOBAL IDS 00097 // ================================== 00098 00103 ErrorCode assign_global_ids(EntityHandle this_set, 00104 const int dimension, 00105 const int start_id = 1, 00106 const bool largest_dim_only = true, 00107 const bool parallel = true, 00108 const bool owned_only = false); 00109 00112 ErrorCode assign_global_ids( Range entities[], 00113 const int dimension, 00114 const int start_id, 00115 const bool parallel, 00116 const bool owned_only); 00117 00122 ErrorCode check_global_ids(EntityHandle this_set, 00123 const int dimension, 00124 const int start_id = 1, 00125 const bool largest_dim_only = true, 00126 const bool parallel = true, 00127 const bool owned_only = false); 00128 00129 // ================================== 00130 // \section HIGH-LEVEL COMMUNICATION (send/recv/bcast/scatter ents, exchange tags) 00131 // ================================== 00132 00148 ErrorCode send_entities(const int to_proc, 00149 Range &orig_ents, 00150 const bool adjs, 00151 const bool tags, 00152 const bool store_remote_handles, 00153 const bool is_iface, 00154 Range &final_ents, 00155 int &incoming1, 00156 int &incoming2, // newly added 00157 TupleList& entprocs, // newly added 00158 std::vector<MPI_Request> &recv_remoteh_reqs, // newly added 00159 bool wait_all = true); 00160 00161 ErrorCode send_entities(std::vector<unsigned int>& send_procs, 00162 std::vector<Range*>& send_ents, 00163 int& incoming1, int& incoming2, 00164 const bool store_remote_handles); 00165 00177 ErrorCode recv_entities(const int from_proc, 00178 const bool store_remote_handles, 00179 const bool is_iface, 00180 Range &final_ents, 00181 int& incomming1, 00182 int& incoming2, 00183 std::vector<std::vector<EntityHandle> > &L1hloc, 00184 std::vector<std::vector<EntityHandle> > &L1hrem, 00185 std::vector<std::vector<int> > &L1p, 00186 std::vector<EntityHandle> &L2hloc, 00187 std::vector<EntityHandle> &L2hrem, 00188 std::vector<unsigned int> &L2p, 00189 std::vector<MPI_Request> &recv_remoteh_reqs, 00190 bool wait_all = true); 00191 00192 ErrorCode recv_entities(std::set<unsigned int>& recv_procs, 00193 int incoming1, int incoming2, 00194 const bool store_remote_handles, 00195 const bool migrate = false); 00196 00205 ErrorCode recv_messages(const int from_proc, 00206 const bool store_remote_handles, 00207 const bool is_iface, 00208 Range &final_ents, 00209 int& incoming1, 00210 int& incoming2, 00211 std::vector<std::vector<EntityHandle> > &L1hloc, 00212 std::vector<std::vector<EntityHandle> > &L1hrem, 00213 std::vector<std::vector<int> > &L1p, 00214 std::vector<EntityHandle> &L2hloc, 00215 std::vector<EntityHandle> &L2hrem, 00216 std::vector<unsigned int> &L2p, 00217 std::vector<MPI_Request> &recv_remoteh_reqs); 00218 00219 ErrorCode recv_remote_handle_messages(const int from_proc, 00220 int& incoming2, 00221 std::vector<EntityHandle> &L2hloc, 00222 std::vector<EntityHandle> &L2hrem, 00223 std::vector<unsigned int> &L2p, 00224 std::vector<MPI_Request> &recv_remoteh_reqs); 00225 00245 ErrorCode exchange_ghost_cells(int ghost_dim, int bridge_dim, 00246 int num_layers, int addl_ents, 00247 bool store_remote_handles, 00248 bool wait_all = true, 00249 EntityHandle *file_set = NULL); 00250 00254 static ErrorCode exchange_ghost_cells(ParallelComm **pc, 00255 unsigned int num_procs, 00256 int ghost_dim, int bridge_dim, 00257 int num_layers, int addl_ents, 00258 bool store_remote_handles, 00259 EntityHandle *file_sets = NULL); 00260 00264 ErrorCode post_irecv(std::vector<unsigned int>& exchange_procs); 00265 00266 ErrorCode post_irecv(std::vector<unsigned int>& shared_procs, 00267 std::set<unsigned int>& recv_procs); 00268 00277 ErrorCode exchange_owned_meshs(std::vector<unsigned int>& exchange_procs, 00278 std::vector<Range*>& exchange_ents, 00279 std::vector<MPI_Request>& recv_ent_reqs, 00280 std::vector<MPI_Request>& recv_remoteh_reqs, 00281 bool store_remote_handles, 00282 bool wait_all = true, 00283 bool migrate = false, 00284 int dim = 0); 00285 00290 ErrorCode exchange_owned_mesh(std::vector<unsigned int>& exchange_procs, 00291 std::vector<Range*>& exchange_ents, 00292 std::vector<MPI_Request>& recv_ent_reqs, 00293 std::vector<MPI_Request>& recv_remoteh_reqs, 00294 const bool recv_posted, 00295 bool store_remote_handles, 00296 bool wait_all, 00297 bool migrate = false); 00298 00309 ErrorCode exchange_tags( const std::vector<Tag> &src_tags, 00310 const std::vector<Tag> &dst_tags, 00311 const Range &entities); 00312 00321 ErrorCode exchange_tags( const char *tag_name, 00322 const Range &entities); 00323 00332 ErrorCode exchange_tags( Tag tagh, 00333 const Range &entities); 00334 00346 ErrorCode reduce_tags( const std::vector<Tag> &src_tags, 00347 const std::vector<Tag> &dst_tags, 00348 const MPI_Op mpi_op, 00349 const Range &entities); 00350 00358 ErrorCode reduce_tags( const char *tag_name, 00359 const MPI_Op mpi_op, 00360 const Range &entities); 00361 00369 ErrorCode reduce_tags( Tag tag_handle, 00370 const MPI_Op mpi_op, 00371 const Range &entities); 00372 00381 ErrorCode broadcast_entities(const int from_proc, 00382 Range& entities, 00383 const bool adjacencies = false, 00384 const bool tags = true ); 00385 00394 ErrorCode scatter_entities(const int from_proc, 00395 std::vector<Range> &entities, 00396 const bool adjacencies = false, 00397 const bool tags = true); 00398 00399 // ================================== 00400 // \section INITIALIZATION OF PARALLEL DATA (resolve_shared_ents, etc.) 00401 // ================================== 00402 00419 ErrorCode resolve_shared_ents(EntityHandle this_set, 00420 Range &proc_ents, 00421 int resolve_dim = -1, 00422 int shared_dim = -1, 00423 Range *skin_ents = NULL, 00424 const Tag* id_tag = 0); 00425 00437 ErrorCode resolve_shared_ents(EntityHandle this_set, 00438 int resolve_dim = 3, 00439 int shared_dim = -1, 00440 const Tag* id_tag = 0); 00441 00442 static ErrorCode resolve_shared_ents(ParallelComm **pc, 00443 const unsigned int np, 00444 EntityHandle this_set, 00445 const int to_dim); 00446 00456 ErrorCode resolve_shared_sets( EntityHandle this_set, const Tag* id_tag = 0 ); 00457 00465 ErrorCode resolve_shared_sets( Range& candidate_sets, Tag id_tag ); 00466 00467 // ================================== 00468 // \section GET PARALLEL DATA (shared/owned/iface entities, etc.) 00469 // ================================== 00470 00477 ErrorCode get_pstatus(EntityHandle entity, 00478 unsigned char &pstatus_val); 00479 00487 ErrorCode get_pstatus_entities(int dim, 00488 unsigned char pstatus_val, 00489 Range &pstatus_ents); 00490 00493 ErrorCode get_owner(EntityHandle entity, int &owner); 00494 00497 ErrorCode get_owner_handle(EntityHandle entity, 00498 int &owner, 00499 EntityHandle &handle); 00500 00510 ErrorCode get_sharing_data(const EntityHandle entity, 00511 int *ps, 00512 EntityHandle *hs, 00513 unsigned char &pstat, 00514 unsigned int &num_ps); 00515 00523 ErrorCode get_sharing_data(const EntityHandle entity, 00524 int *ps, 00525 EntityHandle *hs, 00526 unsigned char &pstat, 00527 int &num_ps); 00528 00537 ErrorCode get_sharing_data(const EntityHandle *entities, 00538 int num_entities, 00539 std::set<int> &procs, 00540 int op = Interface::INTERSECT); 00541 00545 ErrorCode get_sharing_data(const Range &entities, 00546 std::set<int> &procs, 00547 int op = Interface::INTERSECT); 00548 00558 ErrorCode get_shared_entities(int other_proc, 00559 Range &shared_ents, 00560 int dim = -1, 00561 const bool iface = false, 00562 const bool owned_filter = false); 00563 /* 00566 ErrorCode get_partition_sets(EntityHandle this_set, 00567 Range &part_sets, 00568 const char *tag_name = NULL); 00569 */ 00571 ErrorCode get_interface_procs(std::set<unsigned int> &iface_procs, 00572 const bool get_buffs = false); 00573 00575 ErrorCode get_comm_procs(std::set<unsigned int> &procs); 00576 00577 // ================================== 00578 // \section SHARED SETS 00579 // ================================== 00580 00583 ErrorCode get_entityset_procs( EntityHandle entity_set, 00584 std::vector<unsigned>& ranks ) const; 00585 00589 ErrorCode get_entityset_owner( EntityHandle entity_set, 00590 unsigned& owner_rank, 00591 EntityHandle* remote_handle = 0 ) const; 00592 00594 ErrorCode get_entityset_local_handle( unsigned owning_rank, 00595 EntityHandle remote_handle, 00596 EntityHandle& local_handle ) const; 00597 00599 ErrorCode get_shared_sets( Range& result ) const; 00600 00604 ErrorCode get_entityset_owners( std::vector<unsigned>& ranks ) const; 00605 00607 ErrorCode get_owned_sets( unsigned owning_rank, Range& sets_out ) const; 00608 00609 // ================================== 00610 // \section LOW-LEVEL DATA (tags, sets on interface/partition, etc.) 00611 // ================================== 00612 00614 const ProcConfig &proc_config() const {return procConfig;} 00615 00617 ProcConfig &proc_config() {return procConfig;} 00618 00619 unsigned rank() const { return proc_config().proc_rank(); } 00620 unsigned size() const { return proc_config().proc_size(); } 00621 MPI_Comm comm() const { return proc_config().proc_comm(); } 00622 00624 ErrorCode get_shared_proc_tags(Tag &sharedp_tag, 00625 Tag &sharedps_tag, 00626 Tag &sharedh_tag, 00627 Tag &sharedhs_tag, 00628 Tag &pstatus_tag); 00629 00631 Range &partition_sets() {return partitionSets;} 00632 const Range &partition_sets() const {return partitionSets;} 00633 Range &interface_sets() {return interfaceSets;} 00634 const Range &interface_sets() const {return interfaceSets;} 00635 00637 Tag sharedp_tag(); 00638 00640 Tag sharedps_tag(); 00641 00643 Tag sharedh_tag(); 00644 00646 Tag sharedhs_tag(); 00647 00649 Tag pstatus_tag(); 00650 00653 static Tag pcomm_tag(Interface *impl, 00654 bool create_if_missing = true); 00655 00657 Tag partition_tag(); 00658 Tag part_tag() { return partition_tag(); } 00659 00660 // ================================== 00661 // \section DEBUGGING AIDS 00662 // ================================== 00663 00665 void print_pstatus(unsigned char pstat, std::string &ostr); 00666 00668 void print_pstatus(unsigned char pstat); 00669 00670 // ================================== 00671 // \section IMESHP-RELATED FUNCTIONS 00672 // ================================== 00673 00675 ErrorCode get_part_entities(Range &ents, int dim = -1); 00676 00677 EntityHandle get_partitioning() const { return partitioningSet; } 00678 ErrorCode set_partitioning( EntityHandle h ); 00679 ErrorCode get_global_part_count( int& count_out ) const; 00680 ErrorCode get_part_owner( int part_id, int& owner_out ) const; 00681 ErrorCode get_part_id( EntityHandle part, int& id_out ) const; 00682 ErrorCode get_part_handle( int id, EntityHandle& handle_out ) const; 00683 ErrorCode create_part( EntityHandle& part_out ); 00684 ErrorCode destroy_part( EntityHandle part ) ; 00685 ErrorCode collective_sync_partition(); 00686 ErrorCode get_part_neighbor_ids( EntityHandle part, 00687 int neighbors_out[MAX_SHARING_PROCS], 00688 int& num_neighbors_out ); 00689 ErrorCode get_interface_sets( EntityHandle part, 00690 Range& iface_sets_out, 00691 int* adj_part_id = 0 ); 00692 ErrorCode get_owning_part( EntityHandle entity, 00693 int& owning_part_id_out, 00694 EntityHandle* owning_handle = 0 ); 00695 ErrorCode get_sharing_parts( EntityHandle entity, 00696 int part_ids_out[MAX_SHARING_PROCS], 00697 int& num_part_ids_out, 00698 EntityHandle remote_handles[MAX_SHARING_PROCS] = 0); 00699 00720 ErrorCode filter_pstatus( Range &ents, 00721 const unsigned char pstatus_val, 00722 const unsigned char op, 00723 int to_proc = -1, 00724 Range *returned_ents = NULL); 00725 00732 ErrorCode get_iface_entities(int other_proc, 00733 int dim, 00734 Range &iface_ents); 00735 00736 Interface* get_moab() const { return mbImpl; } 00737 00738 00739 ErrorCode clean_shared_tags(std::vector<Range*>& exchange_ents); 00740 00741 class Buffer { 00742 public: 00743 unsigned char *mem_ptr; 00744 unsigned char *buff_ptr; 00745 unsigned int alloc_size; 00746 00747 Buffer(unsigned int sz = 0); 00748 Buffer(const Buffer &); 00749 ~Buffer(); 00750 void reset_buffer(size_t buff_pos = 0) {reset_ptr(buff_pos); reserve(INITIAL_BUFF_SIZE);} 00751 void reset_ptr(size_t buff_pos = 0) {assert((!mem_ptr && !buff_pos)|| (alloc_size >= buff_pos)); buff_ptr = mem_ptr + buff_pos;} 00752 inline void reserve(unsigned int new_size); 00753 void set_stored_size() {*((int*)mem_ptr) = (int)(buff_ptr - mem_ptr);} 00754 int get_stored_size() {return *((int*)mem_ptr);} 00755 00756 void check_space(unsigned int addl_space); 00757 }; 00758 00760 ErrorCode pack_buffer(Range &orig_ents, 00761 const bool adjacencies, 00762 const bool tags, 00763 const bool store_remote_handles, 00764 const int to_proc, 00765 Buffer *buff, 00766 TupleList *entprocs = NULL, 00767 Range *allsent = NULL); 00768 00769 ErrorCode unpack_buffer(unsigned char *buff_ptr, 00770 const bool store_remote_handles, 00771 const int from_proc, 00772 const int ind, 00773 std::vector<std::vector<EntityHandle> > &L1hloc, 00774 std::vector<std::vector<EntityHandle> > &L1hrem, 00775 std::vector<std::vector<int> > &L1p, 00776 std::vector<EntityHandle> &L2hloc, 00777 std::vector<EntityHandle> &L2hrem, 00778 std::vector<unsigned int> &L2p, 00779 std::vector<EntityHandle> &new_ents, 00780 const bool created_iface = false); 00781 00782 ErrorCode pack_entities(Range &entities, 00783 Buffer *buff, 00784 const bool store_remote_handles, 00785 const int to_proc, 00786 const bool is_iface, 00787 TupleList *entprocs = NULL, 00788 Range *allsent = NULL); 00789 00791 ErrorCode unpack_entities(unsigned char *&buff_ptr, 00792 const bool store_remote_handles, 00793 const int from_ind, 00794 const bool is_iface, 00795 std::vector<std::vector<EntityHandle> > &L1hloc, 00796 std::vector<std::vector<EntityHandle> > &L1hrem, 00797 std::vector<std::vector<int> > &L1p, 00798 std::vector<EntityHandle> &L2hloc, 00799 std::vector<EntityHandle> &L2hrem, 00800 std::vector<unsigned int> &L2p, 00801 std::vector<EntityHandle> &new_ents, 00802 const bool created_iface = false); 00803 00806 ErrorCode check_all_shared_handles(bool print_em = false); 00807 00808 static ErrorCode check_all_shared_handles(ParallelComm **pcs, 00809 int num_pcs); 00810 00811 struct SharedEntityData { 00812 EntityHandle local; 00813 EntityHandle remote; 00814 EntityID owner; 00815 }; 00816 00817 ErrorCode pack_shared_handles( 00818 std::vector<std::vector<SharedEntityData> > &send_data); 00819 00820 // check consistency of sharedEnts against their tags and their 00821 // vertices' tags 00822 ErrorCode check_local_shared(); 00823 00824 // check contents of communicated shared entity data against tags 00825 ErrorCode check_my_shared_handles( 00826 std::vector<std::vector<SharedEntityData> > &shents, 00827 const char *prefix = NULL); 00828 00830 void set_rank(unsigned int r); 00831 00833 void set_size(unsigned int r); 00834 00839 int get_buffers(int to_proc, bool *is_new = NULL); 00840 00841 00843 const std::vector<unsigned int> &buff_procs() const; 00844 00845 /* \brief Unpack message with remote handles 00846 * PUBLIC ONLY FOR TESTING! 00847 */ 00848 ErrorCode unpack_remote_handles(unsigned int from_proc, 00849 unsigned char *&buff_ptr, 00850 std::vector<EntityHandle> &L2hloc, 00851 std::vector<EntityHandle> &L2hrem, 00852 std::vector<unsigned int> &L2p); 00853 00854 /* \brief Pack message with remote handles 00855 * PUBLIC ONLY FOR TESTING! 00856 */ 00857 ErrorCode pack_remote_handles(std::vector<EntityHandle> &L1hloc, 00858 std::vector<EntityHandle> &L1hrem, 00859 std::vector<int> &procs, 00860 unsigned int to_proc, 00861 Buffer *buff); 00862 00863 // each iterate in proc_nvecs contains a set of procs and the entities *possibly* 00864 // on the interface between those procs; this function makes sets for each, 00865 // and tags the set with the procs sharing it; interface sets are optionally 00866 // returned; NOTE: a subsequent step is used to verify entities on the interface 00867 // and remove them if they're not shared 00868 ErrorCode create_interface_sets(std::map<std::vector<int>, std::vector<EntityHandle> > &proc_nvecs); 00869 00870 // do the same but working straight from sharedEnts 00871 ErrorCode create_interface_sets(EntityHandle this_set, int resolve_dim, int shared_dim); 00872 00873 ErrorCode tag_shared_verts(TupleList &shared_ents, 00874 std::map<std::vector<int>, std::vector<EntityHandle> > &proc_nvecs, 00875 Range &proc_verts, 00876 unsigned int i_extra = 1); 00877 00878 ErrorCode list_entities(const EntityHandle *ents, int num_ents); 00879 00880 ErrorCode list_entities(const Range &ents); 00881 00882 void set_send_request(int n_request); // set send request array 00883 00884 void set_recv_request(int n_request); // set recv request array 00885 00887 // changed to public function (HJK) 00888 void reset_all_buffers(); 00889 00890 static const unsigned int INITIAL_BUFF_SIZE; 00891 00893 void set_debug_verbosity(int verb); 00894 00896 int get_debug_verbosity(); 00897 00898 /* \brief Gather tag value from entities down to a specified root proc 00899 * This function gathers data from a domain-decomposed mesh onto a global mesh 00900 * represented on the root processor. On the root, this gather mesh is distinct from 00901 * the root's domain-decomposed subdomain. Entities are matched by global id, or by 00902 * another tag if its handle is input. The dimension of all entities in gather_ents should 00903 * be the same, since this is the dimension of entities in gather_set that are queried for 00904 * matching global id tags. 00905 * \param gather_ents (Local) entities from which to gather data 00906 * \param tag_handle Tag whose values are being gathered 00907 * \param id_tag Tag to use for matching entities (global id used by default) 00908 * \param gather_set On root, set containing global mesh onto which to put data 00909 * \param root_proc_rank Rank of the specified root processor (default rank is 0) 00910 */ 00911 ErrorCode gather_data(Range &gather_ents, Tag &tag_handle, 00912 Tag id_tag = 0, EntityHandle gather_set = 0, int root_proc_rank = 0); 00913 00914 /* \brief communicate extra points positions on boundary 00915 * This function is called after intersection of 2 meshes, to settle the 00916 * position of the intersection points on the boundary (interface) 00917 * The initial mesh distributed on each processor is decomposed after 00918 * intersection with another mesh, such as that new points are created on the 00919 * boundary. these points should better match at the interface ! 00920 * we perform an extra caution step, to ensure the robustness of the 00921 * intersection algorithm; only shared edges extra nodes 00922 * will be actually needed to be communicated, but we just pass by reference 00923 * the whole extraNodesVec structure, we do 00924 * not need to construct another data structure 00925 * The node positions on edges that are owned will be communicated to other 00926 * processors 00927 * 00928 * \param edges total range of entities 00929 * \param shared_edges_owned edges for which to communicate data 00930 * \param extraNodesVec handles of intersection vertices on all edges; 00931 */ 00932 ErrorCode settle_intersection_points(Range & edges, Range & shared_edges_owned, 00933 std::vector<std::vector<EntityHandle> *> & extraNodesVec, double tolerance); 00934 00935 private: 00936 00937 ErrorCode reduce_void(int tag_data_type, const MPI_Op mpi_op, int num_ents, void *old_vals, void *new_vals); 00938 00939 template <class T> ErrorCode reduce(const MPI_Op mpi_op, int num_ents, void *old_vals, void *new_vals); 00940 00941 void print_debug_isend(int from, int to, unsigned char *buff, 00942 int tag, int size); 00943 00944 void print_debug_irecv(int to, int from, unsigned char *buff, int size, 00945 int tag, int incoming); 00946 00947 void print_debug_recd(MPI_Status status); 00948 00949 void print_debug_waitany(std::vector<MPI_Request> &reqs, int tag, int proc); 00950 00951 // common initialization code, called from various constructors 00952 void initialize(); 00953 00954 ErrorCode set_sharing_data(EntityHandle ent, unsigned char pstatus, 00955 int old_nump, int new_nump, 00956 int *ps, EntityHandle *hs); 00957 00958 ErrorCode check_clean_iface(Range &allsent); 00959 00960 void define_mpe(); 00961 00962 ErrorCode get_sent_ents(const bool is_iface, 00963 const int bridge_dim, const int ghost_dim, 00964 const int num_layers, const int addl_ents, 00965 Range *sent_ents, Range &allsent, 00966 TupleList &entprocs); 00967 00978 ErrorCode set_pstatus_entities(Range &pstatus_ents, 00979 unsigned char pstatus_val, 00980 bool lower_dim_ents = false, 00981 bool verts_too = true, 00982 int operation = Interface::UNION); 00983 00994 ErrorCode set_pstatus_entities(EntityHandle *pstatus_ents, 00995 int num_ents, 00996 unsigned char pstatus_val, 00997 bool lower_dim_ents = false, 00998 bool verts_too = true, 00999 int operation = Interface::UNION); 01000 01001 int num_subranges(const Range &this_range); 01002 01004 int estimate_ents_buffer_size(Range &entities, 01005 const bool store_remote_handles); 01006 01008 int estimate_sets_buffer_size(Range &entities, 01009 const bool store_remote_handles); 01010 01012 ErrorCode send_buffer(const unsigned int to_proc, 01013 Buffer *send_buff, 01014 const int msg_tag, 01015 MPI_Request &send_req, 01016 MPI_Request &ack_recv_req, 01017 int *ack_buff, 01018 int &this_incoming, 01019 int next_mesg_tag = -1, 01020 Buffer *next_recv_buff = NULL, 01021 MPI_Request *next_recv_req = NULL, 01022 int *next_incoming = NULL); 01023 01027 ErrorCode recv_buffer(int mesg_tag_expected, 01028 const MPI_Status &mpi_status, 01029 Buffer *recv_buff, 01030 MPI_Request &recv_2nd_req, 01031 MPI_Request &ack_req, 01032 int &this_incoming, 01033 Buffer *send_buff, 01034 MPI_Request &send_req, 01035 MPI_Request &sent_ack_req, 01036 bool &done, 01037 Buffer *next_buff = NULL, 01038 int next_tag = -1, 01039 MPI_Request *next_req = NULL, 01040 int *next_incoming = NULL); 01041 01044 ErrorCode pack_entity_seq(const int nodes_per_entity, 01045 const bool store_remote_handles, 01046 const int to_proc, 01047 Range &these_ents, 01048 std::vector<EntityHandle> &entities, 01049 Buffer *buff); 01050 01051 ErrorCode print_buffer(unsigned char *buff_ptr, int mesg_type, int from_proc, 01052 bool sent); 01053 01056 ErrorCode unpack_iface_entities(unsigned char *&buff_ptr, 01057 const int from_proc, 01058 const int ind, 01059 std::vector<EntityHandle> &recd_ents); 01060 01061 ErrorCode pack_sets(Range &entities, 01062 Buffer *buff, 01063 const bool store_handles, 01064 const int to_proc); 01065 01066 ErrorCode unpack_sets(unsigned char *&buff_ptr, 01067 std::vector<EntityHandle> &entities, 01068 const bool store_handles, 01069 const int to_proc); 01070 01071 ErrorCode pack_adjacencies(Range &entities, 01072 Range::const_iterator &start_rit, 01073 Range &whole_range, 01074 unsigned char *&buff_ptr, 01075 int &count, 01076 const bool just_count, 01077 const bool store_handles, 01078 const int to_proc); 01079 01080 ErrorCode unpack_adjacencies(unsigned char *&buff_ptr, 01081 Range &entities, 01082 const bool store_handles, 01083 const int from_proc); 01084 01085 01086 /* \brief Unpack message with remote handles (const pointer to buffer) 01087 */ 01088 ErrorCode unpack_remote_handles(unsigned int from_proc, 01089 const unsigned char *buff_ptr, 01090 std::vector<EntityHandle> &L2hloc, 01091 std::vector<EntityHandle> &L2hrem, 01092 std::vector<unsigned int> &L2p); 01093 01095 ErrorCode find_existing_entity(const bool is_iface, 01096 const int owner_p, 01097 const EntityHandle owner_h, 01098 const int num_ents, 01099 const EntityHandle *connect, 01100 const int num_connect, 01101 const EntityType this_type, 01102 std::vector<EntityHandle> &L2hloc, 01103 std::vector<EntityHandle> &L2hrem, 01104 std::vector<unsigned int> &L2p, 01105 EntityHandle &new_h); 01106 01107 ErrorCode build_sharedhps_list(const EntityHandle entity, 01108 const unsigned char pstatus, 01109 const int sharedp, 01110 const std::set<unsigned int> &procs, 01111 unsigned int &num_ents, 01112 int *tmp_procs, 01113 EntityHandle *tmp_handles); 01114 01129 ErrorCode get_tag_send_list( const Range& all_entities, 01130 std::vector<Tag>& all_tags, 01131 std::vector<Range>& tag_ranges ); 01132 01177 ErrorCode pack_tags(Range &entities, 01178 const std::vector<Tag> &src_tags, 01179 const std::vector<Tag> &dst_tags, 01180 const std::vector<Range> &tag_ranges, 01181 Buffer *buff, 01182 const bool store_handles, 01183 const int to_proc); 01184 01190 ErrorCode packed_tag_size( Tag source_tag, 01191 const Range& entities, 01192 int& count_out ); 01193 01219 ErrorCode pack_tag( Tag source_tag, 01220 Tag destination_tag, 01221 const Range &entities, 01222 const std::vector<EntityHandle> &whole_range, 01223 Buffer *buff, 01224 const bool store_remote_handles, 01225 const int to_proc ); 01226 01227 ErrorCode unpack_tags(unsigned char *&buff_ptr, 01228 std::vector<EntityHandle> &entities, 01229 const bool store_handles, 01230 const int to_proc, 01231 const MPI_Op * const mpi_op = NULL); 01232 01233 ErrorCode tag_shared_verts(TupleList &shared_verts, 01234 Range *skin_ents, 01235 std::map<std::vector<int>, std::vector<EntityHandle> > &proc_nvecs, 01236 Range &proc_verts); 01237 01238 ErrorCode get_proc_nvecs(int resolve_dim, 01239 int shared_dim, 01240 Range *skin_ents, 01241 std::map<std::vector<int>, std::vector<EntityHandle> > &proc_nvecs); 01242 01243 // after verifying shared entities, now parent/child links between sets can be established 01244 ErrorCode create_iface_pc_links(); 01245 01248 ErrorCode pack_range_map(Range &this_range, EntityHandle actual_start, 01249 HandleMap &handle_map); 01250 01252 bool is_iface_proc(EntityHandle this_set, int to_proc); 01253 01256 ErrorCode update_iface_sets(Range &sent_ents, 01257 std::vector<EntityHandle> &remote_handles, 01258 int from_proc); 01259 01263 ErrorCode get_ghosted_entities(int bridge_dim, 01264 int ghost_dim, 01265 int to_proc, 01266 int num_layers, 01267 int addl_ents, 01268 Range &ghosted_ents); 01269 01271 ErrorCode add_verts(Range &sent_ents); 01272 01277 ErrorCode exchange_all_shared_handles( 01278 std::vector<std::vector<SharedEntityData> > &send_data, 01279 std::vector<std::vector<SharedEntityData> > &result); 01280 01286 ErrorCode get_remote_handles(const bool store_remote_handles, 01287 EntityHandle *from_vec, 01288 EntityHandle *to_vec_tmp, 01289 int num_ents, int to_proc, 01290 const std::vector<EntityHandle> &new_ents); 01291 01294 ErrorCode get_remote_handles(const bool store_remote_handles, 01295 const Range &from_range, 01296 Range &to_range, 01297 int to_proc, 01298 const std::vector<EntityHandle> &new_ents); 01299 01301 ErrorCode get_remote_handles(const bool store_remote_handles, 01302 const Range &from_range, 01303 EntityHandle *to_vec, 01304 int to_proc, 01305 const std::vector<EntityHandle> &new_ents); 01306 01309 ErrorCode get_local_handles(EntityHandle *from_vec, 01310 int num_ents, 01311 const Range &new_ents); 01312 01314 ErrorCode get_local_handles(const Range &remote_handles, 01315 Range &local_handles, 01316 const std::vector<EntityHandle> &new_ents); 01317 01319 ErrorCode get_local_handles(EntityHandle *from_vec, 01320 int num_ents, 01321 const std::vector<EntityHandle> &new_ents); 01322 01323 ErrorCode update_remote_data(Range &local_range, 01324 Range &remote_range, 01325 int other_proc, 01326 const unsigned char add_pstat); 01327 01328 ErrorCode update_remote_data(const EntityHandle new_h, 01329 const int *ps, 01330 const EntityHandle *hs, 01331 const int num_ps, 01332 const unsigned char add_pstat); 01333 01334 ErrorCode update_remote_data_old(const EntityHandle new_h, 01335 const int *ps, 01336 const EntityHandle *hs, 01337 const int num_ps, 01338 const unsigned char add_pstat); 01339 01342 ErrorCode tag_iface_entities(); 01343 01345 int add_pcomm(ParallelComm *pc); 01346 01348 void remove_pcomm(ParallelComm *pc); 01349 01352 ErrorCode check_sent_ents(Range &allsent); 01353 01355 ErrorCode assign_entities_part(std::vector<EntityHandle> &entities, const int proc); 01356 01358 ErrorCode remove_entities_part(Range &entities, const int proc); 01359 01361 Interface *mbImpl; 01362 01364 ProcConfig procConfig; 01365 01367 SequenceManager *sequenceManager; 01368 01370 Error *errorHandler; 01371 01373 std::vector<Buffer*> localOwnedBuffs, remoteOwnedBuffs; 01374 01376 //void reset_all_buffers(); 01377 01379 void delete_all_buffers(); 01380 01382 std::vector<MPI_Request> sendReqs; 01383 01385 std::vector<MPI_Request> recvReqs, recvRemotehReqs; 01386 01388 std::vector<unsigned int> buffProcs; 01389 01391 Range partitionSets, interfaceSets; 01392 01394 std::vector<EntityHandle> sharedEnts; 01395 01397 Tag sharedpTag, sharedpsTag, sharedhTag, sharedhsTag, pstatusTag, 01398 ifaceSetsTag, partitionTag; 01399 01400 int globalPartCount; 01401 01402 EntityHandle partitioningSet; 01403 01404 std::ofstream myFile; 01405 01406 int pcommID; 01407 01408 int ackbuff; 01409 01411 DebugOutput *myDebug; 01412 01414 SharedSetData* sharedSetData; 01415 01416 }; 01417 01418 inline ParallelComm::Buffer::Buffer(const Buffer &other_buff) 01419 { 01420 alloc_size = other_buff.alloc_size; 01421 mem_ptr = (unsigned char *)malloc(alloc_size); 01422 memcpy(mem_ptr, other_buff.mem_ptr, alloc_size); 01423 buff_ptr = mem_ptr + (other_buff.buff_ptr - other_buff.mem_ptr); 01424 } 01425 01426 inline ParallelComm::Buffer::Buffer(unsigned int new_size) 01427 : mem_ptr(NULL), buff_ptr(NULL), alloc_size(0) 01428 { 01429 if (new_size) this->reserve(new_size); 01430 } 01431 01432 inline ParallelComm::Buffer::~Buffer() 01433 { 01434 if (mem_ptr) { 01435 free(mem_ptr); 01436 mem_ptr = NULL; 01437 } 01438 } 01439 01440 #define DEBUG_BUFFER 0 01441 01442 inline void ParallelComm::Buffer::reserve(unsigned int new_size) { 01443 01444 #ifdef DEBUG_BUFFER 01445 int tmp_pos = 0; 01446 if (mem_ptr) { 01447 tmp_pos = buff_ptr - mem_ptr; 01448 } 01449 buff_ptr = (unsigned char *)malloc(new_size); 01450 assert(0 <= tmp_pos && tmp_pos <= (int)alloc_size); 01451 if (tmp_pos) memcpy(buff_ptr, mem_ptr, tmp_pos); 01452 if (mem_ptr) free(mem_ptr); 01453 mem_ptr = buff_ptr; 01454 alloc_size = new_size; 01455 buff_ptr = mem_ptr + tmp_pos; 01456 #else 01457 if (mem_ptr && alloc_size < new_size) { 01458 size_t tmp_pos = mem_ptr ? buff_ptr - mem_ptr : 0; 01459 mem_ptr = (unsigned char *)realloc(mem_ptr, new_size); 01460 alloc_size = new_size; 01461 buff_ptr = mem_ptr + tmp_pos; 01462 } 01463 else if (!mem_ptr) { 01464 mem_ptr = (unsigned char *)malloc(new_size); 01465 alloc_size = new_size; 01466 buff_ptr = mem_ptr; 01467 } 01468 #endif 01469 } 01470 01471 inline void ParallelComm::Buffer::check_space(unsigned int addl_space ) 01472 { 01473 assert(buff_ptr >= mem_ptr && buff_ptr <= mem_ptr+alloc_size); 01474 unsigned int new_size = buff_ptr - mem_ptr + addl_space; 01475 if (new_size > alloc_size) 01476 reserve(3*new_size/2); 01477 } 01478 01479 inline void ParallelComm::reset_all_buffers() 01480 { 01481 std::vector<Buffer*>::iterator vit; 01482 for (vit = localOwnedBuffs.begin(); vit != localOwnedBuffs.end(); vit++) 01483 (*vit)->reset_buffer(); 01484 for (vit = remoteOwnedBuffs.begin(); vit != remoteOwnedBuffs.end(); vit++) 01485 (*vit)->reset_buffer(); 01486 } 01487 01488 inline void ParallelComm::delete_all_buffers() 01489 { 01490 std::vector<Buffer*>::iterator vit; 01491 for (vit = localOwnedBuffs.begin(); vit != localOwnedBuffs.end(); vit++) 01492 delete (*vit); 01493 localOwnedBuffs.clear(); 01494 01495 for (vit = remoteOwnedBuffs.begin(); vit != remoteOwnedBuffs.end(); vit++) 01496 delete (*vit); 01497 remoteOwnedBuffs.clear(); 01498 } 01499 01500 inline const std::vector<unsigned int> &ParallelComm::buff_procs() const 01501 { 01502 return buffProcs; 01503 } 01504 01505 inline ErrorCode ParallelComm::get_shared_proc_tags(Tag &sharedp, 01506 Tag &sharedps, 01507 Tag &sharedh, 01508 Tag &sharedhs, 01509 Tag &pstatus) 01510 { 01511 sharedp = sharedp_tag(); 01512 sharedps = sharedps_tag(); 01513 sharedh = sharedh_tag(); 01514 sharedhs = sharedhs_tag(); 01515 pstatus = pstatus_tag(); 01516 01517 return MB_SUCCESS; 01518 } 01519 01520 inline ErrorCode ParallelComm::exchange_tags( const char *tag_name, 01521 const Range &entities) 01522 { 01523 // get the tag handle 01524 std::vector<Tag> tags(1); 01525 ErrorCode result = mbImpl->tag_get_handle(tag_name, 0, MB_TYPE_OPAQUE, tags[0], MB_TAG_ANY); 01526 if (MB_SUCCESS != result) return result; 01527 else if (!tags[0]) return MB_TAG_NOT_FOUND; 01528 01529 return exchange_tags(tags, tags, entities); 01530 } 01531 01532 inline ErrorCode ParallelComm::exchange_tags( Tag tagh, 01533 const Range &entities) 01534 { 01535 // get the tag handle 01536 std::vector<Tag> tags; 01537 tags.push_back(tagh); 01538 01539 return exchange_tags(tags, tags, entities); 01540 } 01541 01542 inline ErrorCode ParallelComm::reduce_tags( const char *tag_name, 01543 const MPI_Op mpi_op, 01544 const Range &entities) 01545 { 01546 // get the tag handle 01547 std::vector<Tag> tags(1); 01548 ErrorCode result = mbImpl->tag_get_handle(tag_name, 0, MB_TYPE_OPAQUE, tags[0], MB_TAG_ANY); 01549 if (MB_SUCCESS != result) return result; 01550 else if (!tags[0]) return MB_TAG_NOT_FOUND; 01551 01552 return reduce_tags(tags, tags, mpi_op, entities); 01553 } 01554 01555 inline ErrorCode ParallelComm::reduce_tags( Tag tagh, 01556 const MPI_Op mpi_op, 01557 const Range &entities) 01558 { 01559 // get the tag handle 01560 std::vector<Tag> tags; 01561 tags.push_back(tagh); 01562 01563 return reduce_tags(tags, tags, mpi_op, entities); 01564 } 01565 01566 inline ErrorCode ParallelComm::get_comm_procs(std::set<unsigned int> &procs) 01567 { 01568 ErrorCode result = get_interface_procs(procs); 01569 if (MB_SUCCESS != result) return result; 01570 01571 std::copy(buffProcs.begin(), buffProcs.end(), std::inserter(procs, procs.begin())); 01572 01573 return MB_SUCCESS; 01574 } 01575 01576 inline ErrorCode ParallelComm::get_owner(EntityHandle entity, 01577 int &owner) 01578 { 01579 EntityHandle tmp_handle; 01580 return get_owner_handle(entity, owner, tmp_handle); 01581 } 01582 01583 /* \brief Unpack message with remote handles (const pointer to buffer) 01584 */ 01585 inline ErrorCode ParallelComm::unpack_remote_handles(unsigned int from_proc, 01586 const unsigned char *buff_ptr, 01587 std::vector<EntityHandle> &L2hloc, 01588 std::vector<EntityHandle> &L2hrem, 01589 std::vector<unsigned int> &L2p) 01590 { 01591 // cast away const-ness, we won't be passing back a modified ptr 01592 unsigned char *tmp_buff = const_cast<unsigned char*>(buff_ptr); 01593 return unpack_remote_handles(from_proc, tmp_buff, L2hloc, L2hrem, L2p); 01594 } 01595 01596 inline void ParallelComm::set_rank(unsigned int r) 01597 { 01598 procConfig.proc_rank(r); 01599 if (procConfig.proc_size() < r) procConfig.proc_size(r+1); 01600 } 01601 01602 inline void ParallelComm::set_size(unsigned int s) 01603 { 01604 procConfig.proc_size(s); 01605 } 01606 01607 inline ErrorCode ParallelComm::get_sharing_data(const EntityHandle *entities, 01608 int num_entities, 01609 std::set<int> &procs, 01610 int op) 01611 { 01612 Range dum_range; 01613 // cast away constness 'cuz the range is passed as const 01614 EntityHandle *ents_cast = const_cast<EntityHandle*>(entities); 01615 std::copy(ents_cast, ents_cast+num_entities, range_inserter(dum_range)); 01616 return get_sharing_data(dum_range, procs, op); 01617 } 01618 01619 inline ErrorCode ParallelComm::get_sharing_data(const EntityHandle entity, 01620 int *ps, 01621 EntityHandle *hs, 01622 unsigned char &pstat, 01623 int &num_ps) 01624 { 01625 unsigned int dum_ps; 01626 ErrorCode result = get_sharing_data(entity, ps, hs, pstat, dum_ps); 01627 if (MB_SUCCESS == result) 01628 num_ps = dum_ps; 01629 return result; 01630 } 01631 01632 inline void ParallelComm::set_send_request(int n_request) 01633 { 01634 sendReqs.resize(n_request, MPI_REQUEST_NULL); 01635 } 01636 01637 inline void ParallelComm::set_recv_request(int n_request) 01638 { 01639 recvReqs.resize(n_request, MPI_REQUEST_NULL); 01640 } 01641 01642 } // namespace moab 01643 01644 #endif