Skip to content

Add new known issue about oneapi::dpl::ranges algorithms - #2811

Merged
SergeyKopienko merged 8 commits into
2022.14-release-notesfrom
dev/skopienko/new_known_issue_in_ranges_algorithms
Sep 3, 2026
Merged

SergeyKopienko merged 8 commits into
2022.14-release-notesfrom
dev/skopienko/new_known_issue_in_ranges_algorithms

Conversation

@SergeyKopienko

@SergeyKopienko SergeyKopienko commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a known-issue entry to documentation/release_notes.rst stating that several oneapi::dpl::ranges algorithms rely on operations that are not guaranteed by the types satisfying their declared requires clauses.

This description documents the detailed analysis behind that entry: for each algorithm, which extra requirements the implementation imposes beyond the declared constraints, and where in the sources they originate.

Detailed analysis

oneapi::dpl::ranges::min / oneapi::dpl::ranges::max

Affected implementations: host.

Additional requirements imposed by the __simd_min_element() implementation. Both algorithms already declare std::indirectly_copyable_storable<iterator_t<_R>, range_value_t<_R>*> (glue_algorithm_ranges_impl.h:750), which covers copy construction and copy assignment; therefore only the following remain extra:

  1. std::ranges::range_value_t<_R> must be default initializable — unseq_backend_simd.h:635
  2. The comparator must be addressable — unseq_backend_simd.h:655

oneapi::dpl::ranges::min_element / oneapi::dpl::ranges::max_element

Affected implementations: host.

Additional requirements imposed by the __simd_min_element() implementation, beyond the declared constraints (random_access_range, sized_range, indirect_strict_weak_order):

  1. std::ranges::range_value_t<_R> must be default initializable — _ComplexType::__min_val{}, unseq_backend_simd.h:635
  2. std::ranges::range_value_t<_R> must be copy constructible and copy assignable — unseq_backend_simd.h:636-640,662-666; note that these algorithms do not declare std::indirectly_copyable_storable, so this is genuinely extra
  3. The comparator must be addressable, i.e. operator& must not be overloaded — &__comp, unseq_backend_simd.h:655

oneapi::dpl::ranges::minmax

Affected implementations: host.

Additional requirements imposed by the __simd_minmax_element() implementation. minmax declares std::indirectly_copyable_storable (glue_algorithm_ranges_impl.h:789), so copy construction/assignment are already part of the contract:

  1. std::ranges::range_value_t<_R> must be default initializable — unseq_backend_simd.h:695
  2. std::ranges::range_value_t<_R> must be assignable from std::iter_reference_t<std::ranges::iterator_t<_R>> without an explicit conversion — unseq_backend_simd.h:742
  3. The comparator must be addressable — unseq_backend_simd.h:733

oneapi::dpl::ranges::minmax_element

Affected implementations: host.

Additional requirements imposed by the __simd_minmax_element() implementation:

  1. std::ranges::range_value_t<_R> must be default initializable — _ComplexType::__min_val{}, __max_val{}, unseq_backend_simd.h:695
  2. std::ranges::range_value_t<_R> must be copy constructible and copy assignable — unseq_backend_simd.h:696-701,710-750; minmax_element does not declare std::indirectly_copyable_storable either
  3. std::ranges::range_value_t<_R> must be constructible and assignable from std::iter_reference_t<std::ranges::iterator_t<_R>> without an explicit conversion — auto __current = __first[__i];, unseq_backend_simd.h:742; unlike __simd_min_element() (line 663) the type is deduced from the reference type, which additionally breaks for proxy iterators
  4. The comparator must be addressable — &__comp, unseq_backend_simd.h:733

oneapi::dpl::ranges::set_union / set_intersection / set_difference / set_symmetric_difference

Affected implementations: host + hetero.

Additional requirements imposed by the implementation:

  1. std::ranges::range_value_t<_OutRange> must be constructible from iter_reference_t of both input iterators — the implementation copy-constructs into raw buffer memory: set_algorithms_utils.h:91, new (std::addressof(*__it_out)) _OutValueType(*__it_in); — whereas std::mergeable only guarantees *out = *in.
  2. std::ranges::iterator_t<_OutRange> must not be a proxy iterator: std::addressof(*__it_out) requires a real lvalue (set_algorithms_utils.h:91).

Summary table

Algorithm Implementations Extra requirements
min, max host default initializable value type; addressable comparator
min_element, max_element host default initializable; copy constructible + copy assignable; addressable comparator
minmax host default initializable; assignable from iter_reference_t; addressable comparator
minmax_element host default initializable; copy constructible + copy assignable; constructible/assignable from iter_reference_t; addressable comparator
set_union, set_intersection, set_difference, set_symmetric_difference host + hetero output value type constructible from iter_reference_t; non-proxy output iterator

Comment thread documentation/release_notes.rst Outdated
@SergeyKopienko SergeyKopienko added this to the 2022.14.0 milestone Aug 31, 2026
@SergeyKopienko

SergeyKopienko commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Detailed analysis after using sycl::is_device_copyable types for hetero policy:

Comment thread documentation/release_notes.rst Outdated
Comment thread documentation/release_notes.rst Outdated
Comment on lines +66 to +75
- Some algorithms in the ``oneapi::dpl::ranges`` family have known implementation issues where the implementation
relies on operations that are not guaranteed to be supported by the types satisfying the requirements
specified in the ``requires`` clauses.
With host policies, ``min``, ``max``, and ``minmax`` require a default-initializable value type and an
addressable comparator, while ``min_element``, ``max_element``, and ``minmax_element`` also require a
copyable value type, and ``minmax_element`` requires construction/assignment from iterator reference types.
With host and device policies, ``set_difference``, ``set_intersection``, ``set_symmetric_difference``, and
``set_union`` require an output value type constructible from input reference types and a non-proxy output
iterator.

@dmitriy-sobolev dmitriy-sobolev Sep 1, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note, there other places where we have such notes:

  • "Known Limitations" from introduction.rst
  • "Difference with Standard C++ Parallel Algorithms" from introduction.rst

Should the note (or its parts) go to these sections instead? If you think that effective implementation of the parallel algorithms is impossible given the restrictions, it's worth moving a note to "Difference with Standard C++ Parallel Algorithms". If you think it is unfeasible to fix in near-term, you can move a note to "Known Limitations".

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applied

Co-authored-by: Dmitriy Sobolev <Dmitriy.Sobolev@intel.com>
Comment thread documentation/release_notes.rst Outdated
Comment thread documentation/release_notes.rst Outdated
Comment thread documentation/release_notes.rst Outdated
Comment on lines +72 to +73
- ``set_difference``, ``set_intersection``, ``set_symmetric_difference``, ``set_union`` require
an output value type constructible from input reference types and a non-proxy output iterator.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to call out zip_iterator here specifically? This would be the most common and relevant one I think. Presumably this does not work?

@dmitriy-sobolev dmitriy-sobolev Sep 2, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not think we should mention zip iterators here - these algorithm have only ranges as arguments. We may mention views::zip, though, but the note may become too complicated.
Upd. suggestion: #2811 (comment)

SergeyKopienko and others added 2 commits September 2, 2026 09:28
Co-authored-by: Dan Hoeflinger <109972525+danhoeflinger@users.noreply.github.com>
Co-authored-by: Dan Hoeflinger <109972525+danhoeflinger@users.noreply.github.com>
Comment thread documentation/release_notes.rst
Comment thread documentation/release_notes.rst Outdated
Co-authored-by: Dmitriy Sobolev <Dmitriy.Sobolev@intel.com>
Comment thread documentation/release_notes.rst Outdated
Co-authored-by: Dmitriy Sobolev <Dmitriy.Sobolev@intel.com>
the type obtained by dereferencing the range's iterator.
* ``set_difference``, ``set_intersection``, ``set_symmetric_difference``, ``set_union`` with both host
and device policies require an output value type constructible from input reference types and
a non-proxy output iterator.

@dmitriy-sobolev dmitriy-sobolev Sep 2, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it is correct (it should be confirmed), but it highlights a "by key" case. This is what Dan was asking above, I think:

Suggested change
a non-proxy output iterator.
a non-proxy output iterator. For instance, proxy iterators are provided by
``dpl::experimental::ranges::zip_view`` and possibly by ``std::ranges::zip_view``.

@danhoeflinger danhoeflinger left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems reasonable to me. The mention of zip_view may be nice to clarify what might be most relevant but its optional Id say

@SergeyKopienko
SergeyKopienko merged commit 588e0c7 into 2022.14-release-notes Sep 3, 2026
@SergeyKopienko
SergeyKopienko deleted the dev/skopienko/new_known_issue_in_ranges_algorithms branch September 3, 2026 10:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants