Skip to content

Implement HPX Future-Sender Bridge (P2300 interoperability)#7256

Open
shivansh023023 wants to merge 1 commit intoTheHPXProject:masterfrom
shivansh023023:feat/future-sender-bridge
Open

Implement HPX Future-Sender Bridge (P2300 interoperability)#7256
shivansh023023 wants to merge 1 commit intoTheHPXProject:masterfrom
shivansh023023:feat/future-sender-bridge

Conversation

@shivansh023023
Copy link
Copy Markdown
Contributor

Implement hpx::future ↔ P2300 Sender Interoperability Bridge

Fixes #5219

Proposed Changes

  • Added libs/core/futures/include/hpx/futures/future_sender.hpp: implements
    future_sender<T>, a P2300-compliant sender that wraps hpx::future<T>,
    exposing as_sender(hpx::future<T>&&) as the public API entry point
  • Added libs/core/futures/include/hpx/futures/sender_future.hpp: implements
    as_future(sender) which converts any P2300 sender into an hpx::future<T>
    using an internal sender_future_receiver that bridges the two completion
    channels
  • Added libs/core/futures/tests/unit/future_sender_test.cpp: unit tests
    covering future→sender conversion, sender→future conversion, error
    propagation through the error channel, and move-only semantics verification
  • Registered the new test in libs/core/futures/tests/unit/CMakeLists.txt
    following the existing alphabetical ordering convention

Any background context you want to provide?

HPX currently has two async worlds that cannot communicate natively:

  • Legacy world: hpx::async() returns hpx::future<T> (HPX's own type)
  • Modern world: P2300 senders/receivers via the imported stdexec library

This PR builds the translator layer between them, so that existing HPX
code producing futures can be seamlessly composed into modern P2300 pipelines,
and vice versa:

// Direction 1: Future → Sender
hpx::future<int> f = hpx::async([]{ return 42; });
auto [result] = stdexec::sync_wait(
    as_sender(std::move(f)) | stdexec::then([](int x){ return x * 2; })
).value();
// result == 84

// Direction 2: Sender → Future
hpx::future<int> f2 = as_future(stdexec::just(42));
assert(f2.get() == 42);

This is a foundational step toward the broader goal of re-implementing the
executor API on top of the sender/receiver infrastructure (issue #5219), as
it allows hpx::async, hpx::dataflow, and other future-returning facilities
to be gradually migrated into P2300 pipelines without breaking existing user
code.

Implementation follows all established HPX bridge conventions:

  • sender_concept / receiver_concept tags for stdexec concept compliance
  • tag_invoke customization points (no virtual dispatch)
  • HPX_CXX_CORE_EXPORT annotations for C++20 Module BMI visibility
  • Move-only operation states with deferred receiver moves to prevent UB
  • NVCC/CUDACC guards on destructors
  • Zero circular dependencies between the futures and executors modules

Checklist

  • I have added a new feature and have added tests to go along with it.

@shivansh023023 shivansh023023 requested a review from hkaiser as a code owner May 7, 2026 14:23
@codacy-production
Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@StellarBot
Copy link
Copy Markdown
Collaborator

Can one of the admins verify this patch?

@hkaiser
Copy link
Copy Markdown
Contributor

hkaiser commented May 7, 2026

@shivansh023023 What's the difference to the existing as_sender(future), make_future(sender), and keep_future(future) facilities we already have (https://github.com/TheHPXProject/hpx/tree/master/libs/core/execution/include/hpx/execution/algorithms)?

@hkaiser hkaiser added type: enhancement type: compatibility issue category: senders/receivers Implementations of the p0443r14 / p2300 + p1897 proposals labels May 7, 2026
@shivansh023023
Copy link
Copy Markdown
Contributor Author

Thank you for pointing this out, @hkaiser I wasn't aware of the existing
as_sender, make_future, and keep_future facilities in
libs/core/execution/include/hpx/execution/algorithms/.

I've now reviewed those headers. Given that the core functionality already
exists, would it be more valuable to:

  1. Extend the existing facilities — for example, ensuring they are
    properly wired to the executor-based schedulers introduced in Implement P2300 get_scheduler bridge for executors #7238
    and Implement P2300 get_scheduler bridge for parallel_executor #7239, so that as_sender(future) preserves the executor context
    from the originating hpx::async() call?

  2. Add missing test coverage — the existing algorithms may lack tests
    for error propagation or move-only semantics that I've written here,
    which could be salvaged into the existing test suite?

  3. Close this PR — if the existing implementation already covers all
    cases correctly, I'm happy to close this and redirect my effort to a
    higher-priority gap.

I'd appreciate your guidance on which direction is most useful. I'm
actively looking for high-impact areas in the S&R domain to contribute
to ahead of GSoC 2027.

@hkaiser
Copy link
Copy Markdown
Contributor

hkaiser commented May 7, 2026

  1. Extend the existing facilities — for example, ensuring they are
    properly wired to the executor-based schedulers introduced in Implement P2300 get_scheduler bridge for executors #7238
    and Implement P2300 get_scheduler bridge for parallel_executor #7239, so that as_sender(future) preserves the executor context
    from the originating hpx::async() call?

If that improves the integration, sure, please do that.

  1. Add missing test coverage — the existing algorithms may lack tests
    for error propagation or move-only semantics that I've written here,
    which could be salvaged into the existing test suite?

If tests are missing this is also a nice addition.

  1. Close this PR — if the existing implementation already covers all
    cases correctly, I'm happy to close this and redirect my effort to a
    higher-priority gap.

That's what I was asking. What would this PR add on top of what's already in place?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

category: senders/receivers Implementations of the p0443r14 / p2300 + p1897 proposals type: compatibility issue type: enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(Re-)Implement executor API on top of sender/receiver infrastructure

3 participants