From decde5ede72d9f846082972e8773ceab536a9cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 22 Jul 2026 11:48:59 +0200 Subject: [PATCH 01/18] Point PaRSEC dependency at its new GitHub home (parsec-4.0.2411) and set dep-count via CMake cache vars instead of a patch --- cmake/resources/parsec/CMakeLists.txt | 7 +++---- .../parsec/patches/increase_max_inout_deps.patch | 15 --------------- 2 files changed, 3 insertions(+), 19 deletions(-) delete mode 100644 thirdparty/parsec/patches/increase_max_inout_deps.patch diff --git a/cmake/resources/parsec/CMakeLists.txt b/cmake/resources/parsec/CMakeLists.txt index eb0a27f..11e20e9 100644 --- a/cmake/resources/parsec/CMakeLists.txt +++ b/cmake/resources/parsec/CMakeLists.txt @@ -6,12 +6,11 @@ include(ExternalProject) if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") ExternalProject_Add(parsec - GIT_REPOSITORY https://bitbucket.org/icldistcomp/parsec.git - GIT_TAG 8f72a0ecab1296fc3d90ba7c164695f4a3738950 + GIT_REPOSITORY https://github.com/icldisco/parsec + GIT_TAG parsec-4.0.2411 SOURCE_DIR "${PARSEC_DOWNLOAD_ROOT}/src" BINARY_DIR "${PARSEC_DOWNLOAD_ROOT}/build" - PATCH_COMMAND cd ${PARSEC_DOWNLOAD_ROOT}/src && git apply ${PARSEC_DOWNLOAD_ROOT}/patches/increase_max_inout_deps.patch - CONFIGURE_COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DBUILD_TESTING=OFF -DPARSEC_DIST_WITH_MPI=${SEWAS_DISTRIBUTED} -DPARSEC_WITH_DEVEL_HEADERS=ON -DCMAKE_INSTALL_PREFIX=${THIRDPARTY_ROOT}/install ${PARSEC_DOWNLOAD_ROOT}/src + CONFIGURE_COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DBUILD_TESTING=OFF -DPARSEC_DIST_WITH_MPI=${SEWAS_DISTRIBUTED} -DPARSEC_WITH_DEVEL_HEADERS=ON -DPARSEC_MAX_DEP_IN_COUNT=16 -DPARSEC_MAX_DEP_OUT_COUNT=16 -DCMAKE_INSTALL_PREFIX=${THIRDPARTY_ROOT}/install ${PARSEC_DOWNLOAD_ROOT}/src BUILD_COMMAND make -j INSTALL_COMMAND make install TEST_COMMAND "" diff --git a/thirdparty/parsec/patches/increase_max_inout_deps.patch b/thirdparty/parsec/patches/increase_max_inout_deps.patch deleted file mode 100644 index 25e5468..0000000 --- a/thirdparty/parsec/patches/increase_max_inout_deps.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff --git a/parsec/include/parsec/parsec_config_bottom.h b/parsec/include/parsec/parsec_config_bottom.h -index 748c3106b..1b6e0c875 100644 ---- a/parsec/include/parsec/parsec_config_bottom.h -+++ b/parsec/include/parsec/parsec_config_bottom.h -@@ -105,8 +105,8 @@ typedef int32_t parsec_dependency_t; - #define MAX_LOCAL_COUNT 20 - #define MAX_PARAM_COUNT 20 - --#define MAX_DEP_IN_COUNT 10 --#define MAX_DEP_OUT_COUNT 10 -+#define MAX_DEP_IN_COUNT 16 -+#define MAX_DEP_OUT_COUNT 16 - - #define MAX_TASK_STRLEN 128 - From fc2967cca96b65d124d675ce0254237fe3eed5c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 22 Jul 2026 11:49:40 +0200 Subject: [PATCH 02/18] Port PaRSEC integration to the 4.0 arena/datatype API (arenas_datatypes, parsec_arena_datatype_construct) --- include/Types.hxx | 4 +++- src/SEWASPaRSEC.cxx | 36 +++++++++++++++++++----------------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/include/Types.hxx b/include/Types.hxx index d15d643..f43a691 100644 --- a/include/Types.hxx +++ b/include/Types.hxx @@ -33,7 +33,9 @@ namespace SWS { using RealType = double; #ifdef SEWAS_WITH_PARSEC -constexpr auto PARSECRealType = parsec_datatype_double_t; +// Not constexpr: under Open MPI, MPI_DOUBLE (and thus parsec_datatype_double_t) +// expands to a pointer cast, which isn't a valid constant expression. +static const auto PARSECRealType = parsec_datatype_double_t; #endif constexpr auto Ordering = Orderings::Y_MAJOR; diff --git a/src/SEWASPaRSEC.cxx b/src/SEWASPaRSEC.cxx index ba8adae..bbd7470 100644 --- a/src/SEWASPaRSEC.cxx +++ b/src/SEWASPaRSEC.cxx @@ -20,6 +20,8 @@ #ifdef SEWAS_WITH_PARSEC +#include // parsec_arena_datatype_construct + #include "Config.hxx" #include "HaloManager.hxx" #include "LinearSeismicWaveModel.hxx" @@ -158,12 +160,12 @@ SEWASPaRSEC::buildDAG() void SEWASPaRSEC::enqueueDAG() { - int status = parsec_enqueue(pPContext_, (parsec_taskpool_t*)pDAG_); - PARSEC_CHECK_ERROR(status, "parsec_enqueue"); + int status = parsec_context_add_taskpool(pPContext_, (parsec_taskpool_t*)pDAG_); + PARSEC_CHECK_ERROR(status, "parsec_context_add_taskpool"); } void -SEWASPaRSEC::addArena(const short arena_idx, const SWS::Locations l) +SEWASPaRSEC::addArena(const short adt_idx, const SWS::Locations l) { parsec_datatype_t oldtype = SWS::PARSECRealType; parsec_datatype_t newtype; @@ -176,7 +178,7 @@ SEWASPaRSEC::addArena(const short arena_idx, const SWS::Locations l) parsec_type_create_contiguous(asize, oldtype, &newtype); parsec_type_extent(newtype, &lb, &extent); - parsec_arena_construct(pDAG_->arenas[arena_idx], extent, SWS::Alignment, newtype); + parsec_arena_datatype_construct(&pDAG_->arenas_datatypes[adt_idx], extent, SWS::Alignment, newtype); } SEWASPaRSEC::SEWASPaRSEC(const int nt, const int nxx, const int nyy, const int nzz) @@ -195,23 +197,23 @@ SEWASPaRSEC::SEWASPaRSEC(const int nt, const int nxx, const int nyy, const int n buildDAG(); /* Default halo arena */ - addArena(PARSEC_sewas_DEFAULT_ARENA); + addArena(PARSEC_sewas_DEFAULT_ADT_IDX); /* Stress field halo arenas */ - addArena(PARSEC_sewas_SLEFT_HALO_ARENA, SWS::LEFT); - addArena(PARSEC_sewas_SRIGHT_HALO_ARENA, SWS::RIGHT); - addArena(PARSEC_sewas_SBACKWARD_HALO_ARENA, SWS::BACKWARD); - addArena(PARSEC_sewas_SFORWARD_HALO_ARENA, SWS::FORWARD); - addArena(PARSEC_sewas_SBOTTOM_HALO_ARENA, SWS::BOTTOM); - addArena(PARSEC_sewas_STOP_HALO_ARENA, SWS::TOP); + addArena(PARSEC_sewas_SLEFT_HALO_ADT_IDX, SWS::LEFT); + addArena(PARSEC_sewas_SRIGHT_HALO_ADT_IDX, SWS::RIGHT); + addArena(PARSEC_sewas_SBACKWARD_HALO_ADT_IDX, SWS::BACKWARD); + addArena(PARSEC_sewas_SFORWARD_HALO_ADT_IDX, SWS::FORWARD); + addArena(PARSEC_sewas_SBOTTOM_HALO_ADT_IDX, SWS::BOTTOM); + addArena(PARSEC_sewas_STOP_HALO_ADT_IDX, SWS::TOP); /* Velocity halo arenas */ - addArena(PARSEC_sewas_VLEFT_HALO_ARENA, SWS::LEFT); - addArena(PARSEC_sewas_VRIGHT_HALO_ARENA, SWS::RIGHT); - addArena(PARSEC_sewas_VBACKWARD_HALO_ARENA, SWS::BACKWARD); - addArena(PARSEC_sewas_VFORWARD_HALO_ARENA, SWS::FORWARD); - addArena(PARSEC_sewas_VBOTTOM_HALO_ARENA, SWS::BOTTOM); - addArena(PARSEC_sewas_VTOP_HALO_ARENA, SWS::TOP); + addArena(PARSEC_sewas_VLEFT_HALO_ADT_IDX, SWS::LEFT); + addArena(PARSEC_sewas_VRIGHT_HALO_ADT_IDX, SWS::RIGHT); + addArena(PARSEC_sewas_VBACKWARD_HALO_ADT_IDX, SWS::BACKWARD); + addArena(PARSEC_sewas_VFORWARD_HALO_ADT_IDX, SWS::FORWARD); + addArena(PARSEC_sewas_VBOTTOM_HALO_ADT_IDX, SWS::BOTTOM); + addArena(PARSEC_sewas_VTOP_HALO_ADT_IDX, SWS::TOP); enqueueDAG(); } From 36bd3e627a9a12c60b14e0fe4360d66e152cd4f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 22 Jul 2026 11:54:17 +0200 Subject: [PATCH 03/18] Pin googletest to v1.17.0 since its default branch is no longer master --- cmake/resources/gtest/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/resources/gtest/CMakeLists.txt b/cmake/resources/gtest/CMakeLists.txt index 8efdbaa..bbbf98e 100644 --- a/cmake/resources/gtest/CMakeLists.txt +++ b/cmake/resources/gtest/CMakeLists.txt @@ -5,7 +5,7 @@ project(googletest-download NONE) include(ExternalProject) ExternalProject_Add(googletest GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG master + GIT_TAG v1.17.0 SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-src" BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/googletest-build" CONFIGURE_COMMAND "" From 43dfa5dfb60c2dc3c992a39c9e2cec57a7420bd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 22 Jul 2026 11:54:53 +0200 Subject: [PATCH 04/18] Fix dead bitbucket PaRSEC clone URL in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 18acef9..192db13 100644 --- a/README.md +++ b/README.md @@ -295,7 +295,7 @@ $ sudo apt-get install libopenmpi-dev openmpi-common + PaRSEC 2.0 ```sh -$ git clone https://bitbucket.org/icldistcomp/parsec.git +$ git clone https://github.com/icldisco/parsec.git $ cd parsec $ cmake .. -DPARSEC_WITH_DEVEL_HEADERS=1 -DPARSEC_GPU_WITH_CUDA=0 $ make install From 59d5af8ac42d3d72292daecd3099d9a41816e05e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 22 Jul 2026 15:52:54 +0200 Subject: [PATCH 05/18] Pin PaRSEC to 4659c2706, the commit right before a reshape-of-datacopies regression breaks cross-rank halo exchange --- cmake/resources/parsec/CMakeLists.txt | 10 +++++-- src/SEWASPaRSEC.cxx | 29 ++++++++++--------- .../patches/increase_max_inout_deps.patch | 15 ++++++++++ 3 files changed, 39 insertions(+), 15 deletions(-) create mode 100644 thirdparty/parsec/patches/increase_max_inout_deps.patch diff --git a/cmake/resources/parsec/CMakeLists.txt b/cmake/resources/parsec/CMakeLists.txt index 11e20e9..ad3d397 100644 --- a/cmake/resources/parsec/CMakeLists.txt +++ b/cmake/resources/parsec/CMakeLists.txt @@ -5,12 +5,18 @@ project(parsec-download) include(ExternalProject) if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + # Pinned to the last commit before PaRSEC's "Reshape of datacopies" rework + # (8f813a179, first shipped in parsec-3.0.2012-rc1). That change and everything + # built on top of it, all the way through parsec-4.0.2411, breaks cross-rank + # halo exchange for SeWaS's task graph (MPI_ERR_TRUNCATE in the 2+ rank case; + # confirmed by bisection, root cause not yet identified upstream). ExternalProject_Add(parsec GIT_REPOSITORY https://github.com/icldisco/parsec - GIT_TAG parsec-4.0.2411 + GIT_TAG 4659c27061ffe2c23b034e09becf7e44e54ef6d8 SOURCE_DIR "${PARSEC_DOWNLOAD_ROOT}/src" BINARY_DIR "${PARSEC_DOWNLOAD_ROOT}/build" - CONFIGURE_COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DBUILD_TESTING=OFF -DPARSEC_DIST_WITH_MPI=${SEWAS_DISTRIBUTED} -DPARSEC_WITH_DEVEL_HEADERS=ON -DPARSEC_MAX_DEP_IN_COUNT=16 -DPARSEC_MAX_DEP_OUT_COUNT=16 -DCMAKE_INSTALL_PREFIX=${THIRDPARTY_ROOT}/install ${PARSEC_DOWNLOAD_ROOT}/src + PATCH_COMMAND cd ${PARSEC_DOWNLOAD_ROOT}/src && git apply ${PARSEC_DOWNLOAD_ROOT}/patches/increase_max_inout_deps.patch && sed -i "s/parsec_profiling_stream_t \\*new )/parsec_profiling_stream_t *new_stream )/" parsec/profiling.h + CONFIGURE_COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DBUILD_TESTING=OFF -DPARSEC_DIST_WITH_MPI=${SEWAS_DISTRIBUTED} -DPARSEC_WITH_DEVEL_HEADERS=ON -DCMAKE_C_FLAGS=-fcommon -DCMAKE_INSTALL_PREFIX=${THIRDPARTY_ROOT}/install ${PARSEC_DOWNLOAD_ROOT}/src BUILD_COMMAND make -j INSTALL_COMMAND make install TEST_COMMAND "" diff --git a/src/SEWASPaRSEC.cxx b/src/SEWASPaRSEC.cxx index bbd7470..0fe6848 100644 --- a/src/SEWASPaRSEC.cxx +++ b/src/SEWASPaRSEC.cxx @@ -197,23 +197,26 @@ SEWASPaRSEC::SEWASPaRSEC(const int nt, const int nxx, const int nyy, const int n buildDAG(); /* Default halo arena */ - addArena(PARSEC_sewas_DEFAULT_ADT_IDX); + /* Macro suffix is _ARENA, not _ADT_IDX: pinned PaRSEC predates the parsec-ptgpp + rename to _ADT_IDX (see cmake/resources/parsec/CMakeLists.txt for why this + specific commit is pinned instead of a later tag). */ + addArena(PARSEC_sewas_DEFAULT_ARENA); /* Stress field halo arenas */ - addArena(PARSEC_sewas_SLEFT_HALO_ADT_IDX, SWS::LEFT); - addArena(PARSEC_sewas_SRIGHT_HALO_ADT_IDX, SWS::RIGHT); - addArena(PARSEC_sewas_SBACKWARD_HALO_ADT_IDX, SWS::BACKWARD); - addArena(PARSEC_sewas_SFORWARD_HALO_ADT_IDX, SWS::FORWARD); - addArena(PARSEC_sewas_SBOTTOM_HALO_ADT_IDX, SWS::BOTTOM); - addArena(PARSEC_sewas_STOP_HALO_ADT_IDX, SWS::TOP); + addArena(PARSEC_sewas_SLEFT_HALO_ARENA, SWS::LEFT); + addArena(PARSEC_sewas_SRIGHT_HALO_ARENA, SWS::RIGHT); + addArena(PARSEC_sewas_SBACKWARD_HALO_ARENA, SWS::BACKWARD); + addArena(PARSEC_sewas_SFORWARD_HALO_ARENA, SWS::FORWARD); + addArena(PARSEC_sewas_SBOTTOM_HALO_ARENA, SWS::BOTTOM); + addArena(PARSEC_sewas_STOP_HALO_ARENA, SWS::TOP); /* Velocity halo arenas */ - addArena(PARSEC_sewas_VLEFT_HALO_ADT_IDX, SWS::LEFT); - addArena(PARSEC_sewas_VRIGHT_HALO_ADT_IDX, SWS::RIGHT); - addArena(PARSEC_sewas_VBACKWARD_HALO_ADT_IDX, SWS::BACKWARD); - addArena(PARSEC_sewas_VFORWARD_HALO_ADT_IDX, SWS::FORWARD); - addArena(PARSEC_sewas_VBOTTOM_HALO_ADT_IDX, SWS::BOTTOM); - addArena(PARSEC_sewas_VTOP_HALO_ADT_IDX, SWS::TOP); + addArena(PARSEC_sewas_VLEFT_HALO_ARENA, SWS::LEFT); + addArena(PARSEC_sewas_VRIGHT_HALO_ARENA, SWS::RIGHT); + addArena(PARSEC_sewas_VBACKWARD_HALO_ARENA, SWS::BACKWARD); + addArena(PARSEC_sewas_VFORWARD_HALO_ARENA, SWS::FORWARD); + addArena(PARSEC_sewas_VBOTTOM_HALO_ARENA, SWS::BOTTOM); + addArena(PARSEC_sewas_VTOP_HALO_ARENA, SWS::TOP); enqueueDAG(); } diff --git a/thirdparty/parsec/patches/increase_max_inout_deps.patch b/thirdparty/parsec/patches/increase_max_inout_deps.patch new file mode 100644 index 0000000..2903354 --- /dev/null +++ b/thirdparty/parsec/patches/increase_max_inout_deps.patch @@ -0,0 +1,15 @@ +diff --git a/parsec/include/parsec/parsec_config_bottom.h b/parsec/include/parsec/parsec_config_bottom.h +index 1176e24c0..e654339af 100644 +--- a/parsec/include/parsec/parsec_config_bottom.h ++++ b/parsec/include/parsec/parsec_config_bottom.h +@@ -153,8 +153,8 @@ typedef int32_t parsec_dependency_t; + #define MAX_LOCAL_COUNT 20 + #define MAX_PARAM_COUNT 20 + +-#define MAX_DEP_IN_COUNT 10 +-#define MAX_DEP_OUT_COUNT 10 ++#define MAX_DEP_IN_COUNT 16 ++#define MAX_DEP_OUT_COUNT 16 + + #define MAX_TASK_STRLEN 128 + From 4cb6cf998760e6ce46cef9b162621d2ee8e6d463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 22 Jul 2026 15:52:59 +0200 Subject: [PATCH 06/18] Ignore local PaRSEC checkout/build and the shared thirdparty install prefix --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index c223b8d..baca25a 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,9 @@ doc/* .vs/tasks.vs.json /thirdparty/vcpkg/src /thirdparty/vcpkg/build +/thirdparty/parsec/src +/thirdparty/parsec/build +/thirdparty/install /out /.vs/SeWaS/v16/.suo /.vs/CMake Overview From c872443c4b35b3fda16c6b69fb3bce9f3fe31231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 24 Jul 2026 12:10:10 +0200 Subject: [PATCH 07/18] Bump actions/checkout from v2 to v4 in CI workflows --- .github/workflows/Linux.yml | 2 +- .github/workflows/Windows.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index d8a2d30..644589a 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: install dependencies run : | diff --git a/.github/workflows/Windows.yml b/.github/workflows/Windows.yml index 8b42792..19cfb8d 100644 --- a/.github/workflows/Windows.yml +++ b/.github/workflows/Windows.yml @@ -11,7 +11,7 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: bootstrap run: .\bootstrap.bat From a9b455c1f2dc7e949cc3cf6ea92ee02003d2a790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 24 Jul 2026 12:10:10 +0200 Subject: [PATCH 08/18] Update vcpkg pin and drop the now-redundant arm64-linux patch --- cmake/resources/vcpkg/CMakeLists.txt | 9 ++++++--- thirdparty/vcpkg/patches/add_aarch64_support.patch | 13 ------------- thirdparty/vcpkg/triplets/arm64-linux.cmake | 5 ----- 3 files changed, 6 insertions(+), 21 deletions(-) delete mode 100644 thirdparty/vcpkg/patches/add_aarch64_support.patch delete mode 100644 thirdparty/vcpkg/triplets/arm64-linux.cmake diff --git a/cmake/resources/vcpkg/CMakeLists.txt b/cmake/resources/vcpkg/CMakeLists.txt index eb0e6b6..2303a76 100644 --- a/cmake/resources/vcpkg/CMakeLists.txt +++ b/cmake/resources/vcpkg/CMakeLists.txt @@ -11,7 +11,7 @@ endif() if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") ExternalProject_Add(vcpkg GIT_REPOSITORY https://github.com/microsoft/vcpkg.git - GIT_TAG 941d5464544eb5812b2cbd6e687c3ebc78ed2624 + GIT_TAG 40f3c709db80acf154ac4b17a1f83c564ebd022e SOURCE_DIR "../src" BUILD_IN_SOURCE true CONFIGURE_COMMAND "" @@ -20,13 +20,16 @@ if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") TEST_COMMAND "" ) elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + # arm64-linux support is native to vcpkg since well before this pin; the old + # add_aarch64_support.patch/community triplet copy is both unneeded and no + # longer applies (scripts/buildsystems/vcpkg.cmake has since been rewritten + # upstream). ExternalProject_Add(vcpkg GIT_REPOSITORY https://github.com/microsoft/vcpkg.git - GIT_TAG 941d5464544eb5812b2cbd6e687c3ebc78ed2624 + GIT_TAG 40f3c709db80acf154ac4b17a1f83c564ebd022e SOURCE_DIR "../src" BUILD_IN_SOURCE true CONFIGURE_COMMAND "" - PATCH_COMMAND cp ../triplets/arm64-linux.cmake ../src/triplets/community && cd ../src && git apply ../patches/add_aarch64_support.patch BUILD_COMMAND ./bootstrap-vcpkg.sh ${_VCPKG_BOOTSTRAP_OPTIONS} INSTALL_COMMAND "" TEST_COMMAND "" diff --git a/thirdparty/vcpkg/patches/add_aarch64_support.patch b/thirdparty/vcpkg/patches/add_aarch64_support.patch deleted file mode 100644 index 65298c4..0000000 --- a/thirdparty/vcpkg/patches/add_aarch64_support.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/scripts/buildsystems/vcpkg.cmake b/scripts/buildsystems/vcpkg.cmake -index 1eebc3b8d..99595c0b8 100644 ---- a/scripts/buildsystems/vcpkg.cmake -+++ b/scripts/buildsystems/vcpkg.cmake -@@ -78,6 +78,8 @@ else() - set(_VCPKG_TARGET_TRIPLET_ARCH x86) - elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64") - set(_VCPKG_TARGET_TRIPLET_ARCH x64) -+ elseif(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "aarch64") -+ set(_VCPKG_TARGET_TRIPLET_ARCH arm64) - else() - if( _CMAKE_IN_TRY_COMPILE ) - message(STATUS "Unable to determine target architecture, continuing without vcpkg.") diff --git a/thirdparty/vcpkg/triplets/arm64-linux.cmake b/thirdparty/vcpkg/triplets/arm64-linux.cmake deleted file mode 100644 index 07452e0..0000000 --- a/thirdparty/vcpkg/triplets/arm64-linux.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(VCPKG_TARGET_ARCHITECTURE arm64) -set(VCPKG_CRT_LINKAGE dynamic) -set(VCPKG_LIBRARY_LINKAGE static) - -set(VCPKG_CMAKE_SYSTEM_NAME Linux) From 67425cc76a60791cdf61fccf632270ca2b0f404a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 24 Jul 2026 12:10:10 +0200 Subject: [PATCH 09/18] Bump ADIOS2 to v2.12.1 and drop the removed DebugON arg --- cmake/resources/adios/CMakeLists.txt | 2 +- src/IOManager.cxx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/resources/adios/CMakeLists.txt b/cmake/resources/adios/CMakeLists.txt index 6a3ce9e..c55ad14 100644 --- a/cmake/resources/adios/CMakeLists.txt +++ b/cmake/resources/adios/CMakeLists.txt @@ -7,7 +7,7 @@ include(ExternalProject) if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") ExternalProject_Add(adios GIT_REPOSITORY https://github.com/ornladios/ADIOS2.git - GIT_TAG v2.5.0 + GIT_TAG v2.12.1 SOURCE_DIR "${ADIOS_DOWNLOAD_ROOT}/src" BINARY_DIR "${ADIOS_DOWNLOAD_ROOT}/build" PATCH_COMMAND "" diff --git a/src/IOManager.cxx b/src/IOManager.cxx index 3d6fa1e..81b0776 100644 --- a/src/IOManager.cxx +++ b/src/IOManager.cxx @@ -146,9 +146,9 @@ IOManager::init() int status = 0; #ifdef ENABLE_IO #if SEWAS_DISTRIBUTED - adios_ = std::make_unique(MPI_COMM_WORLD, adios2::DebugON); + adios_ = std::make_unique(MPI_COMM_WORLD); #else - adios_ = std::make_unique(adios2::DebugON); + adios_ = std::make_unique(); #endif processedTasks_[0] = 3 * lnxx_ * lnyy_ * lnzz_; From d768a09eaa8f239ac2c81188c908a11d42d69d7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 24 Jul 2026 12:10:10 +0200 Subject: [PATCH 10/18] Ignore local ADIOS2 checkout/build like vcpkg and PaRSEC --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index baca25a..c4fab6b 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,8 @@ doc/* /thirdparty/vcpkg/build /thirdparty/parsec/src /thirdparty/parsec/build +/thirdparty/adios/src +/thirdparty/adios/build /thirdparty/install /out /.vs/SeWaS/v16/.suo From 0f0603f0d30f2b859049ef1800236ac291a95caa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 29 Jul 2026 11:53:09 +0200 Subject: [PATCH 11/18] Rewrite README build instructions for the vcpkg-based CMake workflow --- README.md | 87 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 192db13..ba8ad4b 100644 --- a/README.md +++ b/README.md @@ -279,49 +279,76 @@ DisplayStress Those visualization tasks interact with [VTK](http://www.vtk.org/) actors to render the scene. -# Building the application -The application has been tested on Debian 9 and CentOS. The following steps are suitable for a Debian-like OS. Our experiments were carried out using Intel compiler 18, but according to our recent experiments using gcc 7.3 there is no significant performance differences between these two compilers. So all the following experiments can be obtained using gcc. +# Building and installing -## Dependencies -+ Boost 1.62 (program-options module) -```sh -$ sudo apt-get install libboost-program-options-dev -``` +SeWaS is a CMake project. Its dependencies (Boost `program_options`, Eigen3, spdlog, and — for +distributed/PaRSEC builds — OpenMPI and PaRSEC) are resolved automatically at configure time through +[vcpkg](https://github.com/microsoft/vcpkg), vendored under `thirdparty/vcpkg`, so there is no dependency +installation step to perform by hand. It has been validated on Linux (Ubuntu/Debian-like, via CI) and +Windows; a C++17 compiler and CMake 3.10.3+ are required either way. -+ OpenMPI 2.0.2 -```sh -$ sudo apt-get install libopenmpi-dev openmpi-common -``` +## 1. System prerequisites -+ PaRSEC 2.0 -```sh -$ git clone https://github.com/icldisco/parsec.git -$ cd parsec -$ cmake .. -DPARSEC_WITH_DEVEL_HEADERS=1 -DPARSEC_GPU_WITH_CUDA=0 -$ make install -``` +Only build tooling that vcpkg itself cannot provide needs to be present on the system beforehand: + ++ Linux: a C++17 compiler (gcc/clang), CMake, and — only when building with `-DSEWAS_WITH_PARSEC=ON`, + since PaRSEC's JDF files are compiled with `parsec-ptgpp` — `flex` and `bison`: + ```sh + sudo apt-get install build-essential cmake flex bison + ``` ++ Windows: Visual Studio (with the C++ workload) and CMake. + +## 2. Bootstrap + +Run once per clone, before the first configure. This downloads and builds vcpkg into +`thirdparty/vcpkg` if it isn't already present: -+ Eigen 3.3.3 ```sh -$ sudo apt-get install libeigen3-dev +./bootstrap.sh # Linux/macOS +bootstrap.bat # Windows ``` -+ Intel TBB 4.3 +## 3. Configure + ```sh -$ sudo apt-get install libtbb-dev +mkdir build && cd build +cmake .. -DCMAKE_BUILD_TYPE=Release \ + -DSEWAS_DISTRIBUTED=ON -DSEWAS_WITH_PARSEC=ON \ + -DBUILD_TESTING=ON -DCOLLECT_STATS=ON -DVERBOSE=ON ``` - -## SeWaS build + +`SEWAS_DISTRIBUTED` enables MPI-based distributed execution, and `SEWAS_WITH_PARSEC` (which requires it) +enables the PaRSEC task-based scheduler; both are ON in Linux CI, and Windows CI builds with both OFF. With +`DOWNLOAD_MISSING_DEPS` on (the default), CMake will download and build any of the above dependencies not +already found on the system — expect the first configure to take a while, since it also builds PaRSEC from +source. + +Other build options (all defined at the top of `CMakeLists.txt` and OFF unless noted) let you tune what +gets compiled in: + +| Option | Effect | +|---|---| +| `VISUALIZE_EXECUTION` (+ `ENABLE_VELOCITY_RENDERING`, `ENABLE_STRESS_RENDERING`, `ENABLE_CLUSTER_RENDERING`) | Real-time VTK rendering of the simulation | +| `ENABLE_IO` | ADIOS2-based output | +| `USE_BLOCKWISE_FDO` (ON), `VECTORIZE_COMPUTATIONS` (ON), `EIGEN_VECTORIZATION` (ON), `BOOST_SIMD_VECTORIZATION` | Control how the finite-difference operator is vectorized | +| `DOWNLOAD_MISSING_DEPS` (ON) | Auto-fetch missing dependencies through vcpkg instead of failing configure | + +## 4. Build + ```sh -$ export SEWAS_ROOT=/path/to/SeismicWaveSimulator -$ cd $SEWAS_ROOT/build -$ cmake ../src -DCMAKE_BUILD_TYPE=Release -$ make +cmake --build . --config Release ``` -At this stage the `build/` directory should contain an executable `sewas` +This produces the `sewas` executable directly inside `build/` — there is no separate install step/prefix; +run it in place (see [User Interface](#user-interface) above) or copy the binary wherever you need it. -/!\ The results presented in our paper are obtained on a cluster of Intel KNL processors. Hence it is mandatory to build the SeWaS application natively on one co-processor for best performances. +## 5. Test (optional) + +With `-DBUILD_TESTING=ON`, the GoogleTest suite can be run via CTest: + +```sh +ctest -C Release --output-on-failure -V +``` # Benchmarks Performance studies have been carried out using two test cases: TestA and TestB. From 30be0a53f91946f0da77a39483a2f9c54df5cffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 24 Aug 2026 13:24:37 +0200 Subject: [PATCH 12/18] feat: add SEWASStarPU distributed execution engine --- CMakeLists.txt | 38 +++ include/ExecutionContext.hxx | 8 + include/SEWASStarPU.hxx | 119 +++++++ src/ExecutionContext.cxx | 10 + src/LinearSeismicWaveModel.cxx | 14 +- src/SEWASStarPU.cxx | 556 +++++++++++++++++++++++++++++++++ tests/CMakeLists.txt | 1 + 7 files changed, 745 insertions(+), 1 deletion(-) create mode 100644 include/SEWASStarPU.hxx create mode 100644 src/SEWASStarPU.cxx diff --git a/CMakeLists.txt b/CMakeLists.txt index 761c5c6..229553a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules" C option(SEWAS_DISTRIBUTED "Build SeWaS for distributed memory platforms (default OFF)" OFF) option(SEWAS_WITH_PARSEC "Use PaRSEC for task-scheduling (default OFF)" OFF) +option(SEWAS_WITH_STARPU "Use StarPU for task-scheduling (default OFF)" OFF) option(VERBOSE "Enable collecting and displaying of traced events at runtime (default OFF)" OFF) option(BUILD_TESTING "Build the testing tree (default OFF)" OFF) option(COLLECT_STATS "Collect statistics during execution (default ON)" ON) @@ -122,6 +123,14 @@ if(SEWAS_WITH_PARSEC) add_compile_options(-DSEWAS_WITH_PARSEC) endif() +if(SEWAS_WITH_STARPU) + add_compile_options(-DSEWAS_WITH_STARPU) +endif() + +if(SEWAS_WITH_PARSEC AND SEWAS_WITH_STARPU) + message(FATAL_ERROR "SEWAS_WITH_PARSEC and SEWAS_WITH_STARPU are mutually exclusive.") +endif() + if (VERBOSE) add_compile_options(-DVERBOSE) endif(VERBOSE) @@ -354,6 +363,34 @@ if(SEWAS_WITH_PARSEC) set(SEWAS_LIBRARIES ${SEWAS_LIBRARIES} ${PARSEC_LIBRARIES}) endif(SEWAS_WITH_PARSEC) +# ------------------------------------------------------------------- +# StarPU +# ------------------------------------------------------------------- +if(SEWAS_WITH_STARPU) + if (NOT SEWAS_DISTRIBUTED) + message(FATAL_ERROR "The distributed version of SeWaS relies on StarPU.") + endif(NOT SEWAS_DISTRIBUTED) + + find_package(PkgConfig REQUIRED) + set(STARPU_PC_VERSION "1.4" CACHE STRING "StarPU pkg-config version suffix") + pkg_check_modules(STARPU starpumpi-${STARPU_PC_VERSION}) + if (NOT STARPU_FOUND) + message(FATAL_ERROR "StarPU (starpumpi-${STARPU_PC_VERSION}) not found via pkg-config. " + "Install it (e.g. 'apt install libstarpu-dev' on Debian/Ubuntu, or build it " + "via Spack) and make sure its .pc files are on PKG_CONFIG_PATH. " + "Automatic download of StarPU is not currently supported.") + endif() + + message(STATUS "StarPU found") + message(STATUS " STARPU_INCLUDE_DIRS = ${STARPU_INCLUDE_DIRS}") + message(STATUS " STARPU_LIBRARY_DIRS = ${STARPU_LIBRARY_DIRS}") + message(STATUS " STARPU_LIBRARIES = ${STARPU_LIBRARIES}") + + include_directories("${STARPU_INCLUDE_DIRS}") + link_directories("${STARPU_LIBRARY_DIRS}") + set(SEWAS_LIBRARIES ${SEWAS_LIBRARIES} ${STARPU_LIBRARIES}) +endif(SEWAS_WITH_STARPU) + # ------------------------------------------------------------------- # Boost # ------------------------------------------------------------------- @@ -445,6 +482,7 @@ set(SOURCES src/SEWASParameterManager.cxx src/SEWASSequential.cxx src/SEWASPaRSEC.cxx + src/SEWASStarPU.cxx src/Mesh3DPartitioning.cxx src/VisualizationManager.cxx src/MetricsManager.cxx diff --git a/include/ExecutionContext.hxx b/include/ExecutionContext.hxx index 7762d7c..9023f8a 100644 --- a/include/ExecutionContext.hxx +++ b/include/ExecutionContext.hxx @@ -35,6 +35,10 @@ #include "sewas.h" #endif +#ifdef SEWAS_WITH_STARPU +#include "SEWASStarPU.hxx" +#endif + #include "SEWASParameterManager.hxx" class ExecutionContext @@ -63,6 +67,10 @@ public: SEWASPaRSEC::finalize(); #endif +#ifdef SEWAS_WITH_STARPU + SEWASStarPU::finalize(); +#endif + #if SEWAS_DISTRIBUTED MPI_Finalize(); #endif diff --git a/include/SEWASStarPU.hxx b/include/SEWASStarPU.hxx new file mode 100644 index 0000000..45d8a36 --- /dev/null +++ b/include/SEWASStarPU.hxx @@ -0,0 +1,119 @@ +/* + SeWaS + Copyright (C) 2018 ANEO + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +==============================================================================*/ + +#pragma once + +#ifdef SEWAS_WITH_STARPU +#include + +#include +#include + +#include "Config.hxx" +#include "SEWASParameterManager.hxx" + +/* SEWASStarPU drives the same two-phase-per-timestep algorithm as + * SEWASSequential (see SEWASSequential.hxx), but submits one StarPU task per + * local tile per phase (parallel across tiles within a node, via + * --nthreads), and performs cross-rank halo exchange with the explicit + * starpu_mpi_isend_detached/irecv_detached API, which -- unlike PaRSEC and + * StarPU's own starpu_mpi_task_insert API -- does not exhibit a cross-rank + * deadlock under this access pattern. Same-rank neighbor tiles are handled + * with a plain memcpy, exactly like SEWASSequential::sendreceive(). */ +class SEWASStarPU +{ +public: + static SEWASStarPU* getInstance(const int nt = 1, const int nxx = 1, const int nyy = 1, const int nzz = 1); + static void releaseInstance(); + + static void init(SEWASParameterManager& pm); + static void finalize(); + + int run(); + +private: + enum DataTransferStages + { + SEND, + RECEIVE + }; + + SEWASStarPU(const int nt, const int nxx, const int nyy, const int nzz); + ~SEWASStarPU(); + + void buildVelocityArenas(); + void buildStressArenas(); + void destroyVelocityArenas(); + void destroyStressArenas(); + + void exchangeVelocityHalo(const SWS::Directions d, const int ts); + void exchangeStressHalo(const SWS::StressFieldComponents sc, const int ts); + + size_t haloHandleIndex(const int lii, const int ljj, const int lkk, const SWS::Locations l) const noexcept; + + starpu_mpi_tag_t makeTag(const bool isStress, + const int comp, + const int ts, + const int ii, + const int jj, + const int kk, + const SWS::Locations l) const noexcept; + + bool neighborCoords(const int ii, + const int jj, + const int kk, + const SWS::Locations l, + int& nii, + int& njj, + int& nkk) const noexcept; + + static SWS::Locations opposite(const SWS::Locations l) noexcept; + + static void initializeFieldsCodelet(void* buffers[], void* cl_arg); + static void phaseAVelocityCodelet(void* buffers[], void* cl_arg); + static void phaseBStressCodelet(void* buffers[], void* cl_arg); + + static SEWASStarPU* pInstance_; + + int world_; + int rank_; + + int nt_; + int nxx_; + int nyy_; + int nzz_; + + int lnxx_; + int lnyy_; + int lnzz_; + + /* Persistent send/receive halo buffers, sized to the local tile grid + * (mirrors SEWASSequential's own arenas, and HaloManager's own sigmaH_/vH_ + * sizing): sigmaH_[u](sc)(lii,ljj,lkk)(l), vH_[u](d)(lii,ljj,lkk)(l). */ + SWS::StressFieldHalo sigmaH_[2]; + SWS::VelocityHalo vH_[2]; + + /* StarPU handles wrapping the buffers above, flattened per (component, + * local tile, location); only used for cross-rank transfers -- same-rank + * neighbors are handled with a plain memcpy and never touch these. */ + std::vector vSendHandles_[SWS::DIM]; + std::vector vRecvHandles_[SWS::DIM]; + std::vector sSendHandles_[SWS::NB_STRESS_FIELD_COMPONENTS]; + std::vector sRecvHandles_[SWS::NB_STRESS_FIELD_COMPONENTS]; +}; +#endif diff --git a/src/ExecutionContext.cxx b/src/ExecutionContext.cxx index 46e697e..a9e1162 100644 --- a/src/ExecutionContext.cxx +++ b/src/ExecutionContext.cxx @@ -19,6 +19,7 @@ #include "ExecutionContext.hxx" #include "LogManager.hxx" #include "SEWASPaRSEC.hxx" +#include "SEWASStarPU.hxx" int ExecutionContext::init(SEWASParameterManager& pm) @@ -50,5 +51,14 @@ ExecutionContext::init(SEWASParameterManager& pm) LOG(SWS::LOG_INFO, "PaRSEC runtime is started"); #endif +#ifdef SEWAS_WITH_STARPU + /* StarPU initialization */ + LOG(SWS::LOG_INFO, "Starting the StarPU runtime"); + + SEWASStarPU::init(pm); + + LOG(SWS::LOG_INFO, "StarPU runtime is started"); +#endif + return 0; } diff --git a/src/LinearSeismicWaveModel.cxx b/src/LinearSeismicWaveModel.cxx index b0914e8..8880f8c 100644 --- a/src/LinearSeismicWaveModel.cxx +++ b/src/LinearSeismicWaveModel.cxx @@ -42,6 +42,7 @@ #include "MetricsManager.hxx" #include "SEWASPaRSEC.hxx" #include "SEWASSequential.hxx" +#include "SEWASStarPU.hxx" LinearSeismicWaveModel* LinearSeismicWaveModel::pInstance_ = nullptr; @@ -76,7 +77,7 @@ LinearSeismicWaveModel::releaseInstance() int LinearSeismicWaveModel::propagate() noexcept { -#ifdef SEWAS_WITH_PARSEC +#if defined(SEWAS_WITH_PARSEC) LOG(SWS::LOG_INFO, "Starting the PaRSEC-based runner"); SEWASPaRSEC* sewasPaRSEC = SEWASPaRSEC::getInstance(nt_, pm_.nxx(), pm_.nyy(), pm_.nzz()); @@ -87,6 +88,17 @@ LinearSeismicWaveModel::propagate() noexcept LOG(SWS::LOG_INFO, "Seismic simulation completed"); SEWASPaRSEC::releaseInstance(); +#elif defined(SEWAS_WITH_STARPU) + LOG(SWS::LOG_INFO, "Starting the StarPU-based runner"); + + SEWASStarPU* sewasStarPU = SEWASStarPU::getInstance(nt_, pm_.nxx(), pm_.nyy(), pm_.nzz()); + LOG(SWS::LOG_INFO, "StarPU-based runner started"); + + LOG(SWS::LOG_INFO, "Starting execution of the core seismic simulation"); + sewasStarPU->run(); + LOG(SWS::LOG_INFO, "Seismic simulation completed"); + + SEWASStarPU::releaseInstance(); #else LOG(SWS::LOG_INFO, "Starting the sequential runner"); SEWASSequential* sewasSequential = SEWASSequential::getInstance(nt_, pm_.nxx(), pm_.nyy(), pm_.nzz()); diff --git a/src/SEWASStarPU.cxx b/src/SEWASStarPU.cxx new file mode 100644 index 0000000..59cf399 --- /dev/null +++ b/src/SEWASStarPU.cxx @@ -0,0 +1,556 @@ +/* + SeWaS + Copyright (C) 2018 ANEO + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +==============================================================================*/ + +#include "SEWASStarPU.hxx" + +#ifdef SEWAS_WITH_STARPU + +#include + +#include "ExecutionContext.hxx" +#include "HaloManager.hxx" +#include "LinearSeismicWaveModel.hxx" +#include "LogManager.hxx" +#include "Mesh3DPartitioning.hxx" + +namespace { +struct starpu_codelet +makeCodelet(void (*func)(void*[], void*), const char* name) +{ + struct starpu_codelet cl; + memset(&cl, 0, sizeof(cl)); + cl.cpu_funcs[0] = func; + cl.cpu_funcs_name[0] = name; + cl.nbuffers = 0; + return cl; +} +} + +SEWASStarPU* SEWASStarPU::pInstance_ = nullptr; + +SEWASStarPU* +SEWASStarPU::getInstance(const int nt, const int nxx, const int nyy, const int nzz) +{ + if (nullptr == pInstance_) { + pInstance_ = new SEWASStarPU(nt, nxx, nyy, nzz); + } + return pInstance_; +} + +void +SEWASStarPU::releaseInstance() +{ + if (pInstance_) { + delete pInstance_; + pInstance_ = nullptr; + } +} + +void +SEWASStarPU::init(SEWASParameterManager& pm) +{ + struct starpu_conf conf; + starpu_conf_init(&conf); + conf.ncpus = pm.nthreads(); + + int status = starpu_init(&conf); + if (status != 0) { + LOG(SWS::LOG_CRITICAL, "starpu_init failed with status {}", status); + exit(SWS::OBJECT_CREATION_FAILURE); + } + + /* MPI is already initialized by ExecutionContext::init(); StarPU-MPI must not + * re-initialize it -- same ownership model SEWASPaRSEC::init() follows for PaRSEC. */ + status = starpu_mpi_init_comm(&pm.argc(), &pm.argv(), 0, MPI_COMM_WORLD); + if (status != 0) { + LOG(SWS::LOG_CRITICAL, "starpu_mpi_init_comm failed with status {}", status); + exit(SWS::OBJECT_CREATION_FAILURE); + } +} + +void +SEWASStarPU::finalize() +{ + starpu_mpi_shutdown(); + starpu_shutdown(); +} + +size_t +SEWASStarPU::haloHandleIndex(const int lii, const int ljj, const int lkk, const SWS::Locations l) const noexcept +{ + return (((size_t)lii * lnyy_ + ljj) * lnzz_ + lkk) * SWS::NB_LOCATIONS + l; +} + +starpu_mpi_tag_t +SEWASStarPU::makeTag(const bool isStress, + const int comp, + const int ts, + const int ii, + const int jj, + const int kk, + const SWS::Locations l) const noexcept +{ + int64_t t = isStress ? 1 : 0; + t = t * 8 + comp; + t = t * SWS::NB_LOCATIONS + l; + t = t * nxx_ + ii; + t = t * nyy_ + jj; + t = t * nzz_ + kk; + t = t * (nt_ + 1) + ts; + return (starpu_mpi_tag_t)t; +} + +bool +SEWASStarPU::neighborCoords(const int ii, + const int jj, + const int kk, + const SWS::Locations l, + int& nii, + int& njj, + int& nkk) const noexcept +{ + nii = ii; + njj = jj; + nkk = kk; + + switch (l) { + case SWS::LEFT: + if (ii <= 0) return false; + nii = ii - 1; + break; + case SWS::RIGHT: + if (ii >= nxx_ - 1) return false; + nii = ii + 1; + break; + case SWS::BACKWARD: + if (jj <= 0) return false; + njj = jj - 1; + break; + case SWS::FORWARD: + if (jj >= nyy_ - 1) return false; + njj = jj + 1; + break; + case SWS::BOTTOM: + if (kk <= 0) return false; + nkk = kk - 1; + break; + case SWS::TOP: + if (kk >= nzz_ - 1) return false; + nkk = kk + 1; + break; + default: + LOG(SWS::LOG_ERROR, "Unknown location {} requested within SEWASStarPU::neighborCoords()", l); + return false; + } + + return true; +} + +SWS::Locations +SEWASStarPU::opposite(const SWS::Locations l) noexcept +{ + switch (l) { + case SWS::LEFT: + return SWS::RIGHT; + case SWS::RIGHT: + return SWS::LEFT; + case SWS::BACKWARD: + return SWS::FORWARD; + case SWS::FORWARD: + return SWS::BACKWARD; + case SWS::BOTTOM: + return SWS::TOP; + case SWS::TOP: + return SWS::BOTTOM; + default: + LOG(SWS::LOG_ERROR, "Unknown location {} requested within SEWASStarPU::opposite()", l); + return SWS::NB_LOCATIONS; + } +} + +void +SEWASStarPU::buildVelocityArenas() +{ + auto* pHaloManager = HaloManager::getInstance(); + + for (auto d : { SWS::X, SWS::Y, SWS::Z }) { + for (auto u : { SEND, RECEIVE }) { + vH_[u](d).resize(lnxx_, lnyy_, lnzz_); + } + + vSendHandles_[d].assign((size_t)lnxx_ * lnyy_ * lnzz_ * SWS::NB_LOCATIONS, nullptr); + vRecvHandles_[d].assign((size_t)lnxx_ * lnyy_ * lnzz_ * SWS::NB_LOCATIONS, nullptr); + + for (int lii = 0; lii < lnxx_; lii++) { + for (int ljj = 0; ljj < lnyy_; ljj++) { + for (int lkk = 0; lkk < lnzz_; lkk++) { + for (auto l : { SWS::LEFT, SWS::RIGHT, SWS::BACKWARD, SWS::FORWARD, SWS::BOTTOM, SWS::TOP }) { + const auto hsize = pHaloManager->getHaloSize(l, lii, ljj, lkk); + + auto* sendBuf = new SWS::RealType[hsize]; + memset(sendBuf, 0, hsize * sizeof(SWS::RealType)); + vH_[SEND](d)(lii, ljj, lkk)(l) = sendBuf; + + auto* recvBuf = new SWS::RealType[hsize]; + memset(recvBuf, 0, hsize * sizeof(SWS::RealType)); + vH_[RECEIVE](d)(lii, ljj, lkk)(l) = recvBuf; + + const auto idx = haloHandleIndex(lii, ljj, lkk, l); + starpu_vector_data_register( + &vSendHandles_[d][idx], STARPU_MAIN_RAM, (uintptr_t)sendBuf, hsize, sizeof(SWS::RealType)); + starpu_vector_data_register( + &vRecvHandles_[d][idx], STARPU_MAIN_RAM, (uintptr_t)recvBuf, hsize, sizeof(SWS::RealType)); + } + } + } + } + } +} + +void +SEWASStarPU::buildStressArenas() +{ + auto* pHaloManager = HaloManager::getInstance(); + + for (auto sc : { SWS::XX, SWS::YY, SWS::ZZ, SWS::XY, SWS::XZ, SWS::YZ }) { + for (auto u : { SEND, RECEIVE }) { + sigmaH_[u](sc).resize(lnxx_, lnyy_, lnzz_); + } + + sSendHandles_[sc].assign((size_t)lnxx_ * lnyy_ * lnzz_ * SWS::NB_LOCATIONS, nullptr); + sRecvHandles_[sc].assign((size_t)lnxx_ * lnyy_ * lnzz_ * SWS::NB_LOCATIONS, nullptr); + + for (int lii = 0; lii < lnxx_; lii++) { + for (int ljj = 0; ljj < lnyy_; ljj++) { + for (int lkk = 0; lkk < lnzz_; lkk++) { + for (auto l : { SWS::LEFT, SWS::RIGHT, SWS::BACKWARD, SWS::FORWARD, SWS::BOTTOM, SWS::TOP }) { + const auto hsize = pHaloManager->getHaloSize(l, lii, ljj, lkk); + + auto* sendBuf = new SWS::RealType[hsize]; + memset(sendBuf, 0, hsize * sizeof(SWS::RealType)); + sigmaH_[SEND](sc)(lii, ljj, lkk)(l) = sendBuf; + + auto* recvBuf = new SWS::RealType[hsize]; + memset(recvBuf, 0, hsize * sizeof(SWS::RealType)); + sigmaH_[RECEIVE](sc)(lii, ljj, lkk)(l) = recvBuf; + + const auto idx = haloHandleIndex(lii, ljj, lkk, l); + starpu_vector_data_register( + &sSendHandles_[sc][idx], STARPU_MAIN_RAM, (uintptr_t)sendBuf, hsize, sizeof(SWS::RealType)); + starpu_vector_data_register( + &sRecvHandles_[sc][idx], STARPU_MAIN_RAM, (uintptr_t)recvBuf, hsize, sizeof(SWS::RealType)); + } + } + } + } + } +} + +void +SEWASStarPU::destroyVelocityArenas() +{ + for (auto d : { SWS::X, SWS::Y, SWS::Z }) { + for (int lii = 0; lii < lnxx_; lii++) { + for (int ljj = 0; ljj < lnyy_; ljj++) { + for (int lkk = 0; lkk < lnzz_; lkk++) { + for (auto l : { SWS::LEFT, SWS::RIGHT, SWS::BACKWARD, SWS::FORWARD, SWS::BOTTOM, SWS::TOP }) { + const auto idx = haloHandleIndex(lii, ljj, lkk, l); + + starpu_data_unregister(vSendHandles_[d][idx]); + starpu_data_unregister(vRecvHandles_[d][idx]); + + delete[] vH_[SEND](d)(lii, ljj, lkk)(l); + delete[] vH_[RECEIVE](d)(lii, ljj, lkk)(l); + } + } + } + } + } +} + +void +SEWASStarPU::destroyStressArenas() +{ + for (auto sc : { SWS::XX, SWS::YY, SWS::ZZ, SWS::XY, SWS::XZ, SWS::YZ }) { + for (int lii = 0; lii < lnxx_; lii++) { + for (int ljj = 0; ljj < lnyy_; ljj++) { + for (int lkk = 0; lkk < lnzz_; lkk++) { + for (auto l : { SWS::LEFT, SWS::RIGHT, SWS::BACKWARD, SWS::FORWARD, SWS::BOTTOM, SWS::TOP }) { + const auto idx = haloHandleIndex(lii, ljj, lkk, l); + + starpu_data_unregister(sSendHandles_[sc][idx]); + starpu_data_unregister(sRecvHandles_[sc][idx]); + + delete[] sigmaH_[SEND](sc)(lii, ljj, lkk)(l); + delete[] sigmaH_[RECEIVE](sc)(lii, ljj, lkk)(l); + } + } + } + } + } +} + +void +SEWASStarPU::exchangeVelocityHalo(const SWS::Directions d, const int ts) +{ + auto* pHaloManager = HaloManager::getInstance(); + auto& vH_S = vH_[SEND]; + auto& vH_R = vH_[RECEIVE]; + + for (int ii = 0; ii < nxx_; ii++) { + for (int jj = 0; jj < nyy_; jj++) { + for (int kk = 0; kk < nzz_; kk++) { + if (Mesh3DPartitioning::rank_of(ii, jj, kk) != rank_) continue; + + const int lii = ii % lnxx_; + const int ljj = jj % lnyy_; + const int lkk = kk % lnzz_; + + for (auto l : { SWS::LEFT, SWS::RIGHT, SWS::BACKWARD, SWS::FORWARD, SWS::BOTTOM, SWS::TOP }) { + int nii, njj, nkk; + if (!neighborCoords(ii, jj, kk, l, nii, njj, nkk)) { + continue; + } + + const int nrank = Mesh3DPartitioning::rank_of(nii, njj, nkk); + const auto hsize = pHaloManager->getHaloSize(l, lii, ljj, lkk); + const auto lOpp = opposite(l); + + if (nrank == rank_) { + const int nlii = nii % lnxx_, nljj = njj % lnyy_, nlkk = nkk % lnzz_; + memcpy(vH_R(d)(nlii, nljj, nlkk)(lOpp), vH_S(d)(lii, ljj, lkk)(l), hsize * sizeof(SWS::RealType)); + } else { + const auto idx = haloHandleIndex(lii, ljj, lkk, l); + + const auto outTag = makeTag(false, d, ts, ii, jj, kk, l); + starpu_mpi_isend_detached(vSendHandles_[d][idx], nrank, outTag, MPI_COMM_WORLD, nullptr, nullptr); + + const auto inTag = makeTag(false, d, ts, nii, njj, nkk, lOpp); + starpu_mpi_irecv_detached(vRecvHandles_[d][idx], nrank, inTag, MPI_COMM_WORLD, nullptr, nullptr); + } + } + } + } + } +} + +void +SEWASStarPU::exchangeStressHalo(const SWS::StressFieldComponents sc, const int ts) +{ + auto* pHaloManager = HaloManager::getInstance(); + auto& sigmaH_S = sigmaH_[SEND]; + auto& sigmaH_R = sigmaH_[RECEIVE]; + + for (int ii = 0; ii < nxx_; ii++) { + for (int jj = 0; jj < nyy_; jj++) { + for (int kk = 0; kk < nzz_; kk++) { + if (Mesh3DPartitioning::rank_of(ii, jj, kk) != rank_) continue; + + const int lii = ii % lnxx_; + const int ljj = jj % lnyy_; + const int lkk = kk % lnzz_; + + for (auto l : { SWS::LEFT, SWS::RIGHT, SWS::BACKWARD, SWS::FORWARD, SWS::BOTTOM, SWS::TOP }) { + int nii, njj, nkk; + if (!neighborCoords(ii, jj, kk, l, nii, njj, nkk)) { + continue; + } + + const int nrank = Mesh3DPartitioning::rank_of(nii, njj, nkk); + const auto hsize = pHaloManager->getHaloSize(l, lii, ljj, lkk); + const auto lOpp = opposite(l); + + if (nrank == rank_) { + const int nlii = nii % lnxx_, nljj = njj % lnyy_, nlkk = nkk % lnzz_; + memcpy( + sigmaH_R(sc)(nlii, nljj, nlkk)(lOpp), sigmaH_S(sc)(lii, ljj, lkk)(l), hsize * sizeof(SWS::RealType)); + } else { + const auto idx = haloHandleIndex(lii, ljj, lkk, l); + + const auto outTag = makeTag(true, sc, ts, ii, jj, kk, l); + starpu_mpi_isend_detached(sSendHandles_[sc][idx], nrank, outTag, MPI_COMM_WORLD, nullptr, nullptr); + + const auto inTag = makeTag(true, sc, ts, nii, njj, nkk, lOpp); + starpu_mpi_irecv_detached(sRecvHandles_[sc][idx], nrank, inTag, MPI_COMM_WORLD, nullptr, nullptr); + } + } + } + } + } +} + +void +SEWASStarPU::initializeFieldsCodelet(void* /*buffers*/[], void* cl_arg) +{ + int ii, jj, kk; + starpu_codelet_unpack_args(cl_arg, &ii, &jj, &kk); + LinearSeismicWaveModel::initializeFieldsWrapper(ii, jj, kk); +} + +void +SEWASStarPU::phaseAVelocityCodelet(void* /*buffers*/[], void* cl_arg) +{ + int ts, ii, jj, kk, lii, ljj, lkk; + starpu_codelet_unpack_args(cl_arg, &ts, &ii, &jj, &kk, &lii, &ljj, &lkk); + + auto& sigmaH_R = pInstance_->sigmaH_[RECEIVE]; + auto& vH_S = pInstance_->vH_[SEND]; + + for (auto l : { SWS::LEFT, SWS::RIGHT, SWS::BACKWARD, SWS::FORWARD, SWS::BOTTOM, SWS::TOP }) { + for (auto sc : { SWS::XX, SWS::YY, SWS::ZZ, SWS::XY, SWS::XZ, SWS::YZ }) { + HaloManager::updateStressWrapper(l, sc, ts - 1, ii, jj, kk, sigmaH_R(sc)(lii, ljj, lkk)(l)); + } + } + + for (auto d : { SWS::X, SWS::Y, SWS::Z }) { + LinearSeismicWaveModel::computeVelocityWrapper(d, ts, ii, jj, kk); + + for (auto l : { SWS::LEFT, SWS::RIGHT, SWS::BACKWARD, SWS::FORWARD, SWS::BOTTOM, SWS::TOP }) { + HaloManager::extractVelocityHaloWrapper(l, d, ts, ii, jj, kk, vH_S(d)(lii, ljj, lkk)(l)); + } + } +} + +void +SEWASStarPU::phaseBStressCodelet(void* /*buffers*/[], void* cl_arg) +{ + int ts, ii, jj, kk, lii, ljj, lkk; + starpu_codelet_unpack_args(cl_arg, &ts, &ii, &jj, &kk, &lii, &ljj, &lkk); + + auto& vH_R = pInstance_->vH_[RECEIVE]; + auto& sigmaH_S = pInstance_->sigmaH_[SEND]; + + for (auto l : { SWS::LEFT, SWS::RIGHT, SWS::BACKWARD, SWS::FORWARD, SWS::BOTTOM, SWS::TOP }) { + for (auto d : { SWS::X, SWS::Y, SWS::Z }) { + HaloManager::updateVelocityWrapper(l, d, ts, ii, jj, kk, vH_R(d)(lii, ljj, lkk)(l)); + } + } + + for (auto sc : { SWS::XX, SWS::YY, SWS::ZZ, SWS::XY, SWS::XZ, SWS::YZ }) { + LinearSeismicWaveModel::computeStressWrapper(sc, ts + 1, ii, jj, kk); + + for (auto l : { SWS::LEFT, SWS::RIGHT, SWS::BACKWARD, SWS::FORWARD, SWS::BOTTOM, SWS::TOP }) { + HaloManager::extractStressHaloWrapper(l, sc, ts + 1, ii, jj, kk, sigmaH_S(sc)(lii, ljj, lkk)(l)); + } + } +} + +int +SEWASStarPU::run() +{ + int status = 0; + + static struct starpu_codelet initCl = makeCodelet(initializeFieldsCodelet, "initializeFieldsCodelet"); + static struct starpu_codelet phaseACl = makeCodelet(phaseAVelocityCodelet, "phaseAVelocityCodelet"); + static struct starpu_codelet phaseBCl = makeCodelet(phaseBStressCodelet, "phaseBStressCodelet"); + + auto forEachLocalTile = [this](auto&& fn) { + for (int ii = 0; ii < nxx_; ii++) { + for (int jj = 0; jj < nyy_; jj++) { + for (int kk = 0; kk < nzz_; kk++) { + if (Mesh3DPartitioning::rank_of(ii, jj, kk) != rank_) continue; + fn(ii, jj, kk, ii % lnxx_, jj % lnyy_, kk % lnzz_); + } + } + } + }; + + forEachLocalTile([&](int ii, int jj, int kk, int /*lii*/, int /*ljj*/, int /*lkk*/) { + starpu_task_insert(&initCl, + STARPU_VALUE, &ii, sizeof(ii), + STARPU_VALUE, &jj, sizeof(jj), + STARPU_VALUE, &kk, sizeof(kk), + 0); + }); + starpu_task_wait_for_all(); + + for (int ts = 2; ts <= nt_ - 2; ts += 2) { + LOG(SWS::LOG_TRACE, "[start] Processing time-step {}", ts); + + forEachLocalTile([&](int ii, int jj, int kk, int lii, int ljj, int lkk) { + starpu_task_insert(&phaseACl, + STARPU_VALUE, &ts, sizeof(ts), + STARPU_VALUE, &ii, sizeof(ii), + STARPU_VALUE, &jj, sizeof(jj), + STARPU_VALUE, &kk, sizeof(kk), + STARPU_VALUE, &lii, sizeof(lii), + STARPU_VALUE, &ljj, sizeof(ljj), + STARPU_VALUE, &lkk, sizeof(lkk), + 0); + }); + starpu_task_wait_for_all(); + + for (auto d : { SWS::X, SWS::Y, SWS::Z }) { + exchangeVelocityHalo(d, ts); + } + starpu_mpi_wait_for_all(MPI_COMM_WORLD); + + forEachLocalTile([&](int ii, int jj, int kk, int lii, int ljj, int lkk) { + starpu_task_insert(&phaseBCl, + STARPU_VALUE, &ts, sizeof(ts), + STARPU_VALUE, &ii, sizeof(ii), + STARPU_VALUE, &jj, sizeof(jj), + STARPU_VALUE, &kk, sizeof(kk), + STARPU_VALUE, &lii, sizeof(lii), + STARPU_VALUE, &ljj, sizeof(ljj), + STARPU_VALUE, &lkk, sizeof(lkk), + 0); + }); + starpu_task_wait_for_all(); + + for (auto sc : { SWS::XX, SWS::YY, SWS::ZZ, SWS::XY, SWS::XZ, SWS::YZ }) { + exchangeStressHalo(sc, ts); + } + starpu_mpi_wait_for_all(MPI_COMM_WORLD); + + LOG(SWS::LOG_TRACE, "[stop] Processing time-step {}", ts); + } + + return status; +} + +SEWASStarPU::SEWASStarPU(const int nt, const int nxx, const int nyy, const int nzz) + : nt_(nt) + , nxx_(nxx) + , nyy_(nyy) + , nzz_(nzz) +{ + world_ = ExecutionContext::world(); + rank_ = ExecutionContext::rank(); + + auto* pMesh = Mesh3DPartitioning::getInstance(); + lnxx_ = pMesh->lnxx(); + lnyy_ = pMesh->lnyy(); + lnzz_ = pMesh->lnzz(); + + /* Evaluate task priorities: currently unused by this phase-barrier design (there is + * no cross-phase overlap left to schedule around), kept for parity with SEWASPaRSEC + * and as a hook for future, finer-grained pipelining. */ + pMesh->getTaskPriorityManager()->evaluate(); + + buildVelocityArenas(); + buildStressArenas(); +} + +SEWASStarPU::~SEWASStarPU() +{ + destroyVelocityArenas(); + destroyStressArenas(); +} + +#endif // SEWAS_WITH_STARPU diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bb4cda1..8850177 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -38,6 +38,7 @@ add_executable(ComputeVelocityTest ../src/Mesh3DPartitioning.cxx ../src/SEWASParameterManager.cxx ../src/SEWASPaRSEC.cxx + ../src/SEWASStarPU.cxx ../src/SEWASSequential.cxx ../src/ExecutionContext.cxx ../src/MetricsManager.cxx From f32a0d82e5219606ae40237e431c9bf34e972ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 24 Aug 2026 13:32:49 +0200 Subject: [PATCH 13/18] feat: wire task priorities into SEWASStarPU --- src/SEWASStarPU.cxx | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/SEWASStarPU.cxx b/src/SEWASStarPU.cxx index 59cf399..39a86cc 100644 --- a/src/SEWASStarPU.cxx +++ b/src/SEWASStarPU.cxx @@ -20,6 +20,7 @@ #ifdef SEWAS_WITH_STARPU +#include #include #include "ExecutionContext.hxx" @@ -39,6 +40,18 @@ makeCodelet(void (*func)(void*[], void*), const char* name) cl.nbuffers = 0; return cl; } + +/* Clamp into StarPU's currently valid priority range: the active scheduling + * policy may support only a single priority level (or a narrower range than + * MinimumCommunicationPriorityEvaluator's raw output), and starpu_task_insert + * gives no other feedback for an out-of-range value. */ +int +clampPriority(const int priority) noexcept +{ + const int minPrio = starpu_sched_get_min_priority(); + const int maxPrio = starpu_sched_get_max_priority(); + return (std::max)(minPrio, (std::min)(maxPrio, priority)); +} } SEWASStarPU* SEWASStarPU::pInstance_ = nullptr; @@ -459,6 +472,8 @@ SEWASStarPU::run() static struct starpu_codelet phaseACl = makeCodelet(phaseAVelocityCodelet, "phaseAVelocityCodelet"); static struct starpu_codelet phaseBCl = makeCodelet(phaseBStressCodelet, "phaseBStressCodelet"); + auto* pPriorityManager = Mesh3DPartitioning::getInstance()->getTaskPriorityManager(); + auto forEachLocalTile = [this](auto&& fn) { for (int ii = 0; ii < nxx_; ii++) { for (int jj = 0; jj < nyy_; jj++) { @@ -471,10 +486,12 @@ SEWASStarPU::run() }; forEachLocalTile([&](int ii, int jj, int kk, int /*lii*/, int /*ljj*/, int /*lkk*/) { + const auto prio = clampPriority(pPriorityManager->getPriority(INITIALIZE_FIELDS, 0, ii, jj, kk)); starpu_task_insert(&initCl, STARPU_VALUE, &ii, sizeof(ii), STARPU_VALUE, &jj, sizeof(jj), STARPU_VALUE, &kk, sizeof(kk), + STARPU_PRIORITY, (unsigned long long)prio, 0); }); starpu_task_wait_for_all(); @@ -483,6 +500,13 @@ SEWASStarPU::run() LOG(SWS::LOG_TRACE, "[start] Processing time-step {}", ts); forEachLocalTile([&](int ii, int jj, int kk, int lii, int ljj, int lkk) { + /* Bundles UPDATE_STRESS + COMPUTE_VELOCITY + EXTRACT_VELOCITY_HALO into one + * task; take the most urgent of the three sub-steps' priorities. */ + const auto prio = clampPriority((std::max)({ + pPriorityManager->getPriority(UPDATE_STRESS, ts, ii, jj, kk), + pPriorityManager->getPriority(COMPUTE_VELOCITY, ts, ii, jj, kk), + pPriorityManager->getPriority(EXTRACT_VELOCITY_HALO, ts, ii, jj, kk), + })); starpu_task_insert(&phaseACl, STARPU_VALUE, &ts, sizeof(ts), STARPU_VALUE, &ii, sizeof(ii), @@ -491,6 +515,7 @@ SEWASStarPU::run() STARPU_VALUE, &lii, sizeof(lii), STARPU_VALUE, &ljj, sizeof(ljj), STARPU_VALUE, &lkk, sizeof(lkk), + STARPU_PRIORITY, (unsigned long long)prio, 0); }); starpu_task_wait_for_all(); @@ -501,6 +526,13 @@ SEWASStarPU::run() starpu_mpi_wait_for_all(MPI_COMM_WORLD); forEachLocalTile([&](int ii, int jj, int kk, int lii, int ljj, int lkk) { + /* Bundles UPDATE_VELOCITY + COMPUTE_STRESS + EXTRACT_STRESS_HALO into one + * task; take the most urgent of the three sub-steps' priorities. */ + const auto prio = clampPriority((std::max)({ + pPriorityManager->getPriority(UPDATE_VELOCITY, ts, ii, jj, kk), + pPriorityManager->getPriority(COMPUTE_STRESS, ts, ii, jj, kk), + pPriorityManager->getPriority(EXTRACT_STRESS_HALO, ts, ii, jj, kk), + })); starpu_task_insert(&phaseBCl, STARPU_VALUE, &ts, sizeof(ts), STARPU_VALUE, &ii, sizeof(ii), @@ -509,6 +541,7 @@ SEWASStarPU::run() STARPU_VALUE, &lii, sizeof(lii), STARPU_VALUE, &ljj, sizeof(ljj), STARPU_VALUE, &lkk, sizeof(lkk), + STARPU_PRIORITY, (unsigned long long)prio, 0); }); starpu_task_wait_for_all(); From 812cdbd263eff19d95ff82ab465aa9602efb8b94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 24 Aug 2026 14:07:41 +0200 Subject: [PATCH 14/18] build: auto-download and build StarPU when not found via pkg-config --- .gitignore | 2 ++ CMakeLists.txt | 38 +++++++++++++++++++++++---- cmake/resources/starpu/CMakeLists.txt | 31 ++++++++++++++++++++++ 3 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 cmake/resources/starpu/CMakeLists.txt diff --git a/.gitignore b/.gitignore index c4fab6b..e844a67 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,8 @@ doc/* /thirdparty/parsec/build /thirdparty/adios/src /thirdparty/adios/build +/thirdparty/starpu/src +/thirdparty/starpu/build /thirdparty/install /out /.vs/SeWaS/v16/.suo diff --git a/CMakeLists.txt b/CMakeLists.txt index 229553a..a65be4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -373,13 +373,41 @@ if(SEWAS_WITH_STARPU) find_package(PkgConfig REQUIRED) set(STARPU_PC_VERSION "1.4" CACHE STRING "StarPU pkg-config version suffix") + + # Also look under the same install prefix vcpkg-downloaded/built dependencies + # (PaRSEC, ADIOS2, ...) land in, in case a previous DOWNLOAD_MISSING_DEPS run + # already built StarPU there. + set(ENV{PKG_CONFIG_PATH} "${THIRDPARTY_ROOT}/install/lib/pkgconfig:${THIRDPARTY_ROOT}/install/lib64/pkgconfig:$ENV{PKG_CONFIG_PATH}") pkg_check_modules(STARPU starpumpi-${STARPU_PC_VERSION}) + if (NOT STARPU_FOUND) - message(FATAL_ERROR "StarPU (starpumpi-${STARPU_PC_VERSION}) not found via pkg-config. " - "Install it (e.g. 'apt install libstarpu-dev' on Debian/Ubuntu, or build it " - "via Spack) and make sure its .pc files are on PKG_CONFIG_PATH. " - "Automatic download of StarPU is not currently supported.") - endif() + message(WARNING "StarPU not found") + if (DOWNLOAD_MISSING_DEPS) + # StarPU not found; trying to download and build it (autotools-based, + # see cmake/resources/starpu/CMakeLists.txt) + set(STARPU_DOWNLOAD_ROOT ${THIRDPARTY_ROOT}/starpu) + configure_file(${CMAKE_SOURCE_DIR}/cmake/resources/starpu/CMakeLists.txt ${STARPU_DOWNLOAD_ROOT}/build/starpu-download/CMakeLists.txt) + execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . + RESULT_VARIABLE result + WORKING_DIRECTORY ${STARPU_DOWNLOAD_ROOT}/build/starpu-download) + if(result) + message(FATAL_ERROR "CMake step for starpu failed: ${result}") + endif() + execute_process(COMMAND ${CMAKE_COMMAND} --build . + RESULT_VARIABLE result + WORKING_DIRECTORY ${STARPU_DOWNLOAD_ROOT}/build/starpu-download) + if(result) + message(FATAL_ERROR "Build step for starpu failed: ${result}") + endif() + + pkg_check_modules(STARPU REQUIRED starpumpi-${STARPU_PC_VERSION}) + else(DOWNLOAD_MISSING_DEPS) + message(FATAL_ERROR "StarPU (starpumpi-${STARPU_PC_VERSION}) not found via pkg-config. " + "Install it (e.g. 'apt install libstarpu-dev' on Debian/Ubuntu, or build it " + "via Spack) and make sure its .pc files are on PKG_CONFIG_PATH, or set " + "DOWNLOAD_MISSING_DEPS for enabling automatic download of missing dependencies") + endif(DOWNLOAD_MISSING_DEPS) + endif(NOT STARPU_FOUND) message(STATUS "StarPU found") message(STATUS " STARPU_INCLUDE_DIRS = ${STARPU_INCLUDE_DIRS}") diff --git a/cmake/resources/starpu/CMakeLists.txt b/cmake/resources/starpu/CMakeLists.txt new file mode 100644 index 0000000..571b5ea --- /dev/null +++ b/cmake/resources/starpu/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.10.3) + +project(starpu-download) + +include(ExternalProject) + +if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") + # Release tarball (ships a pre-generated `configure`, so no autoreconf/automake/ + # libtool is required at build time). Version/hash pinned to StarPU 1.4.7. + ExternalProject_Add(starpu + URL https://files.inria.fr/starpu/starpu-1.4.7/starpu-1.4.7.tar.gz + URL_HASH SHA256=1eb3df551089153fe6e0b172ad95118434b4a81ea9eaa5a2c38725d0db53b13e + SOURCE_DIR "${STARPU_DOWNLOAD_ROOT}/src" + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND /configure + --prefix=${THIRDPARTY_ROOT}/install + --with-mpicc=${MPI_C_COMPILER} + --with-mpicxx=${MPI_CXX_COMPILER} + --disable-build-tests + --disable-build-examples + --disable-build-doc + --disable-fortran + --disable-cuda + --disable-opencl + BUILD_COMMAND make -j + INSTALL_COMMAND make install + TEST_COMMAND "" + ) +else() + message(FATAL_ERROR "StarPU based version of SeWaS is not yet available on this system: ${CMAKE_SYSTEM_NAME}") +endif() From fb316a3c8e115349bb06e44acbd6813c15b198a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 24 Aug 2026 14:22:32 +0200 Subject: [PATCH 15/18] ci: switch Linux CI's distributed backend from PaRSEC to StarPU Drops the now-unneeded flex/bison install step (only needed for PaRSEC's parsec-ptgpp JDF compiler) and updates README.md/CLAUDE.md to match. --- .github/workflows/Linux.yml | 3 +-- README.md | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/Linux.yml b/.github/workflows/Linux.yml index 644589a..ed64e16 100644 --- a/.github/workflows/Linux.yml +++ b/.github/workflows/Linux.yml @@ -19,13 +19,12 @@ jobs: sudo apt-get install libopenmpi-dev openmpi-common sudo apt-get install libeigen3-dev sudo apt-get install libspdlog-dev - sudo apt-get install flex bison - name: bootstrap run: . bootstrap.sh - name: configure - run: mkdir build && cd build && cmake .. -DBUILD_TESTING=ON -DCOLLECT_STATS=ON -DSEWAS_DISTRIBUTED=ON -DSEWAS_WITH_PARSEC=ON -DVERBOSE=ON && cd - + run: mkdir build && cd build && cmake .. -DBUILD_TESTING=ON -DCOLLECT_STATS=ON -DSEWAS_DISTRIBUTED=ON -DSEWAS_WITH_STARPU=ON -DVERBOSE=ON && cd - - name: build run: cmake --build build --config Release diff --git a/README.md b/README.md index ba8ad4b..a4cf8d5 100644 --- a/README.md +++ b/README.md @@ -282,7 +282,8 @@ Those visualization tasks interact with [VTK](http://www.vtk.org/) actors to ren # Building and installing SeWaS is a CMake project. Its dependencies (Boost `program_options`, Eigen3, spdlog, and — for -distributed/PaRSEC builds — OpenMPI and PaRSEC) are resolved automatically at configure time through +distributed builds — OpenMPI plus PaRSEC or StarPU, depending on which task-based scheduler is +selected) are resolved automatically at configure time through [vcpkg](https://github.com/microsoft/vcpkg), vendored under `thirdparty/vcpkg`, so there is no dependency installation step to perform by hand. It has been validated on Linux (Ubuntu/Debian-like, via CI) and Windows; a C++17 compiler and CMake 3.10.3+ are required either way. @@ -292,7 +293,8 @@ Windows; a C++17 compiler and CMake 3.10.3+ are required either way. Only build tooling that vcpkg itself cannot provide needs to be present on the system beforehand: + Linux: a C++17 compiler (gcc/clang), CMake, and — only when building with `-DSEWAS_WITH_PARSEC=ON`, - since PaRSEC's JDF files are compiled with `parsec-ptgpp` — `flex` and `bison`: + since PaRSEC's JDF files are compiled with `parsec-ptgpp` — `flex` and `bison`. `-DSEWAS_WITH_STARPU=ON` + needs no extra tooling beyond that: ```sh sudo apt-get install build-essential cmake flex bison ``` @@ -313,15 +315,15 @@ bootstrap.bat # Windows ```sh mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release \ - -DSEWAS_DISTRIBUTED=ON -DSEWAS_WITH_PARSEC=ON \ + -DSEWAS_DISTRIBUTED=ON -DSEWAS_WITH_STARPU=ON \ -DBUILD_TESTING=ON -DCOLLECT_STATS=ON -DVERBOSE=ON ``` -`SEWAS_DISTRIBUTED` enables MPI-based distributed execution, and `SEWAS_WITH_PARSEC` (which requires it) -enables the PaRSEC task-based scheduler; both are ON in Linux CI, and Windows CI builds with both OFF. With -`DOWNLOAD_MISSING_DEPS` on (the default), CMake will download and build any of the above dependencies not -already found on the system — expect the first configure to take a while, since it also builds PaRSEC from -source. +`SEWAS_DISTRIBUTED` enables MPI-based distributed execution, and `SEWAS_WITH_STARPU`/`SEWAS_WITH_PARSEC` +(mutually exclusive, each requiring it) select the task-based scheduler. Linux CI builds +`SEWAS_DISTRIBUTED`+`SEWAS_WITH_STARPU`; Windows CI builds with both OFF. With `DOWNLOAD_MISSING_DEPS` on +(the default), CMake will download and build any of the above dependencies not already found on the +system — expect the first configure to take a while, since it also builds StarPU (or PaRSEC) from source. Other build options (all defined at the top of `CMakeLists.txt` and OFF unless noted) let you tune what gets compiled in: From 8860d409d4848fd18108205ffdec704703006403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 24 Aug 2026 15:04:20 +0200 Subject: [PATCH 16/18] build: pin vcpkg eigen3 overlay port to 3.4.1 to fix Windows CI configure failure --- CMakeLists.txt | 7 +++ .../vcpkg/overlay-ports/eigen3/portfile.cmake | 50 +++++++++++++++++++ .../vcpkg/overlay-ports/eigen3/vcpkg.json | 18 +++++++ 3 files changed, 75 insertions(+) create mode 100644 cmake/resources/vcpkg/overlay-ports/eigen3/portfile.cmake create mode 100644 cmake/resources/vcpkg/overlay-ports/eigen3/vcpkg.json diff --git a/CMakeLists.txt b/CMakeLists.txt index a65be4c..814cdea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,10 +78,17 @@ if (DOWNLOAD_MISSING_DEPS) set(TARGET_PLATFORM "${HOST_ARCH}-${SYSTEM_NAME}") + # Ports pinned here to a version older than what the vcpkg commit above ships by + # default, because SEWAS' find_package() calls require compatibility with an older + # version than what is currently in the upstream port tree (e.g. eigen3 defaults to + # a 5.x release, which find_package(Eigen3 3.3.3) rejects as incompatible). + set(VCPKG_OVERLAY_PORTS_DIR ${CMAKE_SOURCE_DIR}/cmake/resources/vcpkg/overlay-ports) + # define helper macro for downloading packages through vpckg macro(_vcpkg_install package) message("[VCPKG] Installing package : ${package}:${TARGET_PLATFORM}") execute_process(COMMAND ${VCPKG_EXE} install ${package}:${TARGET_PLATFORM} + --overlay-ports=${VCPKG_OVERLAY_PORTS_DIR} RESULT_VARIABLE STATUS WORKING_DIRECTORY ${VCPKG_ROOT}) if (STATUS) diff --git a/cmake/resources/vcpkg/overlay-ports/eigen3/portfile.cmake b/cmake/resources/vcpkg/overlay-ports/eigen3/portfile.cmake new file mode 100644 index 0000000..b8a9be6 --- /dev/null +++ b/cmake/resources/vcpkg/overlay-ports/eigen3/portfile.cmake @@ -0,0 +1,50 @@ +vcpkg_buildpath_length_warning(37) + +vcpkg_from_gitlab( + GITLAB_URL https://gitlab.com + OUT_SOURCE_PATH SOURCE_PATH + REPO libeigen/eigen + REF ${VERSION} + SHA512 15b540d2fad25de837d7612456ea65b7fcfa25f886c48dcb3de025e079f5f43f45f1c0bd9a8435430d0e2fb9f0a6129719626dd4fd45dc61fc480f97762b2f56 + HEAD_REF master +) + +vcpkg_cmake_configure( + SOURCE_PATH "${SOURCE_PATH}" + OPTIONS + -DBUILD_TESTING=OFF + -DEIGEN_BUILD_BLAS=OFF + -DEIGEN_BUILD_BTL=OFF + -DEIGEN_BUILD_CMAKE_PACKAGE=ON + -DEIGEN_BUILD_DEMOS=OFF + -DEIGEN_BUILD_DOC=OFF + -DEIGEN_BUILD_LAPACK=OFF + -DEIGEN_BUILD_PKGCONFIG=ON + -DEIGEN_BUILD_SPBENCH=OFF + OPTIONS_RELEASE + "-DCMAKEPACKAGE_INSTALL_DIR=${CURRENT_PACKAGES_DIR}/share/${PORT}" + "-DPKGCONFIG_INSTALL_DIR=${CURRENT_PACKAGES_DIR}/lib/pkgconfig" + OPTIONS_DEBUG + "-DCMAKEPACKAGE_INSTALL_DIR=${CURRENT_PACKAGES_DIR}/debug/share/${PORT}" + "-DPKGCONFIG_INSTALL_DIR=${CURRENT_PACKAGES_DIR}/debug/lib/pkgconfig" +) + +vcpkg_cmake_install() +vcpkg_cmake_config_fixup() + +vcpkg_fixup_pkgconfig() + +# Copy the eigen header files to conventional location for user-wide MSBuild integration +file(GLOB INCLUDES ${CURRENT_PACKAGES_DIR}/include/eigen3/*) +file(COPY ${INCLUDES} DESTINATION ${CURRENT_PACKAGES_DIR}/include) + +file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include" "${CURRENT_PACKAGES_DIR}/debug/share") + +vcpkg_install_copyright( + FILE_LIST + "${SOURCE_PATH}/COPYING.README" + "${SOURCE_PATH}/COPYING.APACHE" + "${SOURCE_PATH}/COPYING.BSD" + "${SOURCE_PATH}/COPYING.MINPACK" + "${SOURCE_PATH}/COPYING.MPL2" +) diff --git a/cmake/resources/vcpkg/overlay-ports/eigen3/vcpkg.json b/cmake/resources/vcpkg/overlay-ports/eigen3/vcpkg.json new file mode 100644 index 0000000..a43dc8c --- /dev/null +++ b/cmake/resources/vcpkg/overlay-ports/eigen3/vcpkg.json @@ -0,0 +1,18 @@ +{ + "name": "eigen3", + "version": "3.4.1", + "port-version": 1, + "description": "C++ template library for linear algebra: matrices, vectors, numerical solvers, and related algorithms.", + "homepage": "http://eigen.tuxfamily.org", + "license": "MPL-2.0", + "dependencies": [ + { + "name": "vcpkg-cmake", + "host": true + }, + { + "name": "vcpkg-cmake-config", + "host": true + } + ] +} From 4bf42431c4237c3c67455e7c6ac2302663b4ae0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 24 Aug 2026 15:22:57 +0200 Subject: [PATCH 17/18] fix: cast enum args to int before formatting to fix Windows CI fmt/spdlog compile errors --- include/CentralFDOperator.hxx | 2 +- include/LogManager.hxx | 2 +- include/SEWASSequential.hxx | 8 ++++++-- src/HaloManager.cxx | 10 +++++++--- src/IOManager.cxx | 8 ++++---- src/LinearSeismicWaveModel.cxx | 6 +++--- src/SEWASStarPU.cxx | 6 ++++-- 7 files changed, 26 insertions(+), 16 deletions(-) diff --git a/include/CentralFDOperator.hxx b/include/CentralFDOperator.hxx index 45b198a..228cee0 100644 --- a/include/CentralFDOperator.hxx +++ b/include/CentralFDOperator.hxx @@ -204,7 +204,7 @@ public: default: LOG(SWS::LOG_ERROR, "Unknown direction {} requested within CentralFDOperator::apply()", - d); + static_cast(d)); break; } diff --git a/include/LogManager.hxx b/include/LogManager.hxx index 8ad0895..4ccbd04 100644 --- a/include/LogManager.hxx +++ b/include/LogManager.hxx @@ -71,7 +71,7 @@ public: default: logger_->warn("The selected log level ({}) is not supported. Fall back " "to INFO level.", - level); + static_cast(level)); logger_->info(msg...); break; } diff --git a/include/SEWASSequential.hxx b/include/SEWASSequential.hxx index 1dfa1f7..c10b892 100644 --- a/include/SEWASSequential.hxx +++ b/include/SEWASSequential.hxx @@ -131,7 +131,9 @@ private: } break; default: - LOG(SWS::LOG_ERROR, "Unknown location {} requested within SEWASSequential::sendreceive()", l); + LOG(SWS::LOG_ERROR, + "Unknown location {} requested within SEWASSequential::sendreceive()", + static_cast(l)); break; } @@ -183,7 +185,9 @@ private: } break; default: - LOG(SWS::LOG_ERROR, "Unknown location {} requested within SEWASSequential::sendreceive()", l); + LOG(SWS::LOG_ERROR, + "Unknown location {} requested within SEWASSequential::sendreceive()", + static_cast(l)); } return status; diff --git a/src/HaloManager.cxx b/src/HaloManager.cxx index e31ef49..7aedf75 100644 --- a/src/HaloManager.cxx +++ b/src/HaloManager.cxx @@ -173,7 +173,7 @@ HaloManager::getHaloSize(const SWS::Locations l, const int ii, const int jj, con hs = cx * cy * hnz_; break; default: - LOG(SWS::LOG_ERROR, "Unknown location {} requested within HaloManager::getHaloSize()", l); + LOG(SWS::LOG_ERROR, "Unknown location {} requested within HaloManager::getHaloSize()", static_cast(l)); break; } @@ -431,7 +431,9 @@ HaloManager::setExtractOffsets(const SWS::Locations l, kShift = kEnd - hnz_; break; default: - LOG(SWS::LOG_ERROR, "Unknown halo location {} requested within HaloManager::setExtractOffsets()", l); + LOG(SWS::LOG_ERROR, + "Unknown halo location {} requested within HaloManager::setExtractOffsets()", + static_cast(l)); break; } } @@ -499,7 +501,9 @@ HaloManager::setUpdateOffsets(const SWS::Locations l, kShift = kEnd; break; default: - LOG(SWS::LOG_ERROR, "Unknown halo location {} requested within HaloManager::setUpdateOffsets()", l); + LOG(SWS::LOG_ERROR, + "Unknown halo location {} requested within HaloManager::setUpdateOffsets()", + static_cast(l)); break; } } diff --git a/src/IOManager.cxx b/src/IOManager.cxx index 81b0776..1e1be68 100644 --- a/src/IOManager.cxx +++ b/src/IOManager.cxx @@ -65,7 +65,7 @@ IOManager::dumpVelocity(const SWS::Directions d, const int ts, const int ii, con int status = 0; #ifdef ENABLE_IO - LOG(SWS::LOG_DEBUG, "[start] Dumping v({})({},{},{}) at ts={}", d, ii, jj, kk, ts); + LOG(SWS::LOG_DEBUG, "[start] Dumping v({})({},{},{}) at ts={}", static_cast(d), ii, jj, kk, ts); const auto& tile3D = LinearSeismicWaveModel::getInstance()->v(d)(ii, jj, kk); @@ -77,7 +77,7 @@ IOManager::dumpVelocity(const SWS::Directions d, const int ts, const int ii, con status = dumpTile(velocityWriter_, tile3D, tileID); } - LOG(SWS::LOG_DEBUG, "[stop] Dumping v({})({},{},{}) at ts={}", d, ii, jj, kk, ts); + LOG(SWS::LOG_DEBUG, "[stop] Dumping v({})({},{},{}) at ts={}", static_cast(d), ii, jj, kk, ts); #endif return status; @@ -105,7 +105,7 @@ IOManager::dumpStress(const SWS::StressFieldComponents sc, int status = 0; #ifdef ENABLE_IO - LOG(SWS::LOG_DEBUG, "[start] Dumping sigma({})({},{},{}) at ts={}", sc, ii, jj, kk, ts); + LOG(SWS::LOG_DEBUG, "[start] Dumping sigma({})({},{},{}) at ts={}", static_cast(sc), ii, jj, kk, ts); const auto& tile3D = LinearSeismicWaveModel::getInstance()->sigma(sc)(ii, jj, kk); @@ -117,7 +117,7 @@ IOManager::dumpStress(const SWS::StressFieldComponents sc, status = dumpTile(stressWriter_, tile3D, tileID); } - LOG(SWS::LOG_DEBUG, "[stop] Dumping sigma({})({},{},{}) at ts={}", sc, ii, jj, kk, ts); + LOG(SWS::LOG_DEBUG, "[stop] Dumping sigma({})({},{},{}) at ts={}", static_cast(sc), ii, jj, kk, ts); #endif return status; diff --git a/src/LinearSeismicWaveModel.cxx b/src/LinearSeismicWaveModel.cxx index 8880f8c..b030a57 100644 --- a/src/LinearSeismicWaveModel.cxx +++ b/src/LinearSeismicWaveModel.cxx @@ -326,7 +326,7 @@ LinearSeismicWaveModel::computeVelocity(const SWS::Directions& d, default: LOG(SWS::LOG_ERROR, "Unknown spatial direction {} requested within LinearSeismicWaveModel::computeVelocity()", - d); + static_cast(d)); break; } @@ -628,7 +628,7 @@ LinearSeismicWaveModel::computeStress(const SWS::StressFieldComponents& sc, default: LOG(SWS::LOG_ERROR, "Unknown stress component {} requested within LinearSeismicWaveModel::computeStress()", - sc); + static_cast(sc)); break; } @@ -726,7 +726,7 @@ LinearSeismicWaveModel::addVelocitySource(const SWS::Directions& d, default: LOG(SWS::LOG_ERROR, "Unknown spatial direction {} requested within LinearSeismicWaveModel::addVelocitySource()", - d); + static_cast(d)); break; } } diff --git a/src/SEWASStarPU.cxx b/src/SEWASStarPU.cxx index 39a86cc..7eb235d 100644 --- a/src/SEWASStarPU.cxx +++ b/src/SEWASStarPU.cxx @@ -167,7 +167,9 @@ SEWASStarPU::neighborCoords(const int ii, nkk = kk + 1; break; default: - LOG(SWS::LOG_ERROR, "Unknown location {} requested within SEWASStarPU::neighborCoords()", l); + LOG(SWS::LOG_ERROR, + "Unknown location {} requested within SEWASStarPU::neighborCoords()", + static_cast(l)); return false; } @@ -191,7 +193,7 @@ SEWASStarPU::opposite(const SWS::Locations l) noexcept case SWS::TOP: return SWS::BOTTOM; default: - LOG(SWS::LOG_ERROR, "Unknown location {} requested within SEWASStarPU::opposite()", l); + LOG(SWS::LOG_ERROR, "Unknown location {} requested within SEWASStarPU::opposite()", static_cast(l)); return SWS::NB_LOCATIONS; } } From 232258694738d11ef85175d435cb253220dec027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Mon, 24 Aug 2026 15:36:39 +0200 Subject: [PATCH 18/18] fix: cast remaining Locations/Directions/StressFieldComponents enum args to int in HaloManager LOG calls for Windows CI --- src/HaloManager.cxx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/HaloManager.cxx b/src/HaloManager.cxx index 7aedf75..11782dd 100644 --- a/src/HaloManager.cxx +++ b/src/HaloManager.cxx @@ -268,8 +268,8 @@ HaloManager::extractStressHalo(const SWS::Locations l, // MetricsManager::getInstance()->start("ExtractStressHalo"); LOG(SWS::LOG_TRACE, "[start] Extracting ({},{})-stress halo at time-step {} on tile ({}, {}, {})", - l, - sc, + static_cast(l), + static_cast(sc), ts, ii, jj, @@ -302,8 +302,8 @@ HaloManager::extractStressHalo(const SWS::Locations l, // MetricsManager::getInstance()->stop("ExtractStressHalo"); LOG(SWS::LOG_TRACE, "[stop] Extracting ({},{})-stress halo at time-step {} on tile ({}, {}, {})", - l, - sc, + static_cast(l), + static_cast(sc), ts, ii, jj, @@ -323,8 +323,8 @@ HaloManager::extractVelocityHalo(const SWS::Locations l, // MetricsManager::getInstance()->start("ExtractVelocityHalo"); LOG(SWS::LOG_TRACE, "[start] Extracting ({},{})-velocity halo at time-step {} on tile ({}, {}, {})", - l, - d, + static_cast(l), + static_cast(d), ts, ii, jj, @@ -358,8 +358,8 @@ HaloManager::extractVelocityHalo(const SWS::Locations l, // MetricsManager::getInstance()->stop("ExtractVelocityHalo"); LOG(SWS::LOG_TRACE, "[stop] Extracting ({},{})-velocity halo at time-step {} on tile ({}, {}, {})", - l, - d, + static_cast(l), + static_cast(d), ts, ii, jj,