#include "ep_lib.hpp" #include #include "ep_declaration.hpp" #include "ep_mpi.hpp" using namespace std; namespace ep_lib { int MPI_Intercomm_merge_unique_leader(MPI_Comm inter_comm, bool high, MPI_Comm *newintracomm) { Debug("intercomm_merge with unique leader\n"); int ep_rank, ep_rank_loc, mpi_rank; int ep_size, num_ep, mpi_size; ep_rank = inter_comm->ep_comm_ptr->size_rank_info[0].first; ep_rank_loc = inter_comm->ep_comm_ptr->size_rank_info[1].first; mpi_rank = inter_comm->ep_comm_ptr->size_rank_info[2].first; ep_size = inter_comm->ep_comm_ptr->size_rank_info[0].second; num_ep = inter_comm->ep_comm_ptr->size_rank_info[1].second; mpi_size = inter_comm->ep_comm_ptr->size_rank_info[2].second; int local_high = high; int remote_high; int remote_ep_size = inter_comm->ep_comm_ptr->intercomm->remote_rank_map->size(); int local_ep_rank, local_ep_rank_loc, local_mpi_rank; int local_ep_size, local_num_ep, local_mpi_size; //local_ep_rank = inter_comm->ep_comm_ptr->intercomm->local_comm->ep_comm_ptr->size_rank_info[0].first; //local_ep_rank_loc = inter_comm->ep_comm_ptr->intercomm->local_comm->ep_comm_ptr->size_rank_info[1].first; //local_mpi_rank = inter_comm->ep_comm_ptr->intercomm->local_comm->ep_comm_ptr->size_rank_info[2].first; //local_ep_size = inter_comm->ep_comm_ptr->intercomm->local_comm->ep_comm_ptr->size_rank_info[0].second; //local_num_ep = inter_comm->ep_comm_ptr->intercomm->local_comm->ep_comm_ptr->size_rank_info[1].second; //local_mpi_size = inter_comm->ep_comm_ptr->intercomm->local_comm->ep_comm_ptr->size_rank_info[2].second; if(local_ep_rank == 0) { MPI_Status status[2]; MPI_Request request[2]; MPI_Isend(&local_high, 1, MPI_INT, 0, inter_comm->ep_comm_ptr->intercomm->intercomm_tag, inter_comm, &request[0]); MPI_Irecv(&remote_high, 1, MPI_INT, 0, inter_comm->ep_comm_ptr->intercomm->intercomm_tag, inter_comm, &request[1]); MPI_Waitall(2, request, status); } //MPI_Bcast(&remote_high, 1, MPI_INT, 0, inter_comm->ep_comm_ptr->intercomm->local_comm); MPI_Comm_dup(inter_comm, newintracomm); int my_ep_rank = local_highep_comm_ptr->size_rank_info[0].first; intra_ep_rank_loc = (*newintracomm)->ep_comm_ptr->size_rank_info[1].first; intra_mpi_rank = (*newintracomm)->ep_comm_ptr->size_rank_info[2].first; intra_ep_size = (*newintracomm)->ep_comm_ptr->size_rank_info[0].second; intra_num_ep = (*newintracomm)->ep_comm_ptr->size_rank_info[1].second; intra_mpi_size = (*newintracomm)->ep_comm_ptr->size_rank_info[2].second; MPI_Barrier_local(*newintracomm); int *reorder; if(intra_ep_rank_loc == 0) { reorder = new int[intra_ep_size]; } MPI_Gather(&my_ep_rank, 1, MPI_INT, reorder, 1, MPI_INT, 0, *newintracomm); if(intra_ep_rank_loc == 0) { ::MPI_Bcast(reorder, intra_ep_size, to_mpi_type(MPI_INT), 0, to_mpi_comm((*newintracomm)->mpi_comm)); vector< pair > tmp_rank_map(intra_ep_size); for(int i=0; iep_rank_map->at(i) ; } //(*newintracomm)->rank_map->swap(tmp_rank_map); (*newintracomm)->ep_rank_map->clear(); for(int i=0; iep_rank_map->insert(std::pair< int, std::pair >(i, tmp_rank_map[i].first, tmp_rank_map[i].second)); } tmp_rank_map.clear(); } MPI_Barrier_local(*newintracomm); (*newintracomm)->ep_comm_ptr->size_rank_info[0].first = my_ep_rank; if(intra_ep_rank_loc == 0) { delete[] reorder; } return MPI_SUCCESS; } int MPI_Intercomm_merge(MPI_Comm inter_comm, bool high, MPI_Comm *newintracomm) { assert(inter_comm->is_intercomm); // determine if only one MPI proc // to be completed ...... // multiple MPI proc and high differs int newcomm_ep_rank = inter_comm->ep_comm_ptr->intercomm->size_rank_info[0].first; int newcomm_ep_rank_loc = inter_comm->ep_comm_ptr->intercomm->size_rank_info[1].first; int newcomm_num_ep = inter_comm->ep_comm_ptr->intercomm->size_rank_info[1].second; int ep_rank = inter_comm->ep_comm_ptr->size_rank_info[0].first; int ep_rank_loc = inter_comm->ep_comm_ptr->size_rank_info[1].first; int num_ep = inter_comm->ep_comm_ptr->size_rank_info[1].second; if(newcomm_ep_rank_loc == 0) { ::MPI_Comm *mpi_intracomm = new ::MPI_Comm; ::MPI_Intercomm_merge(to_mpi_comm(inter_comm->ep_comm_ptr->intercomm->mpi_inter_comm), high, mpi_intracomm); MPI_Info info; MPI_Comm *ep_comm; MPI_Comm_create_endpoints(mpi_intracomm, newcomm_num_ep, info, ep_comm); inter_comm->ep_comm_ptr->comm_list[0]->mem_bridge = ep_comm; } MPI_Barrier_local(inter_comm); int remote_num_ep = newcomm_num_ep - num_ep; *newintracomm = inter_comm->ep_comm_ptr->comm_list[0]->mem_bridge[high? remote_num_ep+ep_rank_loc : ep_rank_loc]; int ep_size = inter_comm->ep_comm_ptr->size_rank_info[0].second; int remote_ep_size = inter_comm->ep_comm_ptr->intercomm->intercomm_rank_map->size(); //printf("ep_size = %d, remote_ep_size = %d\n", ep_size, remote_ep_size); (*newintracomm)->ep_comm_ptr->size_rank_info[0].first = high? remote_ep_size+ep_rank : ep_rank; int my_triple[3]; my_triple[0] = (*newintracomm)->ep_comm_ptr->size_rank_info[0].first; my_triple[1] = (*newintracomm)->ep_comm_ptr->size_rank_info[1].first; my_triple[2] = (*newintracomm)->ep_comm_ptr->size_rank_info[2].first; int *my_triple_list = new int[3 * (*newintracomm)->ep_comm_ptr->size_rank_info[0].second]; MPI_Allgather(my_triple, 3, MPI_INT, my_triple_list, 3, MPI_INT, *newintracomm); if((*newintracomm)->ep_comm_ptr->size_rank_info[1].first == 0) { (*newintracomm)->ep_rank_map->clear(); for(int i=0; i<(*newintracomm)->ep_comm_ptr->size_rank_info[0].second; i++) { (*newintracomm)->ep_rank_map->insert(std::pair< int, std::pair >(my_triple_list[3*i], my_triple_list[3*i+1], my_triple_list[3*i+2])); } } #ifdef _showinfo MPI_Barrier_local(inter_comm); if((*newintracomm)->ep_comm_ptr->size_rank_info[0].first == 15) { for(std::map >::iterator it = (*newintracomm)->ep_rank_map->begin(); it != (*newintracomm)->ep_rank_map->end(); it++) { printf("(%d %d %d)\n", it->first, it->second.first, it->second.second); } } #endif delete my_triple_list; } }