This source file includes following definitions.
- orte_util_dash_host_compute_slots
- orte_util_add_dash_host_nodes
- parse_dash_host
- orte_util_filter_dash_host_nodes
- orte_util_get_ordered_dash_host_list
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
26 #include <string.h>
27 #include <ctype.h>
28
29 #include "orte/constants.h"
30 #include "orte/types.h"
31
32 #include "orte/util/show_help.h"
33 #include "opal/util/argv.h"
34 #include "opal/util/if.h"
35 #include "opal/util/net.h"
36
37 #include "orte/mca/ras/base/base.h"
38 #include "orte/mca/plm/plm_types.h"
39 #include "orte/mca/errmgr/errmgr.h"
40 #include "orte/util/proc_info.h"
41 #include "orte/runtime/orte_globals.h"
42
43 #include "dash_host.h"
44
45 int orte_util_dash_host_compute_slots(orte_node_t *node, char *hosts)
46 {
47 char **specs, *cptr;
48 int slots = 0;
49 int n;
50
51 specs = opal_argv_split(hosts, ',');
52
53
54 for (n=0; NULL != specs[n]; n++) {
55 if (0 == strncmp(node->name, specs[n], strlen(node->name)) ||
56 (orte_ifislocal(node->name) && orte_ifislocal(specs[n]))) {
57
58 if (NULL != (cptr = strchr(specs[n], ':'))) {
59 *cptr = '\0';
60 ++cptr;
61 if ('*' == *cptr || 0 == strcmp(cptr, "auto")) {
62 slots += node->slots - node->slots_inuse;
63 } else {
64 slots += strtol(cptr, NULL, 10);
65 }
66 } else {
67 ++slots;
68 }
69
70 }
71 }
72 opal_argv_free(specs);
73 return slots;
74 }
75
76
77
78
79
80 int orte_util_add_dash_host_nodes(opal_list_t *nodes,
81 char *hosts, bool allocating)
82 {
83 opal_list_item_t *item, *itm;
84 orte_std_cntr_t i, j, k;
85 int rc, nodeidx;
86 char **host_argv=NULL;
87 char **mapped_nodes = NULL, **mini_map, *ndname;
88 orte_node_t *node, *nd;
89 opal_list_t adds;
90 bool found;
91 int slots=0;
92 bool slots_given;
93 char *cptr, *ptr;
94
95 OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
96 "%s dashhost: parsing args %s",
97 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), hosts));
98
99 OBJ_CONSTRUCT(&adds, opal_list_t);
100 host_argv = opal_argv_split(hosts, ',');
101
102
103 for (j = 0; j < opal_argv_count(host_argv); ++j) {
104 mini_map = opal_argv_split(host_argv[j], ',');
105
106 if (mapped_nodes == NULL) {
107 mapped_nodes = mini_map;
108 } else {
109 for (k = 0; NULL != mini_map[k]; ++k) {
110 rc = opal_argv_append_nosize(&mapped_nodes,
111 mini_map[k]);
112 if (OPAL_SUCCESS != rc) {
113 opal_argv_free(host_argv);
114 opal_argv_free(mini_map);
115 goto cleanup;
116 }
117 }
118 opal_argv_free(mini_map);
119 }
120 }
121 opal_argv_free(host_argv);
122 mini_map = NULL;
123
124
125 if (NULL == mapped_nodes) {
126 rc = ORTE_SUCCESS;
127 goto cleanup;
128 }
129
130 for (i = 0; NULL != mapped_nodes[i]; ++i) {
131
132
133
134 if ('+' == mapped_nodes[i][0]) {
135 if (!allocating) {
136 if ('e' == mapped_nodes[i][1] ||
137 'E' == mapped_nodes[i][1]) {
138
139
140
141 if (NULL != (cptr = strchr(mapped_nodes[i], ':'))) {
142
143 ++cptr;
144 j = strtoul(cptr, NULL, 10);
145 } else if ('\0' != mapped_nodes[0][2]) {
146 j = strtoul(&mapped_nodes[0][2], NULL, 10);
147 } else {
148
149 j = orte_node_pool->size;
150 }
151 for (k=0; 0 < j && k < orte_node_pool->size; k++) {
152 if (NULL != (node = (orte_node_t*)opal_pointer_array_get_item(orte_node_pool, k))) {
153 if (0 == node->num_procs) {
154 opal_argv_append_nosize(&mini_map, node->name);
155 --j;
156 }
157 }
158 }
159 } else if ('n' == mapped_nodes[i][1] ||
160 'N' == mapped_nodes[i][1]) {
161
162
163
164 if ('\0' == mapped_nodes[i][2]) {
165
166 orte_show_help("help-dash-host.txt", "dash-host:invalid-relative-node-syntax",
167 true, mapped_nodes[i]);
168 rc = ORTE_ERR_SILENT;
169 goto cleanup;
170 }
171 nodeidx = strtol(&mapped_nodes[i][2], NULL, 10);
172 if (nodeidx < 0 ||
173 nodeidx > (int)orte_node_pool->size) {
174
175 orte_show_help("help-dash-host.txt", "dash-host:relative-node-out-of-bounds",
176 true, nodeidx, mapped_nodes[i]);
177 rc = ORTE_ERR_SILENT;
178 goto cleanup;
179 }
180
181
182
183
184 if (!orte_hnp_is_allocated) {
185 nodeidx++;
186 }
187
188
189 if (NULL == (node = (orte_node_t *) opal_pointer_array_get_item(orte_node_pool, nodeidx))) {
190
191 orte_show_help("help-dash-host.txt", "dash-host:relative-node-not-found",
192 true, nodeidx, mapped_nodes[i]);
193 rc = ORTE_ERR_SILENT;
194 goto cleanup;
195 }
196
197 opal_argv_append_nosize(&mini_map, node->name);
198 } else {
199
200 orte_show_help("help-dash-host.txt", "dash-host:invalid-relative-node-syntax",
201 true, mapped_nodes[i]);
202 rc = ORTE_ERR_SILENT;
203 goto cleanup;
204 }
205 }
206 } else {
207
208 opal_argv_append_nosize(&mini_map, mapped_nodes[i]);
209 }
210 }
211 if (NULL == mini_map) {
212 rc = ORTE_SUCCESS;
213 goto cleanup;
214 }
215
216
217
218
219 for (i=0; NULL != mini_map[i]; i++) {
220 OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
221 "%s dashhost: working node %s",
222 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), mini_map[i]));
223
224
225 slots_given = false;
226 if (NULL != (cptr = strchr(mini_map[i], ':'))) {
227 *cptr = '\0';
228 ++cptr;
229 if ('*' == *cptr || 0 == strcmp(cptr, "auto")) {
230
231 slots = -1;
232 slots_given = false;
233 } else {
234 slots = strtol(cptr, NULL, 10);
235 slots_given = true;
236 }
237 }
238
239
240 if (orte_ifislocal(mini_map[i])) {
241 ndname = orte_process_info.nodename;
242 } else {
243 ndname = mini_map[i];
244 }
245
246
247 if( !orte_keep_fqdn_hostnames && !opal_net_isaddr(ndname) ) {
248 if (NULL != (ptr = strchr(ndname, '.'))) {
249 *ptr = '\0';
250 }
251 }
252
253 if (NULL != (ptr = strchr(ndname, ':'))) {
254 *ptr = '\0';
255 }
256
257 found = false;
258 OPAL_LIST_FOREACH(node, &adds, orte_node_t) {
259 if (0 == strcmp(node->name, ndname)) {
260 found = true;
261 if (slots_given) {
262 node->slots += slots;
263 if (0 < slots) {
264 ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
265 }
266 } else {
267 ++node->slots;
268 ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
269 }
270 OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
271 "%s dashhost: node %s already on list - slots %d",
272 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node->name, node->slots));
273 break;
274 }
275 }
276
277
278 if (!found) {
279 node = OBJ_NEW(orte_node_t);
280 if (NULL == node) {
281 opal_argv_free(mapped_nodes);
282 return ORTE_ERR_OUT_OF_RESOURCE;
283 }
284 node->name = strdup(ndname);
285 OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
286 "%s dashhost: added node %s to list - slots %d",
287 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node->name, slots));
288 node->state = ORTE_NODE_STATE_UP;
289 node->slots_inuse = 0;
290 node->slots_max = 0;
291 if (slots_given) {
292 node->slots = slots;
293 if (0 < slots) {
294 ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
295 }
296 } else if (slots < 0) {
297 node->slots = 0;
298 ORTE_FLAG_UNSET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
299 } else {
300 node->slots = 1;
301 ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
302 }
303 opal_list_append(&adds, &node->super);
304 }
305 }
306 opal_argv_free(mini_map);
307
308
309 while (NULL != (item = opal_list_remove_first(&adds))) {
310 nd = (orte_node_t*)item;
311 found = false;
312 for (itm = opal_list_get_first(nodes);
313 itm != opal_list_get_end(nodes);
314 itm = opal_list_get_next(itm)) {
315 node = (orte_node_t*)itm;
316 if (0 == strcmp(nd->name, node->name)) {
317 found = true;
318 OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
319 "%s dashhost: found existing node %s on input list - adding slots",
320 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), node->name));
321 if (ORTE_FLAG_TEST(nd, ORTE_NODE_FLAG_SLOTS_GIVEN)) {
322
323 node->slots += nd->slots;
324 ORTE_FLAG_SET(node, ORTE_NODE_FLAG_SLOTS_GIVEN);
325 }
326 break;
327 }
328 }
329 if (!found) {
330 OPAL_OUTPUT_VERBOSE((1, orte_ras_base_framework.framework_output,
331 "%s dashhost: adding node %s with %d slots to final list",
332 ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), nd->name, nd->slots));
333 opal_list_append(nodes, &nd->super);
334 } else {
335 OBJ_RELEASE(item);
336 }
337 }
338
339 rc = ORTE_SUCCESS;
340
341 cleanup:
342 if (NULL != mapped_nodes) {
343 opal_argv_free(mapped_nodes);
344 }
345 OPAL_LIST_DESTRUCT(&adds);
346
347 return rc;
348 }
349
350
351
352
353
354
355 static int parse_dash_host(char ***mapped_nodes, char *hosts)
356 {
357 orte_std_cntr_t j, k;
358 int rc=ORTE_SUCCESS;
359 char **mini_map=NULL, *cptr;
360 int nodeidx;
361 orte_node_t *node;
362 char **host_argv=NULL;
363
364 host_argv = opal_argv_split(hosts, ',');
365
366
367 for (j = 0; j < opal_argv_count(host_argv); ++j) {
368 mini_map = opal_argv_split(host_argv[j], ',');
369
370 for (k = 0; NULL != mini_map[k]; ++k) {
371 if ('+' == mini_map[k][0]) {
372
373 if ('e' == mini_map[k][1] ||
374 'E' == mini_map[k][1]) {
375
376
377
378 if (NULL != (cptr = strchr(mini_map[k], ':'))) {
379
380 *cptr = '*';
381 opal_argv_append_nosize(mapped_nodes, cptr);
382 } else {
383
384 opal_argv_append_nosize(mapped_nodes, "*");
385 }
386 } else if ('n' == mini_map[k][1] ||
387 'N' == mini_map[k][1]) {
388
389
390
391 nodeidx = strtol(&mini_map[k][2], NULL, 10);
392 if (nodeidx < 0 ||
393 nodeidx > (int)orte_node_pool->size) {
394
395 orte_show_help("help-dash-host.txt", "dash-host:relative-node-out-of-bounds",
396 true, nodeidx, mini_map[k]);
397 rc = ORTE_ERR_SILENT;
398 goto cleanup;
399 }
400
401
402
403
404 if (!orte_hnp_is_allocated) {
405 nodeidx++;
406 }
407
408
409 if (NULL == (node = (orte_node_t *) opal_pointer_array_get_item(orte_node_pool, nodeidx))) {
410
411 orte_show_help("help-dash-host.txt", "dash-host:relative-node-not-found",
412 true, nodeidx, mini_map[k]);
413 rc = ORTE_ERR_SILENT;
414 goto cleanup;
415 }
416
417 opal_argv_append_nosize(mapped_nodes, node->name);
418 } else {
419
420 orte_show_help("help-dash-host.txt", "dash-host:invalid-relative-node-syntax",
421 true, mini_map[k]);
422 rc = ORTE_ERR_SILENT;
423 goto cleanup;
424 }
425 } else {
426
427 if (NULL != (cptr = strchr(mini_map[k], ':'))) {
428 *cptr = '\0';
429 }
430
431 if (orte_ifislocal(mini_map[k])) {
432 opal_argv_append_nosize(mapped_nodes, orte_process_info.nodename);
433 } else {
434 opal_argv_append_nosize(mapped_nodes, mini_map[k]);
435 }
436 }
437 }
438 opal_argv_free(mini_map);
439 mini_map = NULL;
440 }
441
442 cleanup:
443 if (NULL != host_argv) {
444 opal_argv_free(host_argv);
445 }
446 if (NULL != mini_map) {
447 opal_argv_free(mini_map);
448 }
449 return rc;
450 }
451
452 int orte_util_filter_dash_host_nodes(opal_list_t *nodes,
453 char *hosts,
454 bool remove)
455 {
456 opal_list_item_t* item;
457 opal_list_item_t *next;
458 orte_std_cntr_t i, j, len_mapped_node=0;
459 int rc, test;
460 char **mapped_nodes = NULL;
461 orte_node_t *node;
462 int num_empty=0;
463 opal_list_t keep;
464 bool want_all_empty=false;
465 char *cptr;
466 size_t lst, lmn;
467
468
469
470
471 if (opal_list_is_empty(nodes)) {
472 return ORTE_SUCCESS;
473 }
474
475 if (ORTE_SUCCESS != (rc = parse_dash_host(&mapped_nodes, hosts))) {
476 ORTE_ERROR_LOG(rc);
477 return rc;
478 }
479
480 if (NULL == mapped_nodes) {
481 return ORTE_SUCCESS;
482 }
483
484
485
486
487
488
489 len_mapped_node = opal_argv_count(mapped_nodes);
490
491
492
493
494
495
496 OBJ_CONSTRUCT(&keep, opal_list_t);
497
498 for (i = 0; i < len_mapped_node; ++i) {
499
500
501
502 if ('*' == mapped_nodes[i][0]) {
503
504
505
506 if ('\0' == mapped_nodes[i][1]) {
507
508 num_empty = INT_MAX;
509 want_all_empty = true;
510 } else {
511
512 num_empty = strtol(&mapped_nodes[i][1], NULL, 10);
513 }
514
515 item = opal_list_get_first(nodes);
516 while (0 < num_empty && item != opal_list_get_end(nodes)) {
517 next = opal_list_get_next(item);
518 node = (orte_node_t*)item;
519
520 if (0 == node->slots_inuse) {
521
522 for (j=i+1; j < len_mapped_node; j++) {
523 if (0 == strcmp(mapped_nodes[j], node->name)) {
524
525 goto skipnode;
526 }
527 }
528 if (remove) {
529
530 opal_list_remove_item(nodes, item);
531
532 opal_list_append(&keep, item);
533 } else {
534
535 ORTE_FLAG_SET(node, ORTE_NODE_FLAG_MAPPED);
536 }
537 --num_empty;
538 }
539 skipnode:
540 item = next;
541 }
542 } else {
543
544 if (NULL != (cptr = strchr(mapped_nodes[i], ':'))) {
545 *cptr = '\0';
546 }
547
548
549
550 cptr = NULL;
551 lmn = strtoul(mapped_nodes[i], &cptr, 10);
552 item = opal_list_get_first(nodes);
553 while (item != opal_list_get_end(nodes)) {
554 next = opal_list_get_next(item);
555 node = (orte_node_t*)item;
556
557 if (orte_managed_allocation &&
558 (NULL == cptr || 0 == strlen(cptr))) {
559
560
561
562
563 for (j=strlen(node->name)-1; 0 < j; j--) {
564 if (!isdigit(node->name[j])) {
565 j++;
566 break;
567 }
568 }
569 if (j >= (int)(strlen(node->name) - 1)) {
570 test = 0;
571 } else {
572 lst = strtoul(&node->name[j], NULL, 10);
573 test = (lmn == lst) ? 0 : 1;
574 }
575 } else {
576 test = strcmp(node->name, mapped_nodes[i]);
577 }
578 if (0 == test) {
579 if (remove) {
580
581 opal_list_remove_item(nodes, item);
582
583 opal_list_append(&keep, item);
584 } else {
585
586 ORTE_FLAG_SET(node, ORTE_NODE_FLAG_MAPPED);
587 }
588 break;
589 }
590 item = next;
591 }
592 }
593
594 free(mapped_nodes[i]);
595 mapped_nodes[i] = NULL;
596 }
597
598
599 for (i=0; i < len_mapped_node; i++) {
600 if (NULL != mapped_nodes[i]) {
601 orte_show_help("help-dash-host.txt", "not-all-mapped-alloc",
602 true, mapped_nodes[i]);
603 rc = ORTE_ERR_SILENT;
604 goto cleanup;
605 }
606 }
607
608 if (!remove) {
609
610 rc = ORTE_SUCCESS;
611 goto cleanup;
612 }
613
614
615 while (NULL != (item = opal_list_remove_first(nodes))) {
616 OBJ_RELEASE(item);
617 }
618
619
620 while (NULL != (item = opal_list_remove_first(&keep))) {
621 opal_list_append(nodes, item);
622 }
623
624
625 if (!want_all_empty && 0 < num_empty) {
626 orte_show_help("help-dash-host.txt", "dash-host:not-enough-empty",
627 true, num_empty);
628 rc = ORTE_ERR_SILENT;
629 goto cleanup;
630 }
631
632 rc = ORTE_SUCCESS;
633
634
635 cleanup:
636 for (i=0; i < len_mapped_node; i++) {
637 if (NULL != mapped_nodes[i]) {
638 free(mapped_nodes[i]);
639 mapped_nodes[i] = NULL;
640 }
641 }
642 if (NULL != mapped_nodes) {
643 free(mapped_nodes);
644 }
645
646 return rc;
647 }
648
649 int orte_util_get_ordered_dash_host_list(opal_list_t *nodes,
650 char *hosts)
651 {
652 int rc, i;
653 char **mapped_nodes = NULL;
654 orte_node_t *node;
655
656 if (ORTE_SUCCESS != (rc = parse_dash_host(&mapped_nodes, hosts))) {
657 ORTE_ERROR_LOG(rc);
658 }
659
660
661 for (i=0; NULL != mapped_nodes[i]; i++) {
662 node = OBJ_NEW(orte_node_t);
663 node->name = strdup(mapped_nodes[i]);
664 opal_list_append(nodes, &node->super);
665 }
666
667
668 opal_argv_free(mapped_nodes);
669 return rc;
670 }