From ab16341a1b90c76c279462559bf4a1111d4f6879 Mon Sep 17 00:00:00 2001 From: Mikael Simberg Date: Mon, 16 Dec 2024 17:43:29 +0100 Subject: [PATCH 1/7] Add default values for many thread binding-related configuration options via environment variables --- .../src/runtime_configuration.cpp | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/libs/pika/runtime_configuration/src/runtime_configuration.cpp b/libs/pika/runtime_configuration/src/runtime_configuration.cpp index 0d4ca2d06..aa9f4d190 100644 --- a/libs/pika/runtime_configuration/src/runtime_configuration.cpp +++ b/libs/pika/runtime_configuration/src/runtime_configuration.cpp @@ -263,16 +263,21 @@ namespace pika::util { #endif // add placeholders for keys to be added by command line handling - "ignore_process_mask = 0", + "ignore_process_mask = ${PIKA_IGNORE_PROCESS_MASK:0}", "process_mask = ${PIKA_PROCESS_MASK:}", - "os_threads = cores", - "cores = all", - "first_pu = 0", - "scheduler = local-priority-fifo", - "affinity = core", - "pu_step = 1", - "pu_offset = 0", - "numa_sensitive = 0", + "os_threads = ${PIKA_THREADS:cores}", + "cores = ${PIKA_CORES:all}", + "first_pu = ${PIKA_FIRST_PU:0}", + "scheduler = ${PIKA_SCHEDULER:local-priority-fifo}", +#if defined(__APPLE__) + "bind = ${PIKA_BIND:none}", +#else + "bind = ${PIKA_BIND:balanced}", +#endif + "affinity = ${PIKA_AFFINITY:pu}", + "pu_step = ${PIKA_PU_STEP:1}", + "pu_offset = ${PIKA_PU_OFFSET:0}", + "numa_sensitive = ${PIKA_NUMA_SENSITIVE:0}", "max_idle_loop_count = ${PIKA_MAX_IDLE_LOOP_COUNT:" PIKA_PP_STRINGIZE( PIKA_PP_EXPAND(PIKA_IDLE_LOOP_COUNT_MAX)) "}", "max_busy_loop_count = ${PIKA_MAX_BUSY_LOOP_COUNT:" PIKA_PP_STRINGIZE( From fb2e6e88130481bad9e49451818bf84fbb87655b Mon Sep 17 00:00:00 2001 From: Mikael Simberg Date: Mon, 16 Dec 2024 17:44:12 +0100 Subject: [PATCH 2/7] Remove first_pu configuration option It's unused. --- libs/pika/runtime_configuration/src/runtime_configuration.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/pika/runtime_configuration/src/runtime_configuration.cpp b/libs/pika/runtime_configuration/src/runtime_configuration.cpp index aa9f4d190..67df3735c 100644 --- a/libs/pika/runtime_configuration/src/runtime_configuration.cpp +++ b/libs/pika/runtime_configuration/src/runtime_configuration.cpp @@ -267,7 +267,6 @@ namespace pika::util { "process_mask = ${PIKA_PROCESS_MASK:}", "os_threads = ${PIKA_THREADS:cores}", "cores = ${PIKA_CORES:all}", - "first_pu = ${PIKA_FIRST_PU:0}", "scheduler = ${PIKA_SCHEDULER:local-priority-fifo}", #if defined(__APPLE__) "bind = ${PIKA_BIND:none}", From f43115ef0098063edcb3632e54e59653bb6647bf Mon Sep 17 00:00:00 2001 From: Mikael Simberg Date: Tue, 17 Dec 2024 14:05:01 +0100 Subject: [PATCH 3/7] Refactor thread binding-related configuration options to take environment variables into account as default --- .../src/command_line_handling.cpp | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/libs/pika/command_line_handling/src/command_line_handling.cpp b/libs/pika/command_line_handling/src/command_line_handling.cpp index 9662a0017..9fa9e2d5c 100644 --- a/libs/pika/command_line_handling/src/command_line_handling.cpp +++ b/libs/pika/command_line_handling/src/command_line_handling.cpp @@ -101,12 +101,9 @@ namespace pika::detail { /////////////////////////////////////////////////////////////////////// std::string handle_process_mask(detail::manage_config& cfgmap, - pika::program_options::variables_map& vm, bool use_process_mask) + pika::program_options::variables_map& vm, std::string default_, bool use_process_mask) { - std::string mask_string = cfgmap.get_value("pika.process_mask", ""); - - char const* mask_env = std::getenv("PIKA_PROCESS_MASK"); - if (nullptr != mask_env) { mask_string = mask_env; } + std::string mask_string = cfgmap.get_value("pika.process_mask", default_); if (vm.count("pika:process-mask")) { @@ -439,13 +436,15 @@ namespace pika::detail { #if defined(__APPLE__) false; #else - !((cfgmap.get_value("pika.ignore_process_mask", 0) > 0) || + !((cfgmap.get_value("pika.ignore_process_mask", + pika::detail::get_entry_as(rtcfg_, "pika.ignore_process_mask", 0)) > 0) || (vm.count("pika:ignore-process-mask") > 0)); #endif ini_config.emplace_back("pika.ignore_process_mask!=" + std::to_string(!use_process_mask_)); - process_mask_ = handle_process_mask(cfgmap, vm, use_process_mask_); + process_mask_ = handle_process_mask( + cfgmap, vm, rtcfg_.get_entry("pika.process_mask", ""), use_process_mask_); ini_config.emplace_back("pika.process_mask!=" + process_mask_); if (!process_mask_.empty()) { @@ -454,15 +453,18 @@ namespace pika::detail { } // handle setting related to schedulers - queuing_ = detail::handle_queuing(cfgmap, vm, "local-priority-fifo"); + queuing_ = detail::handle_queuing( + cfgmap, vm, rtcfg_.get_entry("pika.scheduler", "local-priority-fifo")); ini_config.emplace_back("pika.scheduler=" + queuing_); - affinity_domain_ = detail::handle_affinity(cfgmap, vm, "pu"); + affinity_domain_ = + detail::handle_affinity(cfgmap, vm, rtcfg_.get_entry("pika.affinity", "pu")); ini_config.emplace_back("pika.affinity=" + affinity_domain_); check_affinity_domain(); - affinity_bind_ = detail::handle_affinity_bind(cfgmap, vm, ""); + affinity_bind_ = + detail::handle_affinity_bind(cfgmap, vm, rtcfg_.get_entry("pika.bind", "")); if (!affinity_bind_.empty()) { #if defined(__APPLE__) @@ -479,7 +481,8 @@ namespace pika::detail { #endif } - pu_step_ = detail::handle_pu_step(cfgmap, vm, 1); + pu_step_ = detail::handle_pu_step( + cfgmap, vm, pika::detail::get_entry_as(rtcfg_, "pika.pu_step", 1)); #if defined(__APPLE__) if (pu_step_ != 1) { @@ -494,7 +497,8 @@ namespace pika::detail { check_pu_step(); - pu_offset_ = detail::handle_pu_offset(cfgmap, vm, std::size_t(-1)); + pu_offset_ = detail::handle_pu_offset(cfgmap, vm, + pika::detail::get_entry_as(rtcfg_, "pika.pu_offset", std::size_t(-1))); // NOLINTNEXTLINE(bugprone-branch-clone) if (pu_offset_ != std::size_t(-1)) @@ -514,7 +518,8 @@ namespace pika::detail { check_pu_offset(); - numa_sensitive_ = detail::handle_numa_sensitive(cfgmap, vm, affinity_bind_.empty() ? 0 : 1); + numa_sensitive_ = detail::handle_numa_sensitive( + cfgmap, vm, pika::detail::get_entry_as(rtcfg_, "pika.numa_sensitive", 0)); ini_config.emplace_back("pika.numa_sensitive=" + std::to_string(numa_sensitive_)); // default affinity mode is now 'balanced' (only if no pu-step or From 21f9fddbf038f57950b79b0b095d5bd73993c745 Mon Sep 17 00:00:00 2001 From: Mikael Simberg Date: Tue, 17 Dec 2024 14:44:05 +0100 Subject: [PATCH 4/7] Add unit tests to check configuration options on command line and environment variables --- libs/pika/runtime/tests/unit/CMakeLists.txt | 166 ++++++++++++++++-- .../tests/unit/configuration_precedence.cpp | 23 +++ 2 files changed, 176 insertions(+), 13 deletions(-) create mode 100644 libs/pika/runtime/tests/unit/configuration_precedence.cpp diff --git a/libs/pika/runtime/tests/unit/CMakeLists.txt b/libs/pika/runtime/tests/unit/CMakeLists.txt index 49a2872fa..860237e62 100644 --- a/libs/pika/runtime/tests/unit/CMakeLists.txt +++ b/libs/pika/runtime/tests/unit/CMakeLists.txt @@ -4,7 +4,7 @@ # Distributed under the Boost Software License, Version 1.0. (See accompanying # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -set(tests process_mask_flag runtime_initialized) +set(tests configuration_precedence process_mask_flag runtime_initialized) set(process_mask_flag_PARAMETERS THREADS 2 RUN_SERIAL) @@ -23,22 +23,162 @@ foreach(test ${tests}) pika_add_unit_test("modules.runtime" ${test} ${${test}_PARAMETERS}) endforeach() +string(CONCAT no_binding_expected_output " 0: thread binding disabled, on pool \"default\"\n" + " 1: thread binding disabled, on pool \"default\"\n" "All tests passed." +) + +string( + CONCAT + compact_binding_expected_output + " 0: PU L#0\\(P#0\\), Core L#0\\(P#[0-9]+\\)(, Socket L#[0-9]+\\(P#[0-9]+\\))?(, NUMANode L#[0-9]+\\(P#[0-9]+\\))?(, Socket L#[0-9]+\\(P#[0-9]+\\))?, on pool \"default\"\n" + " 1: PU L#[0-9]+\\(P#1\\), Core L#[0-9]+\\(P#[0-9]+\\)(, Socket L#[0-9]+\\(P#[0-9]+\\))?(, NUMANode L#[0-9]+\\(P#[0-9]+\\))?(, Socket L#[0-9]+\\(P#[0-9]+\\))?, on pool \"default\"\n" + "All tests passed." +) + +string( + CONCAT + balanced_binding_expected_output + " 0: PU L#0\\(P#[0-9]+\\), Core L#0\\(P#0\\)(, Socket L#[0-9]+\\(P#[0-9]+\\))?(, NUMANode L#[0-9]+\\(P#[0-9]+\\))?(, Socket L#[0-9]+\\(P#[0-9]+\\))?, on pool \"default\"\n" + " 1: PU L#[0-9]+\\(P#[0-9]+\\), Core L#[0-9]+\\(P#1\\)(, Socket L#[0-9]+\\(P#[0-9]+\\))?(, NUMANode L#[0-9]+\\(P#[0-9]+\\))?(, Socket L#[0-9]+\\(P#[0-9]+\\))?, on pool \"default\"\n" + "All tests passed." +) + if(APPLE) - string(CONCAT process_mask_flag_expected_output - " 0: thread binding disabled, on pool \"default\"\n" - " 1: thread binding disabled, on pool \"default\"\n" "All tests passed." - ) + set(process_mask_flag_expected_output "${no_binding_expected_output}") else() - string( - CONCAT - process_mask_flag_expected_output - " 0: PU L#0\\(P#0\\), Core L#0\\(P#[0-9]+\\)(, Socket L#[0-9]+\\(P#[0-9]+\\))?(, NUMANode L#[0-9]+\\(P#[0-9]+\\))?(, Socket L#[0-9]+\\(P#[0-9]+\\))?, on pool \"default\"\n" - " 1: PU L#[0-9]+\\(P#1\\), Core L#[0-9]+\\(P#[0-9]+\\)(, Socket L#[0-9]+\\(P#[0-9]+\\))?(, NUMANode L#[0-9]+\\(P#[0-9]+\\))?(, Socket L#[0-9]+\\(P#[0-9]+\\))?, on pool \"default\"\n" - "All tests passed." - ) + set(process_mask_flag_expected_output "${compact_binding_expected_output}") endif() - set_tests_properties( tests.unit.modules.runtime.process_mask_flag PROPERTIES PASS_REGULAR_EXPRESSION "${process_mask_flag_expected_output}" ) + +# Helper function to create tests that check for the correct behaviour of various environment +# variables and command line options, including the precedence of them. +function( + pika_add_configuration_precedence_test + base_test_name + id + threads + args + regex + env +) + set(full_name_ ${base_test_name}_${id}) + pika_add_pseudo_target(${full_name_}_test) + pika_add_pseudo_dependencies(${full_name_}_test ${base_test_name}_test) + separate_arguments(args) + pika_add_unit_test( + "modules.runtime" + ${full_name_} + RUN_SERIAL + THREADS + ${threads} + EXECUTABLE + ${base_test_name}_test + ARGS + ${args} + ) + set_tests_properties( + tests.unit.modules.runtime.${full_name_} PROPERTIES PASS_REGULAR_EXPRESSION "${regex}" + ) + if(env) + separate_arguments(env) + set_tests_properties(tests.unit.modules.runtime.${full_name_} PROPERTIES ENVIRONMENT ${env}) + endif() +endfunction() + +# This tests the default behaviour with two threads. This test is identical to the process_mask_flag +# test above. +if(APPLE) + set(configuration_precedence_expected_output "${no_binding_expected_output}") +else() + set(configuration_precedence_expected_output "${balanced_binding_expected_output}") +endif() +pika_add_configuration_precedence_test( + configuration_precedence 1 2 "--pika:print-bind" "${configuration_precedence_expected_output}" "" +) + +# Disable binding through environment variable. +pika_add_configuration_precedence_test( + configuration_precedence 2 2 "--pika:print-bind" "${no_binding_expected_output}" "PIKA_BIND=none" +) + +# Disable binding through through command line option, but enable it through environment variable. +# The former should take precedence. +pika_add_configuration_precedence_test( + configuration_precedence 3 2 "--pika:print-bind --pika:bind=none" "${no_binding_expected_output}" + "PIKA_BIND=balanced" +) + +# Disable binding through environment variable, but enable it through command line option. The +# latter should take precedence. +pika_add_configuration_precedence_test( + configuration_precedence 4 2 "--pika:print-bind --pika:bind=balanced" + "${balanced_binding_expected_output}" "PIKA_BIND=none" +) + +string( + CONCAT + second_pu_binding_one_thread_expected_output + " 0: PU L#[0-9]+\\(P#1\\), Core L#[0-9]+\\(P#[0-9]+\\)(, Socket L#[0-9]+\\(P#[0-9]+\\))?(, NUMANode L#[0-9]+\\(P#[0-9]+\\))?(, Socket L#[0-9]+\\(P#[0-9]+\\))?, on pool \"default\"\n" + "All tests passed." +) +string(CONCAT no_binding_one_thread_expected_output + " 0: thread binding disabled, on pool \"default\"\n" "All tests passed." +) + +# Set process mask through command line option. +if(APPLE) + set(configuration_precedence_expected_output "${no_binding_one_thread_expected_output}") +else() + set(configuration_precedence_expected_output "${second_pu_binding_one_thread_expected_output}") +endif() +pika_add_configuration_precedence_test( + configuration_precedence 5 1 "--pika:print-bind --pika:process-mask=0x2" + "${configuration_precedence_expected_output}" "" +) + +# Set process mask through environment variable. +if(APPLE) + set(configuration_precedence_expected_output "${no_binding_one_thread_expected_output}") +else() + set(configuration_precedence_expected_output "${second_pu_binding_one_thread_expected_output}") +endif() +pika_add_configuration_precedence_test( + configuration_precedence 6 1 "--pika:print-bind" "${configuration_precedence_expected_output}" + "PIKA_PROCESS_MASK=0x2" +) + +# Set process mask through environment variable and command line option. The latter should take +# precedence. +if(APPLE) + set(configuration_precedence_expected_output "${no_binding_one_thread_expected_output}") +else() + set(configuration_precedence_expected_output "${second_pu_binding_one_thread_expected_output}") +endif() +pika_add_configuration_precedence_test( + configuration_precedence 7 1 "--pika:print-bind --pika:process-mask=0x2" + "${configuration_precedence_expected_output}" "PIKA_PROCESS_MASK=0x4" +) + +string(CONCAT one_thread_expected_output " 0:.*\n" "All tests passed.") +string(CONCAT two_threads_expected_output " 0:.*\n" " 1:.*\n" "All tests passed.") + +# Set number of threads through command line option. +pika_add_configuration_precedence_test( + configuration_precedence 8 -3 "--pika:print-bind --pika:threads=1" + "${one_thread_expected_output}" "" +) + +# Set number of threads through environment variable. +pika_add_configuration_precedence_test( + configuration_precedence 9 -3 "--pika:print-bind" "${two_threads_expected_output}" + "PIKA_THREADS=2" +) + +# Set number of threads through environment variable and command line option. +pika_add_configuration_precedence_test( + configuration_precedence 10 -3 "--pika:print-bind --pika:threads=2" + "${two_threads_expected_output}" "PIKA_THREADS=1" +) diff --git a/libs/pika/runtime/tests/unit/configuration_precedence.cpp b/libs/pika/runtime/tests/unit/configuration_precedence.cpp new file mode 100644 index 000000000..2d4063ad3 --- /dev/null +++ b/libs/pika/runtime/tests/unit/configuration_precedence.cpp @@ -0,0 +1,23 @@ +// Copyright (c) 2024 ETH Zurich +// +// SPDX-License-Identifier: BSL-1.0 +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// This test only starts the runtime. Command line options and environment variables are supplied by +// tests defined in the adjacent CMakeLists.txt, and the output of the program is checked for the +// expected values. + +#include +#include + +int main(int argc, char** argv) +{ + pika::start(nullptr, argc, argv); + pika::finalize(); + pika::stop(); + + PIKA_TEST(true); + + return 0; +} From 6bf1a13d0ef2eb0a59b876ea796083d8c07e81dd Mon Sep 17 00:00:00 2001 From: Mikael Simberg Date: Wed, 18 Dec 2024 11:49:24 +0100 Subject: [PATCH 5/7] Add option to not set --pika:threads option in tests --- cmake/pika_add_test.cmake | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cmake/pika_add_test.cmake b/cmake/pika_add_test.cmake index 6293f0c20..575dcfc5e 100644 --- a/cmake/pika_add_test.cmake +++ b/cmake/pika_add_test.cmake @@ -54,10 +54,16 @@ function(pika_add_test category name) elseif(${name}_THREADS EQUAL -2) set(${name}_THREADS "cores") set(run_serial TRUE) + elseif(${name}_THREADS EQUAL -3) + set(${name}_THREADS "default") + set(run_serial TRUE) endif() endif() - set(args "--pika:threads=${${name}_THREADS}") + set(args) + if(NOT ${name}_THREADS STREQUAL "default") + set(args ${args} "--pika:threads=${${name}_THREADS}") + endif() if(PIKA_WITH_TESTS_DEBUG_LOG) set(args ${args} "--pika:log-destination=${PIKA_WITH_TESTS_DEBUG_LOG_DESTINATION}") set(args ${args} "--pika:log-level=0") From 160edc02c3feee104eacabbfb7bb55bbec8a27cf Mon Sep 17 00:00:00 2001 From: Mikael Simberg Date: Wed, 8 Jan 2025 11:22:31 +0100 Subject: [PATCH 6/7] Rename --pika:queuing to --pika:scheduler to match PIKA_SCHEDULER and pika.scheduler --- .gitlab/scripts/run_performance_benchmarks.sh | 2 +- .jenkins/cscs-perftests/launch_perftests.sh | 2 +- .../command_line_handling.hpp | 2 +- .../src/command_line_handling.cpp | 14 +++++------ .../src/parse_command_line.cpp | 24 +++++++++---------- .../oversubscribing_resource_partitioner.cpp | 2 +- .../examples/simple_resource_partitioner.cpp | 2 +- .../src/detail_partitioner.cpp | 2 +- .../thread_manager/src/thread_manager.cpp | 6 ++--- .../regressions/thread_stacksize_current.cpp | 2 +- tests/performance/local/task_overhead.cpp | 8 +++---- .../local/task_overhead_report.cpp | 4 ++-- 12 files changed, 35 insertions(+), 35 deletions(-) diff --git a/.gitlab/scripts/run_performance_benchmarks.sh b/.gitlab/scripts/run_performance_benchmarks.sh index 3f41624eb..d0679cc5b 100755 --- a/.gitlab/scripts/run_performance_benchmarks.sh +++ b/.gitlab/scripts/run_performance_benchmarks.sh @@ -41,7 +41,7 @@ pika_targets=( ) pika_test_options=( "--pika:ini=pika.thread_queue.init_threads_count=100 \ ---pika:queuing=local-priority \ +--pika:scheduler=local-priority \ --repetitions=100 \ --tasks=500000" diff --git a/.jenkins/cscs-perftests/launch_perftests.sh b/.jenkins/cscs-perftests/launch_perftests.sh index 46c68db87..1623f1edf 100755 --- a/.jenkins/cscs-perftests/launch_perftests.sh +++ b/.jenkins/cscs-perftests/launch_perftests.sh @@ -11,7 +11,7 @@ set -ex pika_targets=("task_overhead_report_test") pika_test_options=( "--pika:ini=pika.thread_queue.init_threads_count=100 \ - --pika:queuing=local-priority --pika:threads=4 \ + --pika:scheduler=local-priority --pika:threads=4 \ --repetitions=100 --tasks=500000") # Build binaries for performance tests diff --git a/libs/pika/command_line_handling/include/pika/command_line_handling/command_line_handling.hpp b/libs/pika/command_line_handling/include/pika/command_line_handling/command_line_handling.hpp index 5055f67e1..b921cb929 100644 --- a/libs/pika/command_line_handling/include/pika/command_line_handling/command_line_handling.hpp +++ b/libs/pika/command_line_handling/include/pika/command_line_handling/command_line_handling.hpp @@ -61,7 +61,7 @@ namespace pika::detail { std::size_t num_cores_; std::size_t pu_step_; std::size_t pu_offset_; - std::string queuing_; + std::string scheduler_; std::string affinity_domain_; std::string affinity_bind_; std::size_t numa_sensitive_; diff --git a/libs/pika/command_line_handling/src/command_line_handling.cpp b/libs/pika/command_line_handling/src/command_line_handling.cpp index 9fa9e2d5c..c582990ef 100644 --- a/libs/pika/command_line_handling/src/command_line_handling.cpp +++ b/libs/pika/command_line_handling/src/command_line_handling.cpp @@ -48,7 +48,7 @@ namespace pika::detail { std::ostringstream strm; // default scheduler used for this run - strm << " {scheduler}: " << cfg.queuing_ << "\n"; + strm << " {scheduler}: " << cfg.scheduler_ << "\n"; // amount of threads and cores configured for this run strm << " {os-threads}: " << cfg.num_threads_ << "\n"; @@ -132,11 +132,11 @@ namespace pika::detail { return mask_string; } - std::string handle_queuing(detail::manage_config& cfgmap, + std::string handle_scheduler(detail::manage_config& cfgmap, pika::program_options::variables_map& vm, std::string const& default_) { // command line options is used preferred - if (vm.count("pika:queuing")) return vm["pika:queuing"].as(); + if (vm.count("pika:scheduler")) return vm["pika:scheduler"].as(); // use either cfgmap value or default return cfgmap.get_value("pika.scheduler", default_); @@ -453,9 +453,9 @@ namespace pika::detail { } // handle setting related to schedulers - queuing_ = detail::handle_queuing( + scheduler_ = detail::handle_scheduler( cfgmap, vm, rtcfg_.get_entry("pika.scheduler", "local-priority-fifo")); - ini_config.emplace_back("pika.scheduler=" + queuing_); + ini_config.emplace_back("pika.scheduler=" + scheduler_); affinity_domain_ = detail::handle_affinity(cfgmap, vm, rtcfg_.get_entry("pika.affinity", "pu")); @@ -557,11 +557,11 @@ namespace pika::detail { "(--pika:threads)"); } - if (!(queuing_ == "local-priority" || queuing_ == "abp-priority")) + if (!(scheduler_ == "local-priority" || scheduler_ == "abp-priority")) { throw pika::detail::command_line_error( "Invalid command line option --pika:high-priority-threads, valid for " - "--pika:queuing=local-priority and --pika:queuing=abp-priority only"); + "--pika:scheduler=local-priority and --pika:scheduler=abp-priority only"); } ini_config.emplace_back("pika.thread_queue.high_priority_queues!=" + diff --git a/libs/pika/command_line_handling/src/parse_command_line.cpp b/libs/pika/command_line_handling/src/parse_command_line.cpp index 0c460dc87..83ec92bae 100644 --- a/libs/pika/command_line_handling/src/parse_command_line.cpp +++ b/libs/pika/command_line_handling/src/parse_command_line.cpp @@ -281,21 +281,21 @@ namespace pika::detail { ("pika:pu-offset", value(), "the first processing unit this instance of pika should be " "run on (default: 0), valid for " - "--pika:queuing=local, --pika:queuing=abp-priority, " - "--pika:queuing=static, --pika:queuing=static-priority, " - "and --pika:queuing=local-priority only") + "--pika:scheduler=local, --pika:scheduler=abp-priority, " + "--pika:scheduler=static, --pika:scheduler=static-priority, " + "and --pika:scheduler=local-priority only") ("pika:pu-step", value(), "the step between used processing unit numbers for this " "instance of pika (default: 1), valid for " - "--pika:queuing=local, --pika:queuing=abp-priority, " - "--pika:queuing=static, --pika:queuing=static-priority " - "and --pika:queuing=local-priority only") + "--pika:scheduler=local, --pika:scheduler=abp-priority, " + "--pika:scheduler=static, --pika:scheduler=static-priority " + "and --pika:scheduler=local-priority only") ("pika:affinity", value(), "the affinity domain the OS threads will be confined to, " "possible values: pu, core, numa, machine (default: pu), valid for " - "--pika:queuing=local, --pika:queuing=abp-priority, " - "--pika:queuing=static, --pika:queuing=static-priority " - " and --pika:queuing=local-priority only") + "--pika:scheduler=local, --pika:scheduler=abp-priority, " + "--pika:scheduler=static, --pika:scheduler=static-priority " + " and --pika:scheduler=local-priority only") ("pika:bind", value >()->composing(), "the detailed affinity description for the OS threads, see " "the documentation for a detailed description of possible " @@ -322,7 +322,7 @@ namespace pika::detail { "the number of cores to utilize for the pika " "runtime (default: 'all', i.e. the number of cores is based on " "the number of total cores in the system)") - ("pika:queuing", value(), + ("pika:scheduler", value(), "the queue scheduling policy to use, options are " "'local', 'local-priority-fifo','local-priority-lifo', " "'abp-priority-fifo', 'abp-priority-lifo', 'static', and " @@ -331,8 +331,8 @@ namespace pika::detail { ("pika:high-priority-threads", value(), "the number of operating system threads maintaining a high " "priority queue (default: number of OS threads), valid for " - "--pika:queuing=local-priority,--pika:queuing=static-priority, " - " and --pika:queuing=abp-priority only)") + "--pika:scheduler=local-priority,--pika:scheduler=static-priority, " + " and --pika:scheduler=abp-priority only)") ("pika:numa-sensitive", value()->implicit_value(0), "makes the local-priority scheduler NUMA sensitive (" "allowed values: 0 - no NUMA sensitivity, 1 - allow only for " diff --git a/libs/pika/resource_partitioner/examples/oversubscribing_resource_partitioner.cpp b/libs/pika/resource_partitioner/examples/oversubscribing_resource_partitioner.cpp index c7be24f50..a3c6f3e49 100644 --- a/libs/pika/resource_partitioner/examples/oversubscribing_resource_partitioner.cpp +++ b/libs/pika/resource_partitioner/examples/oversubscribing_resource_partitioner.cpp @@ -209,7 +209,7 @@ void init_resource_partitioner_handler( if (pool_threads > 0) { // we use unspecified as the scheduler type and it will be set according to - // the --pika:queuing=xxx option or default. + // the --pika:scheduler=xxx option or default. auto deft = ::pika::threads::scheduler_mode::default_mode; rp.create_thread_pool(pool_name, pika::resource::scheduling_policy::shared_priority, deft); // add N pus to network pool diff --git a/libs/pika/resource_partitioner/examples/simple_resource_partitioner.cpp b/libs/pika/resource_partitioner/examples/simple_resource_partitioner.cpp index 47a0ec375..8bf25e177 100644 --- a/libs/pika/resource_partitioner/examples/simple_resource_partitioner.cpp +++ b/libs/pika/resource_partitioner/examples/simple_resource_partitioner.cpp @@ -194,7 +194,7 @@ void init_resource_partitioner_handler( if (pool_threads > 0) { // we use unspecified as the scheduler type and it will be set according to - // the --pika:queuing=xxx option or default. + // the --pika:scheduler=xxx option or default. auto deft = ::pika::threads::scheduler_mode::default_mode; rp.create_thread_pool(pool_name, pika::resource::scheduling_policy::shared_priority, deft); // add N pus to network pool diff --git a/libs/pika/resource_partitioner/src/detail_partitioner.cpp b/libs/pika/resource_partitioner/src/detail_partitioner.cpp index 1400a6062..ef008a36d 100644 --- a/libs/pika/resource_partitioner/src/detail_partitioner.cpp +++ b/libs/pika/resource_partitioner/src/detail_partitioner.cpp @@ -437,7 +437,7 @@ namespace pika::resource::detail { else { throw pika::detail::command_line_error( - "Bad value for command line option --pika:queuing"); + "Bad value for command line option --pika:scheduler"); } // set this scheduler on the pools that do not have a specified scheduler yet diff --git a/libs/pika/thread_manager/src/thread_manager.cpp b/libs/pika/thread_manager/src/thread_manager.cpp index 384cda292..c233866f1 100644 --- a/libs/pika/thread_manager/src/thread_manager.cpp +++ b/libs/pika/thread_manager/src/thread_manager.cpp @@ -260,7 +260,7 @@ namespace pika::threads::detail { pools_.push_back(std::move(pool)); #else throw pika::detail::command_line_error( - "Command line option --pika:queuing=local-priority-lifo is not configured in " + "Command line option --pika:scheduler=local-priority-lifo is not configured in " "this build. Please make sure 128bit atomics are available."); #endif break; @@ -356,7 +356,7 @@ namespace pika::threads::detail { pools_.push_back(std::move(pool)); #else throw pika::detail::command_line_error( - "Command line option --pika:queuing=abp-priority-fifo is not configured in " + "Command line option --pika:scheduler=abp-priority-fifo is not configured in " "this build. Please make sure 128bit atomics are available."); #endif break; @@ -396,7 +396,7 @@ namespace pika::threads::detail { pools_.push_back(std::move(pool)); #else throw pika::detail::command_line_error( - "Command line option --pika:queuing=abp-priority-lifo is not configured in " + "Command line option --pika:scheduler=abp-priority-lifo is not configured in " "this build. Please make sure 128bit atomics are available."); #endif break; diff --git a/libs/pika/threading_base/tests/regressions/thread_stacksize_current.cpp b/libs/pika/threading_base/tests/regressions/thread_stacksize_current.cpp index ef21743c0..5dfee560a 100644 --- a/libs/pika/threading_base/tests/regressions/thread_stacksize_current.cpp +++ b/libs/pika/threading_base/tests/regressions/thread_stacksize_current.cpp @@ -80,7 +80,7 @@ int main(int argc, char** argv) for (auto const& scheduler : schedulers) { pika::init_params iparams; - iparams.cfg = {"--pika:queuing=" + std::string(scheduler)}; + iparams.cfg = {"--pika:scheduler=" + std::string(scheduler)}; std::cout << iparams.cfg[0] << std::endl; pika::init(pika_main, argc, argv, iparams); } diff --git a/tests/performance/local/task_overhead.cpp b/tests/performance/local/task_overhead.cpp index d6567a710..9539ccb2c 100644 --- a/tests/performance/local/task_overhead.cpp +++ b/tests/performance/local/task_overhead.cpp @@ -42,7 +42,7 @@ namespace ex = pika::execution::experimental; namespace tt = pika::this_thread::experimental; // global vars we stick here to make printouts easy for plotting -static std::string queuing = "default"; +static std::string scheduler = "default"; static std::size_t numa_sensitive = 0; static std::uint64_t num_threads = 1; static std::string info_string = ""; @@ -56,14 +56,14 @@ void print_stats(char const* title, char const* wait, char const* sched, std::in if (csv) { fmt::print(temp, "{}, {:27}, {:15}, {:45}, {:8}, {:8}, {:20}, {:4}, {:4}, {:20}", count, - title, wait, sched, duration, us, queuing, numa_sensitive, num_threads, info_string); + title, wait, sched, duration, us, scheduler, numa_sensitive, num_threads, info_string); } else { fmt::print(temp, "invoked {:1}, tasks {:27} {:15} {:18} in {:8} seconds : {:8} us/task, queue " "{:20}, numa {:4}, threads {:4}, info {:20}", - count, title, wait, sched, duration, us, queuing, numa_sensitive, num_threads, + count, title, wait, sched, duration, us, scheduler, numa_sensitive, num_threads, info_string); } std::cout << temp.str() << std::endl; @@ -340,7 +340,7 @@ void function_apply_hierarchical_placement(std::uint64_t count, bool csv) int pika_main(variables_map& vm) { { - if (vm.count("pika:queuing")) queuing = vm["pika:queuing"].as(); + if (vm.count("pika:scheduler")) scheduler = vm["pika:scheduler"].as(); if (vm.count("pika:numa-sensitive")) numa_sensitive = 1; diff --git a/tests/performance/local/task_overhead_report.cpp b/tests/performance/local/task_overhead_report.cpp index dc5e4e9ce..dba4ffed0 100644 --- a/tests/performance/local/task_overhead_report.cpp +++ b/tests/performance/local/task_overhead_report.cpp @@ -27,7 +27,7 @@ using pika::program_options::variables_map; using pika::chrono::detail::high_resolution_timer; // global vars we stick here to make printouts easy for plotting -static std::string queuing = "default"; +static std::string scheduler = "default"; [[maybe_unused]] static std::size_t numa_sensitive = 0; [[maybe_unused]] static std::uint64_t num_threads = 1; static std::string info_string = ""; @@ -117,7 +117,7 @@ void measure_function_create_thread_hierarchical_placement( int pika_main(variables_map& vm) { { - if (vm.count("pika:queuing")) queuing = vm["pika:queuing"].as(); + if (vm.count("pika:scheduler")) scheduler = vm["pika:scheduler"].as(); if (vm.count("pika:numa-sensitive")) numa_sensitive = 1; From d932bdd1baf4376f29e2aa0d347273448e3a85c9 Mon Sep 17 00:00:00 2001 From: Mikael Simberg Date: Wed, 8 Jan 2025 11:52:04 +0100 Subject: [PATCH 7/7] Expand configuration_precedence tests to cover ignoring process masks --- libs/pika/runtime/tests/unit/CMakeLists.txt | 111 ++++++++++++++++---- 1 file changed, 89 insertions(+), 22 deletions(-) diff --git a/libs/pika/runtime/tests/unit/CMakeLists.txt b/libs/pika/runtime/tests/unit/CMakeLists.txt index 860237e62..fe1146ad3 100644 --- a/libs/pika/runtime/tests/unit/CMakeLists.txt +++ b/libs/pika/runtime/tests/unit/CMakeLists.txt @@ -43,6 +43,28 @@ string( "All tests passed." ) +string( + CONCAT + first_pu_binding_one_thread_expected_output + " 0: PU L#[0-9]+\\(P#0\\), Core L#[0-9]+\\(P#[0-9]+\\)(, Socket L#[0-9]+\\(P#[0-9]+\\))?(, NUMANode L#[0-9]+\\(P#[0-9]+\\))?(, Socket L#[0-9]+\\(P#[0-9]+\\))?, on pool \"default\"\n" + "All tests passed." +) + +string( + CONCAT + second_pu_binding_one_thread_expected_output + " 0: PU L#[0-9]+\\(P#1\\), Core L#[0-9]+\\(P#[0-9]+\\)(, Socket L#[0-9]+\\(P#[0-9]+\\))?(, NUMANode L#[0-9]+\\(P#[0-9]+\\))?(, Socket L#[0-9]+\\(P#[0-9]+\\))?, on pool \"default\"\n" + "All tests passed." +) + +string(CONCAT no_binding_one_thread_expected_output + " 0: thread binding disabled, on pool \"default\"\n" "All tests passed." +) + +string(CONCAT one_thread_expected_output " 0:.*\n" "All tests passed.") +string(CONCAT two_threads_expected_output " 0:.*\n" " 1:.*\n" "All tests passed.") + +# The test sets the mask 0x3 and expects two threads to be bound, unless on macOS. if(APPLE) set(process_mask_flag_expected_output "${no_binding_expected_output}") else() @@ -88,7 +110,7 @@ function( endif() endfunction() -# This tests the default behaviour with two threads. This test is identical to the process_mask_flag +# This tests the default behaviour with two threads. This test is similar to the process_mask_flag # test above. if(APPLE) set(configuration_precedence_expected_output "${no_binding_expected_output}") @@ -99,7 +121,7 @@ pika_add_configuration_precedence_test( configuration_precedence 1 2 "--pika:print-bind" "${configuration_precedence_expected_output}" "" ) -# Disable binding through environment variable. +# Disable binding through environment variable. Threads should not be bound. pika_add_configuration_precedence_test( configuration_precedence 2 2 "--pika:print-bind" "${no_binding_expected_output}" "PIKA_BIND=none" ) @@ -112,23 +134,19 @@ pika_add_configuration_precedence_test( ) # Disable binding through environment variable, but enable it through command line option. The -# latter should take precedence. +# latter should take precedence. On macOS there should be no binding. +if(APPLE) + set(configuration_precedence_expected_output "${no_binding_expected_output}") +else() + set(configuration_precedence_expected_output "${balanced_binding_expected_output}") +endif() pika_add_configuration_precedence_test( configuration_precedence 4 2 "--pika:print-bind --pika:bind=balanced" - "${balanced_binding_expected_output}" "PIKA_BIND=none" -) - -string( - CONCAT - second_pu_binding_one_thread_expected_output - " 0: PU L#[0-9]+\\(P#1\\), Core L#[0-9]+\\(P#[0-9]+\\)(, Socket L#[0-9]+\\(P#[0-9]+\\))?(, NUMANode L#[0-9]+\\(P#[0-9]+\\))?(, Socket L#[0-9]+\\(P#[0-9]+\\))?, on pool \"default\"\n" - "All tests passed." -) -string(CONCAT no_binding_one_thread_expected_output - " 0: thread binding disabled, on pool \"default\"\n" "All tests passed." + "${configuration_precedence_expected_output}" "PIKA_BIND=none" ) -# Set process mask through command line option. +# Set process mask through command line option. One thread should be bound to the second PU, unless +# on macOS. if(APPLE) set(configuration_precedence_expected_output "${no_binding_one_thread_expected_output}") else() @@ -139,7 +157,7 @@ pika_add_configuration_precedence_test( "${configuration_precedence_expected_output}" "" ) -# Set process mask through environment variable. +# Set process mask through environment variable. The result should be the same as above. if(APPLE) set(configuration_precedence_expected_output "${no_binding_one_thread_expected_output}") else() @@ -162,23 +180,72 @@ pika_add_configuration_precedence_test( "${configuration_precedence_expected_output}" "PIKA_PROCESS_MASK=0x4" ) -string(CONCAT one_thread_expected_output " 0:.*\n" "All tests passed.") -string(CONCAT two_threads_expected_output " 0:.*\n" " 1:.*\n" "All tests passed.") - -# Set number of threads through command line option. +# Set number of threads through command line option. There should only be one thread. pika_add_configuration_precedence_test( configuration_precedence 8 -3 "--pika:print-bind --pika:threads=1" "${one_thread_expected_output}" "" ) -# Set number of threads through environment variable. +# Set number of threads through environment variable. There should be two threads. pika_add_configuration_precedence_test( configuration_precedence 9 -3 "--pika:print-bind" "${two_threads_expected_output}" "PIKA_THREADS=2" ) -# Set number of threads through environment variable and command line option. +# Set number of threads through environment variable and command line option. The latter should take +# precedence and there should be two threads. pika_add_configuration_precedence_test( configuration_precedence 10 -3 "--pika:print-bind --pika:threads=2" "${two_threads_expected_output}" "PIKA_THREADS=1" ) + +# Ignore process mask with command line option. One thread should be bound to the first PU, despite +# a mask being set. On macOS no binding is expected. +if(APPLE) + set(configuration_precedence_expected_output "${no_binding_one_thread_expected_output}") +else() + set(configuration_precedence_expected_output "${first_pu_binding_one_thread_expected_output}") +endif() +pika_add_configuration_precedence_test( + configuration_precedence 11 -3 + "--pika:print-bind --pika:threads=1 --pika:process-mask=0x2 --pika:ignore-process-mask" + "${configuration_precedence_expected_output}" "" +) + +# Ignore process mask with environment variable. One thread should be bound to the first PU, despite +# a mask being set. On macOS no binding is expected. +if(APPLE) + set(configuration_precedence_expected_output "${no_binding_one_thread_expected_output}") +else() + set(configuration_precedence_expected_output "${first_pu_binding_one_thread_expected_output}") +endif() +pika_add_configuration_precedence_test( + configuration_precedence 12 -3 "--pika:print-bind --pika:threads=1 --pika:process-mask=0x2" + "${configuration_precedence_expected_output}" "PIKA_IGNORE_PROCESS_MASK=1" +) + +# Explicitly do not ignore process mask with environment variable. One thread should be bound to the +# second PU, unless on macOS. +if(APPLE) + set(configuration_precedence_expected_output "${no_binding_one_thread_expected_output}") +else() + set(configuration_precedence_expected_output "${second_pu_binding_one_thread_expected_output}") +endif() +pika_add_configuration_precedence_test( + configuration_precedence 13 -3 "--pika:print-bind --pika:threads=1 --pika:process-mask=0x2" + "${configuration_precedence_expected_output}" "PIKA_IGNORE_PROCESS_MASK=0" +) + +# Ignore process mask with command line option, Explicitly do not ignore process mask with +# environment variable. One thread should be bound to the first PU since the command line option +# takes precedence, unless on macOS. +if(APPLE) + set(configuration_precedence_expected_output "${no_binding_one_thread_expected_output}") +else() + set(configuration_precedence_expected_output "${first_pu_binding_one_thread_expected_output}") +endif() +pika_add_configuration_precedence_test( + configuration_precedence 14 -3 + "--pika:print-bind --pika:threads=1 --pika:process-mask=0x2 --pika:ignore-process-mask" + "${configuration_precedence_expected_output}" "PIKA_IGNORE_PROCESS_MASK=0" +)