1 //  Copyright (c) 2016 Hartmut Kaiser
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #if !defined(HPX_PARALLEL_TRAITS_VECTOR_PACK_LOAD_BOOST_SIMD_SEP_26_2016_0719PM)
7 #define HPX_PARALLEL_TRAITS_VECTOR_PACK_LOAD_BOOST_SIMD_SEP_26_2016_0719PM
8 
9 #include <hpx/config.hpp>
10 
11 #if defined(HPX_HAVE_DATAPAR_BOOST_SIMD)
12 #include <hpx/util/tuple.hpp>
13 
14 #include <cstddef>
15 #include <iterator>
16 #include <memory>
17 
18 #include <boost/simd.hpp>
19 #include <boost/simd/function/aligned_load.hpp>
20 #include <boost/simd/function/aligned_store.hpp>
21 #include <boost/simd/function/load.hpp>
22 #include <boost/simd/function/store.hpp>
23 
24 ///////////////////////////////////////////////////////////////////////////////
25 namespace hpx { namespace parallel { namespace traits
26 {
27     ///////////////////////////////////////////////////////////////////////////
28     template <typename T, std::size_t N, typename Abi, typename NewT>
29     struct rebind_pack<boost::simd::pack<T, N, Abi>, NewT>
30     {
31         typedef boost::simd::pack<NewT, N, Abi> type;
32     };
33 
34     // don't wrap types twice
35     template <typename T, std::size_t N1, typename Abi1,
36         typename NewT, std::size_t N2, typename Abi2>
37     struct rebind_pack<boost::simd::pack<T, N1, Abi1>,
38         boost::simd::pack<NewT, N2, Abi2> >
39     {
40         typedef boost::simd::pack<NewT, N2, Abi2> type;
41     };
42 
43     ///////////////////////////////////////////////////////////////////////////
44     template <typename V, typename ValueType, typename Enable>
45     struct vector_pack_load
46     {
47         typedef typename rebind_pack<V, ValueType>::type value_type;
48 
49         template <typename Iter>
alignedhpx::parallel::traits::vector_pack_load50         static value_type aligned(Iter const& iter)
51         {
52             return boost::simd::aligned_load<vector_pack_type>(
53                 std::addressof(*iter));
54         }
55 
56         template <typename Iter>
unalignedhpx::parallel::traits::vector_pack_load57         static value_type unaligned(Iter const& iter)
58         {
59             return boost::simd::load<vector_pack_type>(std::addressof(*iter));
60         }
61     };
62 
63     template <typename V, typename T, std::size_t N, typename Abi>
64     struct vector_pack_load<V, boost::simd::pack<T, N, Abi> >
65     {
66         typedef typename rebind_pack<V, boost::simd::pack<T, N, Abi> >::type
67             value_type;
68 
69         template <typename Iter>
alignedhpx::parallel::traits::vector_pack_load70         static value_type aligned(Iter const& iter)
71         {
72             return *iter;
73         }
74 
75         template <typename Iter>
unalignedhpx::parallel::traits::vector_pack_load76         static value_type unaligned(Iter const& iter)
77         {
78             return *iter;
79         }
80     };
81 
82     ///////////////////////////////////////////////////////////////////////////
83     template <typename V, typename Value_type, typename Enable>
84     struct vector_pack_store
85     {
86         template <typename Iter>
alignedhpx::parallel::traits::vector_pack_store87         static void aligned(V const& value, Iter const& iter)
88         {
89             boost::simd::aligned_store(value, std::addressof(*iter));
90         }
91 
92         template <typename Iter>
unalignedhpx::parallel::traits::vector_pack_store93         static void unaligned(V const& value, Iter const& iter)
94         {
95             boost::simd::store(value, std::addressof(*iter));
96         }
97     };
98 
99     template <typename V, typename T, std::size_t N, typename Abi>
100     struct vector_pack_store<V, boost::simd::pack<T, N, Abi> >
101     {
102         template <typename Iter>
alignedhpx::parallel::traits::vector_pack_store103         static void aligned(V const& value, Iter const& iter)
104         {
105             *iter = value;
106         }
107 
108         template <typename Iter>
unalignedhpx::parallel::traits::vector_pack_store109         static void unaligned(V const& value, Iter const& iter)
110         {
111             *iter = value;
112         }
113     };
114 }}}
115 
116 #endif
117 #endif
118