1 /* Copyright (c) 2010, 2013-2015. The SimGrid Team.
2 * All rights reserved. */
4 /* This program is free software; you can redistribute it and/or modify it
5 * under the terms of the license (GNU LGPL) which comes with this package. */
9 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_group, smpi, "Logging specific to SMPI (group)");
11 typedef struct s_smpi_mpi_group {
13 int *rank_to_index_map;
14 xbt_dict_t index_to_rank_map;
18 static s_smpi_mpi_group_t mpi_MPI_GROUP_EMPTY = {
20 nullptr, /* rank_to_index_map */
21 nullptr, /* index_to_rank_map */
22 1, /* refcount: start > 0 so that this group never gets freed */
25 MPI_Group MPI_GROUP_EMPTY = &mpi_MPI_GROUP_EMPTY;
27 MPI_Group smpi_group_new(int size)
32 group = xbt_new(s_smpi_mpi_group_t, 1);
34 group->rank_to_index_map = xbt_new(int, size);
35 group->index_to_rank_map = xbt_dict_new_homogeneous(xbt_free_f);
37 for (i = 0; i < size; i++) {
38 group->rank_to_index_map[i] = MPI_UNDEFINED;
44 MPI_Group smpi_group_copy(MPI_Group origin)
46 MPI_Group group=origin;
49 xbt_dict_cursor_t cursor = nullptr;
52 if(origin != MPI_GROUP_NULL
53 && origin != MPI_GROUP_EMPTY)
55 group = xbt_new(s_smpi_mpi_group_t, 1);
56 group->size = origin->size;
57 group->rank_to_index_map = xbt_new(int, group->size);
58 group->index_to_rank_map = xbt_dict_new_homogeneous(xbt_free_f);
60 for (i = 0; i < group->size; i++) {
61 group->rank_to_index_map[i] = origin->rank_to_index_map[i];
64 xbt_dict_foreach(origin->index_to_rank_map, cursor, key, ptr_rank) {
65 int * cp = static_cast<int*>(xbt_malloc(sizeof(int)));
66 *cp=*reinterpret_cast<int*>(ptr_rank);
67 xbt_dict_set(group->index_to_rank_map, key, cp, nullptr);
74 void smpi_group_destroy(MPI_Group group)
76 if(group!= smpi_comm_group(MPI_COMM_WORLD)
77 && group != MPI_GROUP_NULL
78 && group != MPI_GROUP_EMPTY)
79 smpi_group_unuse(group);
82 void smpi_group_set_mapping(MPI_Group group, int index, int rank)
86 if (rank < group->size) {
87 group->rank_to_index_map[rank] = index;
88 if (index!=MPI_UNDEFINED ) {
89 val_rank = static_cast<int *>(xbt_malloc(sizeof(int)));
92 char * key = bprintf("%d", index);
93 xbt_dict_set(group->index_to_rank_map, key, val_rank, nullptr);
99 int smpi_group_index(MPI_Group group, int rank)
101 int index = MPI_UNDEFINED;
103 if (0 <= rank && rank < group->size) {
104 index = group->rank_to_index_map[rank];
109 int smpi_group_rank(MPI_Group group, int index)
111 int * ptr_rank = nullptr;
112 if (group==MPI_GROUP_EMPTY)
113 return MPI_UNDEFINED;
114 char * key = bprintf("%d", index);
115 ptr_rank = static_cast<int*>(xbt_dict_get_or_null(group->index_to_rank_map, key));
118 if (ptr_rank==nullptr)
119 return MPI_UNDEFINED;
123 int smpi_group_use(MPI_Group group)
126 return group->refcount;
129 int smpi_group_unuse(MPI_Group group)
132 if (group->refcount <= 0) {
133 xbt_free(group->rank_to_index_map);
134 xbt_dict_free(&group->index_to_rank_map);
138 return group->refcount;
141 int smpi_group_size(MPI_Group group)
146 int smpi_group_compare(MPI_Group group1, MPI_Group group2)
149 int i, index, rank, size;
152 if (smpi_group_size(group1) != smpi_group_size(group2)) {
153 result = MPI_UNEQUAL;
155 size = smpi_group_size(group2);
156 for (i = 0; i < size; i++) {
157 index = smpi_group_index(group1, i);
158 rank = smpi_group_rank(group2, index);
159 if (rank == MPI_UNDEFINED) {
160 result = MPI_UNEQUAL;
164 result = MPI_SIMILAR;
171 int smpi_group_incl(MPI_Group group, int n, int* ranks, MPI_Group* newgroup)
175 *newgroup = MPI_GROUP_EMPTY;
176 } else if (n == smpi_group_size(group)) {
178 if(group!= smpi_comm_group(MPI_COMM_WORLD)
179 && group != MPI_GROUP_NULL
180 && group != smpi_comm_group(MPI_COMM_SELF)
181 && group != MPI_GROUP_EMPTY)
182 smpi_group_use(group);
184 *newgroup = smpi_group_new(n);
185 for (i = 0; i < n; i++) {
186 index = smpi_group_index(group, ranks[i]);
187 smpi_group_set_mapping(*newgroup, index, i);