File indexing completed on 2024-04-06 12:15:40
0001 #ifndef HeterogeneousCore_AlpakaInterface_interface_memory_h
0002 #define HeterogeneousCore_AlpakaInterface_interface_memory_h
0003
0004 #include <type_traits>
0005
0006 #include <alpaka/alpaka.hpp>
0007
0008 #include "HeterogeneousCore/AlpakaInterface/interface/AllocatorPolicy.h"
0009 #include "HeterogeneousCore/AlpakaInterface/interface/CachedBufAlloc.h"
0010 #include "HeterogeneousCore/AlpakaInterface/interface/config.h"
0011 #include "HeterogeneousCore/AlpakaInterface/interface/devices.h"
0012 #include "HeterogeneousCore/AlpakaInterface/interface/traits.h"
0013
0014 namespace cms::alpakatools {
0015
0016
0017 using namespace alpaka_common;
0018
0019
0020 namespace detail {
0021
0022 template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
0023 struct buffer_type {
0024 using type = alpaka::Buf<TDev, T, Dim0D, Idx>;
0025 };
0026
0027 template <typename TDev, typename T>
0028 struct buffer_type<TDev, T[]> {
0029 using type = alpaka::Buf<TDev, T, Dim1D, Idx>;
0030 };
0031
0032 template <typename TDev, typename T, int N>
0033 struct buffer_type<TDev, T[N]> {
0034 using type = alpaka::Buf<TDev, T, Dim1D, Idx>;
0035 };
0036
0037 template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
0038 struct view_type {
0039 using type = alpaka::ViewPlainPtr<TDev, T, Dim0D, Idx>;
0040 };
0041
0042 template <typename TDev, typename T>
0043 struct view_type<TDev, T[]> {
0044 using type = alpaka::ViewPlainPtr<TDev, T, Dim1D, Idx>;
0045 };
0046
0047 template <typename TDev, typename T, int N>
0048 struct view_type<TDev, T[N]> {
0049 using type = alpaka::ViewPlainPtr<TDev, T, Dim1D, Idx>;
0050 };
0051
0052 }
0053
0054
0055
0056 template <typename T>
0057 using host_buffer = typename detail::buffer_type<DevHost, T>::type;
0058
0059 template <typename T>
0060 using const_host_buffer = alpaka::ViewConst<host_buffer<T>>;
0061
0062
0063
0064 template <typename T>
0065 std::enable_if_t<not std::is_array_v<T>, host_buffer<T>> make_host_buffer() {
0066 return alpaka::allocBuf<T, Idx>(host(), Scalar{});
0067 }
0068
0069 template <typename T>
0070 std::enable_if_t<cms::is_unbounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_buffer<T>>
0071 make_host_buffer(Extent extent) {
0072 return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(host(), Vec1D{extent});
0073 }
0074
0075 template <typename T>
0076 std::enable_if_t<cms::is_bounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_buffer<T>>
0077 make_host_buffer() {
0078 return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(host(), Vec1D{std::extent_v<T>});
0079 }
0080
0081
0082
0083
0084 template <typename T, typename TPlatform>
0085 std::enable_if_t<not std::is_array_v<T>, host_buffer<T>> make_host_buffer() {
0086 using Platform = TPlatform;
0087 return alpaka::allocMappedBuf<Platform, T, Idx>(host(), platform<Platform>(), Scalar{});
0088 }
0089
0090 template <typename T, typename TPlatform>
0091 std::enable_if_t<cms::is_unbounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_buffer<T>>
0092 make_host_buffer(Extent extent) {
0093 using Platform = TPlatform;
0094 return alpaka::allocMappedBuf<Platform, std::remove_extent_t<T>, Idx>(host(), platform<Platform>(), Vec1D{extent});
0095 }
0096
0097 template <typename T, typename TPlatform>
0098 std::enable_if_t<cms::is_bounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_buffer<T>>
0099 make_host_buffer() {
0100 using Platform = TPlatform;
0101 return alpaka::allocMappedBuf<Platform, std::remove_extent_t<T>, Idx>(
0102 host(), platform<Platform>(), Vec1D{std::extent_v<T>});
0103 }
0104
0105
0106
0107
0108 template <typename T, typename TQueue>
0109 std::enable_if_t<alpaka::isQueue<TQueue> and not std::is_array_v<T>, host_buffer<T>> make_host_buffer(
0110 TQueue const& queue) {
0111 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0112 return allocCachedBuf<T, Idx>(host(), queue, Scalar{});
0113 } else {
0114 using Platform = alpaka::Platform<alpaka::Dev<TQueue>>;
0115 return alpaka::allocMappedBuf<Platform, T, Idx>(host(), platform<Platform>(), Scalar{});
0116 }
0117 }
0118
0119 template <typename T, typename TQueue>
0120 std::enable_if_t<alpaka::isQueue<TQueue> and cms::is_unbounded_array_v<T> and
0121 not std::is_array_v<std::remove_extent_t<T>>,
0122 host_buffer<T>>
0123 make_host_buffer(TQueue const& queue, Extent extent) {
0124 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0125 return allocCachedBuf<std::remove_extent_t<T>, Idx>(host(), queue, Vec1D{extent});
0126 } else {
0127 using Platform = alpaka::Platform<alpaka::Dev<TQueue>>;
0128 return alpaka::allocMappedBuf<Platform, std::remove_extent_t<T>, Idx>(
0129 host(), platform<Platform>(), Vec1D{extent});
0130 }
0131 }
0132
0133 template <typename T, typename TQueue>
0134 std::enable_if_t<alpaka::isQueue<TQueue> and cms::is_bounded_array_v<T> and
0135 not std::is_array_v<std::remove_extent_t<T>>,
0136 host_buffer<T>>
0137 make_host_buffer(TQueue const& queue) {
0138 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0139 return allocCachedBuf<std::remove_extent_t<T>, Idx>(host(), queue, Vec1D{std::extent_v<T>});
0140 } else {
0141 using Platform = alpaka::Platform<alpaka::Dev<TQueue>>;
0142 return alpaka::allocMappedBuf<Platform, std::remove_extent_t<T>, Idx>(
0143 host(), platform<Platform>(), Vec1D{std::extent_v<T>});
0144 }
0145 }
0146
0147
0148
0149 template <typename T>
0150 using host_view = typename detail::view_type<DevHost, T>::type;
0151
0152 template <typename T>
0153 std::enable_if_t<not std::is_array_v<T>, host_view<T>> make_host_view(T& data) {
0154 return alpaka::ViewPlainPtr<DevHost, T, Dim0D, Idx>(&data, host(), Scalar{});
0155 }
0156
0157 template <typename T>
0158 host_view<T[]> make_host_view(T* data, Extent extent) {
0159 return alpaka::ViewPlainPtr<DevHost, T, Dim1D, Idx>(data, host(), Vec1D{extent});
0160 }
0161
0162 template <typename T>
0163 std::enable_if_t<cms::is_unbounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_view<T>>
0164 make_host_view(T& data, Extent extent) {
0165 return alpaka::ViewPlainPtr<DevHost, std::remove_extent_t<T>, Dim1D, Idx>(data, host(), Vec1D{extent});
0166 }
0167
0168 template <typename T>
0169 std::enable_if_t<cms::is_bounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_view<T>>
0170 make_host_view(T& data) {
0171 return alpaka::ViewPlainPtr<DevHost, std::remove_extent_t<T>, Dim1D, Idx>(data, host(), Vec1D{std::extent_v<T>});
0172 }
0173
0174
0175
0176 template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
0177 using device_buffer = typename detail::buffer_type<TDev, T>::type;
0178
0179 template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
0180 using const_device_buffer = alpaka::ViewConst<device_buffer<TDev, T>>;
0181
0182
0183
0184 template <typename T, typename TDev>
0185 std::enable_if_t<alpaka::isDevice<TDev> and not std::is_array_v<T>, device_buffer<TDev, T>> make_device_buffer(
0186 TDev const& device) {
0187 return alpaka::allocBuf<T, Idx>(device, Scalar{});
0188 }
0189
0190 template <typename T, typename TDev>
0191 std::enable_if_t<alpaka::isDevice<TDev> and cms::is_unbounded_array_v<T> and
0192 not std::is_array_v<std::remove_extent_t<T>>,
0193 device_buffer<TDev, T>>
0194 make_device_buffer(TDev const& device, Extent extent) {
0195 return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(device, Vec1D{extent});
0196 }
0197
0198 template <typename T, typename TDev>
0199 std::enable_if_t<alpaka::isDevice<TDev> and cms::is_bounded_array_v<T> and
0200 not std::is_array_v<std::remove_extent_t<T>>,
0201 device_buffer<TDev, T>>
0202 make_device_buffer(TDev const& device) {
0203 return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(device, Vec1D{std::extent_v<T>});
0204 }
0205
0206
0207
0208 template <typename T, typename TQueue>
0209 std::enable_if_t<alpaka::isQueue<TQueue> and not std::is_array_v<T>, device_buffer<alpaka::Dev<TQueue>, T>>
0210 make_device_buffer(TQueue const& queue) {
0211 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0212 return allocCachedBuf<T, Idx>(alpaka::getDev(queue), queue, Scalar{});
0213 }
0214 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Asynchronous) {
0215 return alpaka::allocAsyncBuf<T, Idx>(queue, Scalar{});
0216 }
0217 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Synchronous) {
0218 return alpaka::allocBuf<T, Idx>(alpaka::getDev(queue), Scalar{});
0219 }
0220 }
0221
0222 template <typename T, typename TQueue>
0223 std::enable_if_t<alpaka::isQueue<TQueue> and cms::is_unbounded_array_v<T> and
0224 not std::is_array_v<std::remove_extent_t<T>>,
0225 device_buffer<alpaka::Dev<TQueue>, T>>
0226 make_device_buffer(TQueue const& queue, Extent extent) {
0227 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0228 return allocCachedBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), queue, Vec1D{extent});
0229 }
0230 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Asynchronous) {
0231 return alpaka::allocAsyncBuf<std::remove_extent_t<T>, Idx>(queue, Vec1D{extent});
0232 }
0233 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Synchronous) {
0234 return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), Vec1D{extent});
0235 }
0236 }
0237
0238 template <typename T, typename TQueue>
0239 std::enable_if_t<alpaka::isQueue<TQueue> and cms::is_bounded_array_v<T> and
0240 not std::is_array_v<std::remove_extent_t<T>>,
0241 device_buffer<alpaka::Dev<TQueue>, T>>
0242 make_device_buffer(TQueue const& queue) {
0243 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0244 return allocCachedBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), queue, Vec1D{std::extent_v<T>});
0245 }
0246 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Asynchronous) {
0247 return alpaka::allocAsyncBuf<std::remove_extent_t<T>, Idx>(queue, Vec1D{std::extent_v<T>});
0248 }
0249 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Synchronous) {
0250 return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), Vec1D{std::extent_v<T>});
0251 }
0252 }
0253
0254
0255
0256 template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
0257 using device_view = typename detail::view_type<TDev, T>::type;
0258
0259 template <typename T, typename TDev>
0260 std::enable_if_t<not std::is_array_v<T>, device_view<TDev, T>> make_device_view(TDev const& device, T& data) {
0261 return alpaka::ViewPlainPtr<TDev, T, Dim0D, Idx>(&data, device, Scalar{});
0262 }
0263
0264 template <typename T, typename TDev>
0265 device_view<TDev, T[]> make_device_view(TDev const& device, T* data, Extent extent) {
0266 return alpaka::ViewPlainPtr<TDev, T, Dim1D, Idx>(data, device, Vec1D{extent});
0267 }
0268
0269 template <typename T, typename TDev>
0270 std::enable_if_t<cms::is_unbounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, device_view<TDev, T>>
0271 make_device_view(TDev const& device, T& data, Extent extent) {
0272 return alpaka::ViewPlainPtr<TDev, std::remove_extent_t<T>, Dim1D, Idx>(data, device, Vec1D{extent});
0273 }
0274
0275 template <typename T, typename TDev>
0276 std::enable_if_t<cms::is_bounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, device_view<TDev, T>>
0277 make_device_view(TDev const& device, T& data) {
0278 return alpaka::ViewPlainPtr<TDev, std::remove_extent_t<T>, Dim1D, Idx>(data, device, Vec1D{std::extent_v<T>});
0279 }
0280
0281 }
0282
0283 #endif