Skip to content

Conversation

@rarutyun
Copy link
Contributor

@rarutyun rarutyun commented Aug 25, 2025

The link to the proposal

Implementing Iterator-based algorithms only. Ranges-based implementation is going on separately.

There are no breaking changes. All the breaking changes in C++ standard come into std::ranges namespace but even they are irrelevant to oneDPL because we implement list-initialization enabling right away, so there is no template parameters swapping

There are two oversights for P2248:

  • find_last was not included (see this paper). However, it's irrelevant for Iterator-based algorithms because find_last exists in std::ranges: namespace only
  • uninitialized_fill was not included (see this paper. However, it's not included for C++26 yet. I've implemented that proactively as was requested. There is a NB comment to include this oversight for C++26.

Binary Search-like algorithms from P2248 (e.g., lower_bound, upper_bound, etc.) are not relevant either because our API for those does not have T-like template parameter.

Linked issue: #1508

@akukanov
Copy link
Contributor

  • uninitialized_fill was not included (see this paper. However, it's not included for C++26. We are trying to achieve that but there is no guarantee. The question is do we want to implement it proactively?

Yes. Let's do that for all algorithms, including - if necessary - non-standard ones in oneDPL.

@danhoeflinger
Copy link
Contributor

Is the intention to merge this for milestone 2022.10.0?

@rarutyun
Copy link
Contributor Author

Is the intention to merge this for milestone 2022.10.0?

Whenever we think it's ready

@rarutyun rarutyun force-pushed the rarutyun/implement_p2248r8 branch from d0441d2 to f1b47c6 Compare October 24, 2025 18:43
@danhoeflinger danhoeflinger added this to the 2022.11.0 milestone Nov 17, 2025
_ForwardIterator2 __result, _UnaryPredicate __pred, const _Tp& __new_value);

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Tp>
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2,
Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't the paper conclude not to make any changes to replace_copy for non ranges api?

Copy link
Contributor

@danhoeflinger danhoeflinger left a comment

Choose a reason for hiding this comment

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

Other than the question on replace_copy, I don't see any issues with the implementation, but I have not yet checked the tests.

EXPECT_TRUE(std::count(v.begin(), v.end(), 0) == v.size(), "a sequence is not filled properly by oneapi::dpl::fill with `unseq` policy");
}

{
Copy link
Contributor

@danhoeflinger danhoeflinger Nov 18, 2025

Choose a reason for hiding this comment

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

[nitpick] Remove extra unnecessary braces (this goes away if we use invoke_on_all_policies)

Copy link
Contributor

Choose a reason for hiding this comment

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

As discussed offline, these tests (for replace_copy, but not replace_copy_if) should be removed along with the default template arg for replace_copy in the implementation.

Comment on lines +147 to +150
static_assert(is_replace_copy_if_well_formed<std::vector<not_implicitly_convertible>::iterator, std::vector<int>::iterator>::value,
"Positive: The default argument of replace_copy_if shall be taken from output iterator");
static_assert(!is_replace_copy_if_well_formed<std::vector<int>::iterator, std::vector<not_implicitly_convertible>::iterator>::value,
"Positive: The default argument of replace_copy_if shall be taken from output iterator");
Copy link
Contributor

Choose a reason for hiding this comment

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

The "Positive" and "Negative" here are confusing for me (and the one on like 150 should be "Negative" I think).

I'd prefer something more like:

"replace_copy_if call is NOT well-formed for valid list_initialization argument"
and
"replace_copy_if call is well-formed for INVALID list_initialization argument"

Or something similar so that it is clear to the user reading the error message what has gone wrong without looking at the tests.

// Test with value that is equal to two different bit patterns (-0.0 and 0.0)
test<float32_t>(-0.0, [](std::int32_t j) { return j & 1 ? 0.0 : -0.0; }, // hit
[](std::int32_t j) { return j == 0 ? ~j : j; }); // miss
[](std::int32_t j) { return j == 0 ? ~j : j; }); // miss
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems like these are bad formatting changes that should be reverted.

Comment on lines +139 to +141
sycl::buffer<int> buf(v);
auto it = oneapi::dpl::search_n(oneapi::dpl::execution::dpcpp_default, oneapi::dpl::begin(buf), oneapi::dpl::end(buf), {});
EXPECT_TRUE(it.get_idx() == 4, "an empty list-initialized value is not found by oneapi::dpl::search_n with `device_policy` policy");
Copy link
Contributor

Choose a reason for hiding this comment

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

[nitpick] Is there a reason to only test the integer variant on dpcpp_default rather that both integer and DefaultInitializedToOne?

I know that from a white box perspective, all these policies are really testing the same part of the code as they share code at the public API level, but for the other policy types we test both.

Same question for the other tests as well.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants