diff --git a/src/mesh/ConnectivityDispatcher.cpp b/src/mesh/ConnectivityDispatcher.cpp index fd99475c2ecdeff01c8aa477e0437d84e08259e5..08fea56bfd2d023b0defffa79a0ed3aeb34d3723 100644 --- a/src/mesh/ConnectivityDispatcher.cpp +++ b/src/mesh/ConnectivityDispatcher.cpp @@ -411,189 +411,203 @@ _buildRecvItemIdCorrespondanceByProc() } template <int Dimension> +template <ItemType item_type> void -ConnectivityDispatcher<Dimension>::_dispatchFaces() +ConnectivityDispatcher<Dimension>::_buildItemReferenceList() { - if constexpr (Dimension>1) { - this->_buildNumberOfSubItemPerItemToRecvByProc<FaceOfCell>(); - this->_buildSubItemNumbersToRecvByProc<FaceOfCell>(); - this->_buildSubItemNumberToIdMap<FaceOfCell>(); - this->_buildItemToExchangeLists<ItemType::face>(); - - this->_gatherFrom(m_connectivity.template number<ItemType::face>(), m_new_descriptor.face_number_vector); - - this->_buildItemToSubItemDescriptor<FaceOfCell>(); - - this->_gatherFrom(m_connectivity.cellFaceIsReversed(), m_new_descriptor.cell_face_is_reversed_vector); - - this->_gatherFrom(this->_dispatchedInfo<ItemType::face>().m_new_owner, m_new_descriptor.face_owner_vector); - - this->_buildNumberOfSubItemPerItemToRecvByProc<NodeOfFace>(); - this->_buildSubItemNumbersToRecvByProc<NodeOfFace>(); - this->_buildItemToSubItemDescriptor<NodeOfFace>(); + using ItemId = ItemIdT<item_type>; - // Getting references - Array<const size_t> number_of_ref_face_list_per_proc - = parallel::allGather(m_connectivity.numberOfRefFaceList()); + // Getting references + Array<const size_t> number_of_item_ref_list_per_proc + = parallel::allGather(m_connectivity.numberOfRefFaceList()); - const size_t number_of_face_list_sender - = [&] () { - size_t number_of_face_list_sender=0; - for (size_t i_rank = 0; i_rank < parallel::size(); ++i_rank) { - number_of_face_list_sender - += (number_of_ref_face_list_per_proc[i_rank] > 0); - } - return number_of_face_list_sender; - }(); - - if (number_of_face_list_sender > 0) { - if (number_of_face_list_sender > 1) { - perr() << __FILE__ << ':' << __LINE__ << ": " - << rang::fgB::red - <<"need to check that knowing procs know the same ref_face_lists!" - << rang::fg::reset << '\n'; - } + const size_t number_of_item_list_sender + = [&] () { + size_t number_of_item_list_sender=0; + for (size_t i_rank = 0; i_rank < parallel::size(); ++i_rank) { + number_of_item_list_sender + += (number_of_item_ref_list_per_proc[i_rank] > 0); + } + return number_of_item_list_sender; + }(); + + if (number_of_item_list_sender > 0) { + if (number_of_item_list_sender > 1) { + perr() << __FILE__ << ':' << __LINE__ << ": " + << rang::fgB::red + <<"need to check that knowing procs know the same item_ref_lists!" + << rang::fg::reset << '\n'; + } - if (number_of_face_list_sender < parallel::size()) { - const size_t sender_rank - = [&] () { - size_t i_rank = 0; - for (; i_rank < parallel::size(); ++i_rank) { - if (number_of_ref_face_list_per_proc[i_rank] > 0) { - break; - } + if (number_of_item_list_sender < parallel::size()) { + const size_t sender_rank + = [&] () { + size_t i_rank = 0; + for (; i_rank < parallel::size(); ++i_rank) { + if (number_of_item_ref_list_per_proc[i_rank] > 0) { + break; } - return i_rank; - }(); - - Assert(number_of_face_list_sender < parallel::size()); - - // sending references tags - Array<RefId::TagNumberType> ref_tag_list{number_of_ref_face_list_per_proc[sender_rank]}; - if (parallel::rank() == sender_rank){ - for (size_t i_ref_face_list=0; i_ref_face_list<m_connectivity.numberOfRefFaceList(); - ++i_ref_face_list) { - auto ref_face_list = m_connectivity.refFaceList(i_ref_face_list); - ref_tag_list[i_ref_face_list] = ref_face_list.refId().tagNumber(); - } + } + return i_rank; + }(); + + Assert(number_of_item_list_sender < parallel::size()); + + // sending references tags + Array<RefId::TagNumberType> ref_tag_list{number_of_item_ref_list_per_proc[sender_rank]}; + if (parallel::rank() == sender_rank){ + for (size_t i_item_ref_list=0; i_item_ref_list<m_connectivity.numberOfRefFaceList(); + ++i_item_ref_list) { + auto item_ref_list = m_connectivity.refFaceList(i_item_ref_list); + ref_tag_list[i_item_ref_list] = item_ref_list.refId().tagNumber(); } - parallel::broadcast(ref_tag_list, sender_rank); - - // sending references name size - Array<size_t> ref_name_size_list{number_of_ref_face_list_per_proc[sender_rank]}; - if (parallel::rank() == sender_rank){ - for (size_t i_ref_face_list=0; i_ref_face_list<m_connectivity.numberOfRefFaceList(); - ++i_ref_face_list) { - auto ref_face_list = m_connectivity.refFaceList(i_ref_face_list); - ref_name_size_list[i_ref_face_list] = ref_face_list.refId().tagName().size(); - } + } + parallel::broadcast(ref_tag_list, sender_rank); + + // sending references name size + Array<size_t> ref_name_size_list{number_of_item_ref_list_per_proc[sender_rank]}; + if (parallel::rank() == sender_rank){ + for (size_t i_item_ref_list=0; i_item_ref_list<m_connectivity.numberOfRefFaceList(); + ++i_item_ref_list) { + auto item_ref_list = m_connectivity.refFaceList(i_item_ref_list); + ref_name_size_list[i_item_ref_list] = item_ref_list.refId().tagName().size(); } - parallel::broadcast(ref_name_size_list, sender_rank); - - // sending references name size - Array<RefId::TagNameType::value_type> ref_name_cat{sum(ref_name_size_list)}; - if (parallel::rank() == sender_rank){ - size_t i_char=0; - for (size_t i_ref_face_list=0; i_ref_face_list<m_connectivity.numberOfRefFaceList(); - ++i_ref_face_list) { - auto ref_face_list = m_connectivity.refFaceList(i_ref_face_list); - for (auto c : ref_face_list.refId().tagName()) { - ref_name_cat[i_char++] = c; - } + } + parallel::broadcast(ref_name_size_list, sender_rank); + + // sending references name size + Array<RefId::TagNameType::value_type> ref_name_cat{sum(ref_name_size_list)}; + if (parallel::rank() == sender_rank){ + size_t i_char=0; + for (size_t i_item_ref_list=0; i_item_ref_list<m_connectivity.numberOfRefFaceList(); + ++i_item_ref_list) { + auto item_ref_list = m_connectivity.refFaceList(i_item_ref_list); + for (auto c : item_ref_list.refId().tagName()) { + ref_name_cat[i_char++] = c; } } - parallel::broadcast(ref_name_cat, sender_rank); - - std::vector<RefId> ref_id_list - = [&] () { - std::vector<RefId> ref_id_list; - ref_id_list.reserve(ref_name_size_list.size()); - size_t begining=0; - for (size_t i_ref=0; i_ref < ref_name_size_list.size(); ++i_ref) { - const size_t size = ref_name_size_list[i_ref]; - ref_id_list.emplace_back(ref_tag_list[i_ref], - std::string{&(ref_name_cat[begining]), size}); - begining += size; - } - return ref_id_list; - } (); - - using block_type = int32_t; - constexpr size_t block_size = sizeof(block_type); - const size_t nb_block = ref_id_list.size()/block_size + (ref_id_list.size()%block_size != 0); - for (size_t i_block=0; i_block<nb_block; ++i_block) { - FaceValue<block_type> face_references(m_connectivity); - face_references.fill(0); - - if (m_connectivity.numberOfRefFaceList() > 0) { - const size_t max_i_ref = std::min(ref_id_list.size(), block_size*(i_block+1)); - for (size_t i_ref=block_size*i_block, i=0; i_ref<max_i_ref; ++i_ref, ++i) { - block_type ref_bit{1<<i}; - auto ref_face_list = m_connectivity.refFaceList(i_ref); - - const auto& face_list = ref_face_list.faceList(); - for (size_t i_face=0; i_face<face_list.size(); ++i_face) { - const FaceId& face_id = face_list[i_face]; - face_references[face_id] |= ref_bit; + } + parallel::broadcast(ref_name_cat, sender_rank); + + std::vector<RefId> ref_id_list + = [&] () { + std::vector<RefId> ref_id_list; + ref_id_list.reserve(ref_name_size_list.size()); + size_t begining=0; + for (size_t i_ref=0; i_ref < ref_name_size_list.size(); ++i_ref) { + const size_t size = ref_name_size_list[i_ref]; + ref_id_list.emplace_back(ref_tag_list[i_ref], + std::string{&(ref_name_cat[begining]), size}); + begining += size; } - } - } - - const auto& nb_face_to_send_by_proc = - this->_dispatchedInfo<ItemType::face>().m_list_to_send_size_by_proc; - const auto& send_face_id_by_proc = m_dispatched_face_info.m_list_to_send_by_proc; - std::vector<Array<const block_type>> send_face_refs_by_proc(parallel::size()); - - for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { - Array<block_type> send_face_refs(nb_face_to_send_by_proc[i_rank]); - const Array<const FaceId> send_face_id = send_face_id_by_proc[i_rank]; - parallel_for(send_face_id.size(), PASTIS_LAMBDA(const size_t& l) { - const FaceId& face_id = send_face_id[l]; - send_face_refs[l] = face_references[face_id]; - }); - send_face_refs_by_proc[i_rank] = send_face_refs; - } + return ref_id_list; + } (); - std::vector<Array<block_type>> recv_face_refs_by_proc(parallel::size()); - for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { - recv_face_refs_by_proc[i_rank] = Array<block_type>(m_dispatched_face_info.m_list_to_recv_size_by_proc[i_rank]); - } - parallel::exchange(send_face_refs_by_proc, recv_face_refs_by_proc); - - const auto& recv_face_id_correspondance_by_proc = m_dispatched_face_info.m_recv_id_correspondance_by_proc; - std::vector<block_type> face_refs(m_new_descriptor.face_number_vector.size()); - for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { - for (size_t r=0; r<recv_face_refs_by_proc[i_rank].size(); ++r) { - const FaceId& face_id = recv_face_id_correspondance_by_proc[i_rank][r]; - face_refs[face_id] = recv_face_refs_by_proc[i_rank][r]; - } - } + using block_type = int32_t; + constexpr size_t block_size = sizeof(block_type); + const size_t nb_block = ref_id_list.size()/block_size + (ref_id_list.size()%block_size != 0); + for (size_t i_block=0; i_block<nb_block; ++i_block) { + FaceValue<block_type> item_references(m_connectivity); + item_references.fill(0); + if (m_connectivity.numberOfRefFaceList() > 0) { const size_t max_i_ref = std::min(ref_id_list.size(), block_size*(i_block+1)); for (size_t i_ref=block_size*i_block, i=0; i_ref<max_i_ref; ++i_ref, ++i) { block_type ref_bit{1<<i}; + auto item_ref_list = m_connectivity.refFaceList(i_ref); - std::vector<FaceId> face_id_vector; - - for (uint32_t i_face=0; i_face<face_refs.size(); ++i_face) { - const FaceId face_id{i_face}; - if (face_refs[face_id] & ref_bit) { - face_id_vector.push_back(face_id); - } + const auto& item_list = item_ref_list.faceList(); + for (size_t i_item=0; i_item<item_list.size(); ++i_item) { + const ItemId& item_id = item_list[i_item]; + item_references[item_id] |= ref_bit; } + } + } + + const auto& nb_item_to_send_by_proc = + this->_dispatchedInfo<item_type>().m_list_to_send_size_by_proc; + + const auto& send_item_id_by_proc = + this->_dispatchedInfo<item_type>().m_list_to_send_by_proc; + + std::vector<Array<const block_type>> send_item_refs_by_proc(parallel::size()); + + for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { + Array<block_type> send_item_refs(nb_item_to_send_by_proc[i_rank]); + const Array<const ItemId> send_item_id = send_item_id_by_proc[i_rank]; + parallel_for(send_item_id.size(), PASTIS_LAMBDA(const size_t& l) { + const ItemId& item_id = send_item_id[l]; + send_item_refs[l] = item_references[item_id]; + }); + send_item_refs_by_proc[i_rank] = send_item_refs; + } + + std::vector<Array<block_type>> recv_item_refs_by_proc(parallel::size()); + for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { + recv_item_refs_by_proc[i_rank] = Array<block_type>(this->_dispatchedInfo<item_type>().m_list_to_recv_size_by_proc[i_rank]); + } + parallel::exchange(send_item_refs_by_proc, recv_item_refs_by_proc); + + const auto& recv_item_id_correspondance_by_proc = + this->_dispatchedInfo<item_type>().m_recv_id_correspondance_by_proc; + std::vector<block_type> item_refs(m_new_descriptor.face_number_vector.size()); + for (size_t i_rank=0; i_rank<parallel::size(); ++i_rank) { + for (size_t r=0; r<recv_item_refs_by_proc[i_rank].size(); ++r) { + const ItemId& item_id = recv_item_id_correspondance_by_proc[i_rank][r]; + item_refs[item_id] = recv_item_refs_by_proc[i_rank][r]; + } + } + + const size_t max_i_ref = std::min(ref_id_list.size(), block_size*(i_block+1)); + for (size_t i_ref=block_size*i_block, i=0; i_ref<max_i_ref; ++i_ref, ++i) { + block_type ref_bit{1<<i}; - Array<const FaceId> face_id_array = convert_to_array(face_id_vector); + std::vector<ItemId> item_id_vector; - m_new_descriptor.addRefFaceList(RefFaceList(ref_id_list[i_ref], face_id_array)); + for (uint32_t i_item=0; i_item<item_refs.size(); ++i_item) { + const ItemId item_id{i_item}; + if (item_refs[item_id] & ref_bit) { + item_id_vector.push_back(item_id); + } } - pout() << __FILE__ << ':' << __LINE__ << ": remains to build lists\n"; + Array<const ItemId> item_id_array = convert_to_array(item_id_vector); + + m_new_descriptor.addRefFaceList(RefFaceList(ref_id_list[i_ref], item_id_array)); } + + pout() << __FILE__ << ':' << __LINE__ << ": remains to build lists\n"; } } } } +template <int Dimension> +void +ConnectivityDispatcher<Dimension>::_dispatchFaces() +{ + if constexpr (Dimension>1) { + this->_buildNumberOfSubItemPerItemToRecvByProc<FaceOfCell>(); + this->_buildSubItemNumbersToRecvByProc<FaceOfCell>(); + this->_buildSubItemNumberToIdMap<FaceOfCell>(); + this->_buildItemToExchangeLists<ItemType::face>(); + + this->_gatherFrom(m_connectivity.template number<ItemType::face>(), m_new_descriptor.face_number_vector); + + this->_buildItemToSubItemDescriptor<FaceOfCell>(); + + this->_gatherFrom(m_connectivity.cellFaceIsReversed(), m_new_descriptor.cell_face_is_reversed_vector); + + this->_gatherFrom(this->_dispatchedInfo<ItemType::face>().m_new_owner, m_new_descriptor.face_owner_vector); + + this->_buildNumberOfSubItemPerItemToRecvByProc<NodeOfFace>(); + this->_buildSubItemNumbersToRecvByProc<NodeOfFace>(); + this->_buildItemToSubItemDescriptor<NodeOfFace>(); + + this->_buildItemReferenceList<ItemType::face>(); + } +} + template <int Dimension> ConnectivityDispatcher<Dimension>::ConnectivityDispatcher(const ConnectivityType& connectivity) diff --git a/src/mesh/ConnectivityDispatcher.hpp b/src/mesh/ConnectivityDispatcher.hpp index 13eb5e69cc14685587ef4b7883a3543148b3d29e..d6a97afcb2bf2459d03e6ce34635b2d05e5b78c6 100644 --- a/src/mesh/ConnectivityDispatcher.hpp +++ b/src/mesh/ConnectivityDispatcher.hpp @@ -193,6 +193,9 @@ class ConnectivityDispatcher template <ItemType item_type> void _buildRecvItemIdCorrespondanceByProc(); + template <ItemType item_type> + void _buildItemReferenceList(); + public: std::shared_ptr<const ConnectivityType> dispatchedConnectivity() const