From 8dad274e26d506b4b95aa837833288c5fddad7f6 Mon Sep 17 00:00:00 2001 From: alwaysprince05 Date: Wed, 16 Sep 2026 02:59:22 +0530 Subject: [PATCH 1/2] test: add scheduler_concept regression guard for all stdexec schedulers Per [exec.sched], scheduler types should define a nested scheduler_concept alias derived from scheduler_tag. PR #2256 (issue #2134) added the missing aliases; this adds compile-time guards so the requirement cannot regress. - New test/exec/test_scheduler_concept.cpp statically asserts the alias and scheduler<> satisfaction for the always-available schedulers: inline, run_loop, task_scheduler, parallel, static_thread_pool, thread_pool_base (CRTP), timed_thread, trampoline, and the internal reschedule scheduler. - Gated schedulers are asserted in their existing gated test files: io_uring, windows_thread_pool, libdispatch, and the nvexec stream and multi-GPU stream schedulers. Generated with Codebuff Co-Authored-By: Codebuff --- test/exec/CMakeLists.txt | 1 + test/exec/test_io_uring_context.cpp | 4 + test/exec/test_libdispatch.cpp | 9 ++ test/exec/test_scheduler_concept.cpp | 100 ++++++++++++++++++ .../exec/test_windows_thread_pool_context.cpp | 9 ++ test/nvexec/scheduler.cpp | 13 +++ 6 files changed, 136 insertions(+) create mode 100644 test/exec/test_scheduler_concept.cpp diff --git a/test/exec/CMakeLists.txt b/test/exec/CMakeLists.txt index 0561ec965..4f149e94d 100644 --- a/test/exec/CMakeLists.txt +++ b/test/exec/CMakeLists.txt @@ -42,6 +42,7 @@ set(exec_test_sources $<$:test_io_uring_context.cpp> $<$:test_windows_thread_pool_context.cpp> test_trampoline_scheduler.cpp + test_scheduler_concept.cpp test_sequence_senders.cpp test_static_thread_pool.cpp test_just_from.cpp diff --git a/test/exec/test_io_uring_context.cpp b/test/exec/test_io_uring_context.cpp index 7f7ceafad..14293d87c 100644 --- a/test/exec/test_io_uring_context.cpp +++ b/test/exec/test_io_uring_context.cpp @@ -83,6 +83,10 @@ namespace { STATIC_REQUIRE(timed_scheduler); STATIC_REQUIRE_FALSE(std::is_move_assignable_v); + + // regression guard for issue #2134: per [exec.sched], schedulers must + // provide the scheduler_concept nested alias + STATIC_REQUIRE(std::same_as); } TEST_CASE("io_uring_context Schedule runs in io thread", "[types][io_uring][schedulers]") diff --git a/test/exec/test_libdispatch.cpp b/test/exec/test_libdispatch.cpp index 7251a57d6..bc82f1c9b 100644 --- a/test/exec/test_libdispatch.cpp +++ b/test/exec/test_libdispatch.cpp @@ -338,4 +338,13 @@ namespace REQUIRE(result.has_value()); CHECK(std::get<0>(*result) == 42); } + + TEST_CASE("libdispatch scheduler provides scheduler_concept", + "[types][libdispatch][schedulers]") + { + // regression guard for issue #2134: per [exec.sched], schedulers must + // provide the scheduler_concept nested alias + STATIC_REQUIRE( + std::same_as); + } } // namespace diff --git a/test/exec/test_scheduler_concept.cpp b/test/exec/test_scheduler_concept.cpp new file mode 100644 index 000000000..9a9360fbc --- /dev/null +++ b/test/exec/test_scheduler_concept.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2026 NVIDIA Corporation + * + * Licensed under the Apache License Version 2.0 with LLVM Exceptions + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://llvm.org/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#if STDEXEC_USE_MODULES() +import std; +#else +# include +# include +#endif + +// Regression tests for issue #2134: per [exec.sched], a scheduler type must +// define a nested `scheduler_concept` alias derived from `scheduler_tag`. +// These tests fail to compile if a scheduler in stdexec forgets it. + +namespace ex = STDEXEC; + +namespace +{ + template + concept has_scheduler_concept = requires { + typename Sch::scheduler_concept; + requires std::derived_from; + }; + +#if !STDEXEC_NO_STDCPP_EXCEPTIONS() + class inline_test_thread_pool : public exec::thread_pool_base + { + public: + [[nodiscard]] + auto available_parallelism() const noexcept -> std::uint32_t + { + return 1; + } + + [[nodiscard]] + static constexpr auto forward_progress_guarantee() noexcept -> ex::forward_progress_guarantee + { + return ex::forward_progress_guarantee::parallel; + } + + void enqueue(exec::_pool_::task_base* task, std::uint32_t tid = 0) noexcept + { + ++enqueued_; + task->execute_(task, tid); + } + + std::uint32_t enqueued_ = 0; + }; +#endif + + TEST_CASE("schedulers provide the scheduler_concept nested alias", + "[types][schedulers][scheduler_concept]") + { + STATIC_REQUIRE(has_scheduler_concept); + STATIC_REQUIRE(has_scheduler_concept); + STATIC_REQUIRE(has_scheduler_concept); + STATIC_REQUIRE(has_scheduler_concept); + STATIC_REQUIRE(has_scheduler_concept); +#if !STDEXEC_NO_STDCPP_EXCEPTIONS() + STATIC_REQUIRE(has_scheduler_concept); +#endif + STATIC_REQUIRE(has_scheduler_concept); + STATIC_REQUIRE(has_scheduler_concept); + STATIC_REQUIRE(has_scheduler_concept); + } + + TEST_CASE("schedulers satisfy the stdexec scheduler concept", + "[types][schedulers][scheduler_concept]") + { + STATIC_REQUIRE(ex::scheduler); + STATIC_REQUIRE(ex::scheduler); + STATIC_REQUIRE(ex::scheduler); + STATIC_REQUIRE(ex::scheduler); + STATIC_REQUIRE(ex::scheduler); + STATIC_REQUIRE(ex::scheduler); + } +} // namespace diff --git a/test/exec/test_windows_thread_pool_context.cpp b/test/exec/test_windows_thread_pool_context.cpp index a7cae997c..f1f1c27c5 100644 --- a/test/exec/test_windows_thread_pool_context.cpp +++ b/test/exec/test_windows_thread_pool_context.cpp @@ -24,6 +24,15 @@ using namespace std::chrono_literals; +TEST_CASE("windows_thread_pool scheduler provides scheduler_concept", + "[types][windows_thread_pool][schedulers]") +{ + // regression guard for issue #2134: per [exec.sched], schedulers must + // provide the scheduler_concept nested alias + STATIC_REQUIRE( + std::same_as); +} + TEST_CASE("windows_thread_pool: construct_destruct", "[types][windows_thread_pool][schedulers]") { exec::windows_thread_pool tp; diff --git a/test/nvexec/scheduler.cpp b/test/nvexec/scheduler.cpp index 5c6f251e0..ce06d2e6a 100644 --- a/test/nvexec/scheduler.cpp +++ b/test/nvexec/scheduler.cpp @@ -39,4 +39,17 @@ namespace CHECK_FALSE(normal == low); CHECK_FALSE(high == low); } + + TEST_CASE("nvexec stream schedulers provide scheduler_concept", "[cuda][stream][scheduler]") + { + // regression guard for issue #2134: per [exec.sched], schedulers must + // provide the scheduler_concept nested alias + STATIC_REQUIRE( + std::same_as); + STATIC_REQUIRE( + std::same_as); + + nvexec::stream_context stream_ctx{}; + STATIC_REQUIRE(std::same_as); + } } // namespace From 0f216e43c3f5f982aa02667227ab6f145d5fb9f7 Mon Sep 17 00:00:00 2001 From: alwaysprince05 Date: Wed, 16 Sep 2026 03:25:17 +0530 Subject: [PATCH 2/2] style: join wrapped TEST_CASE args in test_libdispatch to satisfy clang-format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🤖 Generated with Codebuff Co-Authored-By: Codebuff --- test/exec/test_libdispatch.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/exec/test_libdispatch.cpp b/test/exec/test_libdispatch.cpp index bc82f1c9b..ed9d7aa4a 100644 --- a/test/exec/test_libdispatch.cpp +++ b/test/exec/test_libdispatch.cpp @@ -339,8 +339,7 @@ namespace CHECK(std::get<0>(*result) == 42); } - TEST_CASE("libdispatch scheduler provides scheduler_concept", - "[types][libdispatch][schedulers]") + TEST_CASE("libdispatch scheduler provides scheduler_concept", "[types][libdispatch][schedulers]") { // regression guard for issue #2134: per [exec.sched], schedulers must // provide the scheduler_concept nested alias