From b5a556472b507e327edcb04e718d6b587e0035e2 Mon Sep 17 00:00:00 2001 From: Hartmut Kaiser Date: Tue, 7 Jan 2025 13:38:47 -0600 Subject: [PATCH] Make HPX_HAVE_RUN_MAIN_EVERYWHERE application specific --- CMakeLists.txt | 12 +++++-- docs/sphinx/releases/whats_new_1_11_0.rst | 9 +++++ .../hpx/functional/detail/basic_function.hpp | 8 +++++ .../src/command_line_handling.cpp | 14 ++------ .../init_runtime/include/hpx/hpx_init.hpp | 11 +++--- .../include/hpx/hpx_init_impl.hpp | 18 +++++++++- .../include/hpx/hpx_init_params.hpp | 8 ++--- .../init_runtime/include/hpx/hpx_start.hpp | 10 +++--- .../include/hpx/hpx_start_impl.hpp | 18 +++++++++- .../include/hpx/hpx_user_main_config.hpp | 2 +- libs/full/init_runtime/src/hpx_init.cpp | 7 ++-- wrap/CMakeLists.txt | 4 +-- wrap/include/hpx/hpx_main.hpp | 20 +++++++++++ wrap/src/hpx_main.cpp | 36 +++++++++++++++++++ 14 files changed, 141 insertions(+), 36 deletions(-) create mode 100644 wrap/src/hpx_main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 519c32921524..4bd5de1740c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1582,12 +1582,18 @@ if(HPX_WITH_THREAD_DEBUG_INFO) hpx_add_config_define(HPX_HAVE_THREAD_MINIMAL_DEADLOCK_DETECTION) endif() -# run hpx_main on all localities by default +# run hpx_main on all localities by default (will be removed after V1.11.0) hpx_option( - HPX_WITH_RUN_MAIN_EVERYWHERE BOOL - "Run hpx_main by default on all localities (default: OFF)." OFF ADVANCED + HPX_WITH_RUN_MAIN_EVERYWHERE + BOOL + "Run hpx_main by default on all localities (default: OFF, deprecated, will be removed)." + OFF + ADVANCED ) if(HPX_WITH_RUN_MAIN_EVERYWHERE) + hpx_info("Note: the configuration parameter HPX_WITH_RUN_MAIN_EVERYWHERE is\n" + " deprecated and will be removed in the future." + ) hpx_add_config_define(HPX_HAVE_RUN_MAIN_EVERYWHERE) endif() diff --git a/docs/sphinx/releases/whats_new_1_11_0.rst b/docs/sphinx/releases/whats_new_1_11_0.rst index d093d6e0c7a9..df6c15007a89 100644 --- a/docs/sphinx/releases/whats_new_1_11_0.rst +++ b/docs/sphinx/releases/whats_new_1_11_0.rst @@ -14,6 +14,12 @@ General changes =============== +- Added synchronous versions of all collective operations. Added global predefined + communicator objects that are accessible through new APIs: + ``hpx::collectives::get_world_communicator()`` refers to all localities and + ``hpx::collectives::get_local_communicator()`` refers to all threads on the + calling locality. + Breaking changes ================ @@ -22,6 +28,9 @@ Breaking changes It was not possible to add compatibility facilities that will allow to continue using the old APIs, applications will have to be changed in order to continue functioning correctly. +- The CMake configuration parameter ``HPX_WITH_RUN_MAIN_EVERYWHERE`` is now + deprecated and will be removed in the future. Use the preprocessor macro + ``HPX_HAVE_RUN_MAIN_EVERYWHERE`` on a target-by-target case instead. Closed issues ============= diff --git a/libs/core/functional/include/hpx/functional/detail/basic_function.hpp b/libs/core/functional/include/hpx/functional/detail/basic_function.hpp index d9ef9b5d6eb3..c10c0423858a 100644 --- a/libs/core/functional/include/hpx/functional/detail/basic_function.hpp +++ b/libs/core/functional/include/hpx/functional/detail/basic_function.hpp @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -112,6 +113,13 @@ namespace hpx::util::detail { return detail::is_empty_function_impl(&f); } + template + [[nodiscard]] constexpr bool is_empty_function( + std::function const& f) noexcept + { + return !f; + } + /////////////////////////////////////////////////////////////////////////// template class basic_function; diff --git a/libs/full/command_line_handling/src/command_line_handling.cpp b/libs/full/command_line_handling/src/command_line_handling.cpp index 81aa9c2833bb..279fab742f35 100644 --- a/libs/full/command_line_handling/src/command_line_handling.cpp +++ b/libs/full/command_line_handling/src/command_line_handling.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2023 Hartmut Kaiser +// Copyright (c) 2007-2025 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -584,7 +584,6 @@ namespace hpx::util { { rtcfg_.mode_ = hpx::runtime_mode::worker; -#if !defined(HPX_HAVE_RUN_MAIN_EVERYWHERE) // do not execute any explicit hpx_main except if asked // otherwise if (!vm.count("hpx:run-hpx-main") && @@ -592,7 +591,6 @@ namespace hpx::util { { util::detail::reset_function(hpx_main_f_); } -#endif } else if (vm.count("hpx:connect")) { @@ -628,7 +626,6 @@ namespace hpx::util { hpx::util::from_string(rtcfg_.get_entry( "hpx.parcel.port", HPX_CONNECTING_IP_PORT))); -#if !defined(HPX_HAVE_RUN_MAIN_EVERYWHERE) // do not execute any explicit hpx_main except if asked // otherwise if (!vm.count("hpx:run-hpx-main") && @@ -636,7 +633,6 @@ namespace hpx::util { { util::detail::reset_function(hpx_main_f_); } -#endif } else if (node != static_cast(-1) || vm.count("hpx:node")) @@ -667,11 +663,10 @@ namespace hpx::util { if (hpx_port == 0 && node != 0) hpx_port = HPX_INITIAL_IP_PORT; - // each node gets an unique port + // each node gets a unique port hpx_port = static_cast(hpx_port + node); rtcfg_.mode_ = hpx::runtime_mode::worker; -#if !defined(HPX_HAVE_RUN_MAIN_EVERYWHERE) // do not execute any explicit hpx_main except if asked // otherwise if (!vm.count("hpx:run-hpx-main") && @@ -679,7 +674,6 @@ namespace hpx::util { { util::detail::reset_function(hpx_main_f_); } -#endif } } @@ -778,7 +772,6 @@ namespace hpx::util { // should not run the AGAS server we assume to be in worker mode rtcfg_.mode_ = hpx::runtime_mode::worker; -#if !defined(HPX_HAVE_RUN_MAIN_EVERYWHERE) // do not execute any explicit hpx_main except if asked // otherwise if (!vm.count("hpx:run-hpx-main") && @@ -786,7 +779,6 @@ namespace hpx::util { { util::detail::reset_function(hpx_main_f_); } -#endif } // write HPX and AGAS network parameters to the proper ini-file @@ -1051,7 +1043,7 @@ namespace hpx::util { reg->init(&argc, &argv, rtcfg_); } - // Now re-parse the command line using the node number (if given). This + // Now reparse the command line using the node number (if given). This // will additionally detect any --hpx:N:foo options. hpx::program_options::options_description help; std::vector unregistered_options; diff --git a/libs/full/init_runtime/include/hpx/hpx_init.hpp b/libs/full/init_runtime/include/hpx/hpx_init.hpp index 9d82ccc16a66..674de1826073 100644 --- a/libs/full/init_runtime/include/hpx/hpx_init.hpp +++ b/libs/full/init_runtime/include/hpx/hpx_init.hpp @@ -1,5 +1,5 @@ // Copyright (c) 2018 Mikael Simberg -// Copyright (c) 2007-2023 Hartmut Kaiser +// Copyright (c) 2007-2025 Hartmut Kaiser // Copyright (c) 2010-2011 Phillip LeBlanc, Dylan Stark // Copyright (c) 2011 Bryce Lelbach // @@ -28,6 +28,7 @@ /////////////////////////////////////////////////////////////////////////////// /// \namespace hpx namespace hpx { + /// \brief Main entry point for launching the HPX runtime system. /// /// This is the main entry point for any HPX application. This function @@ -58,7 +59,7 @@ namespace hpx { /// the created runtime system instance will be /// executed in console or worker mode depending on the /// command line arguments passed in `argc`/`argv`. - /// Otherwise it will be executed as specified by the + /// Otherwise, it will be executed as specified by the /// parameter\p mode. inline int init(std::function f, int argc, char** argv, init_params const& params = init_params()); @@ -93,7 +94,7 @@ namespace hpx { /// the created runtime system instance will be /// executed in console or worker mode depending on the /// command line arguments passed in `argc`/`argv`. - /// Otherwise it will be executed as specified by the + /// Otherwise, it will be executed as specified by the /// parameter\p mode. inline int init(std::function f, int argc, char** argv, init_params const& params = init_params()); @@ -123,7 +124,7 @@ namespace hpx { /// the created runtime system instance will be /// executed in console or worker mode depending on the /// command line arguments passed in `argc`/`argv`. - /// Otherwise it will be executed as specified by the + /// Otherwise, it will be executed as specified by the /// parameter\p mode. inline int init( int argc, char** argv, init_params const& params = init_params()); @@ -158,7 +159,7 @@ namespace hpx { /// the created runtime system instance will be /// executed in console or worker mode depending on the /// command line arguments passed in `argc`/`argv`. - /// Otherwise it will be executed as specified by the + /// Otherwise, it will be executed as specified by the /// parameter\p mode. inline int init(std::nullptr_t f, int argc, char** argv, init_params const& params = init_params()); diff --git a/libs/full/init_runtime/include/hpx/hpx_init_impl.hpp b/libs/full/init_runtime/include/hpx/hpx_init_impl.hpp index 70dce85bd250..679983524e14 100644 --- a/libs/full/init_runtime/include/hpx/hpx_init_impl.hpp +++ b/libs/full/init_runtime/include/hpx/hpx_init_impl.hpp @@ -1,5 +1,5 @@ // Copyright (c) 2018 Mikael Simberg -// Copyright (c) 2007-2023 Hartmut Kaiser +// Copyright (c) 2007-2025 Hartmut Kaiser // Copyright (c) 2011 Bryce Lelbach // // SPDX-License-Identifier: BSL-1.0 @@ -50,6 +50,7 @@ namespace hpx_startup { } namespace hpx { + /// \brief Main entry point for launching the HPX runtime system. /// /// This is the main entry point for any HPX application. This function @@ -86,8 +87,15 @@ namespace hpx { /// function given by \p f as a HPX thread. inline int init(int argc, char** argv, init_params const& params) { +#if defined(HPX_HAVE_RUN_MAIN_EVERYWHERE) + init_params pars = params; + pars.cfg.insert(pars.cfg.begin(), "hpx.run_hpx_main!=1"); + return detail::init_impl(hpx_startup::get_main_func(), argc, argv, pars, + HPX_PREFIX, environ); +#else return detail::init_impl(hpx_startup::get_main_func(), argc, argv, params, HPX_PREFIX, environ); +#endif } /// \brief Main entry point for launching the HPX runtime system. @@ -111,8 +119,16 @@ namespace hpx { /// console mode or worker mode depending on the command line settings). inline int init(init_params const& params) { +#if defined(HPX_HAVE_RUN_MAIN_EVERYWHERE) + init_params pars = params; + pars.cfg.insert(pars.cfg.begin(), "hpx.run_hpx_main!=1"); + return detail::init_impl(hpx_startup::get_main_func(), + hpx::local::detail::dummy_argc, hpx::local::detail::dummy_argv, + pars, HPX_PREFIX, environ); +#else return detail::init_impl(hpx_startup::get_main_func(), hpx::local::detail::dummy_argc, hpx::local::detail::dummy_argv, params, HPX_PREFIX, environ); +#endif } } // namespace hpx diff --git a/libs/full/init_runtime/include/hpx/hpx_init_params.hpp b/libs/full/init_runtime/include/hpx/hpx_init_params.hpp index 4f1875103d05..6f44c8584d54 100644 --- a/libs/full/init_runtime/include/hpx/hpx_init_params.hpp +++ b/libs/full/init_runtime/include/hpx/hpx_init_params.hpp @@ -78,10 +78,10 @@ namespace hpx { /// 'hpx.component.enabled=1') /// \var startup A function to be executed inside a HPX thread before /// \p f is called. If this parameter is - /// not given no function will be executed. + /// not given, no function will be executed. /// \var shutdown A function to be executed inside an HPX /// thread while hpx::finalize is executed. If this - /// parameter is not given no function will be executed. + /// parameter is not given, no function will be executed. /// \var mode The mode the created runtime environment /// should be initialized in. There has to be exactly /// one locality in each HPX application which is @@ -112,8 +112,8 @@ namespace hpx { desc_cmdline = hpx::local::detail::default_desc(HPX_APPLICATION_STRING); std::vector cfg; - mutable startup_function_type startup; - mutable shutdown_function_type shutdown; + std::function startup; + std::function shutdown; hpx::runtime_mode mode = ::hpx::runtime_mode::default_; hpx::resource::partitioner_mode rp_mode = ::hpx::resource::partitioner_mode::default_; diff --git a/libs/full/init_runtime/include/hpx/hpx_start.hpp b/libs/full/init_runtime/include/hpx/hpx_start.hpp index 357200ce800a..5fe7d9ac76d2 100644 --- a/libs/full/init_runtime/include/hpx/hpx_start.hpp +++ b/libs/full/init_runtime/include/hpx/hpx_start.hpp @@ -1,5 +1,5 @@ // Copyright (c) 2018 Mikael Simberg -// Copyright (c) 2007-2023 Hartmut Kaiser +// Copyright (c) 2007-2025 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -57,7 +57,7 @@ namespace hpx { /// the created runtime system instance will be /// executed in console or worker mode depending on the /// command line arguments passed in `argc`/`argv`. - /// Otherwise it will be executed as specified by the + /// Otherwise, it will be executed as specified by the /// parameter\p mode. inline bool start( std::function f, int argc, @@ -95,7 +95,7 @@ namespace hpx { /// the created runtime system instance will be /// executed in console or worker mode depending on the /// command line arguments passed in `argc`/`argv`. - /// Otherwise it will be executed as specified by the + /// Otherwise, it will be executed as specified by the /// parameter\p mode. inline bool start(std::function f, int argc, char** argv, init_params const& params = init_params()); @@ -127,7 +127,7 @@ namespace hpx { /// the created runtime system instance will be /// executed in console or worker mode depending on the /// command line arguments passed in `argc`/`argv`. - /// Otherwise it will be executed as specified by the + /// Otherwise, it will be executed as specified by the /// parameter\p mode. inline bool start( int argc, char** argv, init_params const& params = init_params()); @@ -164,7 +164,7 @@ namespace hpx { /// the created runtime system instance will be /// executed in console or worker mode depending on the /// command line arguments passed in `argc`/`argv`. - /// Otherwise it will be executed as specified by the + /// Otherwise, it will be executed as specified by the /// parameter\p mode. inline bool start(std::nullptr_t f, int argc, char** argv, init_params const& params = init_params()); diff --git a/libs/full/init_runtime/include/hpx/hpx_start_impl.hpp b/libs/full/init_runtime/include/hpx/hpx_start_impl.hpp index 57836b153315..8bc7f2f3800d 100644 --- a/libs/full/init_runtime/include/hpx/hpx_start_impl.hpp +++ b/libs/full/init_runtime/include/hpx/hpx_start_impl.hpp @@ -1,5 +1,5 @@ // Copyright (c) 2018 Mikael Simberg -// Copyright (c) 2007-2023 Hartmut Kaiser +// Copyright (c) 2007-2025 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -48,6 +48,7 @@ namespace hpx_startup { } namespace hpx { + /// \brief Main non-blocking entry point for launching the HPX runtime system. /// /// This is the main, non-blocking entry point for any HPX application. @@ -91,8 +92,15 @@ namespace hpx { /// with the runtime system's execution. inline bool start(int argc, char** argv, init_params const& params) { +#if defined(HPX_HAVE_RUN_MAIN_EVERYWHERE) + init_params pars = params; + pars.cfg.insert(pars.cfg.begin(), "hpx.run_hpx_main!=1"); + return detail::start_impl(hpx_startup::get_main_func(), argc, argv, + pars, HPX_PREFIX, environ); +#else return detail::start_impl(hpx_startup::get_main_func(), argc, argv, params, HPX_PREFIX, environ); +#endif } /// \brief Main non-blocking entry point for launching the HPX runtime system. @@ -121,8 +129,16 @@ namespace hpx { /// with the runtime system's execution. inline bool start(init_params const& params) { +#if defined(HPX_HAVE_RUN_MAIN_EVERYWHERE) + init_params pars = params; + pars.cfg.insert(pars.cfg.begin(), "hpx.run_hpx_main!=1"); + return detail::start_impl(hpx_startup::get_main_func(), + hpx::local::detail::dummy_argc, hpx::local::detail::dummy_argv, + pars, HPX_PREFIX, environ); +#else return detail::start_impl(hpx_startup::get_main_func(), hpx::local::detail::dummy_argc, hpx::local::detail::dummy_argv, params, HPX_PREFIX, environ); +#endif } } // namespace hpx diff --git a/libs/full/init_runtime/include/hpx/hpx_user_main_config.hpp b/libs/full/init_runtime/include/hpx/hpx_user_main_config.hpp index 2c15a347ed30..80a1797bdc3f 100644 --- a/libs/full/init_runtime/include/hpx/hpx_user_main_config.hpp +++ b/libs/full/init_runtime/include/hpx/hpx_user_main_config.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2015 Hartmut Kaiser +// Copyright (c) 2007-2055 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying diff --git a/libs/full/init_runtime/src/hpx_init.cpp b/libs/full/init_runtime/src/hpx_init.cpp index 50be6af29c5f..aa879308806b 100644 --- a/libs/full/init_runtime/src/hpx_init.cpp +++ b/libs/full/init_runtime/src/hpx_init.cpp @@ -8,6 +8,7 @@ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #include +#include #include #include @@ -97,6 +98,7 @@ /////////////////////////////////////////////////////////////////////////////// namespace hpx_startup { + std::vector (*user_main_config_function)( std::vector const&) = nullptr; } // namespace hpx_startup @@ -928,8 +930,7 @@ namespace hpx { // contain --hpx:help or --hpx:version, on error result is < 0) if (result != 0) { - if (result > 0) - result = 0; + result = (std::min)(result, 0); return result; } @@ -999,7 +1000,7 @@ namespace hpx { rt->set_app_options(params.desc_cmdline); result = run_or_start(blocking, HPX_MOVE(rt), cmdline, - HPX_MOVE(params.startup), HPX_MOVE(params.shutdown)); + params.startup, params.shutdown); } catch (detail::command_line_error const& e) { diff --git a/wrap/CMakeLists.txt b/wrap/CMakeLists.txt index 6fde4be49b22..b889bc8db6eb 100644 --- a/wrap/CMakeLists.txt +++ b/wrap/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2007-2023 Hartmut Kaiser +# Copyright (c) 2007-2025 Hartmut Kaiser # Copyright (c) 2011 Bryce Lelbach # Copyright (c) 2018 Nikunj Gupta # @@ -16,7 +16,7 @@ set(hpx_wrap_SOURCES "" CACHE INTERNAL "Sources for libhpx_wrap." FORCE ) -list(APPEND hpx_wrap_SOURCES hpx_wrap.cpp) +list(APPEND hpx_wrap_SOURCES hpx_wrap.cpp hpx_main.cpp) # make source groups set(hpx_wrap_SOURCE_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/src) diff --git a/wrap/include/hpx/hpx_main.hpp b/wrap/include/hpx/hpx_main.hpp index 75102fc29ffa..9b4077bba341 100644 --- a/wrap/include/hpx/hpx_main.hpp +++ b/wrap/include/hpx/hpx_main.hpp @@ -1,4 +1,5 @@ // Copyright (c) 2020 ETH Zurich +// Copyright (c) 2025 Hartmut Kaiser // // SPDX-License-Identifier: BSL-1.0 // Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -7,3 +8,22 @@ #pragma once #include + +#if defined(HPX_HAVE_RUN_MAIN_EVERYWHERE) + +namespace hpx_startup { + + void install_user_main_config(); + + struct register_user_main_config + { + register_user_main_config() + { + install_user_main_config(); + } + }; + + inline register_user_main_config cfg; +} // namespace hpx_startup + +#endif diff --git a/wrap/src/hpx_main.cpp b/wrap/src/hpx_main.cpp new file mode 100644 index 000000000000..bce43c781aa1 --- /dev/null +++ b/wrap/src/hpx_main.cpp @@ -0,0 +1,36 @@ +// Copyright (c) 2025 Hartmut Kaiser +// +// 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) + +#include +#include + +#include +#include + +namespace hpx_startup { + + namespace { + + std::vector (*prev_user_main_config_function)( + std::vector const&) = nullptr; + + std::vector enable_run_main( + std::vector const& config) + { + std::vector cfg(config); + cfg.emplace(cfg.begin(), "hpx.run_hpx_main!=1"); + if (prev_user_main_config_function) + return prev_user_main_config_function(cfg); + return cfg; + } + } // namespace + + void install_user_main_config() + { + prev_user_main_config_function = hpx_startup::user_main_config_function; + hpx_startup::user_main_config_function = &enable_run_main; + } +} // namespace hpx_startup