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