1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
4 * University Research and Technology
5 * Corporation. All rights reserved.
6 * Copyright (c) 2004-2017 The University of Tennessee and The University
7 * of Tennessee Research Foundation. All rights
8 * reserved.
9 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
10 * University of Stuttgart. All rights reserved.
11 * Copyright (c) 2004-2005 The Regents of the University of California.
12 * All rights reserved.
13 * Copyright (c) 2006-2007 University of Houston. All rights reserved.
14 * Copyright (c) 2007-2012 Cisco Systems, Inc. All rights reserved.
15 * Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
16 * Copyright (c) 2012 Oak Ridge National Labs. All rights reserved.
17 * Copyright (c) 2015 Research Organization for Information Science
18 * and Technology (RIST). All rights reserved.
19 * $COPYRIGHT$
20 *
21 * Additional copyrights may follow
22 *
23 * $HEADER$
24 */
25
26 #include "ompi_config.h"
27 #include "ompi/group/group.h"
28 #include "ompi/constants.h"
29 #include "mpi.h"
30
31 /* define class information */
32 static void ompi_group_construct(ompi_group_t *);
33 static void ompi_group_destruct(ompi_group_t *);
34
35 OBJ_CLASS_INSTANCE(ompi_group_t,
36 opal_object_t,
37 ompi_group_construct,
38 ompi_group_destruct);
39
40 /*
41 * Table for Fortran <-> C group handle conversion
42 */
43 opal_pointer_array_t ompi_group_f_to_c_table = {{0}};
44
45 /*
46 * Predefined group objects
47 */
48 ompi_predefined_group_t ompi_mpi_group_empty = {{{0}}};
49 ompi_predefined_group_t ompi_mpi_group_null = {{{0}}};
50 ompi_predefined_group_t *ompi_mpi_group_empty_addr = &ompi_mpi_group_empty;
51 ompi_predefined_group_t *ompi_mpi_group_null_addr = &ompi_mpi_group_null;
52
53
54 /*
55 * Allocate a new group structure
56 */
ompi_group_allocate(int group_size)57 ompi_group_t *ompi_group_allocate(int group_size)
58 {
59 /* local variables */
60 ompi_proc_t **procs = calloc (group_size, sizeof (ompi_proc_t *));
61 ompi_group_t *new_group;
62
63 if (NULL == procs) {
64 return NULL;
65 }
66
67 new_group = ompi_group_allocate_plist_w_procs (procs, group_size);
68 if (NULL == new_group) {
69 free (procs);
70 }
71
72 return new_group;
73 }
74
ompi_group_allocate_plist_w_procs(ompi_proc_t ** procs,int group_size)75 ompi_group_t *ompi_group_allocate_plist_w_procs (ompi_proc_t **procs, int group_size)
76 {
77 /* local variables */
78 ompi_group_t * new_group = NULL;
79
80 assert (group_size >= 0);
81
82 /* create new group group element */
83 new_group = OBJ_NEW(ompi_group_t);
84
85 if (NULL == new_group) {
86 return NULL;
87 }
88
89 if (0 > new_group->grp_f_to_c_index) {
90 OBJ_RELEASE (new_group);
91 return NULL;
92 }
93
94 /*
95 * Allocate array of (ompi_proc_t *)'s, one for each
96 * process in the group.
97 */
98 new_group->grp_proc_pointers = procs;
99
100 /* set the group size */
101 new_group->grp_proc_count = group_size;
102
103 /* initialize our rank to MPI_UNDEFINED */
104 new_group->grp_my_rank = MPI_UNDEFINED;
105 OMPI_GROUP_SET_DENSE(new_group);
106
107 ompi_group_increment_proc_count (new_group);
108
109 return new_group;
110 }
111
ompi_group_allocate_sporadic(int group_size)112 ompi_group_t *ompi_group_allocate_sporadic(int group_size)
113 {
114 /* local variables */
115 ompi_group_t *new_group = NULL;
116
117 assert (group_size >= 0);
118
119 /* create new group group element */
120 new_group = OBJ_NEW(ompi_group_t);
121 if( NULL == new_group) {
122 goto error_exit;
123 }
124 if (0 > new_group->grp_f_to_c_index) {
125 OBJ_RELEASE(new_group);
126 new_group = NULL;
127 goto error_exit;
128 }
129 /* allocate array of (grp_sporadic_list )'s */
130 if (0 < group_size) {
131 new_group->sparse_data.grp_sporadic.grp_sporadic_list =
132 (struct ompi_group_sporadic_list_t *)malloc
133 (sizeof(struct ompi_group_sporadic_list_t ) * group_size);
134
135 /* non-empty group */
136 if ( NULL == new_group->sparse_data.grp_sporadic.grp_sporadic_list) {
137 /* sporadic list allocation failed */
138 OBJ_RELEASE (new_group);
139 new_group = NULL;
140 goto error_exit;
141 }
142 }
143
144 /* set the group size */
145 new_group->grp_proc_count = group_size; /* actually it's the number of
146 elements in the sporadic list*/
147
148 /* initialize our rank to MPI_UNDEFINED */
149 new_group->grp_my_rank = MPI_UNDEFINED;
150 new_group->grp_proc_pointers = NULL;
151 OMPI_GROUP_SET_SPORADIC(new_group);
152
153 error_exit:
154 return new_group;
155 }
156
ompi_group_allocate_strided(void)157 ompi_group_t *ompi_group_allocate_strided(void)
158 {
159 ompi_group_t *new_group = NULL;
160
161 /* create new group group element */
162 new_group = OBJ_NEW(ompi_group_t);
163 if( NULL == new_group ) {
164 goto error_exit;
165 }
166 if (0 > new_group->grp_f_to_c_index) {
167 OBJ_RELEASE(new_group);
168 new_group = NULL;
169 goto error_exit;
170 }
171 /* initialize our rank to MPI_UNDEFINED */
172 new_group->grp_my_rank = MPI_UNDEFINED;
173 new_group->grp_proc_pointers = NULL;
174 OMPI_GROUP_SET_STRIDED(new_group);
175 new_group->sparse_data.grp_strided.grp_strided_stride = -1;
176 new_group->sparse_data.grp_strided.grp_strided_offset = -1;
177 new_group->sparse_data.grp_strided.grp_strided_last_element = -1;
178 error_exit:
179 /* return */
180 return new_group;
181 }
ompi_group_allocate_bmap(int orig_group_size,int group_size)182 ompi_group_t *ompi_group_allocate_bmap(int orig_group_size , int group_size)
183 {
184 ompi_group_t *new_group = NULL;
185
186 assert (group_size >= 0);
187
188 /* create new group group element */
189 new_group = OBJ_NEW(ompi_group_t);
190 if( NULL == new_group) {
191 goto error_exit;
192 }
193 if (0 > new_group->grp_f_to_c_index) {
194 OBJ_RELEASE(new_group);
195 new_group = NULL;
196 goto error_exit;
197 }
198 /* allocate the unsigned char list */
199 new_group->sparse_data.grp_bitmap.grp_bitmap_array = (unsigned char *)malloc
200 (sizeof(unsigned char) * ompi_group_div_ceil(orig_group_size,BSIZE));
201
202 new_group->sparse_data.grp_bitmap.grp_bitmap_array_len =
203 ompi_group_div_ceil(orig_group_size,BSIZE);
204
205 new_group->grp_proc_count = group_size;
206
207 /* initialize our rank to MPI_UNDEFINED */
208 new_group->grp_my_rank = MPI_UNDEFINED;
209 new_group->grp_proc_pointers = NULL;
210 OMPI_GROUP_SET_BITMAP(new_group);
211
212 error_exit:
213 /* return */
214 return new_group;
215 }
216
217 /*
218 * increment the reference count of the proc structures
219 */
ompi_group_increment_proc_count(ompi_group_t * group)220 void ompi_group_increment_proc_count(ompi_group_t *group)
221 {
222 ompi_proc_t * proc_pointer;
223 for (int proc = 0 ; proc < group->grp_proc_count ; ++proc) {
224 proc_pointer = ompi_group_peer_lookup_existing (group, proc);
225 if (proc_pointer) {
226 OBJ_RETAIN(proc_pointer);
227 }
228 }
229 }
230
231 /*
232 * decrement the reference count of the proc structures
233 */
234
ompi_group_decrement_proc_count(ompi_group_t * group)235 void ompi_group_decrement_proc_count(ompi_group_t *group)
236 {
237 ompi_proc_t * proc_pointer;
238 for (int proc = 0 ; proc < group->grp_proc_count ; ++proc) {
239 proc_pointer = ompi_group_peer_lookup_existing (group, proc);
240 if (proc_pointer) {
241 OBJ_RELEASE(proc_pointer);
242 }
243 }
244 }
245
246 /*
247 * group constructor
248 */
ompi_group_construct(ompi_group_t * new_group)249 static void ompi_group_construct(ompi_group_t *new_group)
250 {
251 int ret_val;
252
253 /* Note that we do *NOT* increase the refcount on all the included
254 procs here because that is handled at a different level (e.g.,
255 the proc counts are not decreased during the desstructor,
256 either). */
257
258 /* assign entry in fortran <-> c translation array */
259 ret_val = opal_pointer_array_add(&ompi_group_f_to_c_table, new_group);
260 new_group->grp_f_to_c_index = ret_val;
261 new_group->grp_flags = 0;
262
263 /* default the sparse values for groups */
264 new_group->grp_parent_group_ptr = NULL;
265 }
266
267
268 /*
269 * group destructor
270 */
ompi_group_destruct(ompi_group_t * group)271 static void ompi_group_destruct(ompi_group_t *group)
272 {
273 /* Note that we do *NOT* decrease the refcount on all the included
274 procs here because that is handled at a different level (e.g.,
275 the proc counts are not increased during the constructor,
276 either). */
277
278 #if OMPI_GROUP_SPARSE
279 if (OMPI_GROUP_IS_DENSE(group))
280 /* sparse groups do not increment proc reference counters */
281 #endif
282 ompi_group_decrement_proc_count (group);
283
284 /* release thegrp_proc_pointers memory */
285 if (NULL != group->grp_proc_pointers) {
286 free(group->grp_proc_pointers);
287 }
288
289 if (OMPI_GROUP_IS_SPORADIC(group)) {
290 if (NULL != group->sparse_data.grp_sporadic.grp_sporadic_list) {
291 free(group->sparse_data.grp_sporadic.grp_sporadic_list);
292 }
293 }
294
295 if (OMPI_GROUP_IS_BITMAP(group)) {
296 if (NULL != group->sparse_data.grp_bitmap.grp_bitmap_array) {
297 free(group->sparse_data.grp_bitmap.grp_bitmap_array);
298 }
299 }
300
301 if (NULL != group->grp_parent_group_ptr){
302 OBJ_RELEASE(group->grp_parent_group_ptr);
303 }
304
305 /* reset the ompi_group_f_to_c_table entry - make sure that the
306 * entry is in the table */
307 if (NULL != opal_pointer_array_get_item(&ompi_group_f_to_c_table,
308 group->grp_f_to_c_index)) {
309 opal_pointer_array_set_item(&ompi_group_f_to_c_table,
310 group->grp_f_to_c_index, NULL);
311 }
312 }
313
314
315 /*
316 * Initialize OMPI group infrastructure
317 */
ompi_group_init(void)318 int ompi_group_init(void)
319 {
320 /* initialize ompi_group_f_to_c_table */
321 OBJ_CONSTRUCT( &ompi_group_f_to_c_table, opal_pointer_array_t);
322 if( OPAL_SUCCESS != opal_pointer_array_init(&ompi_group_f_to_c_table, 4,
323 OMPI_FORTRAN_HANDLE_MAX, 16) ) {
324 return OMPI_ERROR;
325 }
326
327 /* add MPI_GROUP_NULL to table */
328 OBJ_CONSTRUCT(&ompi_mpi_group_null, ompi_group_t);
329 ompi_mpi_group_null.group.grp_proc_count = 0;
330 ompi_mpi_group_null.group.grp_my_rank = MPI_PROC_NULL;
331 ompi_mpi_group_null.group.grp_proc_pointers = NULL;
332 ompi_mpi_group_null.group.grp_flags |= OMPI_GROUP_DENSE;
333 ompi_mpi_group_null.group.grp_flags |= OMPI_GROUP_INTRINSIC;
334
335 /* add MPI_GROUP_EMPTY to table */
336 OBJ_CONSTRUCT(&ompi_mpi_group_empty, ompi_group_t);
337 ompi_mpi_group_empty.group.grp_proc_count = 0;
338 ompi_mpi_group_empty.group.grp_my_rank = MPI_UNDEFINED;
339 ompi_mpi_group_empty.group.grp_proc_pointers = NULL;
340 ompi_mpi_group_empty.group.grp_flags |= OMPI_GROUP_DENSE;
341 ompi_mpi_group_empty.group.grp_flags |= OMPI_GROUP_INTRINSIC;
342
343 return OMPI_SUCCESS;
344 }
345
346
347 /*
348 * Clean up group infrastructure
349 */
ompi_group_finalize(void)350 int ompi_group_finalize(void)
351 {
352 ompi_mpi_group_null.group.grp_flags = 0;
353 OBJ_DESTRUCT(&ompi_mpi_group_null);
354
355 ompi_mpi_group_null.group.grp_flags = 0;
356 OBJ_DESTRUCT(&ompi_mpi_group_empty);
357
358 OBJ_DESTRUCT(&ompi_group_f_to_c_table);
359
360 return OMPI_SUCCESS;
361 }
362