Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Copy the group when doing a comm_split, to avoid to have shared objects with referenc...
[simgrid.git] / src / smpi / smpi_group.c
1 /* Copyright (c) 2010. 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,
10                                 "Logging specific to SMPI (group)");
11
12 typedef struct s_smpi_mpi_group {
13   int size;
14   int *rank_to_index_map;
15   int *index_to_rank_map;
16   int refcount;
17 } s_smpi_mpi_group_t;
18
19 static s_smpi_mpi_group_t mpi_MPI_GROUP_EMPTY = {
20   0,                            /* size */
21   NULL,                         /* rank_to_index_map */
22   NULL,                         /* index_to_rank_map */
23   1,                            /* refcount: start > 0 so that this group never gets freed */
24 };
25
26 MPI_Group MPI_GROUP_EMPTY = &mpi_MPI_GROUP_EMPTY;
27
28 MPI_Group smpi_group_new(int size)
29 {
30   MPI_Group group;
31   int i, count;
32
33   count = smpi_process_count();
34   group = xbt_new(s_smpi_mpi_group_t, 1);
35   group->size = size;
36   group->rank_to_index_map = xbt_new(int, size);
37   group->index_to_rank_map = xbt_new(int, count);
38   group->refcount = 1;
39   for (i = 0; i < size; i++) {
40     group->rank_to_index_map[i] = MPI_UNDEFINED;
41   }
42   for (i = 0; i < count; i++) {
43     group->index_to_rank_map[i] = MPI_UNDEFINED;
44   }
45
46   return group;
47 }
48
49 MPI_Group smpi_group_copy(MPI_Group origin)
50 {
51   MPI_Group group;
52   int i, count;
53
54   count = smpi_process_count();
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_new(int, count);
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   for (i = 0; i < count; i++) {
64     group->index_to_rank_map[i] = origin->index_to_rank_map[i];
65   }
66
67   return group;
68 }
69
70
71 void smpi_group_destroy(MPI_Group group)
72 {
73   XBT_VERB("trying to free group %p, refcount = %d", group, group->refcount);
74   smpi_group_unuse(group);
75 }
76
77 void smpi_group_set_mapping(MPI_Group group, int index, int rank)
78 {
79   if (rank < group->size && index < smpi_process_count()) {
80     group->rank_to_index_map[rank] = index;
81     group->index_to_rank_map[index] = rank;
82   }
83 }
84
85 int smpi_group_index(MPI_Group group, int rank)
86 {
87   int index = MPI_UNDEFINED;
88
89   if (0 <= rank && rank < group->size) {
90     index = group->rank_to_index_map[rank];
91   }
92   return index;
93 }
94
95 int smpi_group_rank(MPI_Group group, int index)
96 {
97   int rank = MPI_UNDEFINED;
98
99   if (index < smpi_process_count()) {
100     rank = group->index_to_rank_map[index];
101   }
102   return rank;
103 }
104
105 int smpi_group_use(MPI_Group group)
106 {
107   group->refcount++;
108   return group->refcount;
109 }
110
111 int smpi_group_unuse(MPI_Group group)
112 {
113   if (group->refcount-- <= 0) {
114     XBT_VERB("freeing group %p", group);
115     xbt_free(group->rank_to_index_map);
116     xbt_free(group->index_to_rank_map);
117     xbt_free(group);
118   }
119   return group->refcount;
120 }
121
122 int smpi_group_size(MPI_Group group)
123 {
124   return group->size;
125 }
126
127 int smpi_group_compare(MPI_Group group1, MPI_Group group2)
128 {
129   int result;
130   int i, index, rank, size;
131
132   result = MPI_IDENT;
133   if (smpi_group_size(group1) != smpi_group_size(group2)) {
134     result = MPI_UNEQUAL;
135   } else {
136     size = smpi_group_size(group2);
137     for (i = 0; i < size; i++) {
138       index = smpi_group_index(group1, i);
139       rank = smpi_group_rank(group2, index);
140       if (rank == MPI_UNDEFINED) {
141         result = MPI_UNEQUAL;
142         break;
143       }
144       if (rank != i) {
145         result = MPI_SIMILAR;
146       }
147     }
148   }
149   return result;
150 }