338
383
strcat(str, "(null type)"); /* no bits set */
387
void slurm_print_cpu_bind_help(void)
390
"CPU bind options:\n"
391
" --cpu_bind= Bind tasks to CPUs\n"
392
" q[uiet] quietly bind before task runs (default)\n"
393
" v[erbose] verbosely report binding before task runs\n"
394
" no[ne] don't bind tasks to CPUs (default)\n"
395
" rank bind by task rank\n"
396
" map_cpu:<list> specify a CPU ID binding for each task\n"
397
" where <list> is <cpuid1>,<cpuid2>,...<cpuidN>\n"
398
" mask_cpu:<list> specify a CPU ID binding mask for each task\n"
399
" where <list> is <mask1>,<mask2>,...<maskN>\n"
400
" rank_ldom bind task by rank to CPUs in a NUMA locality domain\n"
401
" map_ldom:<list> specify a NUMA locality domain ID for each task\n"
402
" where <list> is <ldom1>,<ldom2>,...<ldomN>\n"
403
" mask_ldom:<list>specify a NUMA locality domain ID mask for each task\n"
404
" where <list> is <mask1>,<mask2>,...<maskN>\n"
405
" sockets auto-generated masks bind to sockets\n"
406
" cores auto-generated masks bind to cores\n"
407
" threads auto-generated masks bind to threads\n"
408
" ldoms auto-generated masks bind to NUMA locality domains\n"
409
" help show this help message\n");
413
* verify cpu_bind arguments
415
* we support different launch policy names
416
* we also allow a verbose setting to be specified
423
* --cpu_bind={MAP_CPU|MASK_CPU}:0,1,2,3,4
426
* returns -1 on error, 0 otherwise
428
int slurm_verify_cpu_bind(const char *arg, char **cpu_bind,
429
cpu_bind_type_t *flags)
433
CPU_BIND_NONE|CPU_BIND_RANK|CPU_BIND_MAP|CPU_BIND_MASK;
435
CPU_BIND_TO_SOCKETS|CPU_BIND_TO_CORES|CPU_BIND_TO_THREADS;
436
uint16_t task_plugin_param = slurm_get_task_plugin_param();
438
bind_bits |= CPU_BIND_LDRANK|CPU_BIND_LDMAP|CPU_BIND_LDMASK;
439
bind_to_bits |= CPU_BIND_TO_LDOMS;
442
if ((*flags != 0) || /* already set values */
443
(task_plugin_param == 0)) /* no system defaults */
446
/* set system defaults */
448
if (task_plugin_param & CPU_BIND_NONE)
449
*flags = CPU_BIND_NONE;
450
else if (task_plugin_param & CPU_BIND_TO_SOCKETS)
451
*flags = CPU_BIND_TO_SOCKETS;
452
else if (task_plugin_param & CPU_BIND_TO_CORES)
453
*flags = CPU_BIND_TO_CORES;
454
else if (task_plugin_param & CPU_BIND_TO_THREADS)
455
*flags |= CPU_BIND_TO_THREADS;
456
else if (task_plugin_param & CPU_BIND_TO_LDOMS)
457
*flags |= CPU_BIND_TO_LDOMS;
458
if (task_plugin_param & CPU_BIND_VERBOSE)
459
*flags |= CPU_BIND_VERBOSE;
463
/* Start with system default verbose flag (if set) */
464
if (task_plugin_param & CPU_BIND_VERBOSE)
465
*flags |= CPU_BIND_VERBOSE;
469
/* change all ',' delimiters not followed by a digit to ';' */
470
/* simplifies parsing tokens while keeping map/mask together */
471
while (p[0] != '\0') {
472
if ((p[0] == ',') && (!_isvalue(&(p[1]))))
478
while ((tok = strsep(&p, ";"))) {
479
if (strcasecmp(tok, "help") == 0) {
480
slurm_print_cpu_bind_help();
482
} else if ((strcasecmp(tok, "q") == 0) ||
483
(strcasecmp(tok, "quiet") == 0)) {
484
*flags &= ~CPU_BIND_VERBOSE;
485
} else if ((strcasecmp(tok, "v") == 0) ||
486
(strcasecmp(tok, "verbose") == 0)) {
487
*flags |= CPU_BIND_VERBOSE;
488
} else if ((strcasecmp(tok, "no") == 0) ||
489
(strcasecmp(tok, "none") == 0)) {
490
_clear_then_set((int *)flags, bind_bits, CPU_BIND_NONE);
492
} else if (strcasecmp(tok, "rank") == 0) {
493
_clear_then_set((int *)flags, bind_bits, CPU_BIND_RANK);
495
} else if ((strncasecmp(tok, "map_cpu", 7) == 0) ||
496
(strncasecmp(tok, "mapcpu", 6) == 0)) {
498
list = strsep(&tok, ":=");
499
list = strsep(&tok, ":=");
500
_clear_then_set((int *)flags, bind_bits, CPU_BIND_MAP);
503
*cpu_bind = xstrdup(list);
505
error("missing list for \"--cpu_bind="
510
} else if ((strncasecmp(tok, "mask_cpu", 8) == 0) ||
511
(strncasecmp(tok, "maskcpu", 7) == 0)) {
513
list = strsep(&tok, ":=");
514
list = strsep(&tok, ":=");
515
_clear_then_set((int *)flags, bind_bits, CPU_BIND_MASK);
518
*cpu_bind = xstrdup(list);
520
error("missing list for \"--cpu_bind="
521
"mask_cpu:<list>\"");
525
} else if (strcasecmp(tok, "rank_ldom") == 0) {
526
_clear_then_set((int *)flags, bind_bits,
529
} else if ((strncasecmp(tok, "map_ldom", 8) == 0) ||
530
(strncasecmp(tok, "mapldom", 7) == 0)) {
532
list = strsep(&tok, ":=");
533
list = strsep(&tok, ":=");
534
_clear_then_set((int *)flags, bind_bits,
538
*cpu_bind = xstrdup(list);
540
error("missing list for \"--cpu_bind="
541
"map_ldom:<list>\"");
545
} else if ((strncasecmp(tok, "mask_ldom", 9) == 0) ||
546
(strncasecmp(tok, "maskldom", 8) == 0)) {
548
list = strsep(&tok, ":=");
549
list = strsep(&tok, ":=");
550
_clear_then_set((int *)flags, bind_bits,
554
*cpu_bind = xstrdup(list);
556
error("missing list for \"--cpu_bind="
557
"mask_ldom:<list>\"");
561
} else if ((strcasecmp(tok, "socket") == 0) ||
562
(strcasecmp(tok, "sockets") == 0)) {
563
if (task_plugin_param &
564
(CPU_BIND_NONE | CPU_BIND_TO_CORES |
565
CPU_BIND_TO_THREADS | CPU_BIND_TO_LDOMS)) {
566
error("--cpu_bind=sockets incompatable with "
567
"TaskPluginParam configuration "
571
_clear_then_set((int *)flags, bind_to_bits,
572
CPU_BIND_TO_SOCKETS);
573
} else if ((strcasecmp(tok, "core") == 0) ||
574
(strcasecmp(tok, "cores") == 0)) {
575
if (task_plugin_param &
576
(CPU_BIND_NONE | CPU_BIND_TO_SOCKETS |
577
CPU_BIND_TO_THREADS | CPU_BIND_TO_LDOMS)) {
578
error("--cpu_bind=cores incompatable with "
579
"TaskPluginParam configuration "
583
_clear_then_set((int *)flags, bind_to_bits,
585
} else if ((strcasecmp(tok, "thread") == 0) ||
586
(strcasecmp(tok, "threads") == 0)) {
587
if (task_plugin_param &
588
(CPU_BIND_NONE | CPU_BIND_TO_SOCKETS |
589
CPU_BIND_TO_CORES | CPU_BIND_TO_LDOMS)) {
590
error("--cpu_bind=threads incompatable with "
591
"TaskPluginParam configuration "
595
_clear_then_set((int *)flags, bind_to_bits,
596
CPU_BIND_TO_THREADS);
597
} else if ((strcasecmp(tok, "ldom") == 0) ||
598
(strcasecmp(tok, "ldoms") == 0)) {
599
if (task_plugin_param &
600
(CPU_BIND_NONE | CPU_BIND_TO_SOCKETS |
601
CPU_BIND_TO_CORES | CPU_BIND_TO_THREADS)) {
602
error("--cpu_bind=threads incompatable with "
603
"TaskPluginParam configuration "
607
_clear_then_set((int *)flags, bind_to_bits,
610
error("unrecognized --cpu_bind argument \"%s\"", tok);
620
void slurm_print_mem_bind_help(void)
623
"Memory bind options:\n"
624
" --mem_bind= Bind memory to locality domains (ldom)\n"
625
" q[uiet] quietly bind before task runs (default)\n"
626
" v[erbose] verbosely report binding before task runs\n"
627
" no[ne] don't bind tasks to memory (default)\n"
628
" rank bind by task rank\n"
629
" local bind to memory local to processor\n"
630
" map_mem:<list> specify a memory binding for each task\n"
631
" where <list> is <cpuid1>,<cpuid2>,...<cpuidN>\n"
632
" mask_mem:<list> specify a memory binding mask for each tasks\n"
633
" where <list> is <mask1>,<mask2>,...<maskN>\n"
634
" help show this help message\n");
638
* verify mem_bind arguments
640
* we support different memory binding names
641
* we also allow a verbose setting to be specified
645
* --mem_bind={MAP_MEM|MASK_MEM}:0,1,2,3,4
647
* returns -1 on error, 0 otherwise
649
int slurm_verify_mem_bind(const char *arg, char **mem_bind,
650
mem_bind_type_t *flags)
653
int bind_bits = MEM_BIND_NONE|MEM_BIND_RANK|MEM_BIND_LOCAL|
654
MEM_BIND_MAP|MEM_BIND_MASK;
662
/* change all ',' delimiters not followed by a digit to ';' */
663
/* simplifies parsing tokens while keeping map/mask together */
664
while (p[0] != '\0') {
665
if ((p[0] == ',') && (!_isvalue(&(p[1]))))
671
while ((tok = strsep(&p, ";"))) {
672
if (strcasecmp(tok, "help") == 0) {
673
slurm_print_mem_bind_help();
676
} else if ((strcasecmp(tok, "q") == 0) ||
677
(strcasecmp(tok, "quiet") == 0)) {
678
*flags &= ~MEM_BIND_VERBOSE;
679
} else if ((strcasecmp(tok, "v") == 0) ||
680
(strcasecmp(tok, "verbose") == 0)) {
681
*flags |= MEM_BIND_VERBOSE;
682
} else if ((strcasecmp(tok, "no") == 0) ||
683
(strcasecmp(tok, "none") == 0)) {
684
_clear_then_set((int *)flags, bind_bits, MEM_BIND_NONE);
686
} else if (strcasecmp(tok, "rank") == 0) {
687
_clear_then_set((int *)flags, bind_bits, MEM_BIND_RANK);
689
} else if (strcasecmp(tok, "local") == 0) {
690
_clear_then_set((int *)flags, bind_bits, MEM_BIND_LOCAL);
692
} else if ((strncasecmp(tok, "map_mem", 7) == 0) ||
693
(strncasecmp(tok, "mapmem", 6) == 0)) {
695
list = strsep(&tok, ":=");
696
list = strsep(&tok, ":=");
697
_clear_then_set((int *)flags, bind_bits, MEM_BIND_MAP);
700
*mem_bind = xstrdup(list);
702
error("missing list for \"--mem_bind=map_mem:<list>\"");
706
} else if ((strncasecmp(tok, "mask_mem", 8) == 0) ||
707
(strncasecmp(tok, "maskmem", 7) == 0)) {
709
list = strsep(&tok, ":=");
710
list = strsep(&tok, ":=");
711
_clear_then_set((int *)flags, bind_bits, MEM_BIND_MASK);
714
*mem_bind = xstrdup(list);
716
error("missing list for \"--mem_bind=mask_mem:<list>\"");
721
error("unrecognized --mem_bind argument \"%s\"", tok);