Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
be a little more tricky and hopefully more portable
[simgrid.git] / src / smpi / smpi_group.c
1 /* Copyright (c) 2010, 2013. 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=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 < smpi_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
107   if (index < smpi_process_count()) {
108     rank = group->index_to_rank_map[index];
109   }
110   return rank;
111 }
112
113 int smpi_group_use(MPI_Group group)
114 {
115   group->refcount++;
116   return group->refcount;
117 }
118
119 int smpi_group_unuse(MPI_Group group)
120 {
121   group->refcount--;
122   if (group->refcount <= 0) {
123     xbt_free(group->rank_to_index_map);
124     xbt_free(group->index_to_rank_map);
125     xbt_free(group);
126     return 0;
127   }
128   return group->refcount;
129
130 }
131
132 int smpi_group_size(MPI_Group group)
133 {
134   return group->size;
135 }
136
137 int smpi_group_compare(MPI_Group group1, MPI_Group group2)
138 {
139   int result;
140   int i, index, rank, size;
141
142   result = MPI_IDENT;
143   if (smpi_group_size(group1) != smpi_group_size(group2)) {
144     result = MPI_UNEQUAL;
145   } else {
146     size = smpi_group_size(group2);
147     for (i = 0; i < size; i++) {
148       index = smpi_group_index(group1, i);
149       rank = smpi_group_rank(group2, index);
150       if (rank == MPI_UNDEFINED) {
151         result = MPI_UNEQUAL;
152         break;
153       }
154       if (rank != i) {
155         result = MPI_SIMILAR;
156       }
157     }
158   }
159   return result;
160 }