#include "ep_lib.hpp" #include #include "ep_declaration.hpp" #include "ep_mpi.hpp" using namespace std; namespace ep_lib { /* int MPI_Intercomm_create_unique_leader(MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm, int remote_leader, int tag, MPI_Comm *newintercomm) { //! mpi_size of local comm = 1 //! same world rank of leaders int ep_rank, ep_rank_loc, mpi_rank; int ep_size, num_ep, mpi_size; ep_rank = local_comm->ep_comm_ptr->size_rank_info[0].first; ep_rank_loc = local_comm->ep_comm_ptr->size_rank_info[1].first; mpi_rank = local_comm->ep_comm_ptr->size_rank_info[2].first; ep_size = local_comm->ep_comm_ptr->size_rank_info[0].second; num_ep = local_comm->ep_comm_ptr->size_rank_info[1].second; mpi_size = local_comm->ep_comm_ptr->size_rank_info[2].second; std::vector rank_info[4]; //! 0->rank_in_world of local_comm, 1->rank_in_local_parent of local_comm //! 2->rank_in_world of remote_comm, 3->rank_in_local_parent of remote_comm int rank_in_world; int rank_in_peer_mpi[2]; ::MPI_Comm_rank(to_mpi_comm(MPI_COMM_WORLD->mpi_comm), &rank_in_world); int local_num_ep = num_ep; int remote_num_ep; int total_num_ep; int leader_rank_in_peer[2]; int my_position; int tag_label[2]; vector send_buf(4); vector recv_buf(4); if(ep_rank == local_leader) { MPI_Status status; MPI_Comm_rank(peer_comm, &leader_rank_in_peer[0]); send_buf[0] = local_num_ep; send_buf[1] = leader_rank_in_peer[0]; MPI_Request req_s, req_r; MPI_Isend(send_buf.data(), 2, MPI_INT, remote_leader, tag, peer_comm, &req_s); MPI_Irecv(recv_buf.data(), 2, MPI_INT, remote_leader, tag, peer_comm, &req_r); MPI_Wait(&req_s, &status); MPI_Wait(&req_r, &status); recv_buf[2] = leader_rank_in_peer[0]; } MPI_Bcast(recv_buf.data(), 3, MPI_INT, local_leader, local_comm); remote_num_ep = recv_buf[0]; leader_rank_in_peer[1] = recv_buf[1]; leader_rank_in_peer[0] = recv_buf[2]; total_num_ep = local_num_ep + remote_num_ep; if(leader_rank_in_peer[0] < leader_rank_in_peer[1]) { my_position = ep_rank_loc; //! LEADER create EP if(ep_rank == local_leader) { ::MPI_Comm *mpi_dup = new ::MPI_Comm; ::MPI_Comm_dup(to_mpi_comm(local_comm->mpi_comm), mpi_dup); MPI_Comm *ep_intercomm; MPI_Info info; MPI_Comm_create_endpoints(mpi_dup, total_num_ep, info, ep_intercomm); for(int i=0; iis_intercomm = true; ep_intercomm[i]->ep_comm_ptr->intercomm = new ep_lib::ep_intercomm; ep_intercomm[i]->ep_comm_ptr->intercomm->mpi_inter_comm = 0; ep_intercomm[i]->ep_comm_ptr->comm_label = leader_rank_in_peer[0]; } tag_label[0] = TAG++; tag_label[1] = rank_in_world; #pragma omp critical (write_to_tag_list) tag_list.push_back(make_pair( make_pair(tag_label[0], tag_label[1]) , ep_intercomm)); MPI_Request req_s; MPI_Status sta_s; MPI_Isend(tag_label, 2, MPI_INT, remote_leader, tag, peer_comm, &req_s); MPI_Wait(&req_s, &sta_s); } } else { //! Wait for EP creation my_position = remote_num_ep + ep_rank_loc; if(ep_rank == local_leader) { MPI_Status status; MPI_Request req_r; MPI_Irecv(tag_label, 2, MPI_INT, remote_leader, tag, peer_comm, &req_r); MPI_Wait(&req_r, &status); } } MPI_Bcast(tag_label, 2, MPI_INT, local_leader, local_comm); #pragma omp critical (read_from_tag_list) { bool found = false; while(!found) { for(std::list, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++) { if((*iter).first == make_pair(tag_label[0], tag_label[1])) { *newintercomm = iter->second[my_position]; found = true; // tag_list.erase(iter); break; } } } } MPI_Barrier_local(local_comm); if(leader_rank_in_peer[0] < leader_rank_in_peer[1]) { for(std::list, MPI_Comm* > >::iterator iter = tag_list.begin(); iter!=tag_list.end(); iter++) { if((*iter).first == make_pair(tag_label[0], tag_label[1])) { tag_list.erase(iter); break; } } } int intercomm_ep_rank, intercomm_ep_rank_loc, intercomm_mpi_rank; int intercomm_ep_size, intercomm_num_ep, intercomm_mpi_size; intercomm_ep_rank = (*newintercomm)->ep_comm_ptr->size_rank_info[0].first; intercomm_ep_rank_loc = (*newintercomm)->ep_comm_ptr->size_rank_info[1].first; intercomm_mpi_rank = (*newintercomm)->ep_comm_ptr->size_rank_info[2].first; intercomm_ep_size = (*newintercomm)->ep_comm_ptr->size_rank_info[0].second; intercomm_num_ep = (*newintercomm)->ep_comm_ptr->size_rank_info[1].second; intercomm_mpi_size = (*newintercomm)->ep_comm_ptr->size_rank_info[2].second; (*newintercomm)->ep_comm_ptr->intercomm->loc_rank_map = new RANK_MAP; (*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map = new RANK_MAP; (*newintercomm)->ep_comm_ptr->intercomm->loc_rank_map->resize(local_num_ep); (*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map->resize(remote_num_ep); (*newintercomm)->ep_comm_ptr->intercomm->size_rank_info[0] = local_comm->ep_comm_ptr->size_rank_info[0]; (*newintercomm)->ep_comm_ptr->intercomm->size_rank_info[1] = local_comm->ep_comm_ptr->size_rank_info[1]; (*newintercomm)->ep_comm_ptr->intercomm->size_rank_info[2] = local_comm->ep_comm_ptr->size_rank_info[2]; int local_rank_map_ele[2]; local_rank_map_ele[0] = intercomm_ep_rank; local_rank_map_ele[1] = (*newintercomm)->ep_comm_ptr->comm_label; MPI_Allgather(local_rank_map_ele, 2, MPI_INT, (*newintercomm)->ep_comm_ptr->intercomm->loc_rank_map->data(), 2, MPI_INT, local_comm); if(ep_rank == local_leader) { MPI_Status status; MPI_Request req_s, req_r; MPI_Isend((*newintercomm)->ep_comm_ptr->intercomm->loc_rank_map->data(), 2*local_num_ep, MPI_INT, remote_leader, tag, peer_comm, &req_s); MPI_Irecv((*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_num_ep, MPI_INT, remote_leader, tag, peer_comm, &req_r); MPI_Wait(&req_s, &status); MPI_Wait(&req_r, &status); } MPI_Bcast((*newintercomm)->ep_comm_ptr->intercomm->remote_rank_map->data(), 2*remote_num_ep, MPI_INT, local_leader, local_comm); //(*newintercomm)->ep_comm_ptr->intercomm->local_comm = (local_comm->ep_comm_ptr->comm_list[ep_rank_loc]); (*newintercomm)->ep_comm_ptr->intercomm->intercomm_tag = tag; return MPI_SUCCESS; } */ }