18 MPI_Comm * group_comms) {
20 yac_mpi_call(MPI_Comm_test_inter(comm, &is_intercomm), comm);
21 YAC_ASSERT(!is_intercomm,
"inter-communicators are not supported");
24 enum {MPI_HANDSHAKE_VERSION = 1};
25 int version = MPI_HANDSHAKE_VERSION;
27 MPI_Allreduce(MPI_IN_PLACE, &version, 1, MPI_INT, MPI_MIN, comm),
30 version == MPI_HANDSHAKE_VERSION,
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 "broadcasting rank cannot be negativ or greater than communicator size.");
50 if(broadcasting_rank == size)
break;
54 if(broadcasting_rank == rank){
55 size_t len = strlen(group_names[group_idx]);
56 YAC_ASSERT(len <= INT_MAX,
"group name is too long");
57 groupnamelen = (int)len;
60 MPI_Bcast(&groupnamelen, 1, MPI_INT, broadcasting_rank, comm),
62 char * groupname =
xmalloc((
size_t)(groupnamelen + 1) *
sizeof(*groupname));
63 if(broadcasting_rank == rank){
64 strcpy(groupname, group_names[group_idx]);
67 MPI_Bcast(groupname, groupnamelen, MPI_CHAR, broadcasting_rank, comm),
69 groupname[groupnamelen] =
'\0';
73 for (
size_t i = 0; (i < n) && (group_idx == SIZE_MAX); ++i)
74 if (!strcmp(groupname, group_names[i])){
76 "Group communicator for group '%s' was already created, "
77 "but was broadcasted again.", groupname);
83 MPI_Comm_split(comm, (group_idx != SIZE_MAX)?0:MPI_UNDEFINED, rank, &new_comm),
85 if(group_idx != SIZE_MAX)
86 group_comms[group_idx] = new_comm;