Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
doh, I broke SMPI
[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   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));
116   xbt_free(key);
117
118   if (ptr_rank==nullptr)
119     return MPI_UNDEFINED;
120   return *ptr_rank;
121 }
122
123 int smpi_group_use(MPI_Group group)
124 {
125   group->refcount++;
126   return group->refcount;
127 }
128
129 int smpi_group_unuse(MPI_Group group)
130 {
131   group->refcount--;
132   if (group->refcount <= 0) {
133     xbt_free(group->rank_to_index_map);
134     xbt_dict_free(&group->index_to_rank_map);
135     xbt_free(group);
136     return 0;
137   }
138   return group->refcount;
139 }
140
141 int smpi_group_size(MPI_Group group)
142 {
143   return group->size;
144 }
145
146 int smpi_group_compare(MPI_Group group1, MPI_Group group2)
147 {
148   int result;
149   int i, index, rank, size;
150
151   result = MPI_IDENT;
152   if (smpi_group_size(group1) != smpi_group_size(group2)) {
153     result = MPI_UNEQUAL;
154   } else {
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;
161         break;
162       }
163       if (rank != i) {
164         result = MPI_SIMILAR;
165       }
166     }
167   }
168   return result;
169 }
170
171 int smpi_group_incl(MPI_Group group, int n, int* ranks, MPI_Group* newgroup)
172 {
173   int i=0, index=0;
174   if (n == 0) {
175     *newgroup = MPI_GROUP_EMPTY;
176   } else if (n == smpi_group_size(group)) {
177     *newgroup = 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);
183   } else {
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);
188     }
189   }
190   return MPI_SUCCESS;
191 }