This source file includes following definitions.
- ompi_win_init
- ompi_win_dump
- ompi_win_finalize
- alloc_window
- config_window
- ompi_win_create
- ompi_win_allocate
- ompi_win_allocate_shared
- ompi_win_create_dynamic
- ompi_win_free
- ompi_win_set_name
- ompi_win_get_name
- ompi_win_group
- ompi_win_construct
- ompi_win_destruct
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 #include "ompi_config.h"
28
29 #include "opal/util/info_subscriber.h"
30 #include "opal/util/string_copy.h"
31
32 #include "mpi.h"
33 #include "ompi/win/win.h"
34 #include "ompi/errhandler/errhandler.h"
35 #include "ompi/constants.h"
36 #include "ompi/attribute/attribute.h"
37 #include "ompi/group/group.h"
38 #include "ompi/info/info.h"
39 #include "ompi/mca/osc/base/base.h"
40 #include "ompi/mca/osc/osc.h"
41
42 #include "ompi/runtime/params.h"
43
44
45
46
47
48 opal_pointer_array_t ompi_mpi_windows = {{0}};
49
50 ompi_predefined_win_t ompi_mpi_win_null = {{{{0}}}};
51 ompi_predefined_win_t *ompi_mpi_win_null_addr = &ompi_mpi_win_null;
52 mca_base_var_enum_t *ompi_win_accumulate_ops = NULL;
53 mca_base_var_enum_flag_t *ompi_win_accumulate_order = NULL;
54
55 static mca_base_var_enum_value_t accumulate_ops_values[] = {
56 {.value = OMPI_WIN_ACCUMULATE_OPS_SAME_OP_NO_OP, .string = "same_op_no_op",},
57 {.value = OMPI_WIN_ACCUMULATE_OPS_SAME_OP, .string = "same_op",},
58 {.value = -1, .string = NULL},
59 };
60
61 static mca_base_var_enum_value_flag_t accumulate_order_flags[] = {
62 {.flag = OMPI_WIN_ACC_ORDER_NONE, .string = "none", .conflicting_flag = OMPI_WIN_ACC_ORDER_RAR |
63 OMPI_WIN_ACC_ORDER_WAR | OMPI_WIN_ACC_ORDER_RAW | OMPI_WIN_ACC_ORDER_WAW},
64 {.flag = OMPI_WIN_ACC_ORDER_RAR, .string = "rar", .conflicting_flag = OMPI_WIN_ACC_ORDER_NONE},
65 {.flag = OMPI_WIN_ACC_ORDER_WAR, .string = "war", .conflicting_flag = OMPI_WIN_ACC_ORDER_NONE},
66 {.flag = OMPI_WIN_ACC_ORDER_RAW, .string = "raw", .conflicting_flag = OMPI_WIN_ACC_ORDER_NONE},
67 {.flag = OMPI_WIN_ACC_ORDER_WAW, .string = "waw", .conflicting_flag = OMPI_WIN_ACC_ORDER_NONE},
68 {0},
69 };
70
71 static void ompi_win_construct(ompi_win_t *win);
72 static void ompi_win_destruct(ompi_win_t *win);
73
74 OBJ_CLASS_INSTANCE(ompi_win_t, opal_infosubscriber_t,
75 ompi_win_construct, ompi_win_destruct);
76
77 int
78 ompi_win_init(void)
79 {
80 int ret;
81
82 assert (sizeof (ompi_predefined_win_t) >= sizeof (ompi_win_t));
83
84
85 OBJ_CONSTRUCT(&ompi_mpi_windows, opal_pointer_array_t);
86 if( OPAL_SUCCESS != opal_pointer_array_init(&ompi_mpi_windows, 4,
87 OMPI_FORTRAN_HANDLE_MAX, 16) ) {
88 return OMPI_ERROR;
89 }
90
91
92 OBJ_CONSTRUCT(&ompi_mpi_win_null.win, ompi_win_t);
93 ompi_mpi_win_null.win.w_flags = OMPI_WIN_INVALID;
94 ompi_mpi_win_null.win.w_group = &ompi_mpi_group_null.group;
95 OBJ_RETAIN(&ompi_mpi_group_null);
96 ompi_win_set_name(&ompi_mpi_win_null.win, "MPI_WIN_NULL");
97 opal_pointer_array_set_item(&ompi_mpi_windows, 0, &ompi_mpi_win_null.win);
98
99 ret = mca_base_var_enum_create ("accumulate_ops", accumulate_ops_values, &ompi_win_accumulate_ops);
100 if (OPAL_SUCCESS != ret) {
101 return ret;
102 }
103
104 ret = mca_base_var_enum_create_flag ("accumulate_order", accumulate_order_flags, &ompi_win_accumulate_order);
105 if (OPAL_SUCCESS != ret) {
106 return ret;
107 }
108
109 return OMPI_SUCCESS;
110 }
111
112 static void ompi_win_dump (ompi_win_t *win)
113 {
114 opal_output(0, "Dumping information for window: %s\n", win->w_name);
115 opal_output(0," Fortran window handle: %d, window size: %d\n",
116 win->w_f_to_c_index, ompi_group_size (win->w_group));
117 }
118
119 int ompi_win_finalize(void)
120 {
121 size_t size = opal_pointer_array_get_size (&ompi_mpi_windows);
122
123 for (size_t i = 1 ; i < size ; ++i) {
124 ompi_win_t *win =
125 (ompi_win_t *) opal_pointer_array_get_item (&ompi_mpi_windows, i);
126 if (NULL != win) {
127 if (ompi_debug_show_handle_leaks && !ompi_win_invalid(win)){
128 opal_output(0,"WARNING: MPI_Win still allocated in MPI_Finalize\n");
129 ompi_win_dump (win);
130 }
131 ompi_win_free (win);
132 }
133 }
134
135 OBJ_DESTRUCT(&ompi_mpi_win_null.win);
136 OBJ_DESTRUCT(&ompi_mpi_windows);
137 OBJ_RELEASE(ompi_win_accumulate_ops);
138 OBJ_RELEASE(ompi_win_accumulate_order);
139
140 return OMPI_SUCCESS;
141 }
142
143 static int alloc_window(struct ompi_communicator_t *comm, opal_info_t *info, int flavor, ompi_win_t **win_out)
144 {
145 ompi_win_t *win;
146 ompi_group_t *group;
147 int acc_ops, acc_order, flag, ret;
148
149
150 win = OBJ_NEW(ompi_win_t);
151 if (NULL == win) {
152 return OMPI_ERR_OUT_OF_RESOURCE;
153 }
154
155 ret = opal_info_get_value_enum (info, "accumulate_ops", &acc_ops,
156 OMPI_WIN_ACCUMULATE_OPS_SAME_OP_NO_OP,
157 ompi_win_accumulate_ops, &flag);
158 if (OMPI_SUCCESS != ret) {
159 OBJ_RELEASE(win);
160 return ret;
161 }
162
163 win->w_acc_ops = (ompi_win_accumulate_ops_t)acc_ops;
164
165 ret = opal_info_get_value_enum (info, "accumulate_order", &acc_order,
166 OMPI_WIN_ACC_ORDER_RAR | OMPI_WIN_ACC_ORDER_WAR |
167 OMPI_WIN_ACC_ORDER_RAW | OMPI_WIN_ACC_ORDER_WAW,
168 &(ompi_win_accumulate_order->super), &flag);
169 if (OMPI_SUCCESS != ret) {
170 OBJ_RELEASE(win);
171 return ret;
172 }
173
174 win->w_acc_order = acc_order;
175
176 win->w_flavor = flavor;
177
178
179 group = comm->c_local_group;
180 OBJ_RETAIN(group);
181 win->w_group = group;
182
183
184 win->super.s_info = OBJ_NEW(opal_info_t);
185 if (info) {
186 opal_info_dup(info, &(win->super.s_info));
187 }
188
189 *win_out = win;
190
191 return OMPI_SUCCESS;
192 }
193
194 static int
195 config_window(void *base, size_t size, int disp_unit,
196 int flavor, int model, ompi_win_t *win)
197 {
198 int ret;
199
200 ret = ompi_attr_set_c(WIN_ATTR, win, &win->w_keyhash,
201 MPI_WIN_BASE, base, true);
202 if (OMPI_SUCCESS != ret) return ret;
203
204 ret = ompi_attr_set_aint(WIN_ATTR, win,
205 &win->w_keyhash,
206 MPI_WIN_SIZE, size, true);
207 if (OMPI_SUCCESS != ret) return ret;
208
209 ret = ompi_attr_set_int(WIN_ATTR, win,
210 &win->w_keyhash,
211 MPI_WIN_DISP_UNIT, disp_unit,
212 true);
213 if (OMPI_SUCCESS != ret) return ret;
214
215 ret = ompi_attr_set_int(WIN_ATTR, win,
216 &win->w_keyhash,
217 MPI_WIN_CREATE_FLAVOR, flavor, true);
218 if (OMPI_SUCCESS != ret) return ret;
219
220 ret = ompi_attr_set_int(WIN_ATTR, win,
221 &win->w_keyhash,
222 MPI_WIN_MODEL, model, true);
223 if (OMPI_SUCCESS != ret) return ret;
224
225 win->w_f_to_c_index = opal_pointer_array_add(&ompi_mpi_windows, win);
226 if (-1 == win->w_f_to_c_index) return OMPI_ERR_OUT_OF_RESOURCE;
227
228 return OMPI_SUCCESS;
229 }
230
231 int
232 ompi_win_create(void *base, size_t size,
233 int disp_unit, ompi_communicator_t *comm,
234 opal_info_t *info,
235 ompi_win_t** newwin)
236 {
237 ompi_win_t *win;
238 int model;
239 int ret;
240
241 ret = alloc_window (comm, info, MPI_WIN_FLAVOR_CREATE, &win);
242 if (OMPI_SUCCESS != ret) {
243 return ret;
244 }
245
246 ret = ompi_osc_base_select(win, &base, size, disp_unit, comm, info, MPI_WIN_FLAVOR_CREATE, &model);
247 if (OMPI_SUCCESS != ret) {
248 OBJ_RELEASE(win);
249 return ret;
250 }
251
252 ret = config_window(base, size, disp_unit, MPI_WIN_FLAVOR_CREATE, model, win);
253 if (OMPI_SUCCESS != ret) {
254 OBJ_RELEASE(win);
255 return ret;
256 }
257
258 *newwin = win;
259
260 return OMPI_SUCCESS;
261 }
262
263
264 int
265 ompi_win_allocate(size_t size, int disp_unit, opal_info_t *info,
266 ompi_communicator_t *comm, void *baseptr, ompi_win_t **newwin)
267 {
268 ompi_win_t *win;
269 int model;
270 int ret;
271 void *base;
272
273 ret = alloc_window (comm, info, MPI_WIN_FLAVOR_ALLOCATE, &win);
274 if (OMPI_SUCCESS != ret) {
275 return ret;
276 }
277
278 ret = ompi_osc_base_select(win, &base, size, disp_unit, comm, info, MPI_WIN_FLAVOR_ALLOCATE, &model);
279 if (OMPI_SUCCESS != ret) {
280 OBJ_RELEASE(win);
281 return ret;
282 }
283
284 ret = config_window(base, size, disp_unit, MPI_WIN_FLAVOR_ALLOCATE, model, win);
285 if (OMPI_SUCCESS != ret) {
286 OBJ_RELEASE(win);
287 return ret;
288 }
289
290 *((void**) baseptr) = base;
291 *newwin = win;
292
293 return OMPI_SUCCESS;
294 }
295
296
297 int
298 ompi_win_allocate_shared(size_t size, int disp_unit, opal_info_t *info,
299 ompi_communicator_t *comm, void *baseptr, ompi_win_t **newwin)
300 {
301 ompi_win_t *win;
302 int model;
303 int ret;
304 void *base;
305
306 ret = alloc_window (comm, info, MPI_WIN_FLAVOR_SHARED, &win);
307 if (OMPI_SUCCESS != ret) {
308 return ret;
309 }
310
311 ret = ompi_osc_base_select(win, &base, size, disp_unit, comm, info, MPI_WIN_FLAVOR_SHARED, &model);
312 if (OMPI_SUCCESS != ret) {
313 OBJ_RELEASE(win);
314 return ret;
315 }
316
317 ret = config_window(base, size, disp_unit, MPI_WIN_FLAVOR_SHARED, model, win);
318 if (OMPI_SUCCESS != ret) {
319 OBJ_RELEASE(win);
320 return ret;
321 }
322
323 *((void**) baseptr) = base;
324 *newwin = win;
325
326 return OMPI_SUCCESS;
327 }
328
329
330 int
331 ompi_win_create_dynamic(opal_info_t *info, ompi_communicator_t *comm, ompi_win_t **newwin)
332 {
333 ompi_win_t *win;
334 int model;
335 int ret;
336
337 ret = alloc_window (comm, info, MPI_WIN_FLAVOR_DYNAMIC, &win);
338 if (OMPI_SUCCESS != ret) {
339 return ret;
340 }
341
342 ret = ompi_osc_base_select(win, MPI_BOTTOM, 0, 1, comm, info, MPI_WIN_FLAVOR_DYNAMIC, &model);
343 if (OMPI_SUCCESS != ret) {
344 OBJ_RELEASE(win);
345 return ret;
346 }
347
348 ret = config_window(MPI_BOTTOM, 0, 1, MPI_WIN_FLAVOR_DYNAMIC, model, win);
349 if (OMPI_SUCCESS != ret) {
350 OBJ_RELEASE(win);
351 return ret;
352 }
353
354 *newwin = win;
355
356 return OMPI_SUCCESS;
357 }
358
359
360 int
361 ompi_win_free(ompi_win_t *win)
362 {
363 int ret = win->w_osc_module->osc_free(win);
364
365 if (-1 != win->w_f_to_c_index) {
366 opal_pointer_array_set_item(&ompi_mpi_windows,
367 win->w_f_to_c_index,
368 NULL);
369 }
370
371 if (NULL != (win->super.s_info)) {
372 OBJ_RELEASE(win->super.s_info);
373 }
374
375 if (OMPI_SUCCESS == ret) {
376 OBJ_RELEASE(win);
377 }
378
379 return ret;
380 }
381
382
383 int
384 ompi_win_set_name(ompi_win_t *win, const char *win_name)
385 {
386 OPAL_THREAD_LOCK(&(win->w_lock));
387 opal_string_copy(win->w_name, win_name, MPI_MAX_OBJECT_NAME);
388 OPAL_THREAD_UNLOCK(&(win->w_lock));
389
390 return OMPI_SUCCESS;
391 }
392
393
394 int
395 ompi_win_get_name(ompi_win_t *win, char *win_name, int *length)
396 {
397 OPAL_THREAD_LOCK(&(win->w_lock));
398 opal_string_copy(win_name, win->w_name, MPI_MAX_OBJECT_NAME);
399 *length = (int)strlen(win->w_name);
400 OPAL_THREAD_UNLOCK(&(win->w_lock));
401
402 return OMPI_SUCCESS;
403 }
404
405
406 int
407 ompi_win_group(ompi_win_t *win, ompi_group_t **group) {
408 OBJ_RETAIN(win->w_group);
409 *group = win->w_group;
410
411 return OMPI_SUCCESS;
412 }
413
414
415 static void
416 ompi_win_construct(ompi_win_t *win)
417 {
418 OBJ_CONSTRUCT(&win->w_lock, opal_mutex_t);
419 win->w_name[0] = '\0';
420 win->w_group = NULL;
421 win->w_keyhash = NULL;
422 win->w_f_to_c_index = 0;
423
424
425
426 OBJ_RETAIN(&ompi_mpi_errors_are_fatal.eh);
427 win->error_handler = &ompi_mpi_errors_are_fatal.eh;
428 win->errhandler_type = OMPI_ERRHANDLER_TYPE_WIN;
429
430 win->w_flags = 0;
431 win->w_osc_module = NULL;
432 }
433
434
435 static void
436 ompi_win_destruct(ompi_win_t *win)
437 {
438 if (NULL != win->w_keyhash) {
439 ompi_attr_delete_all(WIN_ATTR, win, win->w_keyhash);
440 OBJ_RELEASE(win->w_keyhash);
441 }
442
443 if (NULL != win->error_handler) {
444 OBJ_RELEASE(win->error_handler);
445 }
446
447 if (NULL != win->w_group) {
448 OBJ_RELEASE(win->w_group);
449 }
450
451 OBJ_DESTRUCT(&win->w_lock);
452 }