-
Notifications
You must be signed in to change notification settings - Fork 769
[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
Changes from 17 commits
d0d2a86
415c939
41365d7
ee55a6a
976dfec
33da077
5dba583
809061d
e9b9246
ccb172f
ff28dc2
49028d5
c22997b
c4cebba
0091796
d70980c
3277faa
2c04881
ed8efd7
e982a29
7a51468
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 || | ||
!sycl::detail::IsCompileTimePropertyInstance<PropT>::value, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now, if the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was done to skip runtime properties, but that was probably the wrong place. Moved. |
||
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 || | ||
!sycl::detail::IsCompileTimePropertyInstance< | ||
typename ContainerT::Head>::value), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same question here |
||
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 to lists of properties contain the same set of | ||
alexbatashev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// compile-time-constant properties in any order. | ||
template <typename ContainerT, typename... OtherProps> | ||
struct ContainsSameProperties | ||
: std::conditional< | ||
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) |
Uh oh!
There was an error while loading. Please reload this page.