Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
oups, forgot to adapt MC to my last change in config
[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   NULL,                         /* rank_to_index_map */
21   NULL,                         /* 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 = NULL;
50   
51   int i;
52   if(origin!= smpi_comm_group(MPI_COMM_WORLD) && origin != MPI_GROUP_NULL
53             && origin != smpi_comm_group(MPI_COMM_SELF) && 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         xbt_dict_set(group->index_to_rank_map, key, ptr_rank, NULL);
66       }
67     }
68
69   return group;
70 }
71
72 void smpi_group_destroy(MPI_Group group)
73 {
74   if(group!= smpi_comm_group(MPI_COMM_WORLD)
75           && group != MPI_GROUP_NULL
76           && group != smpi_comm_group(MPI_COMM_SELF)
77           && group != MPI_GROUP_EMPTY)
78   smpi_group_unuse(group);
79 }
80
81 void smpi_group_set_mapping(MPI_Group group, int index, int rank)
82 {
83   int * val_rank;
84
85   if (rank < group->size) {
86     group->rank_to_index_map[rank] = index;
87     if (index!=MPI_UNDEFINED ) {
88       val_rank = (int *) malloc(sizeof(int));
89       *val_rank = rank;
90
91       char * key = bprintf("%d", index);
92       xbt_dict_set(group->index_to_rank_map, key, val_rank, NULL);
93       free(key);
94     }
95   }
96 }
97
98 int smpi_group_index(MPI_Group group, int rank)
99 {
100   int index = MPI_UNDEFINED;
101
102   if (0 <= rank && rank < group->size) {
103     index = group->rank_to_index_map[rank];
104   }
105   return index;
106 }
107
108 int smpi_group_rank(MPI_Group group, int index)
109 {
110   int * ptr_rank = NULL;
111   char * key = bprintf("%d", index);
112   ptr_rank = static_cast<int*>(xbt_dict_get_or_null(group->index_to_rank_map, key));
113   xbt_free(key);
114
115   if (!ptr_rank)
116     return MPI_UNDEFINED;
117   return *ptr_rank;
118 }
119
120 int smpi_group_use(MPI_Group group)
121 {
122   group->refcount++;
123   return group->refcount;
124 }
125
126 int smpi_group_unuse(MPI_Group group)
127 {
128   group->refcount--;
129   if (group->refcount <= 0) {
130     xbt_free(group->rank_to_index_map);
131     xbt_dict_free(&group->index_to_rank_map);
132     xbt_free(group);
133     return 0;
134   }
135   return group->refcount;
136 }
137
138 int smpi_group_size(MPI_Group group)
139 {
140   return group->size;
141 }
142
143 int smpi_group_compare(MPI_Group group1, MPI_Group group2)
144 {
145   int result;
146   int i, index, rank, size;
147
148   result = MPI_IDENT;
149   if (smpi_group_size(group1) != smpi_group_size(group2)) {
150     result = MPI_UNEQUAL;
151   } else {
152     size = smpi_group_size(group2);
153     for (i = 0; i < size; i++) {
154       index = smpi_group_index(group1, i);
155       rank = smpi_group_rank(group2, index);
156       if (rank == MPI_UNDEFINED) {
157         result = MPI_UNEQUAL;
158         break;
159       }
160       if (rank != i) {
161         result = MPI_SIMILAR;
162       }
163     }
164   }
165   return result;
166 }
167
168 int smpi_group_incl(MPI_Group group, int n, int* ranks, MPI_Group* newgroup)
169 {
170   int i=0, index=0;
171   if (n == 0) {
172     *newgroup = MPI_GROUP_EMPTY;
173   } else if (n == smpi_group_size(group)) {
174     *newgroup = group;
175     if(group!= smpi_comm_group(MPI_COMM_WORLD)
176               && group != MPI_GROUP_NULL
177               && group != smpi_comm_group(MPI_COMM_SELF)
178               && group != MPI_GROUP_EMPTY)
179     smpi_group_use(group);
180   } else {
181     *newgroup = smpi_group_new(n);
182     for (i = 0; i < n; i++) {
183       index = smpi_group_index(group, ranks[i]);
184       smpi_group_set_mapping(*newgroup, index, i);
185     }
186   }
187   return MPI_SUCCESS;
188 }