This source file includes following definitions.
- orte_rmaps_base_filter_nodes
- orte_rmaps_base_get_target_nodes
- orte_rmaps_base_setup_proc
- orte_rmaps_base_get_starting_point
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include "orte_config.h"
25 #include "orte/constants.h"
26
27 #include <sys/types.h>
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31 #include <string.h>
32
33 #include "opal/util/argv.h"
34 #include "opal/util/if.h"
35 #include "opal/util/output.h"
36 #include "orte/mca/mca.h"
37 #include "opal/mca/base/base.h"
38 #include "opal/mca/hwloc/base/base.h"
39 #include "opal/threads/tsd.h"
40
41 #include "orte/types.h"
42 #include "orte/util/show_help.h"
43 #include "orte/util/name_fns.h"
44 #include "orte/runtime/orte_globals.h"
45 #include "orte/util/hostfile/hostfile.h"
46 #include "orte/util/dash_host/dash_host.h"
47 #include "orte/mca/errmgr/errmgr.h"
48 #include "orte/mca/ess/ess.h"
49 #include "orte/runtime/data_type_support/orte_dt_support.h"
50
51 #include "orte/mca/rmaps/base/rmaps_private.h"
52 #include "orte/mca/rmaps/base/base.h"
53
54 int orte_rmaps_base_filter_nodes(orte_app_context_t *app,
55 opal_list_t *nodes, bool remove)
56 {
57 int rc=ORTE_ERR_TAKE_NEXT_OPTION;
58 char *hosts;
59
60
61 if (orte_get_attribute(&app->attributes, ORTE_APP_HOSTFILE, (void**)&hosts, OPAL_STRING)) {
62
63
64
65 if (ORTE_SUCCESS != (rc = orte_util_filter_hostfile_nodes(nodes, hosts, remove))) {
66 ORTE_ERROR_LOG(rc);
67 free(hosts);
68 return rc;
69 }
70
71 if (0 == opal_list_get_size(nodes)) {
72 orte_show_help("help-orte-rmaps-base.txt", "orte-rmaps-base:no-mapped-node",
73 true, app->app, "-hostfile", hosts);
74 free(hosts);
75 return ORTE_ERR_SILENT;
76 }
77 free(hosts);
78 }
79
80 if (orte_get_attribute(&app->attributes, ORTE_APP_ADD_HOSTFILE, (void**)&hosts, OPAL_STRING)) {
81
82
83
84 if (ORTE_SUCCESS != (rc = orte_util_filter_hostfile_nodes(nodes, hosts, remove))) {
85 free(hosts);
86 ORTE_ERROR_LOG(rc);
87 return rc;
88 }
89
90 if (0 == opal_list_get_size(nodes)) {
91 orte_show_help("help-orte-rmaps-base.txt", "orte-rmaps-base:no-mapped-node",
92 true, app->app, "-add-hostfile", hosts);
93 free(hosts);
94 return ORTE_ERR_SILENT;
95 }
96 free(hosts);
97 }
98
99 if (!orte_soft_locations &&
100 orte_get_attribute(&app->attributes, ORTE_APP_DASH_HOST, (void**)&hosts, OPAL_STRING)) {
101 if (ORTE_SUCCESS != (rc = orte_util_filter_dash_host_nodes(nodes, hosts, remove))) {
102 ORTE_ERROR_LOG(rc);
103 free(hosts);
104 return rc;
105 }
106
107 if (0 == opal_list_get_size(nodes)) {
108 orte_show_help("help-orte-rmaps-base.txt", "orte-rmaps-base:no-mapped-node",
109 true, app->app, "-host", hosts);
110 free(hosts);
111 return ORTE_ERR_SILENT;
112 }
113 free(hosts);
114 }
115
116 if (orte_get_attribute(&app->attributes, ORTE_APP_ADD_HOST, (void**)&hosts, OPAL_STRING)) {
117 if (ORTE_SUCCESS != (rc = orte_util_filter_dash_host_nodes(nodes, hosts, remove))) {
118 ORTE_ERROR_LOG(rc);
119 free(hosts);
120 return rc;
121 }
122
123 if (0 == opal_list_get_size(nodes)) {
124 orte_show_help("help-orte-rmaps-base.txt", "orte-rmaps-base:no-mapped-node",
125 true, app->app, "-add-host", hosts);
126 free(hosts);
127 return ORTE_ERR_SILENT;
128 }
129 free(hosts);
130 }
131
132 return rc;
133 }
134
135
136
137
138
139 int orte_rmaps_base_get_target_nodes(opal_list_t *allocated_nodes, orte_std_cntr_t *total_num_slots,
140 orte_app_context_t *app, orte_mapping_policy_t policy,
141 bool initial_map, bool silent)
142 {
143 opal_list_item_t *item;
144 orte_node_t *node, *nd, *nptr, *next;
145 orte_std_cntr_t num_slots;
146 orte_std_cntr_t i;
147 int rc;
148 orte_job_t *daemons;
149 bool novm;
150 opal_list_t nodes;
151 char *hosts = NULL;
152
153
154 *total_num_slots = 0;
155
156
157 daemons = orte_get_job_data_object(ORTE_PROC_MY_NAME->jobid);
158
159 novm = orte_get_attribute(&daemons->attributes, ORTE_JOB_NO_VM, NULL, OPAL_BOOL);
160
161
162
163
164
165 if (!orte_managed_allocation) {
166 OBJ_CONSTRUCT(&nodes, opal_list_t);
167
168
169
170 hosts = NULL;
171 if (!orte_soft_locations &&
172 orte_get_attribute(&app->attributes, ORTE_APP_DASH_HOST, (void**)&hosts, OPAL_STRING)) {
173 OPAL_OUTPUT_VERBOSE((5, orte_rmaps_base_framework.framework_output,
174 "%s using dash_host %s",
175 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), hosts));
176 if (ORTE_SUCCESS != (rc = orte_util_add_dash_host_nodes(&nodes, hosts, false))) {
177 ORTE_ERROR_LOG(rc);
178 free(hosts);
179 return rc;
180 }
181 free(hosts);
182 } else if (orte_get_attribute(&app->attributes, ORTE_APP_HOSTFILE, (void**)&hosts, OPAL_STRING)) {
183
184 OPAL_OUTPUT_VERBOSE((5, orte_rmaps_base_framework.framework_output,
185 "%s using hostfile %s",
186 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), hosts));
187 if (ORTE_SUCCESS != (rc = orte_util_add_hostfile_nodes(&nodes, hosts))) {
188 free(hosts);
189 ORTE_ERROR_LOG(rc);
190 return rc;
191 }
192 free(hosts);
193 } else {
194
195
196
197 OPAL_OUTPUT_VERBOSE((5, orte_rmaps_base_framework.framework_output,
198 "%s using known nodes",
199 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME)));
200 goto addknown;
201 }
202
203 if (0 == opal_list_get_size(&nodes)) {
204 if (!silent) {
205 orte_show_help("help-orte-rmaps-base.txt",
206 "orte-rmaps-base:no-available-resources",
207 true);
208 }
209 OBJ_DESTRUCT(&nodes);
210 return ORTE_ERR_SILENT;
211 }
212
213
214
215 OPAL_LIST_FOREACH_SAFE(nptr, next, &nodes, orte_node_t) {
216 for (i=0; i < orte_node_pool->size; i++) {
217 if (NULL == (node = (orte_node_t*)opal_pointer_array_get_item(orte_node_pool, i))) {
218 continue;
219 }
220
221 if (ORTE_FLAG_TEST(node, ORTE_NODE_NON_USABLE)) {
222 continue;
223 }
224 if (0 != strcmp(node->name, nptr->name)) {
225 OPAL_OUTPUT_VERBOSE((10, orte_rmaps_base_framework.framework_output,
226 "NODE %s DOESNT MATCH NODE %s",
227 node->name, nptr->name));
228 continue;
229 }
230
231 if (ORTE_NODE_STATE_DO_NOT_USE == node->state) {
232 OPAL_OUTPUT_VERBOSE((10, orte_rmaps_base_framework.framework_output,
233 "NODE %s IS MARKED NO_USE", node->name));
234
235 node->state = ORTE_NODE_STATE_UP;
236 continue;
237 }
238 if (ORTE_NODE_STATE_DOWN == node->state) {
239 OPAL_OUTPUT_VERBOSE((10, orte_rmaps_base_framework.framework_output,
240 "NODE %s IS DOWN", node->name));
241 continue;
242 }
243 if (ORTE_NODE_STATE_NOT_INCLUDED == node->state) {
244 OPAL_OUTPUT_VERBOSE((10, orte_rmaps_base_framework.framework_output,
245 "NODE %s IS MARKED NO_INCLUDE", node->name));
246
247 continue;
248 }
249
250
251
252 if (NULL == node->daemon && !novm) {
253 OPAL_OUTPUT_VERBOSE((10, orte_rmaps_base_framework.framework_output,
254 "NODE %s HAS NO DAEMON", node->name));
255 continue;
256 }
257
258
259
260 OBJ_RETAIN(node);
261 if (initial_map) {
262
263
264
265
266 ORTE_FLAG_UNSET(node, ORTE_NODE_FLAG_MAPPED);
267 }
268
269
270 opal_list_append(allocated_nodes, &node->super);
271 break;
272 }
273
274 opal_list_remove_item(&nodes, (opal_list_item_t*)nptr);
275 OBJ_RELEASE(nptr);
276 }
277 OBJ_DESTRUCT(&nodes);
278
279 goto complete;
280 }
281
282 addknown:
283
284
285
286
287
288
289 if (0 == opal_list_get_size(allocated_nodes)) {
290
291 if (orte_hnp_is_allocated) {
292 nd = (orte_node_t*)opal_pointer_array_get_item(orte_node_pool, 0);
293 OBJ_RETAIN(nd);
294 opal_list_append(allocated_nodes, &nd->super);
295 } else {
296 nd = NULL;
297 }
298 } else {
299 nd = (orte_node_t*)opal_list_get_last(allocated_nodes);
300 }
301 for (i=1; i < orte_node_pool->size; i++) {
302 if (NULL != (node = (orte_node_t*)opal_pointer_array_get_item(orte_node_pool, i))) {
303
304 if (ORTE_FLAG_TEST(node, ORTE_NODE_NON_USABLE)) {
305 continue;
306 }
307
308 if (ORTE_NODE_STATE_DO_NOT_USE == node->state) {
309 OPAL_OUTPUT_VERBOSE((10, orte_rmaps_base_framework.framework_output,
310 "NODE %s IS MARKED NO_USE", node->name));
311
312 node->state = ORTE_NODE_STATE_UP;
313 continue;
314 }
315 if (ORTE_NODE_STATE_DOWN == node->state) {
316 OPAL_OUTPUT_VERBOSE((10, orte_rmaps_base_framework.framework_output,
317 "NODE %s IS MARKED DOWN", node->name));
318 continue;
319 }
320 if (ORTE_NODE_STATE_NOT_INCLUDED == node->state) {
321 OPAL_OUTPUT_VERBOSE((10, orte_rmaps_base_framework.framework_output,
322 "NODE %s IS MARKED NO_INCLUDE", node->name));
323
324 continue;
325 }
326
327
328
329 if (NULL == node->daemon && !novm) {
330 OPAL_OUTPUT_VERBOSE((10, orte_rmaps_base_framework.framework_output,
331 "NODE %s HAS NO DAEMON", node->name));
332 continue;
333 }
334
335
336
337 OBJ_RETAIN(node);
338 if (initial_map) {
339
340
341
342
343 ORTE_FLAG_UNSET(node, ORTE_NODE_FLAG_MAPPED);
344 }
345 if (NULL == nd || NULL == nd->daemon ||
346 NULL == node->daemon ||
347 nd->daemon->name.vpid < node->daemon->name.vpid) {
348
349 opal_list_append(allocated_nodes, &node->super);
350 nd = node;
351 } else {
352
353 while (node->daemon->name.vpid < nd->daemon->name.vpid) {
354 if (opal_list_get_begin(allocated_nodes) == opal_list_get_prev(&nd->super)) {
355
356 opal_list_prepend(allocated_nodes, &node->super);
357 goto moveon;
358 }
359 nd = (orte_node_t*)opal_list_get_prev(&nd->super);
360 }
361 item = opal_list_get_next(&nd->super);
362 if (item == opal_list_get_end(allocated_nodes)) {
363
364 opal_list_append(allocated_nodes, &node->super);
365 } else {
366 nd = (orte_node_t*)item;
367 opal_list_insert_pos(allocated_nodes, item, &node->super);
368 }
369 moveon:
370
371 nd = (orte_node_t*)opal_list_get_last(allocated_nodes);
372 }
373 }
374 }
375
376 OPAL_OUTPUT_VERBOSE((5, orte_rmaps_base_framework.framework_output,
377 "%s Starting with %d nodes in list",
378 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
379 (int)opal_list_get_size(allocated_nodes)));
380
381
382 if (0 == opal_list_get_size(allocated_nodes)) {
383 if (!silent) {
384 orte_show_help("help-orte-rmaps-base.txt",
385 "orte-rmaps-base:no-available-resources",
386 true);
387 }
388 return ORTE_ERR_SILENT;
389 }
390
391
392 OPAL_OUTPUT_VERBOSE((5, orte_rmaps_base_framework.framework_output,
393 "%s Filtering thru apps",
394 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME)));
395
396 if (ORTE_SUCCESS != (rc = orte_rmaps_base_filter_nodes(app, allocated_nodes, true))
397 && ORTE_ERR_TAKE_NEXT_OPTION != rc) {
398 ORTE_ERROR_LOG(rc);
399 return rc;
400 }
401 OPAL_OUTPUT_VERBOSE((5, orte_rmaps_base_framework.framework_output,
402 "%s Retained %d nodes in list",
403 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
404 (int)opal_list_get_size(allocated_nodes)));
405
406 complete:
407 num_slots = 0;
408
409
410
411
412 if (ORTE_MAPPING_DEBUGGER & ORTE_GET_MAPPING_DIRECTIVE(policy)) {
413 num_slots = opal_list_get_size(allocated_nodes);
414 } else {
415 item = opal_list_get_first(allocated_nodes);
416 OPAL_LIST_FOREACH_SAFE(node, next, allocated_nodes, orte_node_t) {
417
418
419 if (!orte_hnp_is_allocated || (ORTE_GET_MAPPING_DIRECTIVE(policy) & ORTE_MAPPING_NO_USE_LOCAL)) {
420 if (0 == node->index) {
421 opal_list_remove_item(allocated_nodes, &node->super);
422 OBJ_RELEASE(node);
423 continue;
424 }
425 }
426
427 if (0 != node->slots_max && node->slots_inuse > node->slots_max) {
428 OPAL_OUTPUT_VERBOSE((5, orte_rmaps_base_framework.framework_output,
429 "%s Removing node %s: max %d inuse %d",
430 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
431 node->name, node->slots_max, node->slots_inuse));
432 opal_list_remove_item(allocated_nodes, &node->super);
433 OBJ_RELEASE(node);
434 continue;
435 }
436 if (node->slots <= node->slots_inuse &&
437 (ORTE_MAPPING_NO_OVERSUBSCRIBE & ORTE_GET_MAPPING_DIRECTIVE(policy))) {
438
439 OPAL_OUTPUT_VERBOSE((5, orte_rmaps_base_framework.framework_output,
440 "%s Removing node %s slots %d inuse %d",
441 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
442 node->name, node->slots, node->slots_inuse));
443 opal_list_remove_item(allocated_nodes, &node->super);
444 OBJ_RELEASE(node);
445 continue;
446 }
447 if (node->slots > node->slots_inuse) {
448 orte_std_cntr_t s;
449
450 if (orte_get_attribute(&app->attributes, ORTE_APP_DASH_HOST, (void**)&hosts, OPAL_STRING)) {
451 s = orte_util_dash_host_compute_slots(node, hosts);
452 } else {
453 s = node->slots - node->slots_inuse;
454 }
455
456 OPAL_OUTPUT_VERBOSE((5, orte_rmaps_base_framework.framework_output,
457 "%s node %s has %d slots available",
458 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
459 node->name, s));
460 num_slots += s;
461 continue;
462 }
463 if (!(ORTE_MAPPING_NO_OVERSUBSCRIBE & ORTE_GET_MAPPING_DIRECTIVE(policy))) {
464
465
466
467
468 OPAL_OUTPUT_VERBOSE((5, orte_rmaps_base_framework.framework_output,
469 "%s node %s is fully used, but available for oversubscription",
470 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
471 node->name));
472 } else {
473
474 opal_list_remove_item(allocated_nodes, &node->super);
475 OBJ_RELEASE(node);
476 }
477 }
478 }
479
480
481 if (0 == opal_list_get_size(allocated_nodes)) {
482 if (silent) {
483
484
485
486 return ORTE_ERR_RESOURCE_BUSY;
487 } else {
488 orte_show_help("help-orte-rmaps-base.txt",
489 "orte-rmaps-base:all-available-resources-used", true);
490 return ORTE_ERR_SILENT;
491 }
492 }
493
494
495 *total_num_slots = num_slots;
496
497 if (4 < opal_output_get_verbosity(orte_rmaps_base_framework.framework_output)) {
498 opal_output(0, "AVAILABLE NODES FOR MAPPING:");
499 for (item = opal_list_get_first(allocated_nodes);
500 item != opal_list_get_end(allocated_nodes);
501 item = opal_list_get_next(item)) {
502 node = (orte_node_t*)item;
503 opal_output(0, " node: %s daemon: %s", node->name,
504 (NULL == node->daemon) ? "NULL" : ORTE_VPID_PRINT(node->daemon->name.vpid));
505 }
506 }
507
508 return ORTE_SUCCESS;
509 }
510
511 orte_proc_t* orte_rmaps_base_setup_proc(orte_job_t *jdata,
512 orte_node_t *node,
513 orte_app_idx_t idx)
514 {
515 orte_proc_t *proc;
516 int rc;
517
518 proc = OBJ_NEW(orte_proc_t);
519
520 proc->name.jobid = jdata->jobid;
521
522 proc->state = ORTE_PROC_STATE_INIT;
523 proc->app_idx = idx;
524
525 ORTE_FLAG_SET(proc, ORTE_PROC_FLAG_UPDATED);
526 if (NULL == node->daemon) {
527 proc->parent = ORTE_VPID_INVALID;
528 } else {
529 proc->parent = node->daemon->name.vpid;
530 }
531
532 OBJ_RETAIN(node);
533 proc->node = node;
534
535
536 if (!ORTE_FLAG_TEST(jdata, ORTE_JOB_FLAG_DEBUGGER_DAEMON)) {
537 node->num_procs++;
538 ++node->slots_inuse;
539 }
540 if (0 > (rc = opal_pointer_array_add(node->procs, (void*)proc))) {
541 ORTE_ERROR_LOG(rc);
542 OBJ_RELEASE(proc);
543 return NULL;
544 }
545
546 OBJ_RETAIN(proc);
547
548 return proc;
549 }
550
551
552
553
554 orte_node_t* orte_rmaps_base_get_starting_point(opal_list_t *node_list,
555 orte_job_t *jdata)
556 {
557 opal_list_item_t *item, *cur_node_item;
558 orte_node_t *node, *nd1, *ndmin;
559 int overload;
560
561
562 if (NULL != jdata->bookmark) {
563 cur_node_item = NULL;
564
565 for (item = opal_list_get_first(node_list);
566 item != opal_list_get_end(node_list);
567 item = opal_list_get_next(item)) {
568 node = (orte_node_t*)item;
569
570 if (node->index == jdata->bookmark->index) {
571 cur_node_item = item;
572 break;
573 }
574 }
575
576 if (NULL == cur_node_item) {
577 cur_node_item = opal_list_get_first(node_list);
578 }
579 } else {
580
581 cur_node_item = opal_list_get_first(node_list);
582 }
583
584 OPAL_OUTPUT_VERBOSE((5, orte_rmaps_base_framework.framework_output,
585 "%s Starting bookmark at node %s",
586 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
587 ((orte_node_t*)cur_node_item)->name));
588
589
590
591
592
593 node = (orte_node_t*)cur_node_item;
594 ndmin = node;
595 overload = ndmin->slots_inuse - ndmin->slots;
596 if (node->slots_inuse >= node->slots) {
597
598
599
600 if (cur_node_item != opal_list_get_last(node_list)) {
601 item = opal_list_get_next(cur_node_item);
602 } else {
603 item = opal_list_get_first(node_list);
604 }
605 nd1 = NULL;
606 while (item != cur_node_item) {
607 nd1 = (orte_node_t*)item;
608 if (nd1->slots_inuse < nd1->slots) {
609
610 cur_node_item = item;
611 goto process;
612 }
613
614
615
616
617
618 if (overload >= (nd1->slots_inuse - nd1->slots)) {
619 ndmin = nd1;
620 overload = ndmin->slots_inuse - ndmin->slots;
621 }
622 if (item == opal_list_get_last(node_list)) {
623 item = opal_list_get_first(node_list);
624 } else {
625 item= opal_list_get_next(item);
626 }
627 }
628
629
630
631
632
633 if (NULL != nd1 &&
634 (nd1->slots_inuse - nd1->slots) < (node->slots_inuse - node->slots)) {
635 cur_node_item = (opal_list_item_t*)ndmin;
636 }
637 }
638
639 process:
640 OPAL_OUTPUT_VERBOSE((5, orte_rmaps_base_framework.framework_output,
641 "%s Starting at node %s",
642 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME),
643 ((orte_node_t*)cur_node_item)->name));
644
645 return (orte_node_t*)cur_node_item;
646 }