From 49a5cf4f66bbf189b5619a796f235bce1613f8d7 Mon Sep 17 00:00:00 2001 From: Ian Henriksen Date: Tue, 6 May 2025 11:05:52 -0600 Subject: [PATCH 1/6] Test with gcc 15 in CI. --- .circleci/config.yml | 72 ++++++++++++++++++++++++---------------- .cirrus.yml | 4 +-- .github/workflows/CI.yml | 52 +++++++++++++++++------------ 3 files changed, 75 insertions(+), 53 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index adb8304db..8319d3037 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,32 +8,35 @@ jobs: type: string topology: type: string - machine: - image: ubuntu-2404:edge + #machine: + # image: ubuntu-2504:edge + docker: + - image: ubuntu:25.04 resource_class: arm.medium environment: - CC: gcc-14 - CXX: g++-14 + CC: gcc-15 + CXX: g++-15 steps: - run: | + apt-get update + apt-get install -y sudo + sudo apt-get install -y git # Updating and installing sudo and git is only neccesary in a container. + # Installing sudo is just so that the later commands using sudo can be the same whether in a container or not. export REPO_HTTPS=`echo "$CIRCLE_REPOSITORY_URL" | sed "s|git@github.com:|https://github.com/|g"` git clone -b "$CIRCLE_BRANCH" "$REPO_HTTPS" . --depth=1 - run: | - sudo apt-add-repository -y universe - sudo apt-get install -y gcc-14 g++-14 + sudo apt-get install -y gcc-15 g++-15 sudo apt-get install -y cmake sudo apt-get install -y hwloc libhwloc-dev - run: | mkdir build - pushd build + cd build cmake -DCMAKE_BUILD_TYPE=Release -DQTHREADS_SCHEDULER=<< parameters.scheduler >> -DQTHREADS_TOPOLOGY=<< parameters.topology >> .. make -j2 VERBOSE=1 - popd - run: command: | - pushd build + cd build CTEST_OUTPUT_ON_FAILURE=1 timeout --foreground -k 10s 2m make test VERBOSE=1 - popd no_output_timeout: 180s arm_clang: @@ -42,35 +45,40 @@ jobs: type: string topology: type: string - machine: - image: ubuntu-2404:edge + #machine: + # image: ubuntu-2504:edge + docker: + - image: ubuntu:25.04 resource_class: arm.medium environment: CC: clang-20 CXX: clang++-20 steps: - run: | + apt-get update + apt-get install -y sudo + sudo apt-get install -y git # Updating and installing sudo and git is only neccesary in a container. + # Installing sudo is just so that the later commands using sudo can be the same whether in a container or not. export REPO_HTTPS=`echo "$CIRCLE_REPOSITORY_URL" | sed "s|git@github.com:|https://github.com/|g"` git clone -b "$CIRCLE_BRANCH" "$REPO_HTTPS" . --depth=1 - run: | - sudo apt-add-repository -y universe - sudo apt-get install -y gcc-14 g++-14 + sudo apt-get install -y gnupg wget # Only needed in container. + sudo apt-get install -y gcc-15 g++-15 sudo apt-get install -y cmake sudo apt-get install -y hwloc libhwloc-dev - wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - - sudo apt-add-repository -y 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-20 main' + # tzdata is required by clang and has to be installed carefully to avoid user prompts stalling the script. + ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime + DEBIAN_FRONTEND=noninteractive sudo apt-get install -y --no-install-recommends tzdata sudo apt-get install -y clang-20 - run: | mkdir build - pushd build + cd build cmake -DCMAKE_BUILD_TYPE=Release -DQTHREADS_SCHEDULER=<< parameters.scheduler >> -DQTHREADS_TOPOLOGY=<< parameters.topology >> .. make -j2 VERBOSE=1 - popd - run: command: | - pushd build + cd build CTEST_OUTPUT_ON_FAILURE=1 timeout --foreground -k 10s 2m make test VERBOSE=1 - popd no_output_timeout: 180s arm_sanitizers: @@ -81,8 +89,10 @@ jobs: type: string sanitizer: type: string - machine: - image: ubuntu-2404:edge + #machine: + # image: ubuntu-2504:edge + docker: + - image: ubuntu:25.04 resource_class: arm.medium environment: CC: clang-20 @@ -94,25 +104,29 @@ jobs: ASAN_OPTIONS: "check_initialization_order=1" steps: - run: | + apt-get update + apt-get install -y sudo + sudo apt-get install -y git # Updating and installing sudo and git is only neccesary in a container. + # Installing sudo is just so that the later commands using sudo can be the same whether in a container or not. export REPO_HTTPS=`echo "$CIRCLE_REPOSITORY_URL" | sed "s|git@github.com:|https://github.com/|g"` git clone -b "$CIRCLE_BRANCH" "$REPO_HTTPS" . --depth=1 - run: | - sudo apt-add-repository -y universe - sudo apt-get install -y gcc-14 g++-14 + sudo apt-get install -y gnupg wget # Only needed in container. + sudo apt-get install -y gcc-15 g++-15 sudo apt-get install -y cmake sudo apt-get install -y hwloc libhwloc-dev - wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - - sudo apt-add-repository -y 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-20 main' + # tzdata is required by clang and has to be installed carefully to avoid user prompts stalling the script. + ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime + DEBIAN_FRONTEND=noninteractive sudo apt-get install -y --no-install-recommends tzdata sudo apt-get install -y clang-20 - run: | mkdir build - pushd build + cd build cmake -DCMAKE_BUILD_TYPE=Release -DQTHREADS_SCHEDULER=<< parameters.scheduler >> -DQTHREADS_TOPOLOGY=<< parameters.topology >> .. make -j2 VERBOSE=1 - popd - run: command: | - pushd build + cd build if [[ "<< parameters.sanitizer >>" == "thread" ]]; then cd test/basics; fi CTEST_OUTPUT_ON_FAILURE=1 timeout --foreground -k 10s 4m make test VERBOSE=1 no_output_timeout: 180s diff --git a/.cirrus.yml b/.cirrus.yml index 1345b4e7e..3a7becffc 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -74,7 +74,7 @@ freebsd_task: arm_linux_task: arm_container: - image: gcc:14-bookworm + image: gcc:15-bookworm timeout_in: 5m matrix: env: @@ -109,7 +109,7 @@ arm_linux_task: arm_linux_clang_task: arm_container: - image: gcc:14-bookworm + image: gcc:15-bookworm timeout_in: 5m matrix: env: diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 6e713bad3..2aaaf55e0 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -14,7 +14,7 @@ jobs: continue-on-error: true strategy: matrix: - gcc_version: [9, 10, 11, 12, 13] + gcc_version: [9, 10, 11, 12, 13, 14] scheduler: [nemesis, sherwood, distrib] topology: [hwloc, binders, no] env: @@ -259,6 +259,7 @@ jobs: sanitizers: runs-on: ubuntu-24.04 + container: ubuntu:25.04 continue-on-error: true strategy: matrix: @@ -291,35 +292,39 @@ jobs: - uses: actions/checkout@v4 - if: ${{ ! matrix.use_libcxx }} run: | - sudo apt-get install gcc-14 g++-14 + apt-get update + apt-get install -y sudo # Updating and installing sudo is only neccesary in a container. + # Installing sudo is just so that the later commands using sudo can be the same whether in a container or not. + sudo apt-get install -y gcc-15 g++-15 + sudo apt-get install -y cmake # Only needed in a container. Cmake is installed by default on VM images. - name: install compiler run: | + sudo apt-get install -y software-properties-common # Only needed in container. wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - && break || sleep 1 - sudo apt-add-repository 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-20 main' && break || sleep 1 - sudo apt-get install clang-20 + sudo apt-add-repository 'deb https://apt.llvm.org/oracular/ llvm-toolchain-oracular-20 main' && break || sleep 1 + sudo apt-get install -y clang-20 - if: ${{ matrix.use_libcxx }} - run: sudo apt-get install libc++-20-dev libc++abi-20-dev + run: sudo apt-get install -y libc++-20-dev libc++abi-20-dev - if: ${{ matrix.topology != 'no' }} run: | - sudo apt-get install hwloc libhwloc-dev + sudo apt-get install -y hwloc libhwloc-dev hwloc-ls --version - name: build qthreads run: | mkdir build - pushd build + cd build cmake -DCMAKE_BUILD_TYPE=Release -DQTHREADS_SCHEDULER=${{ matrix.scheduler }} -DQTHREADS_TOPOLOGY=${{ matrix.topology }} .. make -j2 VERBOSE=1 - popd - name: run tests run: | - pushd build - if [[ "${{ matrix.sanitizer }}" == "thread" ]]; then cd test/basics; fi + cd build + if [ "${{ matrix.sanitizer }}" = "thread" ]; then cd test/basics; fi CTEST_OUTPUT_ON_FAILURE=1 timeout -k 10s --foreground 18m make test VERBOSE=1 - popd timeout-minutes: 19 linux-thorough: runs-on: ubuntu-24.04 + container: ubuntu:25.04 continue-on-error: true strategy: matrix: @@ -332,37 +337,40 @@ jobs: - compiler: gcc use_libcxx: true env: - CC: ${{ matrix.compiler == 'gcc' && 'gcc-14' || 'clang-20' }} - CXX: ${{ matrix.compiler == 'gcc' && 'g++-14' || 'clang++-20' }} + CC: ${{ matrix.compiler == 'gcc' && 'gcc-15' || 'clang-20' }} + CXX: ${{ matrix.compiler == 'gcc' && 'g++-15' || 'clang++-20' }} CXXFLAGS: ${{ matrix.use_libcxx && '-stdlib=libc++' || '' }} QTHREADS_ENABLE_ASSERTS: ${{ matrix.use_asserts && '--enable-asserts' || '' }} steps: - uses: actions/checkout@v4 - run: | - sudo apt-get install gcc-14 g++-14 + apt-get update + apt-get install -y sudo # Updating and installing sudo is only neccesary in a container. + # Installing sudo is just so that the later commands using sudo can be the same whether in a container or not. + sudo apt-get install -y gcc-15 g++-15 + sudo apt-get install -y cmake # Only needed in a container. Cmake is installed by default on VM images. - if: ${{ matrix.compiler == 'clang' }} run: | + sudo apt-get install -y software-properties-common # Only needed in container. wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add - && break || sleep 1 - sudo apt-add-repository 'deb https://apt.llvm.org/noble/ llvm-toolchain-noble-20 main' && break || sleep 1 - sudo apt-get install clang-20 + sudo apt-add-repository 'deb https://apt.llvm.org/oracular/ llvm-toolchain-oracular-20 main' && break || sleep 1 + sudo apt-get install -y clang-20 - if: ${{ matrix.use_libcxx }} - run: sudo apt-get install libc++-20-dev libc++abi-20-dev + run: sudo apt-get install -y libc++-20-dev libc++abi-20-dev - if: ${{ matrix.topology != 'no' }} run: | - sudo apt-get install hwloc libhwloc-dev + sudo apt-get install -y hwloc libhwloc-dev hwloc-ls --version - name: build qthreads run: | mkdir build - pushd build + cd build cmake -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DQTHREADS_SCHEDULER=${{ matrix.scheduler }} -DQTHREADS_TOPOLOGY=${{ matrix.topology }} .. make -j2 VERBOSE=1 - popd - name: run tests run: | - pushd build + cd build CTEST_OUTPUT_ON_FAILURE=1 timeout -k 10s --foreground 18m make test VERBOSE=1 - popd timeout-minutes: 19 clang-format: From b0731a5a6d003c39a35833329fe8f79e29144093 Mon Sep 17 00:00:00 2001 From: Ian Henriksen Date: Tue, 6 May 2025 14:34:51 -0600 Subject: [PATCH 2/6] Use the latest icx (2025.1) in CI. --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 2aaaf55e0..41bf2f1b3 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -113,7 +113,7 @@ jobs: run: | wget -O - https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB | sudo apt-key add - && break || sleep 1 sudo apt-add-repository 'deb https://apt.repos.intel.com/oneapi all main' && break || sleep 1 - sudo apt-get install intel-oneapi-compiler-dpcpp-cpp-2024.2 + sudo apt-get install intel-oneapi-compiler-dpcpp-cpp-2025.1 source /opt/intel/oneapi/setvars.sh icx -v - name: build qthreads From 6231e6130608828cc3faac5a7b211f2991c62db1 Mon Sep 17 00:00:00 2001 From: Ian Henriksen Date: Tue, 6 May 2025 14:43:08 -0600 Subject: [PATCH 3/6] Use the latest aocc (5.0.0) in CI. --- .github/workflows/CI.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 41bf2f1b3..5d6acbfd9 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -197,7 +197,7 @@ jobs: sudo apt-get install gcc-13 g++-13 - name: install aocc run: | - wget -nv -O aocc.deb https://download.amd.com/developer/eula/aocc/aocc-4-2/aocc-compiler-4.2.0_1_amd64.deb + wget -nv -O aocc.deb https://download.amd.com/developer/eula/aocc/aocc-5-0/aocc-compiler-5.0.0_1_amd64.deb sudo apt install -y ./aocc.deb clang -v - name: build qthreads From 362df1ae4cd15d2b52e14e4da1fff4bf9af4db4d Mon Sep 17 00:00:00 2001 From: Ian Henriksen Date: Thu, 8 May 2025 11:48:19 -0600 Subject: [PATCH 4/6] Work around bug in the latest nvc compilers. They (erroneously) assume that the __sync_val_compare_and_swap intrinsic is a pure founction and that, if the resulting value is discarded, the corresponding function cal can be discarded too. Some of the older code in qthreads liked to write atomic stores using CAS operations with discarded return values. While there's technically nothing wrong with that, it's an odd idiom now that we have c11 atomics. This switches those cases over to c11 atomic stores instead. --- src/ds/qlfqueue.c | 8 +++++--- src/qthread.c | 3 ++- src/shepherds.c | 4 ++-- src/workers.c | 6 ++++-- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/ds/qlfqueue.c b/src/ds/qlfqueue.c index c76b2642b..a10f6e5f3 100644 --- a/src/ds/qlfqueue.c +++ b/src/ds/qlfqueue.c @@ -100,7 +100,8 @@ API_FUNC int qlfqueue_enqueue(qlfqueue_t *q, void *elem) { next = tail->next; if (next != NULL) { /* tail not pointing to last node */ - (void)qthread_cas_ptr((void **)&(q->tail), (void *)tail, next); + atomic_store_explicit( + (void *_Atomic *)&q->tail, next, memory_order_relaxed); continue; } /* tail must be pointing to the last node */ @@ -108,7 +109,7 @@ API_FUNC int qlfqueue_enqueue(qlfqueue_t *q, void *elem) { break; /* success! */ } } - (void)qthread_cas_ptr((void **)&(q->tail), (void *)tail, node); + atomic_store_explicit((void *_Atomic *)&q->tail, node, memory_order_relaxed); hazardous_ptr(0, NULL); // release the ptr (avoid hazardptr resource exhaustion) return QTHREAD_SUCCESS; @@ -139,7 +140,8 @@ API_FUNC void *qlfqueue_dequeue(qlfqueue_t *q) { if (next_ptr == NULL) { return NULL; } /* queue is empty */ if (head == tail) { /* tail is falling behind! */ /* advance tail ptr... */ - (void)qthread_cas_ptr((void **)&(q->tail), (void *)tail, next_ptr); + atomic_store_explicit( + (void *_Atomic *)&q->tail, next_ptr, memory_order_relaxed); continue; } /* read value before CAS, otherwise another dequeue might free the next node diff --git a/src/qthread.c b/src/qthread.c index 5f8e90999..778d3ec56 100644 --- a/src/qthread.c +++ b/src/qthread.c @@ -999,7 +999,8 @@ void API_FUNC qthread_finalize(void) { qt_threadqueue_enqueue(qlib->shepherds[i].ready, t); if (!atomic_load_explicit(&qlib->shepherds[i].workers[j].active, memory_order_relaxed)) { - (void)QT_CAS(qlib->shepherds[i].workers[j].active, 0, 1); + atomic_store_explicit( + &qlib->shepherds[i].workers[j].active, 1, memory_order_relaxed); } } } diff --git a/src/shepherds.c b/src/shepherds.c index ac21fbfbf..7170aafec 100644 --- a/src/shepherds.c +++ b/src/shepherds.c @@ -155,7 +155,7 @@ int API_FUNC qthread_disable_shepherd(qthread_shepherd_id_t const shep) { } qthread_internal_incr( &(qlib->nshepherds_active), &(qlib->nshepherds_active_lock), (aligned_t)-1); - (void)QT_CAS(qlib->shepherds[shep].active, 1, 0); + atomic_store_explicit(&qlib->shepherds[shep].active, 0, memory_order_relaxed); return QTHREAD_SUCCESS; } @@ -164,7 +164,7 @@ void API_FUNC qthread_enable_shepherd(qthread_shepherd_id_t const shep) { assert(shep < qlib->nshepherds); qthread_internal_incr( &(qlib->nshepherds_active), &(qlib->nshepherds_active_lock), 1); - (void)QT_CAS(qlib->shepherds[shep].active, 0, 1); + atomic_store_explicit(&qlib->shepherds[shep].active, 1, memory_order_relaxed); } /*************************************************************************** diff --git a/src/workers.c b/src/workers.c index 1c96f715f..46f06c310 100644 --- a/src/workers.c +++ b/src/workers.c @@ -32,7 +32,8 @@ int API_FUNC qthread_disable_worker(qthread_worker_id_t const w) { return QTHREAD_NOT_ALLOWED; } - (void)QT_CAS(qlib->shepherds[shep].workers[worker].active, 1, 0); + atomic_store_explicit( + &qlib->shepherds[shep].workers[worker].active, 0, memory_order_relaxed); qlib->nworkers_active--; // decrement active count if (worker == 0) { qthread_disable_shepherd(shep); } @@ -52,7 +53,8 @@ void API_FUNC qthread_enable_worker(qthread_worker_id_t const w) { if (worker < qlib->nworkerspershep) { qthread_internal_incr( &(qlib->nworkers_active), &(qlib->nworkers_active_lock), 1); - (void)QT_CAS(qlib->shepherds[shep].workers[worker].active, 0, 1); + atomic_store_explicit( + &qlib->shepherds[shep].workers[worker].active, 1, memory_order_relaxed); } } From b0753db9cc02d325d309248dfd392722cf667a2a Mon Sep 17 00:00:00 2001 From: Ian Henriksen Date: Tue, 6 May 2025 14:47:38 -0600 Subject: [PATCH 5/6] Use the latest nvc (25.3) in CI. --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8319d3037..9e98ff320 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -204,13 +204,13 @@ jobs: if [ ${MACHINE_TYPE} == 'x86_64' ]; then echo 'deb [signed-by=/usr/share/keyrings/nvidia-hpcsdk-archive-keyring.gpg] https://developer.download.nvidia.com/hpc-sdk/ubuntu/amd64 /' | sudo tee /etc/apt/sources.list.d/nvhpc.list; fi if [ ${MACHINE_TYPE} == 'aarch64' ]; then echo 'deb [signed-by=/usr/share/keyrings/nvidia-hpcsdk-archive-keyring.gpg] https://developer.download.nvidia.com/hpc-sdk/ubuntu/arm64 /' | sudo tee /etc/apt/sources.list.d/nvhpc.list; fi sudo apt-get update -y - sudo apt-get install -y nvhpc-24-9 + sudo apt-get install -y nvhpc-25-3 sudo apt-get install -y cmake sudo apt-get install -y hwloc libhwloc-dev - run: | export MACHINE_TYPE=`uname -m` - if [ ${MACHINE_TYPE} == 'x86_64' ]; then export PATH="$PATH:/opt/nvidia/hpc_sdk/Linux_x86_64/24.9/compilers/bin"; fi - if [ ${MACHINE_TYPE} == 'aarch64' ]; then export PATH="$PATH:/opt/nvidia/hpc_sdk/Linux_aarch64/24.9/compilers/bin"; fi + if [ ${MACHINE_TYPE} == 'x86_64' ]; then export PATH="$PATH:/opt/nvidia/hpc_sdk/Linux_x86_64/25.3/compilers/bin"; fi + if [ ${MACHINE_TYPE} == 'aarch64' ]; then export PATH="$PATH:/opt/nvidia/hpc_sdk/Linux_aarch64/25.3/compilers/bin"; fi nvc --version mkdir build pushd build From 045b7820d2a922a165cf4aa42400a3e1625cf433 Mon Sep 17 00:00:00 2001 From: Ian Henriksen Date: Tue, 6 May 2025 14:56:31 -0600 Subject: [PATCH 6/6] Have apt-get update retry a few times to avoid CI failures due to its unreliability. --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9e98ff320..86c32a65e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -18,7 +18,7 @@ jobs: CXX: g++-15 steps: - run: | - apt-get update + apt-get update --quiet=2 || apt-get update --quiet=2 || apt-get update --quiet=2 apt-get install -y sudo sudo apt-get install -y git # Updating and installing sudo and git is only neccesary in a container. # Installing sudo is just so that the later commands using sudo can be the same whether in a container or not. @@ -55,7 +55,7 @@ jobs: CXX: clang++-20 steps: - run: | - apt-get update + apt-get update --quiet=2 || apt-get update --quiet=2 || apt-get update --quiet=2 apt-get install -y sudo sudo apt-get install -y git # Updating and installing sudo and git is only neccesary in a container. # Installing sudo is just so that the later commands using sudo can be the same whether in a container or not. @@ -104,7 +104,7 @@ jobs: ASAN_OPTIONS: "check_initialization_order=1" steps: - run: | - apt-get update + apt-get update --quiet=2 || apt-get update --quiet=2 || apt-get update --quiet=2 apt-get install -y sudo sudo apt-get install -y git # Updating and installing sudo and git is only neccesary in a container. # Installing sudo is just so that the later commands using sudo can be the same whether in a container or not.