Loading include/dca/linalg/multi_vector.hpp +3 −7 Original line number Diff line number Diff line Loading @@ -16,9 +16,6 @@ #include "dca/linalg/util/cuda_stream.hpp" #include "dca/util/type_list.hpp" #include "dca/util/pack_operations.hpp" #ifdef DCA_HAVE_CUDA #include <cuda_runtime.h> #endif namespace dca { namespace linalg { Loading @@ -37,14 +34,12 @@ public: // Resize the container so that each sub-array has size n, invalidating references and values. void resizeNoCopy(std::size_t n); #ifdef DCA_HAVE_CUDA // Copy the values of rhs asynchronously. template <DeviceType other_device> void setAsync(const MultiVector<other_device, Ts...>& rhs, cudaStream_t stream) { void setAsync(const MultiVector<other_device, Ts...>& rhs, const linalg::util::CudaStream& stream) { size_ = rhs.size_; data_.setAsync(rhs.data_, stream); } #endif // DCA_HAVE_CUDA // Returns a pointer to the beginning of the id-th array // Preconditions: 0 <= id < length(Ts...). Loading Loading @@ -97,7 +92,7 @@ auto MultiVector<device, Ts...>::get() const -> const Type<id>* { template <DeviceType device, typename... Ts> template <unsigned id> std::size_t MultiVector<device, Ts...>::offset() const { static_assert(id < dca::util::Length<Types>::value, "Invalid sub-array id."); static_assert(id < sizeof...(Ts), "Invalid sub-array id."); constexpr unsigned size_t_sum = dca::util::size_sum<dca::util::Sublist<id, Ts...>>; return size_ * size_t_sum; Loading @@ -105,4 +100,5 @@ std::size_t MultiVector<device, Ts...>::offset() const { } // namespace linalg } // namespace dca #endif // DCA_LINALG_MULTI_VECTOR_HPP include/dca/util/type_list.hpp +32 −108 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ // See CITATION.md for citation guidelines, if DCA++ is used for scientific publications. // // Author: John Biddiscombe (john.biddiscombe@cscs.ch) // Giovanni Balduzzi (gbalduzz@itp.phys.ethz.ch) // // This file provides a type list and type list operations. // Loading @@ -31,60 +32,24 @@ namespace util { template <class... T> struct mp_list {}; // mp_rename: A<...> -> B<...> template <class A, template <class...> class B> struct mp_rename_impl; template <template <class...> class A, class... T, template <class...> class B> struct mp_rename_impl<A<T...>, B> { using type = B<T...>; }; template <class A, template <class...> class B> using mp_rename = typename mp_rename_impl<A, B>::type; // mp_size template <class L> struct mp_size_impl; struct mp_size; template <template <class...> class L, class... T> struct mp_size_impl<L<T...>> { using type = std::integral_constant<std::size_t, sizeof...(T)>; }; template <class L> using mp_size = typename mp_size_impl<L>::type; // mp_plus template <class... T> struct mp_plus_impl; template <class... T> using mp_plus = typename mp_plus_impl<T...>::type; template <> struct mp_plus_impl<> { using type = std::integral_constant<int, 0>; }; template <class T1, class... T> struct mp_plus_impl<T1, T...> { static constexpr auto _v = T1::value + mp_plus<T...>::value; using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>; struct mp_size<L<T...>> { constexpr static int value = sizeof...(T); }; // mp_count template <class L, class V> struct mp_count_impl; struct mp_count; template <template <class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V> { using type = mp_plus<std::is_same<T, V>...>; struct mp_count<L<T...>, V> { constexpr static int value = (0 + ... + std::is_same_v<T, V>); }; template <class L, class V> using mp_count = typename mp_count_impl<L, V>::type; // mp_append template <typename T, typename... TL> struct mp_append; Loading @@ -96,17 +61,17 @@ struct mp_append<mp_list<Ts...>> { template <typename T, typename... Ts> struct mp_append<mp_list<Ts...>, T> { typedef mp_list<Ts..., T> type; using type = mp_list<Ts..., T>; }; template <typename... Ts1, typename... Ts2> struct mp_append<mp_list<Ts1...>, mp_list<Ts2...>> { typedef mp_list<Ts1..., Ts2...> type; using type = mp_list<Ts1..., Ts2...>; }; template <typename... Ts1, typename... Ts2, typename... Ts> struct mp_append<mp_list<Ts1...>, mp_list<Ts2...>, Ts...> { typedef typename mp_append<mp_list<Ts1..., Ts2...>, Ts...>::type type; using type = typename mp_append<mp_list<Ts1..., Ts2...>, Ts...>::type; }; // mp_prepend Loading @@ -115,84 +80,43 @@ struct mp_prepend; template <typename T, typename... Ts> struct mp_prepend<mp_list<Ts...>, T> { typedef mp_list<T, Ts...> type; using type = mp_list<T, Ts...>; }; template <typename... Ts1, typename... Ts2> struct mp_prepend<mp_list<Ts1...>, mp_list<Ts2...>> { typedef mp_list<Ts2..., Ts1...> type; using type = mp_list<Ts2..., Ts1...>; }; // mp_element // Get the n'th type from a typelist/tuple efficiently without recursion. // Reference: True Story: Efficient Packing // http://talesofcpp.fusionfenix.com/post-22/true-story-efficient-packing template <std::size_t I, typename T> struct _indexed { using type = T; }; template <typename Is, typename... Ts> struct _indexer; template <std::size_t... Is, typename... Ts> struct _indexer<std::index_sequence<Is...>, Ts...> : _indexed<Is, Ts>... {}; template <std::size_t I, typename... Ts> struct _at_index { template <typename T> static _indexed<I, T> _select(_indexed<I, T>); using _impl = _indexer<std::index_sequence_for<Ts...>, Ts...>; using type = typename decltype(_select(_impl{}))::type; }; // Was tuple_element, but we want typelist_element. template <std::size_t I, typename Tuple> struct mp_element; template <std::size_t I, typename... Ts> struct mp_element<I, mp_list<Ts...>> : _at_index<I, Ts...> {}; // mp_index_of // Search a typelist for a first occurrence of the type T. // Implementation: has index as a template parameter template <size_t idx, typename T, class List> struct mp_index_of_impl; template <size_t idx, typename T> // The type T is not in the list. struct mp_index_of_impl<idx, T, mp_list<>> { using type = std::integral_constant<int, -1>; struct mp_element<I, mp_list<Ts...>> { using type = std::tuple_element_t<I, std::tuple<Ts...>>; }; template <size_t idx, typename T, typename... Ts> // The type is found. struct mp_index_of_impl<idx, T, mp_list<T, Ts...>> { using type = std::integral_constant<int, idx>; }; // mp_index_of // Search a typelist for a first occurrence of the type T. Value is -1 if the type is not found. template <typename V, typename... Ts> struct mp_index_of; template <size_t idx, typename T, typename H, typename... Ts> // Recursion. struct mp_index_of_impl<idx, T, mp_list<H, Ts...>> { using type = typename mp_index_of_impl<idx + 1, T, mp_list<Ts...>>::type; template <typename V, typename... Ts> struct mp_index_of<V, mp_list<V, Ts...>> { // Index found. static constexpr int value = 0; }; // Wrapping to supply initial index 0. template <typename T, class List> struct mp_index_of { template <typename V> struct mp_index_of<V, mp_list<>> { // Index not found. static constexpr int value = -1; }; // Specializing for idx >= 0. template <typename T, typename... Ts> struct mp_index_of<T, mp_list<Ts...>> { using type = typename mp_index_of_impl<0, T, mp_list<Ts...>>::type; using value_type = typename type::value_type; static constexpr value_type value = type::value; }; // Specializing for idx >= 0. template <typename T, typename... Ts> struct mp_index_of<mp_list<Ts...>, T> { // static_assert(false, "Parameter ordering incorrect"); template <typename V, typename T1, typename... Ts> struct mp_index_of<V, mp_list<T1, Ts...>> { // Recursion. static constexpr int next = mp_index_of<V, mp_list<Ts...>>::value; static constexpr int value = next == -1 ? -1 : next + 1; }; // mp_swap Loading @@ -202,22 +126,22 @@ struct mp_swap {}; template <typename T1, typename T2> struct mp_swap<mp_list<>, T1, T2> { typedef mp_list<> type; using type = mp_list<>; }; template <typename T1, typename T2, typename... Ts> struct mp_swap<mp_list<T1, Ts...>, T1, T2> { typedef mp_list<T2, Ts...> type; using type = mp_list<T2, Ts...>; }; template <typename T0, typename... Ts, typename T1, typename T2> struct mp_swap<mp_list<T0, Ts...>, T1, T2> { typedef typename mp_prepend<typename mp_swap<mp_list<Ts...>, T1, T2>::type, T0>::type type; using type = typename mp_prepend<typename mp_swap<mp_list<Ts...>, T1, T2>::type, T0>::type; }; template <typename T1, typename Ts> template <typename T1, typename Domain> constexpr bool contained() { return mp_index_of<T1, Ts>::value != -1; return mp_index_of<T1, typename Domain::this_type>::value != -1; } // mp_sublist Loading Loading
include/dca/linalg/multi_vector.hpp +3 −7 Original line number Diff line number Diff line Loading @@ -16,9 +16,6 @@ #include "dca/linalg/util/cuda_stream.hpp" #include "dca/util/type_list.hpp" #include "dca/util/pack_operations.hpp" #ifdef DCA_HAVE_CUDA #include <cuda_runtime.h> #endif namespace dca { namespace linalg { Loading @@ -37,14 +34,12 @@ public: // Resize the container so that each sub-array has size n, invalidating references and values. void resizeNoCopy(std::size_t n); #ifdef DCA_HAVE_CUDA // Copy the values of rhs asynchronously. template <DeviceType other_device> void setAsync(const MultiVector<other_device, Ts...>& rhs, cudaStream_t stream) { void setAsync(const MultiVector<other_device, Ts...>& rhs, const linalg::util::CudaStream& stream) { size_ = rhs.size_; data_.setAsync(rhs.data_, stream); } #endif // DCA_HAVE_CUDA // Returns a pointer to the beginning of the id-th array // Preconditions: 0 <= id < length(Ts...). Loading Loading @@ -97,7 +92,7 @@ auto MultiVector<device, Ts...>::get() const -> const Type<id>* { template <DeviceType device, typename... Ts> template <unsigned id> std::size_t MultiVector<device, Ts...>::offset() const { static_assert(id < dca::util::Length<Types>::value, "Invalid sub-array id."); static_assert(id < sizeof...(Ts), "Invalid sub-array id."); constexpr unsigned size_t_sum = dca::util::size_sum<dca::util::Sublist<id, Ts...>>; return size_ * size_t_sum; Loading @@ -105,4 +100,5 @@ std::size_t MultiVector<device, Ts...>::offset() const { } // namespace linalg } // namespace dca #endif // DCA_LINALG_MULTI_VECTOR_HPP
include/dca/util/type_list.hpp +32 −108 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ // See CITATION.md for citation guidelines, if DCA++ is used for scientific publications. // // Author: John Biddiscombe (john.biddiscombe@cscs.ch) // Giovanni Balduzzi (gbalduzz@itp.phys.ethz.ch) // // This file provides a type list and type list operations. // Loading @@ -31,60 +32,24 @@ namespace util { template <class... T> struct mp_list {}; // mp_rename: A<...> -> B<...> template <class A, template <class...> class B> struct mp_rename_impl; template <template <class...> class A, class... T, template <class...> class B> struct mp_rename_impl<A<T...>, B> { using type = B<T...>; }; template <class A, template <class...> class B> using mp_rename = typename mp_rename_impl<A, B>::type; // mp_size template <class L> struct mp_size_impl; struct mp_size; template <template <class...> class L, class... T> struct mp_size_impl<L<T...>> { using type = std::integral_constant<std::size_t, sizeof...(T)>; }; template <class L> using mp_size = typename mp_size_impl<L>::type; // mp_plus template <class... T> struct mp_plus_impl; template <class... T> using mp_plus = typename mp_plus_impl<T...>::type; template <> struct mp_plus_impl<> { using type = std::integral_constant<int, 0>; }; template <class T1, class... T> struct mp_plus_impl<T1, T...> { static constexpr auto _v = T1::value + mp_plus<T...>::value; using type = std::integral_constant<typename std::remove_const<decltype(_v)>::type, _v>; struct mp_size<L<T...>> { constexpr static int value = sizeof...(T); }; // mp_count template <class L, class V> struct mp_count_impl; struct mp_count; template <template <class...> class L, class... T, class V> struct mp_count_impl<L<T...>, V> { using type = mp_plus<std::is_same<T, V>...>; struct mp_count<L<T...>, V> { constexpr static int value = (0 + ... + std::is_same_v<T, V>); }; template <class L, class V> using mp_count = typename mp_count_impl<L, V>::type; // mp_append template <typename T, typename... TL> struct mp_append; Loading @@ -96,17 +61,17 @@ struct mp_append<mp_list<Ts...>> { template <typename T, typename... Ts> struct mp_append<mp_list<Ts...>, T> { typedef mp_list<Ts..., T> type; using type = mp_list<Ts..., T>; }; template <typename... Ts1, typename... Ts2> struct mp_append<mp_list<Ts1...>, mp_list<Ts2...>> { typedef mp_list<Ts1..., Ts2...> type; using type = mp_list<Ts1..., Ts2...>; }; template <typename... Ts1, typename... Ts2, typename... Ts> struct mp_append<mp_list<Ts1...>, mp_list<Ts2...>, Ts...> { typedef typename mp_append<mp_list<Ts1..., Ts2...>, Ts...>::type type; using type = typename mp_append<mp_list<Ts1..., Ts2...>, Ts...>::type; }; // mp_prepend Loading @@ -115,84 +80,43 @@ struct mp_prepend; template <typename T, typename... Ts> struct mp_prepend<mp_list<Ts...>, T> { typedef mp_list<T, Ts...> type; using type = mp_list<T, Ts...>; }; template <typename... Ts1, typename... Ts2> struct mp_prepend<mp_list<Ts1...>, mp_list<Ts2...>> { typedef mp_list<Ts2..., Ts1...> type; using type = mp_list<Ts2..., Ts1...>; }; // mp_element // Get the n'th type from a typelist/tuple efficiently without recursion. // Reference: True Story: Efficient Packing // http://talesofcpp.fusionfenix.com/post-22/true-story-efficient-packing template <std::size_t I, typename T> struct _indexed { using type = T; }; template <typename Is, typename... Ts> struct _indexer; template <std::size_t... Is, typename... Ts> struct _indexer<std::index_sequence<Is...>, Ts...> : _indexed<Is, Ts>... {}; template <std::size_t I, typename... Ts> struct _at_index { template <typename T> static _indexed<I, T> _select(_indexed<I, T>); using _impl = _indexer<std::index_sequence_for<Ts...>, Ts...>; using type = typename decltype(_select(_impl{}))::type; }; // Was tuple_element, but we want typelist_element. template <std::size_t I, typename Tuple> struct mp_element; template <std::size_t I, typename... Ts> struct mp_element<I, mp_list<Ts...>> : _at_index<I, Ts...> {}; // mp_index_of // Search a typelist for a first occurrence of the type T. // Implementation: has index as a template parameter template <size_t idx, typename T, class List> struct mp_index_of_impl; template <size_t idx, typename T> // The type T is not in the list. struct mp_index_of_impl<idx, T, mp_list<>> { using type = std::integral_constant<int, -1>; struct mp_element<I, mp_list<Ts...>> { using type = std::tuple_element_t<I, std::tuple<Ts...>>; }; template <size_t idx, typename T, typename... Ts> // The type is found. struct mp_index_of_impl<idx, T, mp_list<T, Ts...>> { using type = std::integral_constant<int, idx>; }; // mp_index_of // Search a typelist for a first occurrence of the type T. Value is -1 if the type is not found. template <typename V, typename... Ts> struct mp_index_of; template <size_t idx, typename T, typename H, typename... Ts> // Recursion. struct mp_index_of_impl<idx, T, mp_list<H, Ts...>> { using type = typename mp_index_of_impl<idx + 1, T, mp_list<Ts...>>::type; template <typename V, typename... Ts> struct mp_index_of<V, mp_list<V, Ts...>> { // Index found. static constexpr int value = 0; }; // Wrapping to supply initial index 0. template <typename T, class List> struct mp_index_of { template <typename V> struct mp_index_of<V, mp_list<>> { // Index not found. static constexpr int value = -1; }; // Specializing for idx >= 0. template <typename T, typename... Ts> struct mp_index_of<T, mp_list<Ts...>> { using type = typename mp_index_of_impl<0, T, mp_list<Ts...>>::type; using value_type = typename type::value_type; static constexpr value_type value = type::value; }; // Specializing for idx >= 0. template <typename T, typename... Ts> struct mp_index_of<mp_list<Ts...>, T> { // static_assert(false, "Parameter ordering incorrect"); template <typename V, typename T1, typename... Ts> struct mp_index_of<V, mp_list<T1, Ts...>> { // Recursion. static constexpr int next = mp_index_of<V, mp_list<Ts...>>::value; static constexpr int value = next == -1 ? -1 : next + 1; }; // mp_swap Loading @@ -202,22 +126,22 @@ struct mp_swap {}; template <typename T1, typename T2> struct mp_swap<mp_list<>, T1, T2> { typedef mp_list<> type; using type = mp_list<>; }; template <typename T1, typename T2, typename... Ts> struct mp_swap<mp_list<T1, Ts...>, T1, T2> { typedef mp_list<T2, Ts...> type; using type = mp_list<T2, Ts...>; }; template <typename T0, typename... Ts, typename T1, typename T2> struct mp_swap<mp_list<T0, Ts...>, T1, T2> { typedef typename mp_prepend<typename mp_swap<mp_list<Ts...>, T1, T2>::type, T0>::type type; using type = typename mp_prepend<typename mp_swap<mp_list<Ts...>, T1, T2>::type, T0>::type; }; template <typename T1, typename Ts> template <typename T1, typename Domain> constexpr bool contained() { return mp_index_of<T1, Ts>::value != -1; return mp_index_of<T1, typename Domain::this_type>::value != -1; } // mp_sublist Loading