Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
spellcheck mc. Don't ask why
[simgrid.git] / src / smpi / smpi_group.cpp
1 /* Copyright (c) 2010, 2013-2015. The SimGrid Team.
2  * All rights reserved.                                                     */
3
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. */
6
7 #include "private.h"
8
9 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_group, smpi, "Logging specific to SMPI (group)");
10
11 typedef struct s_smpi_mpi_group {
12   int size;
13   int *rank_to_index_map;
14   xbt_dict_t index_to_rank_map;
15   int refcount;
16 } s_smpi_mpi_group_t;
17
18 static s_smpi_mpi_group_t mpi_MPI_GROUP_EMPTY = {
19   0,                            /* size */
20   nullptr,                         /* rank_to_index_map */
21   nullptr,                         /* index_to_rank_map */
22   1,                            /* refcount: start > 0 so that this group never gets freed */
23 };
24
25 MPI_Group MPI_GROUP_EMPTY = &mpi_MPI_GROUP_EMPTY;
26
27 MPI_Group smpi_group_new(int size)
28 {
29   MPI_Group group;
30   int i;
31
32   group = xbt_new(s_smpi_mpi_group_t, 1);
33   group->size = size;
34   group->rank_to_index_map = xbt_new(int, size);
35   group->index_to_rank_map = xbt_dict_new_homogeneous(xbt_free_f);
36   group->refcount = 1;
37   for (i = 0; i < size; i++) {
38     group->rank_to_index_map[i] = MPI_UNDEFINED;
39   }
40
41   return group;
42 }
43
44 MPI_Group smpi_group_copy(MPI_Group origin)
45 {
46   MPI_Group group=origin;
47   char *key;
48   char *ptr_rank;
49   xbt_dict_cursor_t cursor = nullptr;
50   
51   int i;
52   if(origin != MPI_GROUP_NULL
53             && origin != MPI_GROUP_EMPTY)
54     {
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);
59       group->refcount = 1;
60       for (i = 0; i < group->size; i++) {
61         group->rank_to_index_map[i] = origin->rank_to_index_map[i];
62       }
63
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);
68       }
69     }
70
71   return group;
72 }
73
74 void smpi_group_destroy(MPI_Group group)
75 {
76   if(group!= smpi_comm_group(MPI_COMM_WORLD)
77           && group != MPI_GROUP_NULL
78           && group != MPI_GROUP_EMPTY)
79   smpi_group_unuse(group);
80 }
81
82 void smpi_group_set_mapping(MPI_Group group, int index, int rank)
83 {
84   int * val_rank;
85
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)));
90       *val_rank = rank;
91
92       char * key = bprintf("%d", index);
93       xbt_dict_set(group->index_to_rank_map, key, val_rank, nullptr);
94       xbt_free(key);
95     }
96   }
97 }
98
99 int smpi_group_index(MPI_Group group, int rank)
100 {
101   int index = MPI_UNDEFINED;
102
103   if (0 <= rank && rank < group->size) {
104     index = group->rank_to_index_map[rank];
105   }
106   return index;
107 }
108
109 int smpi_group_rank(MPI_Group group, int index)
110 {
111   int * ptr_rank = nullptr;
112   char * key = bprintf("%d", index);
113   ptr_rank = static_cast<int*>(xbt_dict_get_or_null(group->index_to_rank_map, key));
114   xbt_free(key);
115
116   if (ptr_rank==nullptr)
117     return MPI_UNDEFINED;
118   return *ptr_rank;
119 }
120
121 int smpi_group_use(MPI_Group group)
122 {
123   group->refcount++;
124   return group->refcount;
125 }
126
127 int smpi_group_unuse(MPI_Group group)
128 {
129   group->refcount--;
130   if (group->refcount <= 0) {
131     xbt_free(group->rank_to_index_map);
132     xbt_dict_free(&group->index_to_rank_map);
133     xbt_free(group);
134     return 0;
135   }
136   return group->refcount;
137 }
138
139 int smpi_group_size(MPI_Group group)
140 {
141   return group->size;
142 }
143
144 int smpi_group_compare(MPI_Group group1, MPI_Group group2)
145 {
146   int result;
147   int i, index, rank, size;
148
149   result = MPI_IDENT;
150   if (smpi_group_size(group1) != smpi_group_size(group2)) {
151     result = MPI_UNEQUAL;
152   } else {
153     size = smpi_group_size(group2);
154     for (i = 0; i < size; i++) {
155       index = smpi_group_index(group1, i);
156       rank = smpi_group_rank(group2, index);
157       if (rank == MPI_UNDEFINED) {
158         result = MPI_UNEQUAL;
159         break;
160       }
161       if (rank != i) {
162         result = MPI_SIMILAR;
163       }
164     }
165   }
166   return result;
167 }
168
169 int smpi_group_incl(MPI_Group group, int n, int* ranks, MPI_Group* newgroup)
170 {
171   int i=0, index=0;
172   if (n == 0) {
173     *newgroup = MPI_GROUP_EMPTY;
174   } else if (n == smpi_group_size(group)) {
175     *newgroup = group;
176     if(group!= smpi_comm_group(MPI_COMM_WORLD)
177               && group != MPI_GROUP_NULL
178               && group != smpi_comm_group(MPI_COMM_SELF)
179               && group != MPI_GROUP_EMPTY)
180     smpi_group_use(group);
181   } else {
182     *newgroup = smpi_group_new(n);
183     for (i = 0; i < n; i++) {
184       index = smpi_group_index(group, ranks[i]);
185       smpi_group_set_mapping(*newgroup, index, i);
186     }
187   }
188   return MPI_SUCCESS;
189 }