Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow sorting via native oneDPL to support views with stride = 1 #6322

Merged
merged 9 commits into from
Aug 4, 2023

Conversation

fnrizzi
Copy link
Contributor

@fnrizzi fnrizzi commented Jul 31, 2023

Before this PR, the call to native sort in oneDPL was guarded with static asserts for views to have layoutRight and layoutLeft.
Since technically oneDPL can support stride = 1, this PR also allows for LayoutStride but adds a runtime check that stride ==1.

@fnrizzi fnrizzi changed the title start addressing #6287 allow native oneDPL to be called for views with stride = 1 Jul 31, 2023
@fnrizzi fnrizzi linked an issue Jul 31, 2023 that may be closed by this pull request
@fnrizzi fnrizzi changed the title allow native oneDPL to be called for views with stride = 1 allow sorting via native oneDPL to support views with stride = 1 Jul 31, 2023
Copy link
Member

@crtrott crtrott left a comment

Choose a reason for hiding this comment

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

We don't have a is_always_strided property like mdspan does, but basically that is what you need to check for here. LayoutTiled for example breaks this.

static_assert(ViewType::rank == 1, "SYCL sort only supports rank-1 Views");
if (view.stride(0) != 1) {
Kokkos::abort("SYCL sort only supports rank-1 Views with stride = 1".);
}
Copy link
Member

Choose a reason for hiding this comment

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

This ignored LayoutTiled, and would compile with it

Copy link
Contributor Author

@fnrizzi fnrizzi Aug 1, 2023

Choose a reason for hiding this comment

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

ops, yes totally right, i actually had it that way in the first place and then simplified too much.
Thanks for catching it !

Copy link
Contributor

@nliber nliber left a comment

Choose a reason for hiding this comment

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

I agree with @crtrott. The old static_assert needs to be there.

// strided views not supported in dpl so use the most generic case
copy_to_host_run_stdsort_copy_back(exec, view, comparator);
} else {
if (view.stride(0) == 1) {
Copy link
Contributor

Choose a reason for hiding this comment

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

We also need to match the checks in sort_onedpl above

          rank == 1 && 
          (std::is_same_v<typename ViewType::array_layout, LayoutRight> ||
           std::is_same_v<typename ViewType::array_layout, LayoutLeft> ||
           std::is_same_v<typename ViewType::array_layout, LayoutStride>),

here so we can fallback to copy_to_host_run_stdsort_copy_back in case of a different layout without running into the Kokkos::abort or static_assert.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, so i changed this because it makes sense for this specific function. However, this is within the impl namespace and as far as usability, we have a static assert in the public API that alreay statically checks only for these layouts. so one cannot pass a view with a different layout anyway. makes sense?

Copy link
Contributor

Choose a reason for hiding this comment

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

we have a static assert in the public API that alreay statically checks only for these layouts.

That's not true for the overloads without comparator, see

template <class ExecutionSpace, class DataType, class... Properties>
void sort([[maybe_unused]] const ExecutionSpace& exec,
const Kokkos::View<DataType, Properties...>& view) {
// constraints
using ViewType = Kokkos::View<DataType, Properties...>;
using MemSpace = typename ViewType::memory_space;
static_assert(ViewType::rank == 1,
"Kokkos::sort: currently only supports rank-1 Views.");
static_assert(SpaceAccessibility<ExecutionSpace, MemSpace>::accessible,
"Kokkos::sort: execution space instance is not able to access "
"the memory space of the "
"View argument!");
if (view.extent(0) <= 1) {
return;
}
if constexpr (Impl::better_off_calling_std_sort_v<ExecutionSpace>) {
auto first = ::Kokkos::Experimental::begin(view);
auto last = ::Kokkos::Experimental::end(view);
std::sort(first, last);
} else {
Impl::sort_device_view_without_comparator(exec, view);
}
}
template <class DataType, class... Properties>
void sort(const Kokkos::View<DataType, Properties...>& view) {
using ViewType = Kokkos::View<DataType, Properties...>;
static_assert(ViewType::rank == 1,
"Kokkos::sort: currently only supports rank-1 Views.");
Kokkos::fence("Kokkos::sort: before");
if (view.extent(0) <= 1) {
return;
}
typename ViewType::execution_space exec;
sort(exec, view);
exec.fence("Kokkos::sort: fence after sorting");
}
, but the ones with comparator have them
template <class ExecutionSpace, class ComparatorType, class DataType,
class... Properties>
void sort([[maybe_unused]] const ExecutionSpace& exec,
const Kokkos::View<DataType, Properties...>& view,
const ComparatorType& comparator) {
// constraints
using ViewType = Kokkos::View<DataType, Properties...>;
using MemSpace = typename ViewType::memory_space;
static_assert(
ViewType::rank == 1 &&
(std::is_same_v<typename ViewType::array_layout, LayoutRight> ||
std::is_same_v<typename ViewType::array_layout, LayoutLeft> ||
std::is_same_v<typename ViewType::array_layout, LayoutStride>),
"Kokkos::sort with comparator: supports 1D Views with LayoutRight, "
"LayoutLeft or LayoutStride.");
static_assert(SpaceAccessibility<ExecutionSpace, MemSpace>::accessible,
"Kokkos::sort: execution space instance is not able to access "
"the memory space of the View argument!");
if (view.extent(0) <= 1) {
return;
}
if constexpr (Impl::better_off_calling_std_sort_v<ExecutionSpace>) {
auto first = ::Kokkos::Experimental::begin(view);
auto last = ::Kokkos::Experimental::end(view);
std::sort(first, last, comparator);
} else {
Impl::sort_device_view_with_comparator(exec, view, comparator);
}
}
template <class ComparatorType, class DataType, class... Properties>
void sort(const Kokkos::View<DataType, Properties...>& view,
const ComparatorType& comparator) {
using ViewType = Kokkos::View<DataType, Properties...>;
static_assert(
ViewType::rank == 1 &&
(std::is_same_v<typename ViewType::array_layout, LayoutRight> ||
std::is_same_v<typename ViewType::array_layout, LayoutLeft> ||
std::is_same_v<typename ViewType::array_layout, LayoutStride>),
"Kokkos::sort with comparator: supports 1D Views with LayoutRight, "
"LayoutLeft or LayoutStride.");
Kokkos::fence("Kokkos::sort with comparator: before");
if (view.extent(0) <= 1) {
return;
}
typename ViewType::execution_space exec;
sort(exec, view, comparator);
exec.fence("Kokkos::sort with comparator: fence after sorting");
}
.

Copy link
Contributor Author

@fnrizzi fnrizzi Aug 1, 2023

Choose a reason for hiding this comment

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

yes but the code you are requesting changes in the impl is inside sort_device_view_with_comparator so that is only called by the piublic API if a comparator is present

Copy link
Contributor

Choose a reason for hiding this comment

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

Then we need this check when calling the version without comparator (since it's also hitting sort_onedpl), right?

Copy link
Contributor Author

@fnrizzi fnrizzi Aug 3, 2023

Choose a reason for hiding this comment

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

yes you are right. I did not want touch the existing code, yes, but makes sense to add the constraints as much as possible into the public API rather than having them hidden. So i am changing this to also add these constraints to the public API of the sort without comparator.

@crtrott crtrott merged commit 40fb259 into kokkos:develop Aug 4, 2023
27 of 28 checks passed
@masterleinad masterleinad mentioned this pull request Sep 14, 2023
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.

sort: fix call to oneDPL for strided views with stride = 1
4 participants