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

[SYCL] Refactor address space casts functionality #15543

Merged
merged 11 commits into from
Oct 14, 2024

Conversation

aelovikov-intel
Copy link
Contributor

@aelovikov-intel aelovikov-intel commented Sep 27, 2024

This follows the interfaces designed in https://github.com/intel/llvm/blob/3a1c3cb53566f904a73361d5c57b939d981564b5/sycl/doc/extensions/proposed/sycl_ext_oneapi_address_cast.asciidoc, but instead of operating on multi_ptr, these work on decorated C++ pointers (as that's what we need throughout our implementation, including multi_ptr implementation itself).

Basically, I've moved the implementation of the extension to the new detail::static|dynamic_address_cast functions and replaced all uses of the old detail::cast_AS (that had inconsistent static vs dynamic behavior depending on address spaces/backends) and also uses of direct SPIRV builtin/wrappers invocations.

This isn't NFC, because by doing that I've changed "dynamic" behavior to "static" whenever the spec allows that (e.g. if it's UB if runtime pointers doesn't point to a proper allocation).

multi_ptr(accessor) - correct AS is guaranteed by SFINAE
explicit operatr multi_ptr<...> - UB if mismatch

TODO: constant_space ?
auto *ptrGlobalAS = __SYCL_GenericCastToPtrExplicit_ToGlobal<const char>(ptr);
auto *ptrGlobalAS =
reinterpret_cast<__attribute__((opencl_global)) const char *>(
detail::static_address_cast<access::address_space::global_space>(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

See https://github.com/intel/llvm/blob/sycl/sycl/doc/extensions/experimental/sycl_ext_oneapi_prefetch.asciidoc, it states (for non-accessor overloads):

Preconditions: ptr must point to an object in global memory.

@@ -449,12 +449,12 @@ template <int Dimensions = 1> class __SYCL_TYPE(group) group {
using QualSrcT =
std::conditional_t<std::is_const_v<SrcT>, const uint8_t, uint8_t>;
auto DestP = multi_ptr<uint8_t, DestS, access::decorated::yes>(
detail::cast_AS<typename multi_ptr<uint8_t, DestS,
access::decorated::yes>::pointer>(
reinterpret_cast<typename multi_ptr<uint8_t, DestS,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We're changing element type of the decorated C++ pointer type here, no address space changes. Same throughout this file.

@@ -384,12 +384,12 @@ template <int Dimensions = 1> class nd_item {
using QualSrcT =
std::conditional_t<std::is_const_v<SrcT>, const uint8_t, uint8_t>;
auto DestP = multi_ptr<uint8_t, DestS, access::decorated::yes>(
detail::cast_AS<typename multi_ptr<uint8_t, DestS,
access::decorated::yes>::pointer>(
reinterpret_cast<typename multi_ptr<uint8_t, DestS,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We're changing element type of the decorated C++ pointer type here, no address space changes. Same throughout this file.

@@ -272,7 +272,7 @@ class __SYCL_TYPE(multi_ptr) multi_ptr {
OtherSpace != access::address_space::constant_space>>
multi_ptr &
operator=(const multi_ptr<value_type, OtherSpace, OtherIsDecorated> &Other) {
m_Pointer = detail::cast_AS<decorated_type *>(Other.get_decorated());
m_Pointer = detail::static_address_cast<Space>(Other.get_decorated());
Copy link
Contributor Author

Choose a reason for hiding this comment

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

"static" cast from non-constant_space to generic_space is always possible.

@@ -282,15 +282,18 @@ class __SYCL_TYPE(multi_ptr) multi_ptr {
OtherSpace != access::address_space::constant_space>>
multi_ptr &
operator=(multi_ptr<value_type, OtherSpace, OtherIsDecorated> &&Other) {
m_Pointer = detail::cast_AS<decorated_type *>(std::move(Other.m_Pointer));
m_Pointer = detail::static_address_cast<Space>(std::move(Other.m_Pointer));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Likewise.

@@ -638,7 +630,7 @@ class __SYCL_TYPE(multi_ptr) multi_ptr<void, Space, DecorateAddress> {
multi_ptr(accessor<ElementType, Dimensions, Mode, target::device,
isPlaceholder, PropertyListT>
Accessor)
: multi_ptr(detail::cast_AS<decorated_type *>(
: multi_ptr(detail::static_address_cast<Space>(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

because accessor.

pointer get() const { return detail::cast_AS<pointer>(m_Pointer); }
pointer get() const {
return detail::static_address_cast<
is_decorated ? Space : access::address_space::generic_space>(m_Pointer);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

See above - either no-op/identity or cast away decoration.

Comment on lines +701 to +702
static_cast<typename multi_ptr<ElementType, Space,
access::decorated::yes>::pointer>(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changing element type from void to ElementType, no address space changes.

return multi_ptr<void, GlobalSpace, DecorateAddress>(
detail::cast_AS<global_pointer_t>(m_Pointer));
detail::static_address_cast<GlobalSpace>(m_Pointer));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Subsections of the global_space per definition, known to succeed.

@@ -782,14 +775,17 @@ class __SYCL2020_DEPRECATED(
#endif

multi_ptr(ElementType *pointer)
: m_Pointer(detail::cast_AS<pointer_t>(pointer)) {
: m_Pointer(detail::dynamic_address_cast<
Copy link
Contributor Author

Choose a reason for hiding this comment

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

See comment near the definition of detail::dynamic_address_cast, that part is mostly NFC. The exception is non-SPIRV backends when we know that address spaces are NOT compatible. Previously we were doing C-style cast anyway, now nullptr is returned.

Same for ctors below.

@@ -63,39 +41,14 @@ multi_ptr<ElementType, Space, DecorateAddress> static_address_cast(
if constexpr (Space == generic_space)
return Ptr;
else
return {static_address_cast<Space>(Ptr.get_raw())};
return {static_address_cast<Space>(Ptr.get_decorated())};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We were limited by the extension interface before, so had to drop this bit of information in order to delegate. Now that we're calling something from detail:: we can keep decoration in place.

@aelovikov-intel aelovikov-intel changed the title [NFCI][SYCL] Refactor address space casts functionality [SYCL] Refactor address space casts functionality Oct 9, 2024
@aelovikov-intel aelovikov-intel marked this pull request as ready for review October 9, 2024 18:18
@aelovikov-intel aelovikov-intel requested a review from a team as a code owner October 9, 2024 18:18
Copy link
Contributor

@bso-intel bso-intel left a comment

Choose a reason for hiding this comment

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

LGTM.
Thanks for extra comments about your code changes.

Copy link
Contributor

@steffenlarsen steffenlarsen left a comment

Choose a reason for hiding this comment

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

Very nice!

@aelovikov-intel aelovikov-intel merged commit 9ea0f20 into intel:sycl Oct 14, 2024
12 checks passed
@aelovikov-intel aelovikov-intel deleted the refactor-as-casts branch October 14, 2024 18:23
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