diff --git a/.circleci/config.yml b/.circleci/config.yml index 1a577e2b3..b8743728e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -21,7 +21,7 @@ working_dir_default: &working_dir_default docker_default: &docker_default docker: - - image: pikaorg/pika-ci-base:7 + - image: pikaorg/pika-ci-base:8 defaults: &defaults <<: *working_dir_default diff --git a/.github/bors.toml b/.github/bors.toml index d3be882c3..7588319a2 100644 --- a/.github/bors.toml +++ b/.github/bors.toml @@ -45,7 +45,7 @@ status = [ "jenkins/cscs/clang-11-debug", "jenkins/cscs/clang-12-debug", "jenkins/cscs/clang-13-debug", - "jenkins/cscs/clang-14-debug", + "jenkins/cscs/clang-14-cuda-debug", "jenkins/cscs/gcc-9-debug", "jenkins/cscs/gcc-10-apex-debug", "jenkins/cscs/gcc-11-debug", diff --git a/.github/workflows/linux_coverage.yml b/.github/workflows/linux_coverage.yml new file mode 100644 index 000000000..f58655876 --- /dev/null +++ b/.github/workflows/linux_coverage.yml @@ -0,0 +1,64 @@ +# Copyright (c) 2020-2022 ETH Zurich +# +# SPDX-License-Identifier: BSL-1.0 +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +name: Linux CI (Coverage) + +on: + push: + branches: + - main + pull_request: + +jobs: + build: + name: github/linux/coverage + runs-on: ubuntu-latest + container: pikaorg/pika-ci-base:8 + + steps: + - uses: actions/checkout@v2 + - name: Configure + shell: bash + run: | + cmake \ + . \ + -Bbuild \ + -GNinja \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_CXX_FLAGS="--coverage" \ + -DCMAKE_EXE_LINKER_FLAGS="--coverage" \ + -DPIKA_WITH_UNITY_BUILD=ON \ + -DPIKA_WITH_PRECOMPILED_HEADERS=ON \ + -DPIKA_WITH_MALLOC=system \ + -DPIKA_WITH_EXAMPLES=ON \ + -DPIKA_WITH_TESTS=ON \ + -DPIKA_WITH_TESTS_HEADERS=OFF \ + -DPIKA_WITH_TESTS_MAX_THREADS=2 \ + -DPIKA_WITH_PARALLEL_TESTS_BIND_NONE=ON + - name: Build + shell: bash + run: | + cmake --build build --target tests + - name: Test + shell: bash + working-directory: build + continue-on-error: true + run: | + ctest -j2 --timeout 120 --output-on-failure + - name: Upload coverage report + shell: bash + working-directory: build + run: | + grcov . \ + --source-dir .. \ + --output-path lcov.info \ + --output-type lcov \ + --llvm \ + --ignore-not-existing + bash <(curl -Ls https://coverage.codacy.com/get.sh) report \ + --project-token ${{ secrets.CODACY_PIKA_PROJECT_TOKEN }} \ + --language CPP \ + --coverage-reports lcov.info diff --git a/.github/workflows/linux_debug.yml b/.github/workflows/linux_debug.yml index e90d38ce8..37565e2e2 100644 --- a/.github/workflows/linux_debug.yml +++ b/.github/workflows/linux_debug.yml @@ -21,7 +21,7 @@ jobs: build: name: github/linux/debug/fast runs-on: ubuntu-latest - container: pikaorg/pika-ci-base:7 + container: pikaorg/pika-ci-base:8 steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/linux_release_fetchcontent.yml b/.github/workflows/linux_release_fetchcontent.yml index 45131db41..a6eb3b067 100644 --- a/.github/workflows/linux_release_fetchcontent.yml +++ b/.github/workflows/linux_release_fetchcontent.yml @@ -20,7 +20,7 @@ jobs: build: name: github/linux/fetchcontent/fast runs-on: ubuntu-latest - container: pikaorg/pika-ci-base:7 + container: pikaorg/pika-ci-base:8 steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/linux_sanitizers.yml b/.github/workflows/linux_sanitizers.yml index 860959768..6ddc104c9 100644 --- a/.github/workflows/linux_sanitizers.yml +++ b/.github/workflows/linux_sanitizers.yml @@ -20,7 +20,7 @@ jobs: build: name: github/linux/sanitizers/fast runs-on: ubuntu-latest - container: pikaorg/pika-ci-base:7 + container: pikaorg/pika-ci-base:8 steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/linux_tracy.yml b/.github/workflows/linux_tracy.yml index 90c235a8c..472c82d93 100644 --- a/.github/workflows/linux_tracy.yml +++ b/.github/workflows/linux_tracy.yml @@ -20,7 +20,7 @@ jobs: build: name: github/linux/tracy/fast runs-on: ubuntu-latest - container: pikaorg/pika-ci-base:7 + container: pikaorg/pika-ci-base:8 steps: - name: Check out Tracy diff --git a/.jenkins/cscs/Jenkinsfile b/.jenkins/cscs/Jenkinsfile index 79339dbc1..a1fd333d1 100644 --- a/.jenkins/cscs/Jenkinsfile +++ b/.jenkins/cscs/Jenkinsfile @@ -42,7 +42,7 @@ pipeline { axes { axis { name 'configuration_name' - values 'gcc-12', 'gcc-11', 'gcc-10-apex', 'gcc-9', 'gcc-cuda', 'clang-14', 'clang-13', 'clang-12', 'clang-11', 'cce-cuda' + values 'gcc-12', 'gcc-11', 'gcc-10-apex', 'gcc-9', 'gcc-cuda', 'clang-14-cuda', 'clang-13', 'clang-12', 'clang-11', 'cce-cuda' } axis { name 'build_type' diff --git a/.jenkins/cscs/env-clang-14.sh b/.jenkins/cscs/env-clang-14-cuda.sh similarity index 59% rename from .jenkins/cscs/env-clang-14.sh rename to .jenkins/cscs/env-clang-14-cuda.sh index 054d7aa56..da98be8f8 100644 --- a/.jenkins/cscs/env-clang-14.sh +++ b/.jenkins/cscs/env-clang-14-cuda.sh @@ -5,14 +5,16 @@ # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) cxx_std="20" -clang_version="14.0.2" +clang_version="14.0.6" boost_version="1.79.0" hwloc_version="2.7.0" +cuda_version="11.5.0" spack_compiler="clang@${clang_version}" -spack_arch="cray-cnl7-broadwell" +spack_arch="cray-cnl7-haswell" -spack_spec="pika@main arch=${spack_arch} %${spack_compiler} malloc=system cxxstd=${cxx_std} ^boost@${boost_version} ^hwloc@${hwloc_version}" +spack_spec="pika@main arch=${spack_arch} %${spack_compiler} +cuda malloc=system cxxstd=${cxx_std} ^boost@${boost_version} ^cuda@${cuda_version} +allow-unsupported-compilers ^hwloc@${hwloc_version}" configure_extra_options+=" -DPIKA_WITH_CXX_STANDARD=${cxx_std}" configure_extra_options+=" -DPIKA_WITH_MALLOC=system" configure_extra_options+=" -DPIKA_WITH_SPINLOCK_DEADLOCK_DETECTION=ON" +configure_extra_options+=" -DPIKA_WITH_P2300_REFERENCE_IMPLEMENTATION=ON" diff --git a/.jenkins/cscs/slurm-constraint-clang-14.sh b/.jenkins/cscs/slurm-constraint-clang-14-cuda.sh similarity index 100% rename from .jenkins/cscs/slurm-constraint-clang-14.sh rename to .jenkins/cscs/slurm-constraint-clang-14-cuda.sh diff --git a/README.rst b/README.rst index 311ad336e..c08a3dd64 100644 --- a/README.rst +++ b/README.rst @@ -12,6 +12,7 @@ |github_actions_linux_sanitizers_status| |github_actions_macos_debug_status| |codacy| +|codacy_coverage| ==== pika @@ -147,3 +148,7 @@ Pick your favourite meaning from the following: .. |codacy| image:: https://api.codacy.com/project/badge/Grade/e03f57f1c4cd40e7b514e552a723c125 :target: https://www.codacy.com/gh/pika-org/pika :alt: Codacy + +.. |codacy_coverage| image:: https://api.codacy.com/project/badge/Coverage/e03f57f1c4cd40e7b514e552a723c125 + :target: https://www.codacy.com/gh/pika-org/pika + :alt: Codacy coverage diff --git a/libs/pika/async_cuda/include/pika/async_cuda/cuda_scheduler.hpp b/libs/pika/async_cuda/include/pika/async_cuda/cuda_scheduler.hpp index a8ee08b2e..a89930b30 100644 --- a/libs/pika/async_cuda/include/pika/async_cuda/cuda_scheduler.hpp +++ b/libs/pika/async_cuda/include/pika/async_cuda/cuda_scheduler.hpp @@ -88,6 +88,12 @@ namespace pika::cuda::experimental { cuda_scheduler scheduler; PIKA_NO_UNIQUE_ADDRESS std::decay_t receiver; + template + operation_state(cuda_scheduler scheduler, Receiver_&& receiver) + : scheduler(PIKA_MOVE(scheduler)) + , receiver(PIKA_FORWARD(Receiver_, receiver)) + { + } operation_state(operation_state&&) = delete; operation_state(operation_state const&) = delete; operation_state& operator=(operation_state&&) = delete; @@ -148,7 +154,7 @@ namespace pika::cuda::experimental { friend cuda_scheduler tag_invoke( pika::execution::experimental::get_completion_scheduler_t< pika::execution::experimental::set_value_t>, - cuda_scheduler_sender const& s) + cuda_scheduler_sender const& s) noexcept { return s.scheduler; } diff --git a/libs/pika/async_cuda/include/pika/async_cuda/cuda_scheduler_bulk.hpp b/libs/pika/async_cuda/include/pika/async_cuda/cuda_scheduler_bulk.hpp index 0370ea757..c8630656e 100644 --- a/libs/pika/async_cuda/include/pika/async_cuda/cuda_scheduler_bulk.hpp +++ b/libs/pika/async_cuda/include/pika/async_cuda/cuda_scheduler_bulk.hpp @@ -19,6 +19,7 @@ #include #include #include +#include #include diff --git a/libs/pika/async_cuda/include/pika/async_cuda/then_on_host.hpp b/libs/pika/async_cuda/include/pika/async_cuda/then_on_host.hpp index bdbf8f9d5..5def0fdb3 100644 --- a/libs/pika/async_cuda/include/pika/async_cuda/then_on_host.hpp +++ b/libs/pika/async_cuda/include/pika/async_cuda/then_on_host.hpp @@ -23,14 +23,26 @@ namespace pika::cuda::experimental { namespace then_on_host_detail { template - struct then_on_host_receiver + struct then_on_host_receiver_impl + { + struct then_on_host_receiver_type; + }; + + template + using then_on_host_receiver = + typename then_on_host_receiver_impl::then_on_host_receiver_type; + + template + struct then_on_host_receiver_impl::then_on_host_receiver_type { PIKA_NO_UNIQUE_ADDRESS std::decay_t receiver; PIKA_NO_UNIQUE_ADDRESS std::decay_t f; cuda_scheduler sched; template - then_on_host_receiver( + then_on_host_receiver_type( Receiver_&& receiver, F_&& f, cuda_scheduler sched) : receiver(PIKA_FORWARD(Receiver_, receiver)) , f(PIKA_FORWARD(F_, f)) @@ -38,29 +50,32 @@ namespace pika::cuda::experimental { { } - then_on_host_receiver(then_on_host_receiver&&) = default; - then_on_host_receiver& operator=(then_on_host_receiver&&) = default; - then_on_host_receiver(then_on_host_receiver const&) = delete; - then_on_host_receiver& operator=( - then_on_host_receiver const&) = delete; + then_on_host_receiver_type(then_on_host_receiver_type&&) = default; + then_on_host_receiver_type& operator=( + then_on_host_receiver_type&&) = default; + then_on_host_receiver_type( + then_on_host_receiver_type const&) = delete; + then_on_host_receiver_type& operator=( + then_on_host_receiver_type const&) = delete; template friend void tag_invoke(pika::execution::experimental::set_error_t, - then_on_host_receiver&& r, Error&& error) noexcept + then_on_host_receiver_type&& r, Error&& error) noexcept { pika::execution::experimental::set_error( PIKA_MOVE(r.receiver), PIKA_FORWARD(Error, error)); } friend void tag_invoke(pika::execution::experimental::set_stopped_t, - then_on_host_receiver&& r) noexcept + then_on_host_receiver_type&& r) noexcept { pika::execution::experimental::set_stopped( PIKA_MOVE(r.receiver)); } template - void set_value(Ts&&... ts) noexcept + friend void tag_invoke(pika::execution::experimental::set_value_t, + then_on_host_receiver_type&& r, Ts&&... ts) noexcept { pika::detail::try_catch_exception_ptr( [&]() { @@ -70,12 +85,14 @@ namespace pika::cuda::experimental { // Certain versions of GCC with optimizations fail on // the move with an internal compiler error. #if defined(PIKA_GCC_VERSION) && (PIKA_GCC_VERSION < 100000) - PIKA_INVOKE(std::move(f), PIKA_FORWARD(Ts, ts)...); + PIKA_INVOKE( + std::move(r.f), PIKA_FORWARD(Ts, ts)...); #else - PIKA_INVOKE(PIKA_MOVE(f), PIKA_FORWARD(Ts, ts)...); + PIKA_INVOKE( + PIKA_MOVE(r.f), PIKA_FORWARD(Ts, ts)...); #endif pika::execution::experimental::set_value( - PIKA_MOVE(receiver)); + PIKA_MOVE(r.receiver)); } else { @@ -83,59 +100,85 @@ namespace pika::cuda::experimental { // the move with an internal compiler error. #if defined(PIKA_GCC_VERSION) && (PIKA_GCC_VERSION < 100000) auto&& result = PIKA_INVOKE( - std::move(f), PIKA_FORWARD(Ts, ts)...); + std::move(r.f), PIKA_FORWARD(Ts, ts)...); #else auto&& result = PIKA_INVOKE( - PIKA_MOVE(f), PIKA_FORWARD(Ts, ts)...); + PIKA_MOVE(r.f), PIKA_FORWARD(Ts, ts)...); #endif pika::execution::experimental::set_value( - PIKA_MOVE(receiver), PIKA_MOVE(result)); + PIKA_MOVE(r.receiver), PIKA_MOVE(result)); } }, [&](std::exception_ptr ep) { pika::execution::experimental::set_error( - PIKA_MOVE(receiver), PIKA_MOVE(ep)); + PIKA_MOVE(r.receiver), PIKA_MOVE(ep)); }); } + + friend constexpr pika::execution::experimental::detail::empty_env + tag_invoke(pika::execution::experimental::get_env_t, + then_on_host_receiver_type const&) noexcept + { + return {}; + } + }; + + template + struct then_on_host_sender_impl + { + struct then_on_host_sender_type; }; - template - struct then_on_host_sender + template + using then_on_host_sender = typename then_on_host_sender_impl::then_on_host_sender_type; + + template + struct then_on_host_sender_impl::then_on_host_sender_type { - std::decay_t s; + std::decay_t sender; std::decay_t f; cuda_scheduler sched; - template - then_on_host_sender(S_&& s, F_&& f, cuda_scheduler sched) - : s(PIKA_FORWARD(S_, s)) + template + then_on_host_sender_type( + Sender_&& sender, F_&& f, cuda_scheduler sched) + : sender(PIKA_FORWARD(Sender_, sender)) , f(PIKA_FORWARD(F_, f)) , sched(PIKA_MOVE(sched)) { } - then_on_host_sender(then_on_host_sender&&) = default; - then_on_host_sender& operator=(then_on_host_sender&&) = default; - then_on_host_sender(then_on_host_sender const&) = default; - then_on_host_sender& operator=( - then_on_host_sender const&) = default; + then_on_host_sender_type(then_on_host_sender_type&&) = default; + then_on_host_sender_type& operator=( + then_on_host_sender_type&&) = default; + then_on_host_sender_type(then_on_host_sender_type const&) = default; + then_on_host_sender_type& operator=( + then_on_host_sender_type const&) = default; #if defined(PIKA_HAVE_P2300_REFERENCE_IMPLEMENTATION) - template - struct invoke_result_helper + template + struct result_type_signature_helper { - using result_type = std::decay_t< - typename pika::util::invoke_result::type>; - using type = - typename std::conditional::value, - pika::execution::experimental::set_value_t(), - pika::execution::experimental::set_value_t( - result_type)>::type; + using type = pika::execution::experimental::set_value_t(T); + }; + + template <> + struct result_type_signature_helper + { + using type = pika::execution::experimental::set_value_t(); }; + template + requires pika::is_invocable_v + using invoke_result_helper = + pika::execution::experimental::completion_signatures< + typename result_type_signature_helper< + pika::util::invoke_result_t>::type>; + using completion_signatures = - pika::execution::experimental::make_completion_signatures, @@ -159,14 +202,14 @@ namespace pika::cuda::experimental { using value_types = pika::util::detail::unique_t::template value_types, + Sender>::template value_types, invoke_result_helper>>; template