Skip to content

Commit

Permalink
more removals in xfunction, and fixes regarding review
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfv committed Oct 11, 2018
1 parent ef222ee commit d83e0fa
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 180 deletions.
3 changes: 0 additions & 3 deletions include/xtensor/xcomplex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,6 @@ namespace xt
template <class E>
inline auto conj(E&& e) noexcept
{
using value_type = typename std::decay_t<E>::value_type;
using functor = math::conj_impl_fun;
using type = xfunction<functor, const_xclosure_t<E>>;
return type(functor(), std::forward<E>(e));
Expand All @@ -205,7 +204,6 @@ namespace xt
template <class E>
inline auto arg(E&& e) noexcept
{
using value_type = typename std::decay_t<E>::value_type;
using functor = math::arg_fun;
using type = xfunction<functor, const_xclosure_t<E>>;
return type(functor(), std::forward<E>(e));
Expand Down Expand Up @@ -237,7 +235,6 @@ namespace xt
template <class E>
inline auto norm(E&& e) noexcept
{
using value_type = typename std::decay_t<E>::value_type;
using functor = math::norm_fun;
using type = xfunction<functor, const_xclosure_t<E>>;
return type(functor(), std::forward<E>(e));
Expand Down
9 changes: 5 additions & 4 deletions include/xtensor/xcontainer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,8 @@ namespace xt

template <class align, class simd>
void store_simd(size_type i, const simd& e);
template <class align, class requested_type = value_type, std::ptrdiff_t N = -1>
template <class align, class requested_type = value_type,
std::size_t N = xsimd::simd_traits<requested_type>::size>
simd_return_type<requested_type> load_simd(size_type i) const;

storage_iterator storage_begin() noexcept;
Expand Down Expand Up @@ -802,11 +803,11 @@ namespace xt
}

template <class D>
template <class alignment, class requested_type, std::ptrdiff_t N>
inline auto xcontainer<D>::load_simd(size_type i) const -> simd_return_type<requested_type>
template <class alignment, class requested_type, std::size_t N>
inline auto xcontainer<D>::load_simd(size_type i) const
-> simd_return_type<requested_type>
{
using align_mode = driven_align_mode_t<alignment, data_alignment>;
using batch_type = simd_return_type<requested_type>;
return xsimd::load_simd<value_type, requested_type>(&(storage()[i]), align_mode());
}

Expand Down
199 changes: 48 additions & 151 deletions include/xtensor/xfunction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,104 +81,6 @@ namespace xt
template <class... Args>
using common_difference_type_t = typename common_difference_type<Args...>::type;

/*********************
* common_value_type *
*********************/

template <class... Args>
struct common_value_type
{
using type = typename std::common_type<xvalue_type_t<Args>...>::type;
};

template <class... Args>
using common_value_type_t = typename common_value_type<Args...>::type;

/**********************
* promote_value_type *
**********************/

template <class... Args>
struct promote_value_type
{
using type = typename promote_type<xvalue_type_t<Args>...>::type;
};

template <class... Args>
using promote_value_type_t = typename promote_value_type<Args...>::type;

/**********************
* functor_value_type *
**********************/

template <class T, class R>
struct functor_value_type
{
using type = R;
};

template <class T, class R>
using functor_value_type_t = typename functor_value_type<T, R>::type;

/********************
* simd_return_type *
********************/

template <class F, class CST, class R, class = void_t<>>
struct simd_return_type
{
};

template <class F, class CST, class R>
struct simd_return_type<F, CST, R, void_t<decltype(&F(std::declval<CST>()))>>
{
using type = xsimd::simd_return_type<CST, R>;
};

template <class F, class CST, class R>
using simd_return_type_t = typename simd_return_type<F, CST, R>::type;

/*********************
* functor_simd_type *
*********************/

// General case
template <class T, class R>
struct functor_simd_type
{
// Never use xsimd::simd_type<R>. A function may operates on int32_t but
// be asked to load arguments as batches of floating point numbers because it is part
// of an expression whose promote_type is a floating point number.
using type = xsimd::simd_type<T>;
};

// Comparison functions
template <class T>
struct functor_simd_type<T, bool>
{
using type = xsimd::simd_bool_type<T>;
};

// complex reducers (abs, args)
template <class T>
struct functor_simd_type<std::complex<T>, T>
{
using type = xsimd::simd_type<T>;
};

template <class T, class R>
using functor_simd_type_t = typename functor_simd_type<T, R>::type;

template <class B, class R>
struct functor_batch_simd_type
{
using batch_value_type = typename xsimd::revert_simd_traits<B>::type;
using type = typename functor_simd_type<batch_value_type, R>::type;
};

template <class B, class R>
using functor_batch_simd_type_t = typename functor_batch_simd_type<B, R>::type;

// State storage
template<class S, class is_shape_trivial>
struct xfunction_cache_impl
Expand Down Expand Up @@ -209,34 +111,7 @@ namespace xt
template <std::size_t... N, class is_shape_trivial>
constexpr bool xfunction_cache_impl<fixed_shape<N...>, is_shape_trivial>::is_initialized;
#endif
}

template<class promote>
struct xfunction_cache : detail::xfunction_cache_impl<typename promote::type, promote> {};

template <class F, class... CT>
class xfunction_iterator;

template <class F, class... CT>
class xfunction_stepper;

template <class F, class... CT>
class xfunction_base;

template <class F, class... CT>
struct xiterable_inner_types<xfunction_base<F, CT...>>
{
using inner_shape_type = promote_shape_t<typename std::decay_t<CT>::shape_type...>;
using const_stepper = xfunction_stepper<F, CT...>;
using stepper = const_stepper;
};

/******************
* xfunction_base *
******************/

namespace detail
{
template <class F, class B, class = void>
struct has_simd_apply : std::false_type {};

Expand All @@ -252,34 +127,57 @@ namespace xt
{
};

template <class T>
struct meta_identity
{
using type = T;
};

// This meta struct checks wether SIMD should be activated for our
// functor "F"
template <class V, class F, class... CT>
struct xsimd_meta_getter
{
using scalar_value_type = V;
using functor = F;
using scalar_result_type = V;

// check if all arguments are supported by SIMD
using simd_arguments_exist = xtl::conjunction<has_simd_type<V>, has_simd_type<xvalue_type_t<std::decay_t<CT>>>...>;
using simd_arguments_exist = xtl::conjunction<has_simd_type<scalar_result_type>,
has_simd_type<xvalue_type_t<std::decay_t<CT>>>...>;
// if yes, insert correct type here
using simd_value_type = xtl::mpl::eval_if_t<simd_arguments_exist,
std::common_type<xsimd::simd_type<V>>,
make_invalid_type<> >;

using use_xsimd = xtl::conjunction<simd_arguments_exist, has_simd_apply<F, scalar_value_type>, has_simd_interface<std::decay_t<CT>>...>;
using simd_return_type = xsimd::simd_type<V>;
meta_identity<xsimd::simd_type<scalar_result_type>>,
make_invalid_type<>>;
// if all types are supported, check that the functor has a working
// simd_apply and all arguments have the simd interface
using use_xsimd = xtl::conjunction<simd_arguments_exist,
has_simd_apply<F, scalar_result_type>,
has_simd_interface<std::decay_t<CT>>...>;
};
}

namespace detail
template<class promote>
struct xfunction_cache : detail::xfunction_cache_impl<typename promote::type, promote> {};

template <class F, class... CT>
class xfunction_iterator;

template <class F, class... CT>
class xfunction_stepper;

template <class F, class... CT>
class xfunction_base;

template <class F, class... CT>
struct xiterable_inner_types<xfunction_base<F, CT...>>
{
template <class T>
struct meta_identity
{
using type = T;
};
}
using inner_shape_type = promote_shape_t<typename std::decay_t<CT>::shape_type...>;
using const_stepper = xfunction_stepper<F, CT...>;
using stepper = const_stepper;
};

/******************
* xfunction_base *
******************/

#define DL XTENSOR_DEFAULT_LAYOUT

Expand Down Expand Up @@ -318,13 +216,10 @@ namespace xt

using has_simd_interface = typename simd_meta_getter::use_xsimd;
using simd_value_type = typename simd_meta_getter::simd_value_type;
using simd_argument_type = xsimd::simd_type<value_type>;

template <class T>
using simd_return_type = typename simd_meta_getter::simd_return_type;
using simd_argument_type = simd_value_type;

// template <class simd>
// using simd_return_type = detail::simd_return_type_t<functor_type, simd_argument_type, simd>;
template <class requested_type>
using simd_return_type = xsimd::simd_return_type<value_type, requested_type>;

using iterable_base = xconst_iterable<xfunction_base<F, CT...>>;
using inner_shape_type = typename iterable_base::inner_shape_type;
Expand Down Expand Up @@ -422,8 +317,9 @@ namespace xt
template <class UT = self_type, class = typename std::enable_if<UT::only_scalar::value>::type>
operator value_type() const;

template <class align, class requested_type = value_type, std::ptrdiff_t N = -1>
auto load_simd(size_type i) const;
template <class align, class requested_type = value_type,
std::size_t N = xsimd::simd_traits<requested_type>::size>
simd_return_type<requested_type> load_simd(size_type i) const;

const tuple_type& arguments() const noexcept;

Expand Down Expand Up @@ -457,7 +353,7 @@ namespace xt
template <std::size_t... I>
const_reference data_element_impl(std::index_sequence<I...>, size_type i) const;

template <class align, class requested_type, std::ptrdiff_t N, std::size_t... I>
template <class align, class requested_type, std::size_t N, std::size_t... I>
auto load_simd_impl(std::index_sequence<I...>, size_type i) const;

template <class Func, std::size_t... I>
Expand Down Expand Up @@ -970,8 +866,9 @@ namespace xt
}

template <class F, class... CT>
template <class align, class requested_type, std::ptrdiff_t N>
template <class align, class requested_type, std::size_t N>
inline auto xfunction_base<F, CT...>::load_simd(size_type i) const
-> simd_return_type<requested_type>
{
return load_simd_impl<align, requested_type, N>(std::make_index_sequence<sizeof...(CT)>(), i);
}
Expand Down Expand Up @@ -1044,7 +941,7 @@ namespace xt
}

template <class F, class... CT>
template <class align, class requested_type, std::ptrdiff_t N, std::size_t... I>
template <class align, class requested_type, std::size_t N, std::size_t... I>
inline auto xfunction_base<F, CT...>::load_simd_impl(std::index_sequence<I...>, size_type i) const
{
return m_f.simd_apply((std::get<I>(m_e)
Expand Down
5 changes: 2 additions & 3 deletions include/xtensor/xmath.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,13 @@ XTENSOR_INT_SPECIALIZATION_IMPL(FUNC_NAME, RETURN_VAL, unsigned long long);
struct NAME##_fun \
{ \
template <class T1, class T2> \
constexpr auto operator()(const T1& arg1, const T2& arg2) const \
constexpr auto operator()(const T1& arg1, const T2& arg2) const \
{ \
using math::NAME; \
return NAME(arg1, arg2); \
} \
template <class B> \
constexpr auto \
simd_apply(const B& arg1, const B& arg2) const \
constexpr auto simd_apply(const B& arg1, const B& arg2) const \
{ \
using math::NAME; \
return NAME(arg1, arg2); \
Expand Down
11 changes: 0 additions & 11 deletions include/xtensor/xoptional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,6 @@ namespace xt

namespace detail
{
template <class CT, class CB>
struct functor_value_type<xtl::xoptional<CT, CB>, bool>
{
using type = xtl::xoptional<bool>;
};

template <class CT, class CB>
struct functor_simd_type<xtl::xoptional<CT, CB>, bool>
{
using type = xtl::xoptional<bool>;
};

template <class T, class Tag>
struct split_optional_expression_impl
Expand Down
10 changes: 6 additions & 4 deletions include/xtensor/xscalar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,10 @@ namespace xt

template <class align, class simd = simd_value_type>
void store_simd(size_type i, const simd& e);
template <class align, class requested_type = value_type>
auto load_simd(size_type i) const;
template <class align, class requested_type = value_type,
std::size_t N = xsimd::simd_traits<requested_type>::size>
xsimd::simd_return_type<value_type, requested_type>
load_simd(size_type i) const;

private:

Expand Down Expand Up @@ -941,10 +943,10 @@ namespace xt
}

template <class CT>
template <class align, class requested_type>
template <class align, class requested_type, std::size_t N>
inline auto xscalar<CT>::load_simd(size_type) const
-> xsimd::simd_return_type<value_type, requested_type>
{
using type = xsimd::simd_return_type<value_type, requested_type>;
return xsimd::set_simd<value_type, requested_type>(m_value);
}

Expand Down
2 changes: 1 addition & 1 deletion include/xtensor/xtensor_simd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ namespace xsimd
using revert_simd_type = typename revert_simd_traits<T>::type;

template <class T, class V>
inline simd_type<V> set_simd(const T& value)
inline simd_type<T> set_simd(const T& value)
{
return value;
}
Expand Down
3 changes: 0 additions & 3 deletions include/xtensor/xutils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -804,9 +804,6 @@ namespace xt
/**
* @brief Abbreviation of 'typename promote_type<T>::type'.
*/
// template <class... T>
// using promote_type_t = xtl::mpl::eval_if_t<xtl::conjunction<std::is_scalar<T>...>,
// promote_type<T...>,
template <class... T>
using promote_type_t = typename promote_type<T...>::type;
/**
Expand Down
Loading

0 comments on commit d83e0fa

Please sign in to comment.