16 MPI_Comm * group_comms) {
18 yac_mpi_call(MPI_Comm_test_inter(comm, &is_intercomm), comm);
20 "ERROR(yac_mpi_handshake): inter-communicators are not supported");
23 enum {MPI_HANDSHAKE_VERSION = 1};
24 int version = MPI_HANDSHAKE_VERSION;
26 MPI_Allreduce(MPI_IN_PLACE, &version, 1, MPI_INT, MPI_MIN, comm),
29 version == MPI_HANDSHAKE_VERSION,
30 "ERROR(yac_mpi_handshake): "
31 "Version check failed. YAC only supports MPI handshake version %d",
32 MPI_HANDSHAKE_VERSION);
35 MPI_Comm_rank(comm, &rank);
36 MPI_Comm_size(comm, &size);
37 for (
size_t i = 0; i < n; ++i) group_comms[i] = MPI_COMM_NULL;
41 size_t group_idx = SIZE_MAX;
42 for (
size_t i = 0; (i < n) && (group_idx == SIZE_MAX); ++i)
43 if (group_comms[i] == MPI_COMM_NULL) group_idx = i;
44 int broadcasting_rank = group_idx != SIZE_MAX ? rank : size;
46 MPI_Allreduce(MPI_IN_PLACE, &broadcasting_rank, 1, MPI_INT, MPI_MIN, comm),
48 YAC_ASSERT(broadcasting_rank >= 0 && broadcasting_rank <= size,
49 "ERROR(yac_mpi_handshake): "
50 "broadcasting rank cannot be negativ or greater than communicator size.");
51 if(broadcasting_rank == size)
break;
55 if(broadcasting_rank == rank){
56 size_t len = strlen(group_names[group_idx]);
58 "ERROR(yac_mpi_handshake): group name is too long");
59 groupnamelen = (int)len;
62 MPI_Bcast(&groupnamelen, 1, MPI_INT, broadcasting_rank, comm),
64 char * groupname =
xmalloc((
size_t)(groupnamelen + 1) *
sizeof(*groupname));
65 if(broadcasting_rank == rank){
66 strcpy(groupname, group_names[group_idx]);
69 MPI_Bcast(groupname, groupnamelen, MPI_CHAR, broadcasting_rank, comm),
71 groupname[groupnamelen] =
'\0';
75 for (
size_t i = 0; (i < n) && (group_idx == SIZE_MAX); ++i)
76 if (!strcmp(groupname, group_names[i])){
78 "ERROR(yac_mpi_handshake): "
79 "Group communicator for group '%s' was already created, "
80 "but was broadcasted again.",
87 MPI_Comm_split(comm, (group_idx != SIZE_MAX)?0:MPI_UNDEFINED, rank, &new_comm),
89 if(group_idx != SIZE_MAX)
90 group_comms[group_idx] = new_comm;