Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
MPI_Comm_split is back to life.
[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 = 0;
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   return group;
46 }
47
48 void smpi_group_destroy(MPI_Group group)
49 {
50   if (smpi_group_unuse(group) <= 0) {
51     xbt_free(group->rank_to_index_map);
52     xbt_free(group->index_to_rank_map);
53     xbt_free(group);
54   }
55 }
56
57 void smpi_group_set_mapping(MPI_Group group, int index, int rank)
58 {
59   if (rank < group->size && index < smpi_process_count()) {
60     group->rank_to_index_map[rank] = index;
61     group->index_to_rank_map[index] = rank;
62   }
63 }
64
65 int smpi_group_index(MPI_Group group, int rank)
66 {
67   int index = MPI_UNDEFINED;
68
69   if (rank < group->size) {
70     index = group->rank_to_index_map[rank];
71   }
72   return index;
73 }
74
75 int smpi_group_rank(MPI_Group group, int index)
76 {
77   int rank = MPI_UNDEFINED;
78
79   if (index < smpi_process_count()) {
80     rank = group->index_to_rank_map[index];
81   }
82   return rank;
83 }
84
85 int smpi_group_use(MPI_Group group)
86 {
87   group->refcount++;
88   return group->refcount;
89 }
90
91 int smpi_group_unuse(MPI_Group group)
92 {
93   group->refcount--;
94   return group->refcount;
95 }
96
97 int smpi_group_size(MPI_Group group)
98 {
99   return group->size;
100 }
101
102 int smpi_group_compare(MPI_Group group1, MPI_Group group2)
103 {
104   int result;
105   int i, index, rank, size;
106
107   result = MPI_IDENT;
108   if (smpi_group_size(group1) != smpi_group_size(group2)) {
109     result = MPI_UNEQUAL;
110   } else {
111     size = smpi_group_size(group2);
112     for (i = 0; i < size; i++) {
113       index = smpi_group_index(group1, i);
114       rank = smpi_group_rank(group2, index);
115       if (rank == MPI_UNDEFINED) {
116         result = MPI_UNEQUAL;
117         break;
118       }
119       if (rank != i) {
120         result = MPI_SIMILAR;
121       }
122     }
123   }
124   return result;
125 }