Reducing the code by generalising sycl backend functions/structs.

This commit is contained in:
Mehdi Goli
2016-10-14 12:09:55 +01:00
parent d7f9679a34
commit 524fa4c46f
17 changed files with 755 additions and 1911 deletions

View File

@@ -18,24 +18,23 @@
*
*****************************************************************/
#ifndef UNSUPPORTED_EIGEN_CXX11_SRC_TENSORSYCL_TUPLE_HPP
#define UNSUPPORTED_EIGEN_CXX11_SRC_TENSORSYCL_TUPLE_HPP
#ifndef UNSUPPORTED_EIGEN_CXX11_SRC_TENSOR_TENSORSYCL_TUPLE_HPP
#define UNSUPPORTED_EIGEN_CXX11_SRC_TENSOR_TENSORSYCL_TUPLE_HPP
namespace utility {
namespace tuple {
/// \struct EnableIf
/// \brief The EnableIf struct is used to statically define type based on the
/// \struct StaticIf
/// \brief The StaticIf struct is used to statically choose the type based on the
/// condition.
template <bool, typename T = void>
struct EnableIf {};
/// \brief specialisation of the \ref EnableIf when the condition is true
template <bool, typename T = void> struct StaticIf;
/// \brief specialisation of the \ref StaticIf when the condition is true
template <typename T>
struct EnableIf<true, T> {
struct StaticIf<true, T> {
typedef T type;
};
/// \struct Tuple
/// \brief is a fixed-size collection of heterogeneous values
/// \ztparam Ts... - the types of the elements that the tuple stores.
/// \ztparam Ts... - the types of the elements that the tuple stores.
/// Empty list is supported.
template <class... Ts>
struct Tuple {};
@@ -47,12 +46,11 @@ struct Tuple {};
template <class T, class... Ts>
struct Tuple<T, Ts...> {
Tuple(T t, Ts... ts) : head(t), tail(ts...) {}
T head;
Tuple<Ts...> tail;
};
/// \struct ElemTypeHolder
///\ struct ElemTypeHolder
/// \brief ElemTypeHolder class is used to specify the types of the
/// elements inside the tuple
/// \tparam size_t the number of elements inside the tuple
@@ -60,78 +58,59 @@ struct Tuple<T, Ts...> {
template <size_t, class>
struct ElemTypeHolder;
/// \brief specialisation of the \ref ElemTypeHolder class when the number
/// \brief specialisation of the \ref ElemTypeHolder class when the number of
/// elements inside the tuple is 1
template <class T, class... Ts>
struct ElemTypeHolder<0, Tuple<T, Ts...>> {
struct ElemTypeHolder<0, Tuple<T, Ts...> > {
typedef T type;
};
/// \brief specialisation of the \ref ElemTypeHolder class when the number of
/// elements inside the tuple is bigger than 1. It recursively call itself to
/// elements inside the tuple is bigger than 1. It recursively calls itself to
/// detect the type of each element in the tuple
/// \tparam T : the type of the first element in the tuple.
/// \tparam Ts... the rest of the elements in the tuple. Ts... can be empty.
/// \tparam K is the Kth element in the tuple
template <size_t k, class T, class... Ts>
struct ElemTypeHolder<k, Tuple<T, Ts...>> {
typedef typename ElemTypeHolder<k - 1, Tuple<Ts...>>::type type;
struct ElemTypeHolder<k, Tuple<T, Ts...> > {
typedef typename ElemTypeHolder<k - 1, Tuple<Ts...> >::type type;
};
/// get
/// \brief Extracts the first element from the tuple.
/// K=0 represents the first element of the tuple. The tuple cannot be empty.
/// \tparam Ts... are the elements type in the tuple.
/// \tparam Ts... are the type of the elements in the tuple.
/// \param t is the tuple whose contents to extract
/// \return typename ElemTypeHolder<0, Tuple<Ts...>>::type &>::type
template <size_t k, class... Ts>
typename EnableIf<k == 0,
typename ElemTypeHolder<0, Tuple<Ts...>>::type &>::type
get(Tuple<Ts...> &t) {
return t.head;
/// \return typename ElemTypeHolder<0, Tuple<Ts...> >::type &>::type
#define TERMINATE_CONDS_TUPLE_GET(CVQual) \
template <size_t k, class... Ts> \
typename StaticIf<k == 0, CVQual typename ElemTypeHolder<0, Tuple<Ts...> >::type &>::type \
get(CVQual Tuple<Ts...> &t) { \
static_assert(sizeof...(Ts)!=0, "The requseted value is bigger than the size of the tuple"); \
return t.head; \
}
TERMINATE_CONDS_TUPLE_GET(const)
TERMINATE_CONDS_TUPLE_GET()
#undef TERMINATE_CONDS_TUPLE_GET
/// get
/// \brief Extracts the Kth element from the tuple.
/// \tparam K is an integer value in [0,sizeof...(Types)).
///\tparam K is an integer value in [0,sizeof...(Types)).
/// \tparam T is the (sizeof...(Types) -(K+1)) element in the tuple
/// \tparam Ts... are the elements type in the tuple.
/// \tparam Ts... are the type of the elements in the tuple.
/// \param t is the tuple whose contents to extract
/// \return typename ElemTypeHolder<K, Tuple<Ts...>>::type &>::type
template <size_t k, class T, class... Ts>
typename EnableIf<k != 0,
typename ElemTypeHolder<k, Tuple<T, Ts...>>::type &>::type
get(Tuple<T, Ts...> &t) {
return get<k - 1>(t.tail);
/// \return typename ElemTypeHolder<K, Tuple<Ts...> >::type &>::type
#define RECURSIVE_TUPLE_GET(CVQual) \
template <size_t k, class T, class... Ts> \
typename StaticIf<k != 0, CVQual typename ElemTypeHolder<k, Tuple<T, Ts...> >::type &>::type \
get(CVQual Tuple<T, Ts...> &t) { \
return get<k - 1>(t.tail); \
}
RECURSIVE_TUPLE_GET(const)
RECURSIVE_TUPLE_GET()
#undef RECURSIVE_TUPLE_GET
/// get
/// \brief Extracts the first element from the tuple when the tuple and all the
/// elements inside are const.
/// K=0 represents the first element of the tuple. The tuple cannot be empty.
/// \tparam Ts... are the elements type in the tuple.
/// \param t is the const tuple whose contents to extract
/// \return const typename ElemTypeHolder<0, Tuple<Ts...>>::type &>::type
template <size_t k, class... Ts>
typename EnableIf<k == 0,
const typename ElemTypeHolder<0, Tuple<Ts...>>::type &>::type
get(const Tuple<Ts...> &t) {
return t.head;
}
/// get
/// \brief Extracts the Kth element from the tuple when the tuple and all the
/// elements inside are const.
/// \tparam K is an integer value in [0,sizeof...(Types)).
/// \tparam T is the (sizeof...(Types) -(K+1)) element in the tuple
/// \tparam Ts... are the elements type in the tuple.
/// \param t is the const tuple whose contents to extract
/// \return const typename ElemTypeHolder<K, Tuple<Ts...>>::type &>::type
template <size_t k, class T, class... Ts>
typename EnableIf<
k != 0, const typename ElemTypeHolder<k, Tuple<T, Ts...>>::type &>::type
get(const Tuple<T, Ts...> &t) {
return get<k - 1>(t.tail);
}
/// make_tuple
/// \brief Creates a tuple object, deducing the target type from the types of
/// arguments.
@@ -153,17 +132,17 @@ static constexpr size_t size(Tuple<Args...> &) {
return sizeof...(Args);
}
/// \struct Index_list
/// \struct IndexList
/// \brief Creates a list of index from the elements in the tuple
/// \tparam Is... a list of index from [0 to sizeof...(tuple elements))
template <size_t... Is>
struct Index_list {};
struct IndexList {};
/// \struct RangeBuilder
/// \brief Collects internal details for generating index ranges [MIN, MAX)
/// Declare primary template for index range builder
/// \tparam MIN is the starting index in the tuple
/// \tparam N represents sizeof..(elements)- sizeof...(Is)
/// \tparam N represents sizeof..(elemens)- sizeof...(Is)
/// \tparam Is... are the list of generated index so far
template <size_t MIN, size_t N, size_t... Is>
struct RangeBuilder;
@@ -174,14 +153,14 @@ struct RangeBuilder;
/// \tparam Is is [0 to sizeof...(tuple elements))
template <size_t MIN, size_t... Is>
struct RangeBuilder<MIN, MIN, Is...> {
typedef Index_list<Is...> type;
typedef IndexList<Is...> type;
};
/// Induction step: Specialisation of the RangeBuilder class when N!=MIN
/// in this case we are recursively subtracting the N by one and adding one
/// in this case we are recursively subtracting N by one and adding one
/// index to Is... list until MIN==N
/// \tparam MIN is the starting index in the tuple
/// \tparam N represents sizeof..(elements)- sizeof...(Is)
/// \tparam N represents sizeof..(elemens)- sizeof...(Is)
/// \tparam Is... are the list of generated index so far
template <size_t MIN, size_t N, size_t... Is>
struct RangeBuilder : public RangeBuilder<MIN, N - 1, N - 1, Is...> {};
@@ -190,75 +169,66 @@ struct RangeBuilder : public RangeBuilder<MIN, N - 1, N - 1, Is...> {};
/// \tparam MIN is the starting index in the tuple
/// \tparam MAX is the size of the tuple
template <size_t MIN, size_t MAX>
using Index_range = typename RangeBuilder<MIN, MAX>::type;
struct IndexRange: RangeBuilder<MIN, MAX>::type {};
/// append_impl
/// append_base
/// \brief unpacking the elements of the input tuple t and creating a new tuple
/// by adding element a at the end of it.
/// \tparam Args... the type of the elements inside the tuple t
///\tparam Args... the type of the elements inside the tuple t
/// \tparam T the type of the new element going to be added at the end of tuple
/// \tparam I... is the list of index from [0 to sizeof...(t))
/// \param t the tuple on which we want to append a.
/// \param a the new elements going to be added to the tuple
/// \return Tuple<Args..., T>
template <typename... Args, typename T, size_t... I>
Tuple<Args..., T> append_impl(utility::tuple::Tuple<Args...> t, T a,
utility::tuple::Index_list<I...>) {
return utility::tuple::make_tuple(get<I>(t)..., a);
Tuple<Args..., T> append_base(Tuple<Args...> t, T a,IndexList<I...>) {
return make_tuple(get<I>(t)..., a);
}
/// append
/// \brief the deduction function for \ref append_impl that automatically
/// generate the \ref Index_range
/// \tparam Args... the type of the elements inside the tuple t
/// \brief the deduction function for \ref append_base that automatically
/// generate the \ref IndexRange
///\tparam Args... the type of the elements inside the tuple t
/// \tparam T the type of the new element going to be added at the end of tuple
/// \param t the tuple on which we want to append a.
/// \param a the new elements going to be added to the tuple
/// \return Tuple<Args..., T>
template <typename... Args, typename T>
Tuple<Args..., T> append(Tuple<Args...> t, T a) {
return utility::tuple::append_impl(
t, a, utility::tuple::Index_range<0, sizeof...(Args)>());
return append_base(t, a, IndexRange<0, sizeof...(Args)>());
}
/// append_impl
/// \brief This is an specialised of \ref append_impl when we want to
/// append_base
/// \brief This is a specialisation of \ref append_base when we want to
/// concatenate
/// tuple t2 at the end of the tuple t1. Here we unpack both tuples, generate
/// the
/// Index_range for each of them and create an output tuple T that contains both
/// tuple t2 at the end of the tuple t1. Here we unpack both tuples, generate the
/// IndexRange for each of them and create an output tuple T that contains both
/// elements of t1 and t2.
/// \tparam Args1... the type of the elements inside the tuple t1
/// \tparam Args2... the type of the elements inside the tuple t2
///\tparam Args1... the type of the elements inside the tuple t1
///\tparam Args2... the type of the elements inside the tuple t2
/// \tparam I1... is the list of index from [0 to sizeof...(t1))
/// \tparam I2... is the list of index from [0 to sizeof...(t2))
/// \param t1 is the tuple on which we want to append t2.
/// \param t2 is the tuple that is going to be added on t1.
/// \return Tuple<Args1..., Args2...>
template <typename... Args1, typename... Args2, size_t... I1, size_t... I2>
Tuple<Args1..., Args2...> append_impl(utility::tuple::Tuple<Args1...> t1,
utility::tuple::Tuple<Args2...> t2,
utility::tuple::Index_list<I1...>,
utility::tuple::Index_list<I2...>) {
return utility::tuple::make_tuple(utility::tuple::get<I1>(t1)...,
utility::tuple::get<I2>(t2)...);
Tuple<Args1..., Args2...> append_base(Tuple<Args1...> t1, Tuple<Args2...> t2, IndexList<I1...>, IndexList<I2...>) {
return make_tuple(get<I1>(t1)...,get<I2>(t2)...);
}
/// append
/// \brief deduction function for \ref append_impl when we are appending tuple
/// t1 by tuple t2. In this case the \ref Index_range for both tuple are
/// \brief deduction function for \ref append_base when we are appending tuple
/// t1 by tuple t2. In this case the \ref IndexRange for both tuple are
/// automatically generated.
/// \tparam Args1... the type of the elements inside the tuple t1
/// \tparam Args2... the type of the elements inside the tuple t2
///\tparam Args1... the type of the elements inside the tuple t1
///\tparam Args2... the type of the elements inside the tuple t2
/// \param t1 is the tuple on which we want to append t2.
/// \param t2 is the tuple that is going to be added on t1.
/// \return Tuple<Args1..., Args2...>
template <typename... Args1, typename... Args2>
Tuple<Args1..., Args2...> append(utility::tuple::Tuple<Args1...> t1,
utility::tuple::Tuple<Args2...> t2) {
return utility::tuple::append_impl(
t1, t2, utility::tuple::Index_range<0, sizeof...(Args1)>(),
utility::tuple::Index_range<0, sizeof...(Args2)>());
Tuple<Args1..., Args2...> append(Tuple<Args1...> t1,Tuple<Args2...> t2) {
return append_base(t1, t2, IndexRange<0, sizeof...(Args1)>(), IndexRange<0, sizeof...(Args2)>());
}
} // tuple
} // utility
#endif // UNSUPPORTED_EIGEN_CXX11_SRC_TENSORSYCL_TUPLE_HPP
#endif // UNSUPPORTED_EIGEN_CXX11_SRC_TENSOR_TENSORSYCL_TUPLE_HPP