Skip to content
Open
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
48c6c34
include/oneapi/dpl/pstl/utils_ranges.h - introduce view_type_on_next_…
SergeyKopienko Nov 4, 2025
72f6bb8
include/oneapi/dpl/pstl/utils_ranges.h - place base type std::true_ty…
SergeyKopienko Nov 4, 2025
20bd154
include/oneapi/dpl/pstl/utils_ranges.h - add support for retrieving a…
SergeyKopienko Nov 4, 2025
c831d48
include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h - implement …
SergeyKopienko Nov 4, 2025
2b13025
include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h - add compil…
SergeyKopienko Nov 4, 2025
07e29f0
test/support/utils.h - split struct MinimalisticView to struct Minima…
SergeyKopienko Nov 4, 2025
ec09a2b
test/general/implementation_details/subscription_view.pass.cpp - addi…
SergeyKopienko Nov 4, 2025
34368c5
test/parallel_api/ranges/range_minimal_type_requirements.pass.cpp - i…
SergeyKopienko Nov 4, 2025
75c7319
include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h - apply GitH…
SergeyKopienko Nov 4, 2025
69672db
Move __contains_host_pointer_v into tests because it's used only in t…
SergeyKopienko Nov 4, 2025
bc8354f
test/general/implementation_details/subscription_view.pass.cpp - intr…
SergeyKopienko Nov 4, 2025
2da3e63
include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h - remove ext…
SergeyKopienko Nov 4, 2025
9cff760
include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h - remove ext…
SergeyKopienko Nov 4, 2025
3c05b6d
include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h - remove ext…
SergeyKopienko Nov 4, 2025
7bfa70c
test/general/implementation_details/subscription_view.pass.cpp - fix …
SergeyKopienko Nov 4, 2025
3896354
test/general/implementation_details/subscription_view.pass.cpp - fix …
SergeyKopienko Nov 4, 2025
c180296
include/oneapi/dpl/pstl/utils_ranges.h - remove struct pipeline_base_…
SergeyKopienko Nov 5, 2025
b0cad39
include/oneapi/dpl/pstl/utils_ranges.h - remove duplicated type defin…
SergeyKopienko Nov 5, 2025
0c5c4a6
Introduce the new type struct pipeline_base_range::has_next_layer_t (…
SergeyKopienko Nov 5, 2025
5b0a64f
Move and rename the type definition struct pipeline_base::view_type_o…
SergeyKopienko Nov 5, 2025
ad5b8d9
include/oneapi/dpl/pstl/utils_ranges.h - remove extra changes from st…
SergeyKopienko Nov 5, 2025
aa66198
include/oneapi/dpl/pstl/utils_ranges.h - remove extra changes from st…
SergeyKopienko Nov 5, 2025
1885cc1
test/parallel_api/ranges/range_minimal_type_requirements.pass.cpp - e…
SergeyKopienko Nov 6, 2025
bf02fc2
test/parallel_api/ranges/range_minimal_type_requirements.pass.cpp - r…
SergeyKopienko Nov 6, 2025
8f877be
Define std::basic_string_view specializations as containing host poin…
SergeyKopienko Nov 6, 2025
350143e
include/oneapi/dpl/pstl/onedpl_config.h - introduce the new macro _ON…
SergeyKopienko Nov 6, 2025
7a4814a
Define std::span specializations as containing host pointers
SergeyKopienko Nov 6, 2025
c517a5e
include/oneapi/dpl/pstl/onedpl_config.h - introduce the new macro ONE…
SergeyKopienko Nov 6, 2025
82648ad
Add support or public inheritance into the checked types
SergeyKopienko Nov 6, 2025
c42b7be
Add support or public inheritance into the checked types
SergeyKopienko Nov 6, 2025
a7e4d8d
Remove std::span detection - it has raw-pointers but it can be USM-me…
SergeyKopienko Nov 6, 2025
39b8fab
Remove std::basic_string_view (and their specialization) detection - …
SergeyKopienko Nov 6, 2025
176c783
Remove the definition of ONEDPL_CPP20_REMOVE_CVREF_T_PRESENT and it's…
SergeyKopienko Nov 6, 2025
a10051d
include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h - apply GitH…
SergeyKopienko Nov 6, 2025
286d3c3
test/general/implementation_details/subscription_view.pass.cpp - fix …
SergeyKopienko Nov 6, 2025
f5a7312
test/general/implementation_details/subscription_view.pass.cpp - addi…
SergeyKopienko Nov 6, 2025
8ff1b07
include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h - modify mes…
SergeyKopienko Nov 7, 2025
6269b98
remove static_assert_not_contains_host_pointer as not required: move …
SergeyKopienko Nov 7, 2025
64322f6
include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h - fix review…
SergeyKopienko Nov 7, 2025
2d1ce66
include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h - remove ext…
SergeyKopienko Nov 7, 2025
c4b9908
test/general/implementation_details/subscription_view.pass.cpp - remo…
SergeyKopienko Nov 7, 2025
bb91e23
include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h - fix review…
SergeyKopienko Nov 7, 2025
673809a
test/general/implementation_details/subscription_view.pass.cpp - expa…
SergeyKopienko Nov 7, 2025
74f3830
include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h - apply GitH…
SergeyKopienko Nov 7, 2025
596a8b6
test/general/implementation_details/subscription_view.pass.cpp - fix …
SergeyKopienko Nov 7, 2025
ae32ca8
test/general/implementation_details/subscription_view.pass.cpp - fix …
SergeyKopienko Nov 7, 2025
fea0d4d
test/general/implementation_details/subscription_view.pass.cpp - fix …
SergeyKopienko Nov 7, 2025
8b98829
test/general/implementation_details/contains_host_pointers.pass.cpp -…
SergeyKopienko Nov 7, 2025
51bec86
test/parallel_api/ranges/range_minimal_type_requirements.pass.cpp - r…
SergeyKopienko Nov 7, 2025
553a5f7
test/general/implementation_details/contains_host_pointers.pass.cpp -…
SergeyKopienko Nov 7, 2025
610bf38
test/general/implementation_details/contains_host_pointers.pass.cpp -…
SergeyKopienko Nov 7, 2025
7775879
include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h - Update zip…
SergeyKopienko Nov 7, 2025
760a5dc
Fix review comment: struct __contains_host_pointer_on_any_layers<_Vie…
SergeyKopienko Nov 7, 2025
8c5cb5d
include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h - fix review…
SergeyKopienko Nov 7, 2025
2429167
Fix review comment: remove has_next_layer_t
SergeyKopienko Nov 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions include/oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,60 @@ __require_access_range(sycl::handler& __cgh, oneapi::dpl::__internal::tuple<_Ran
::std::make_index_sequence<__num_ranges>());
}

template <typename...>
constexpr auto
__contains_host_pointer_probe(...) -> std::false_type;

// for std::ranges::ref_view
#if _ONEDPL_CPP20_RANGES_PRESENT
template <std::ranges::range Rng>
constexpr auto
__contains_host_pointer_probe(std::ranges::ref_view<Rng>*) -> std::true_type;
#endif // _ONEDPL_CPP20_RANGES_PRESENT

template <typename T>
using __remove_cv_ref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type;

template <typename T>
struct __contains_host_pointer : decltype(__contains_host_pointer_probe(static_cast<T*>(nullptr))){};

template <typename...>
struct __contains_host_pointer_on_any_layers;

// 1. Checking the top-level view
// 2. Searching view with host pointer in internal views(layers)
template <typename _View>
struct __contains_host_pointer_on_any_layers<_View>
: std::disjunction<
__contains_host_pointer<__remove_cv_ref_t<_View>>,
std::conditional_t<oneapi::dpl::__ranges::pipeline_base_range<_View>::has_next_layer_t::value,
__contains_host_pointer_on_any_layers<
typename oneapi::dpl::__ranges::pipeline_base_range<_View>::next_layer_view_t>,
std::false_type>>
{
};

// 1.1. Checking the top-level view
// 1.2. Searching view with host pointer in internal views(layers)
// 2.1. Searching view with host pointer in the rest of views
template <typename _View, typename... _Views>
struct __contains_host_pointer_on_any_layers<_View, _Views...>
: std::disjunction<__contains_host_pointer_on_any_layers<_View>, __contains_host_pointer_on_any_layers<_Views...>>
{
};

template <typename _Range, typename... _Ranges>
struct __contains_host_pointer_on_any_layers<oneapi::dpl::__ranges::zip_view<_Range, _Ranges...>>
: std::disjunction<__contains_host_pointer_on_any_layers<_Range>, __contains_host_pointer_on_any_layers<_Ranges...>>
{
};

template <typename _BaseRange>
void
__require_access_range(sycl::handler&, _BaseRange&)
{
static_assert(!__contains_host_pointer_on_any_layers<_BaseRange>::value,
"oneDPL does not support std::ranges::ref_view in SYCL-kernel code");
Comment on lines +354 to +355
Copy link
Contributor

Choose a reason for hiding this comment

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

Will you add a corresponding comment into the release notes or oneDPL guide? I think it is worth mentioning.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@timmiesmith, what is the best place to document this compile-time check?

Copy link
Contributor

@dmitriy-sobolev dmitriy-sobolev Nov 7, 2025

Choose a reason for hiding this comment

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

To be more precise, it's not about the check per se, but about the fact that that one should not pass anything for execution with device policies which can create std::ranges::ref_view underneath, e.g. std::ranges::views::all wrapping a range which is not a view.

My recommendation is the release notes for the upcoming release if we believe it is temporary and known limitations in the library guide if its for long. I am inclined towards the later.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think for now it is better considered a temporary limitation.

}

template <typename _Range, typename... _Ranges>
Expand Down
4 changes: 4 additions & 0 deletions include/oneapi/dpl/pstl/utils_ranges.h
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,8 @@ template <typename Range, typename = void>
struct pipeline_base_range
{
Range rng;
using has_next_layer_t = std::false_type;
using next_layer_view_t = Range;

pipeline_base_range(Range r) : rng(r) {}
constexpr Range
Expand All @@ -318,6 +320,8 @@ template <typename Range>
struct pipeline_base_range<Range, ::std::enable_if_t<is_pipeline_object<Range>::value>>
{
Range rng;
using has_next_layer_t = std::true_type;
using next_layer_view_t = decltype(std::declval<Range>().base());

pipeline_base_range(Range r) : rng(r) {}
constexpr auto
Expand Down
177 changes: 177 additions & 0 deletions test/general/implementation_details/contains_host_pointers.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Copyright (C) Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// This file incorporates work covered by the following copyright and permission
// notice:
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
//
//===----------------------------------------------------------------------===//

#include "support/test_config.h"

#include "support/utils.h"

#if _ENABLE_STD_RANGES_TESTING && TEST_DPCPP_BACKEND_PRESENT
#include <oneapi/dpl/pstl/hetero/dpcpp/utils_ranges_sycl.h>

using IntVector = std::vector<int>;
using IteratorOfIntVector = typename IntVector::iterator;

using MinimalisticRangeForIntVec = TestUtils::MinimalisticRange<IteratorOfIntVector>;
using MinimalisticRangeViewForIntVec = TestUtils::MinimalisticView <IteratorOfIntVector>;

template <typename RandomIt>
struct MinimalisticViewWithSubscription : TestUtils::MinimalisticView<RandomIt>
{
MinimalisticViewWithSubscription(RandomIt it_begin, RandomIt it_end)
: TestUtils::MinimalisticView<RandomIt>(it_begin, it_end)
{
}

auto operator[](std::size_t index) const
{
return *(oneapi::dpl::__ranges::__begin(*this) + index);
}
};

template <typename _Rng>
inline constexpr bool contains_host_pointer_v = oneapi::dpl::__ranges::__contains_host_pointer<_Rng>::value;

template <typename... _Rng>
inline constexpr bool contains_host_pointer_on_any_layers_v = oneapi::dpl::__ranges::__contains_host_pointer_on_any_layers<_Rng...>::value;

// oneapi::dpl::__ranges::__contains_host_pointer functional
void
check_contains_host_pointer()
{
{
IntVector vec;
auto all_view = std::ranges::views::all(MinimalisticRangeForIntVec(vec.begin(), vec.end()));
static_assert(contains_host_pointer_v<decltype(all_view)> == false);
static_assert(contains_host_pointer_on_any_layers_v<decltype(all_view)> == false);
}

{
IntVector vec;
MinimalisticViewWithSubscription mr_view(vec.begin(), vec.end());
auto all_view = std::ranges::views::all(mr_view);
static_assert(contains_host_pointer_v<decltype(all_view)> == false);
static_assert(contains_host_pointer_on_any_layers_v<decltype(all_view)> == false);
}

{
IntVector vec;

MinimalisticViewWithSubscription mr_view(vec.begin(), vec.end());
auto all_view1 = std::ranges::views::all(mr_view);

MinimalisticRangeForIntVec mr(vec.begin(), vec.end());
auto all_view2 = std::ranges::views::all(mr);

static_assert(contains_host_pointer_on_any_layers_v<decltype(all_view1)> == false);
static_assert(contains_host_pointer_on_any_layers_v<decltype(all_view2)> == true);
static_assert(contains_host_pointer_on_any_layers_v<decltype(all_view1), decltype(all_view2)> == true);
}
}

// oneapi::dpl::__ranges::__contains_host_pointer functional with oneapi::dpl::__ranges::zip_view
void
check_contains_host_pointer_in_zip_view()
{
{
IntVector vec;

MinimalisticRangeForIntVec mr(vec.begin(), vec.end());
auto all_view = std::ranges::views::all(mr);

auto zip_view = oneapi::dpl::__ranges::make_zip_view(all_view, all_view);

static_assert(contains_host_pointer_v<decltype(all_view)> == true);
static_assert(contains_host_pointer_v<decltype(zip_view)> == false);
static_assert(contains_host_pointer_on_any_layers_v<decltype(zip_view)> == true);
}

{
IntVector vec;

MinimalisticViewWithSubscription mrv(vec.begin(), vec.end());
auto all_view1 = std::ranges::views::all(mrv);

MinimalisticRangeForIntVec mr(vec.begin(), vec.end());
auto all_view2 = std::ranges::views::all(mr);

auto zip_view = oneapi::dpl::__ranges::make_zip_view(all_view1, all_view2);

static_assert(contains_host_pointer_v<decltype(all_view1)> == false);
static_assert(contains_host_pointer_v<decltype(all_view2)> == true);
static_assert(contains_host_pointer_v<decltype(zip_view)> == false);
static_assert(contains_host_pointer_on_any_layers_v<decltype(zip_view)> == true);
}

{
IntVector vec;

MinimalisticViewWithSubscription mrv(vec.begin(), vec.end());
auto all_view = std::ranges::views::all(mrv);

auto zip_view = oneapi::dpl::__ranges::make_zip_view(all_view, all_view);

static_assert(contains_host_pointer_v<decltype(all_view)> == false);
static_assert(contains_host_pointer_v<decltype(zip_view)> == false);
static_assert(contains_host_pointer_on_any_layers_v<decltype(zip_view)> == false);
}
}

// oneapi::dpl::__ranges::__contains_host_pointer functional with std::ranges::take_view
void
check_contains_host_pointer_in_take_view()
{
IntVector vec;
MinimalisticRangeForIntVec mr(vec.begin(), vec.end());
auto all_view = std::ranges::views::all(mr);
auto taken_view = std::ranges::take_view(all_view, all_view.size());

static_assert(contains_host_pointer_v<decltype(all_view)> == true);
static_assert(contains_host_pointer_v<decltype(taken_view)> == false);
static_assert(contains_host_pointer_on_any_layers_v<decltype(taken_view)> == true);
}

// oneapi::dpl::__ranges::__contains_host_pointer functional with std::ranges::drop_view
void
check_contains_host_pointer_in_drop_view()
{
IntVector vec;
MinimalisticRangeForIntVec mr(vec.begin(), vec.end());
auto all_view = std::ranges::views::all(mr);
auto dropped_view = std::ranges::drop_view(all_view, 0);

static_assert(contains_host_pointer_v<decltype(all_view)> == true);
static_assert(contains_host_pointer_v<decltype(dropped_view)> == false);
static_assert(contains_host_pointer_on_any_layers_v<decltype(dropped_view)> == true);
}
#endif // _ENABLE_STD_RANGES_TESTING && TEST_DPCPP_BACKEND_PRESENT

int
main()
{
bool bProcessed = false;

#if _ENABLE_STD_RANGES_TESTING && TEST_DPCPP_BACKEND_PRESENT

check_contains_host_pointer();
check_contains_host_pointer_in_zip_view();
check_contains_host_pointer_in_take_view();
check_contains_host_pointer_in_drop_view();

bProcessed = true;

#endif // _ENABLE_STD_RANGES_TESTING && TEST_DPCPP_BACKEND_PRESENT

return TestUtils::done(bProcessed);
}
33 changes: 29 additions & 4 deletions test/support/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -1342,21 +1342,46 @@ struct NoDefaultCtorWrapper {

#if _ENABLE_STD_RANGES_TESTING

// A minimalistic view to detect an accidental use of methods such as begin(), end(), empty(), operator[] and etc,
// which are not required for a class to be considered a range.
// A minimalistic range: it can't be applied directly to hetero range-based algorithms,
// but can be used for internal checks
// Note, begin() and end() functions are still required, but they can be provided as ADL-discoverable free functions.
template <typename RandomIt>
struct MinimalisticView : std::ranges::view_base
struct MinimalisticRange
{
RandomIt it_begin;
RandomIt it_end;

MinimalisticView(RandomIt it_begin, RandomIt it_end)
MinimalisticRange(RandomIt it_begin, RandomIt it_end)
: it_begin(it_begin), it_end(it_end)
{
}
};

template <typename RandomIt>
RandomIt
begin(MinimalisticRange<RandomIt> range)
{
return range.it_begin;
}

template <typename RandomIt>
RandomIt
end(MinimalisticRange<RandomIt> range)
{
return range.it_end;
}

// A minimalistic view to detect an accidental use of methods such as begin(), end(), empty(), operator[] and etc,
// which are not required for a class to be considered a range.
template <typename RandomIt>
struct MinimalisticView : MinimalisticRange<RandomIt>, std::ranges::view_base
{
MinimalisticView(RandomIt it_begin, RandomIt it_end)
: MinimalisticRange<RandomIt>(it_begin, it_end)
{
}
};

template <typename RandomIt>
RandomIt
begin(MinimalisticView<RandomIt> view)
Expand Down