Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid
[simgrid.git] / src / smpi / smpi_group.c
1 /* Copyright (c) 2010, 2013-2014. 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 = SIMIX_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=origin;
52   int i, count;
53   if(origin!= smpi_comm_group(MPI_COMM_WORLD)
54             && origin != MPI_GROUP_NULL
55             && origin != smpi_comm_group(MPI_COMM_SELF)
56             && origin != MPI_GROUP_EMPTY)
57     {
58       count = smpi_process_count();
59       group = xbt_new(s_smpi_mpi_group_t, 1);
60       group->size = origin->size;
61       group->rank_to_index_map = xbt_new(int, group->size);
62       group->index_to_rank_map = xbt_new(int, count);
63       group->refcount = 1;
64       for (i = 0; i < group->size; i++) {
65         group->rank_to_index_map[i] = origin->rank_to_index_map[i];
66       }
67       for (i = 0; i < count; i++) {
68         group->index_to_rank_map[i] = origin->index_to_rank_map[i];
69       }
70     }
71
72   return group;
73 }
74
75
76 void smpi_group_destroy(MPI_Group group)
77 {
78   if(group!= smpi_comm_group(MPI_COMM_WORLD)
79           && group != MPI_GROUP_NULL
80           && group != smpi_comm_group(MPI_COMM_SELF)
81           && group != MPI_GROUP_EMPTY)
82   smpi_group_unuse(group);
83 }
84
85 void smpi_group_set_mapping(MPI_Group group, int index, int rank)
86 {
87   if (rank < group->size && index < SIMIX_process_count()) {
88     group->rank_to_index_map[rank] = index;
89     if(index!=MPI_UNDEFINED)group->index_to_rank_map[index] = rank;
90   }
91 }
92
93 int smpi_group_index(MPI_Group group, int rank)
94 {
95   int index = MPI_UNDEFINED;
96
97   if (0 <= rank && rank < group->size) {
98     index = group->rank_to_index_map[rank];
99   }
100   return index;
101 }
102
103 int smpi_group_rank(MPI_Group group, int index)
104 {
105   int rank = MPI_UNDEFINED;
106   rank = group->index_to_rank_map[index];
107   return rank;
108 }
109
110 int smpi_group_use(MPI_Group group)
111 {
112   group->refcount++;
113   return group->refcount;
114 }
115
116 int smpi_group_unuse(MPI_Group group)
117 {
118   group->refcount--;
119   if (group->refcount <= 0) {
120     xbt_free(group->rank_to_index_map);
121     xbt_free(group->index_to_rank_map);
122     xbt_free(group);
123     return 0;
124   }
125   return group->refcount;
126
127 }
128
129 int smpi_group_size(MPI_Group group)
130 {
131   return group->size;
132 }
133
134 int smpi_group_compare(MPI_Group group1, MPI_Group group2)
135 {
136   int result;
137   int i, index, rank, size;
138
139   result = MPI_IDENT;
140   if (smpi_group_size(group1) != smpi_group_size(group2)) {
141     result = MPI_UNEQUAL;
142   } else {
143     size = smpi_group_size(group2);
144     for (i = 0; i < size; i++) {
145       index = smpi_group_index(group1, i);
146       rank = smpi_group_rank(group2, index);
147       if (rank == MPI_UNDEFINED) {
148         result = MPI_UNEQUAL;
149         break;
150       }
151       if (rank != i) {
152         result = MPI_SIMILAR;
153       }
154     }
155   }
156   return result;
157 }