-
Notifications
You must be signed in to change notification settings - Fork 768
[SYCL] Implement SYCL_ONEAPI_accessor_properties #2456
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
Merged
Merged
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
d0d2a86
[SYCL] Implement SYCL_ONEAPI_accessor_properties extension
415c939
Minor fix
41365d7
Update for latest revision
ee55a6a
Fix tests
976dfec
More clang-format
33da077
Fix template arguments
5dba583
Fix more missing templates
809061d
clang-format
e9b9246
Propagate template arguments to accessor_common
ccb172f
More clang-format
ff28dc2
Remove unused code
49028d5
Fix empty prop list lookup
c22997b
Fix include
c4cebba
Fix small typo
alexbatashev 0091796
Split CT and RT tests
d70980c
Attempt to improve code readability
3277faa
Merge remote-tracking branch 'origin/sycl' into accessor_property_list
2c04881
Apply suggestions from code review
alexbatashev ed8efd7
Address more comments
e982a29
Fix merge artifacts
7a51468
Merge remote-tracking branch 'upstream/sycl' into accessor_property_list
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,232 @@ | ||
//==----- accessor_property_list.hpp --- SYCL accessor property list -------==// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#pragma once | ||
|
||
#include <CL/sycl/access/access.hpp> | ||
#include <CL/sycl/detail/common.hpp> | ||
#include <CL/sycl/detail/property_list_base.hpp> | ||
#include <CL/sycl/property_list.hpp> | ||
|
||
#include <type_traits> | ||
|
||
__SYCL_INLINE_NAMESPACE(cl) { | ||
namespace sycl { | ||
// Forward declaration | ||
template <typename, int, access::mode, access::target, access::placeholder, | ||
typename PropertyListT> | ||
class accessor; | ||
namespace detail { | ||
// This helper template must be specialized for nested instance template | ||
// of each compile-time-constant property. | ||
template <typename T> struct IsCompileTimePropertyInstance : std::false_type {}; | ||
} // namespace detail | ||
namespace ONEAPI { | ||
|
||
template <typename T> struct is_compile_time_property : std::false_type {}; | ||
|
||
/// Objects of the accessor_property_list class are containers for the SYCL | ||
/// properties. | ||
/// | ||
/// Unlike \c property_list, accessor_property_list can take | ||
/// compile-time-constant properties. | ||
/// | ||
/// \sa accessor | ||
/// \sa property_list | ||
/// | ||
/// \ingroup sycl_api | ||
template <typename... PropsT> | ||
class accessor_property_list : protected sycl::detail::PropertyListBase { | ||
// These structures check if compile-time-constant property is present in | ||
// list. For runtime properties this check is always true. | ||
template <class T, class U> struct AreSameTemplate : std::is_same<T, U> {}; | ||
template <template <class...> class T, class T1, class T2> | ||
struct AreSameTemplate<T<T1>, T<T2>> : std::true_type {}; | ||
#if __cplusplus >= 201703L | ||
// Declaring non-type template parameters with auto is a C++17 feature. Since | ||
// the extension is written against SYCL 2020, which implies use of C++17, | ||
// there's no need to provide alternative implementations for older standards. | ||
template <template <auto...> class T, auto... T1, auto... T2> | ||
struct AreSameTemplate<T<T1...>, T<T2...>> : std::true_type {}; | ||
#endif | ||
// This template helps to identify if PropListT parameter pack contains | ||
// property of PropT type, where PropT is a nested instance template of | ||
// compile-time-constant property. | ||
template <typename PropT, typename... PropListT> struct ContainsProperty; | ||
template <typename PropT> struct ContainsProperty<PropT> : std::false_type {}; | ||
template <typename PropT, typename Head, typename... Tail> | ||
struct ContainsProperty<PropT, Head, Tail...> | ||
: std::conditional<AreSameTemplate<PropT, Head>::value, std::true_type, | ||
ContainsProperty<PropT, Tail...>>::type {}; | ||
|
||
// PropertyContainer is a helper structure, that holds list of properties. | ||
// It is used to avoid multiple parameter packs in templates. | ||
template <typename...> struct PropertyContainer { | ||
using Head = void; | ||
using Rest = void; | ||
}; | ||
template <typename T, typename... Other> | ||
struct PropertyContainer<T, Other...> { | ||
using Head = T; | ||
using Rest = PropertyContainer<Other...>; | ||
}; | ||
template <typename T> struct PropertyContainer<T> { | ||
using Head = T; | ||
using Rest = void; | ||
}; | ||
|
||
#if __cplusplus >= 201703L | ||
// This template serves the same purpose as ContainsProperty, but operates on | ||
// template template arguments. | ||
template <typename ContainerT, template <auto...> typename PropT, | ||
auto... Args> | ||
struct ContainsPropertyInstance | ||
: std::conditional_t< | ||
!std::is_same_v<typename ContainerT::Head, void> && | ||
AreSameTemplate<PropT<Args...>, | ||
typename ContainerT::Head>::value, | ||
std::true_type, | ||
ContainsPropertyInstance<typename ContainerT::Rest, PropT, | ||
Args...>> {}; | ||
|
||
template <template <auto...> typename PropT, auto... Args> | ||
struct ContainsPropertyInstance<void, PropT, Args...> : std::false_type {}; | ||
#endif | ||
|
||
// This template checks if two lists of properties contain the same set of | ||
// compile-time-constant properties in any order. Run time properties are | ||
// skipped. | ||
template <typename ContainerT, typename... OtherProps> | ||
struct ContainsSameProperties | ||
: std::conditional< | ||
!detail::IsCompileTimePropertyInstance< | ||
typename ContainerT::Head>::value || | ||
ContainsProperty<typename ContainerT::Head, | ||
OtherProps...>::value, | ||
ContainsSameProperties<typename ContainerT::Rest, OtherProps...>, | ||
std::false_type>::type {}; | ||
template <typename... OtherProps> | ||
struct ContainsSameProperties<void, OtherProps...> : std::true_type {}; | ||
|
||
#if __cplusplus >= 201703L | ||
// This template helps to extract exact property instance type based on | ||
// template template argument. If there's an instance of target property in | ||
// ContainerT, find instance template and use it as type. Otherwise, just | ||
// use void as return type. | ||
template <typename ContainerT, template <auto...> class PropT, auto... Args> | ||
struct GetCompileTimePropertyHelper { | ||
using type = typename std::conditional_t< | ||
AreSameTemplate<typename ContainerT::Head, PropT<Args...>>::value, | ||
typename ContainerT::Head, | ||
typename GetCompileTimePropertyHelper<typename ContainerT::Rest, PropT, | ||
Args...>::type>; | ||
}; | ||
template <typename Head, template <auto...> class PropT, auto... Args> | ||
struct GetCompileTimePropertyHelper<PropertyContainer<Head>, PropT, Args...> { | ||
using type = typename std::conditional_t< | ||
AreSameTemplate<Head, PropT<Args...>>::value, Head, void>; | ||
}; | ||
#endif | ||
|
||
// The structs validate that all objects passed are SYCL properties. | ||
// Properties are either run time SYCL 1.2.1 properties, and thus derive from | ||
// either DataLessPropertyBase or from PropertyWithDataBase, or | ||
// compile-time-constant properties, and thus specialize | ||
// IsCompileTimePropertyInstance template. | ||
template <typename... Tail> struct AllProperties : std::true_type {}; | ||
template <typename T, typename... Tail> | ||
struct AllProperties<T, Tail...> | ||
: std::conditional< | ||
std::is_base_of<sycl::detail::DataLessPropertyBase, T>::value || | ||
std::is_base_of<sycl::detail::PropertyWithDataBase, T>::value || | ||
sycl::detail::IsCompileTimePropertyInstance<T>::value, | ||
AllProperties<Tail...>, std::false_type>::type {}; | ||
|
||
accessor_property_list( | ||
std::bitset<sycl::detail::DataLessPropKind::DataLessPropKindSize> | ||
DataLessProps, | ||
std::vector<std::shared_ptr<sycl::detail::PropertyWithDataBase>> | ||
PropsWithData) | ||
: sycl::detail::PropertyListBase(DataLessProps, PropsWithData) {} | ||
|
||
public: | ||
template < | ||
typename = typename std::enable_if<AllProperties<PropsT...>::value>::type> | ||
accessor_property_list(PropsT... Props) | ||
: sycl::detail::PropertyListBase(false) { | ||
ctorHelper(Props...); | ||
} | ||
|
||
accessor_property_list(const sycl::property_list &Props) | ||
: sycl::detail::PropertyListBase(Props.MDataLessProps, | ||
Props.MPropsWithData) {} | ||
|
||
template <typename... OtherProps, | ||
typename = typename std::enable_if< | ||
ContainsSameProperties<PropertyContainer<PropsT...>, | ||
OtherProps...>::value && | ||
ContainsSameProperties<PropertyContainer<OtherProps...>, | ||
PropsT...>::value>::type> | ||
accessor_property_list(const accessor_property_list<OtherProps...> &OtherList) | ||
: sycl::detail::PropertyListBase(OtherList.MDataLessProps, | ||
OtherList.MPropsWithData) {} | ||
|
||
template <typename PropT, typename = typename std::enable_if< | ||
!is_compile_time_property<PropT>::value>::type> | ||
PropT get_property() const { | ||
if (!has_property<PropT>()) | ||
throw sycl::invalid_object_error("The property is not found", | ||
PI_INVALID_VALUE); | ||
|
||
return get_property_helper<PropT>(); | ||
} | ||
|
||
template <class PropT> | ||
typename std::enable_if<!is_compile_time_property<PropT>::value, bool>::type | ||
has_property() const { | ||
return has_property_helper<PropT>(); | ||
} | ||
|
||
#if __cplusplus >= 201703L | ||
template <typename T> | ||
static constexpr | ||
typename std::enable_if_t<is_compile_time_property<T>::value, bool> | ||
has_property() { | ||
return ContainsPropertyInstance<PropertyContainer<PropsT...>, | ||
T::template instance>::value; | ||
} | ||
|
||
template <typename T, | ||
typename = typename std::enable_if_t< | ||
is_compile_time_property<T>::value && has_property<T>()>> | ||
static constexpr auto get_property() { | ||
return typename GetCompileTimePropertyHelper<PropertyContainer<PropsT...>, | ||
T::template instance>::type{}; | ||
} | ||
#endif | ||
|
||
private: | ||
template <typename, int, access::mode, access::target, access::placeholder, | ||
typename PropertyListT> | ||
friend class sycl::accessor; | ||
|
||
template <typename... OtherProps> friend class accessor_property_list; | ||
|
||
friend class sycl::property_list; | ||
|
||
// Helper method, used by accessor to restrict conversions to compatible | ||
// property lists. | ||
template <typename... OtherPropsT> | ||
static constexpr bool areSameCompileTimeProperties() { | ||
return ContainsSameProperties<PropertyContainer<OtherPropsT...>, | ||
PropsT...>::value; | ||
} | ||
}; | ||
} // namespace ONEAPI | ||
} // namespace sycl | ||
} // __SYCL_INLINE_NAMESPACE(cl) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.