Remove experimental async interface - #2794
SergeyKopienko wants to merge 17 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Removes the experimental asynchronous API and simplifies SYCL backend synchronization and storage ownership.
Changes:
- Deletes async APIs, documentation, and tests.
- Replaces internal futures with events and owned storage tuples.
- Makes device algorithm completion and exception handling explicit.
Reviewed changes
Copilot reviewed 33 out of 33 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
test/parallel_api/experimental/asynch.pass.cpp |
Removes async algorithm tests. |
test/parallel_api/experimental/asynch-scan.pass.cpp |
Removes async scan tests. |
test/general/multiple_translation_units/header_umbrella.h |
Removes async umbrella inclusion. |
test/general/header_inclusion_order_async_1.pass.cpp |
Removes async inclusion-order test. |
test/general/header_inclusion_order_async_0.pass.cpp |
Removes async inclusion-order test. |
include/oneapi/dpl/pstl/utils.h |
Removes the future declaration. |
include/oneapi/dpl/pstl/utils_ranges.h |
Adds a reusable difference tuple alias. |
include/oneapi/dpl/pstl/onedpl_config.h |
Removes deferred-wait configuration. |
include/oneapi/dpl/pstl/hetero/numeric_ranges_impl_hetero.h |
Explicitly waits and loads numeric results. |
include/oneapi/dpl/pstl/hetero/numeric_impl_hetero.h |
Replaces future operations with event waits. |
include/oneapi/dpl/pstl/hetero/histogram_impl_hetero.h |
Uses throwing event waits. |
include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl.h |
Converts backend futures to events and storage tuples. |
include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_utils.h |
Removes future and legacy storage machinery. |
include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_reduce.h |
Returns reduction events with owned storage. |
include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_reduce_then_scan_pos_tools.h |
Reuses the difference tuple alias. |
include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_reduce_by_segment.h |
Propagates asynchronous exceptions. |
include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_radix_sort.h |
Returns plain events. |
include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_merge.h |
Introduces value-owned merge storage. |
include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_merge_sort.h |
Value-owns split-point storage. |
include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_histogram.h |
Returns plain histogram events. |
include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_fpga.h |
Returns plain FPGA events. |
include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_for.h |
Returns plain parallel-for events. |
include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h |
Makes range algorithms explicitly blocking. |
include/oneapi/dpl/pstl/hetero/algorithm_impl_hetero.h |
Removes wait modes and loads results directly. |
include/oneapi/dpl/internal/binary_search_impl.h |
Uses throwing event waits. |
include/oneapi/dpl/internal/async_impl/glue_async_impl.h |
Removes public async implementations. |
include/oneapi/dpl/internal/async_impl/async_impl_hetero.h |
Removes internal async patterns. |
include/oneapi/dpl/internal/async_extension_defs.h |
Removes async API declarations. |
include/oneapi/dpl/experimental/kt/single_pass_scan.h |
Propagates asynchronous scan errors. |
include/oneapi/dpl/execution |
Stops loading async implementations. |
include/oneapi/dpl/async |
Removes the async public header. |
documentation/library_guide/parallel_api/async_api.rst |
Removes async API documentation. |
documentation/library_guide/macros.rst |
Removes deferred-wait macro documentation. |
Suppressed comments (1)
documentation/library_guide/parallel_api/async_api.rst:1
- Removing this page leaves
documentation/library_guide/guide_toc.rst:22pointing at/library_guide/parallel_api/async_api. Sphinx will report a missing toctree document and the Technology Preview navigation remains stale. Remove that toctree entry as part of this deletion.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 34 out of 34 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
documentation/library_guide/parallel_api/async_api.rst:1
- Deleting this page leaves
/library_guide/parallel_api/async_apireferenced bydocumentation/library_guide/guide_toc.rst:22. Sphinx will report a missing toctree document, so remove that toctree entry as part of this removal.
rfcs/archived/asynchronous_api_general/readme.md:173 - Removing this section also removes the
#onedpl-experimental-asynchronous-algorithmsanchor, but the introduction at line 14 still links to that anchor. Update or remove that link (or retain an anchor explaining the API's removal) to avoid a broken internal RFC link.
### C++ async & future
ba54c80 to
f8aa159
Compare
dae98ba to
644966d
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 33 out of 33 changed files in this pull request and generated 1 comment.
Suppressed comments (2)
include/oneapi/dpl/experimental/kt/single_pass_scan.h:304
- If
wait_and_throw()reports an asynchronous exception, control leaves beforesycl::free, leaking themalloc_deviceallocation. Free the temporary allocation on both success and exception paths (preferably with RAII).
__prev_event.wait_and_throw();
sycl::free(__device_mem, __queue);
include/oneapi/dpl/experimental/kt/single_pass_scan.h:303
- The PR states that all
sycl::event::wait()calls are replaced so asynchronous exceptions are consistently observable, butcore_resource_backend::async_waiter::wait()still callsmy_end_event.wait()ininclude/oneapi/dpl/internal/dynamic_selection_impl/sycl_backend.h:102-105. Convert that remaining event wait towait_and_throw(), or narrow the stated behavior if dynamic-selection waits are intentionally excluded.
__prev_event.wait_and_throw();
a53651d to
b991297
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 33 out of 33 changed files in this pull request and generated no new comments.
Suppressed comments (6)
include/oneapi/dpl/pstl/hetero/algorithm_impl_hetero.h:524
- This no-argument
__load_resultrequires the result tuple—and therefore the input value type—to be default-constructible.minmax_elementhas no such value-type requirement, so valid non-default-constructible element types regress from the previous future-based extraction. Use result extraction that copy-constructs from storage.
const _ReduceValueType __result = __load_result(std::get<1>(__res));
include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h:1654
- This extraction default-constructs
_ReduceValueType, which embeds two copies of the range value type. Device rangesminmax_elementtherefore rejects valid non-default-constructible values; the removed future extraction did not impose that requirement. Use construction-based result extraction instead.
[[maybe_unused]] auto [__idx_min, __idx_max, __min, __max] = __load_result(std::get<1>(__res));
include/oneapi/dpl/pstl/hetero/algorithm_impl_hetero.h:469
__load_result(storage)is enabled only when_ReduceValueTypeis default-constructible. Because this reduction tuple embeds the iterator's value type,min_elementnow fails for non-default-constructible value types that the algorithm otherwise supports; the removed future path copy-constructed the stored value instead. Extract the result without first default-constructing the tuple.
This issue also appears on line 524 of the same file.
const _ReduceValueType __result = __load_result(std::get<1>(__res));
include/oneapi/dpl/pstl/hetero/algorithm_ranges_impl_hetero.h:1575
- The ranges reduction tuple contains the range value type, but this overload of
__load_resultis constrained to default-constructible tuples. Consequently, device rangesmin/min_elementno longer compile for a non-default-constructible value type, although those APIs do not require one. Restore construction-based extraction from storage.
This issue also appears on line 1654 of the same file.
[[maybe_unused]] auto [__idx, __val] = __load_result(std::get<1>(__res));
include/oneapi/dpl/pstl/hetero/dpcpp/parallel_backend_sycl_utils.h:792
- The claimed conversion of all
sycl::event::wait()calls is incomplete:include/oneapi/dpl/internal/dynamic_selection_impl/sycl_backend.h:87-104stores asycl::eventand still callsmy_end_event.wait(). Async exceptions in that backend remain unobservable at the wait site, contrary to the stated behavior; convert that call too or narrow the PR's behavior claim.
else if constexpr (std::is_same_v<_WaitModeTag, __sync_mode>)
{
__event.wait_and_throw();
}
include/oneapi/dpl/experimental/kt/single_pass_scan.h:304
- If
wait_and_throw()reports an asynchronous exception, control skipssycl::free, leaking the raw device allocation. Free the allocation on both success and exception paths before propagating the error.
__prev_event.wait_and_throw();
sycl::free(__device_mem, __queue);
411ab03 to
0229e89
Compare
5b069de to
cbb8acd
Compare
…nts __finalize_sycl_call() and etc. staff
…remove struct __copyable_storage_state + struct __combined_storage::__move_state() as unused anymore
… fix compile error: non-constant-expression cannot be narrowed from type 'long' to 'std::size_t' (aka 'unsigned long') in initializer list [-Wc++11-narrowing]
…ible result types
…elf review comment: remove extra [[maybe_unused]] in __pattern_minmax_element_impl()
…elf review comment: remove extra [[maybe_unused]] in __pattern_min_element_impl()
…ed_on_finalize_sycl_call()
…fix self review comment: remove __is_wait_required_on_finalize_sycl_call()
…ro::__parallel_for() calls instead of using auto
…y namespace in __finalize_sycl_call() calls
cbb8acd to
468fd05
Compare
Summary
This PR removes the experimental asynchronous algorithms interface (
oneapi::dpl::experimental::*_async,wait_for_all) together with the internal machinery that existed only to support it: the__futureclass and the legacy__result_and_scratch_storagecontainer.Since the async API was the only user-visible feature that could return a handle to an incomplete computation, dropping it lets the backend return plain
sycl::event/std::tuplevalues instead of wrapping them into__future, and replaces the type-erasedshared_ptr<__result_and_scratch_storage_base>lifetime management with value-semantics storage types.What is removed
Public, experimental API (all in
oneapi::dpl::experimental):<oneapi/dpl/async>headercopy_async,fill_async,for_each_async,reduce_async,sort_async,inclusive_scan_async,exclusive_scan_async,transform_async,transform_reduce_async,transform_inclusive_scan_async,transform_exclusive_scan_asyncwait_for_allInternal entities:
__future,__create_future()__checked_deferrable_wait()__result_and_scratch_storage,__result_and_scratch_storage_base,__copyable_storage_state,__combined_storage::__move_state()async_extension_defs.h,async_impl/async_impl_hetero.h,async_impl/glue_async_impl.h_ONEDPL_ASYNC_FORWARD_DECLAREDhook in<oneapi/dpl/execution>Backend changes
__finalize_sycl_call()inparallel_backend_sycl_utils.has the single point where a pattern result is waited for. It is dispatched on a wait-mode tag and has two overloads: one for a baresycl::event, and one for a tuple whose first element is asycl::event. The tuple overload consults the__wait_required_of_finalize_sycl_calltrait and forces__sync_modewhen the tuple carries a storage type whose value must be read on the host, regardless of the requested mode.__future::wait()/__future::get()/__checked_deferrable_wait()call sites with__finalize_sycl_call()plus an explicit__load_result()/__copy_result()read.sycl::event::wait()calls withsycl::event::wait_and_throw(), including inexperimental/kt/single_pass_scan.h. This makes asynchronous SYCL exceptions consistently observable at the call site instead of being silently swallowed.__parallel_for,__parallel_copy_impl,__parallel_histogram,__parallel_radix_sortand__parallel_partial_sortnow return a plainsycl::event.__parallel_transform_reduce,__parallel_transform_scan,__parallel_merge,__parallel_stable_sort,__merge_sortand the reduce/scan-by-segment helpers now return astd::tuplebuilt on the new__device_storage/__result_storage/__combined_storagetypes, which own their memory directly._split_points_device_storage_taliases and the__parallel_merge_return_data_thelper, replacing manualnew+shared_ptrlifetime extension. Split-point buffers are now value types moved out of the submitters._OutSizeLimittemplate parameters were converted fromstd::true_type/std::false_typeto plainbool.oneapi::dpl::__internal::__difference_tuple_tinutils_ranges.hand reused it in merge and set operations instead of spelling out tuples of__difference_t.Documentation
documentation/library_guide/parallel_api/async_api.rstand its entry indocumentation/library_guide/guide_toc.rst.rfcs/archived/asynchronous_api_general/readme.md.documentation/CHANGES.rstanddocumentation/release_notes.rstare left untouched.Tests
test/parallel_api/experimental/asynch.pass.cppandasynch-scan.pass.cpp.test/general/header_inclusion_order_async_0.pass.cppandheader_inclusion_order_async_1.pass.cpp.<oneapi/dpl/async>from the multiple-translation-units header umbrella.Behavior impact
oneapi::dpl::experimental::*_asyncfunctions,wait_for_all, or<oneapi/dpl/async>will no longer compile. These interfaces were experimental and are not part of the oneDPL specification.wait()towait_and_throw()means an exception reported to the SYCL queue's async handler is now rethrown at the point where the algorithm waits, instead of being ignored there.Implementation details
Instead of
__futurestructure, now we operate bystd::tuple<sycl::event, .....>structure and introduce new__finalize_sycl_call()function for finalize eachsyclcall:Example: