File indexing completed on 2025-01-22 07:34:10
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<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<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<std::remove_extent_t<T>, Idx>(host(), platform<Platform>(), Vec1D{std::extent_v<T>});
0102 }
0103
0104
0105
0106
0107 template <typename T, typename TQueue>
0108 std::enable_if_t<alpaka::isQueue<TQueue> and not std::is_array_v<T>, host_buffer<T>> make_host_buffer(
0109 TQueue const& queue) {
0110 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0111 return allocCachedBuf<T, Idx>(host(), queue, Scalar{});
0112 } else {
0113 using Platform = alpaka::Platform<alpaka::Dev<TQueue>>;
0114 return alpaka::allocMappedBuf<T, Idx>(host(), platform<Platform>(), Scalar{});
0115 }
0116 }
0117
0118 template <typename T, typename TQueue>
0119 std::enable_if_t<alpaka::isQueue<TQueue> and cms::is_unbounded_array_v<T> and
0120 not std::is_array_v<std::remove_extent_t<T>>,
0121 host_buffer<T>>
0122 make_host_buffer(TQueue const& queue, Extent extent) {
0123 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0124 return allocCachedBuf<std::remove_extent_t<T>, Idx>(host(), queue, Vec1D{extent});
0125 } else {
0126 using Platform = alpaka::Platform<alpaka::Dev<TQueue>>;
0127 return alpaka::allocMappedBuf<std::remove_extent_t<T>, Idx>(host(), platform<Platform>(), Vec1D{extent});
0128 }
0129 }
0130
0131 template <typename T, typename TQueue>
0132 std::enable_if_t<alpaka::isQueue<TQueue> and cms::is_bounded_array_v<T> and
0133 not std::is_array_v<std::remove_extent_t<T>>,
0134 host_buffer<T>>
0135 make_host_buffer(TQueue const& queue) {
0136 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0137 return allocCachedBuf<std::remove_extent_t<T>, Idx>(host(), queue, Vec1D{std::extent_v<T>});
0138 } else {
0139 using Platform = alpaka::Platform<alpaka::Dev<TQueue>>;
0140 return alpaka::allocMappedBuf<std::remove_extent_t<T>, Idx>(
0141 host(), platform<Platform>(), Vec1D{std::extent_v<T>});
0142 }
0143 }
0144
0145
0146
0147 template <typename T>
0148 using host_view = typename detail::view_type<DevHost, T>::type;
0149
0150 template <typename T>
0151 std::enable_if_t<not std::is_array_v<T>, host_view<T>> make_host_view(T& data) {
0152 return alpaka::ViewPlainPtr<DevHost, T, Dim0D, Idx>(&data, host(), Scalar{});
0153 }
0154
0155 template <typename T>
0156 host_view<T[]> make_host_view(T* data, Extent extent) {
0157 return alpaka::ViewPlainPtr<DevHost, T, Dim1D, Idx>(data, host(), Vec1D{extent});
0158 }
0159
0160 template <typename T>
0161 std::enable_if_t<cms::is_unbounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_view<T>>
0162 make_host_view(T& data, Extent extent) {
0163 return alpaka::ViewPlainPtr<DevHost, std::remove_extent_t<T>, Dim1D, Idx>(data, host(), Vec1D{extent});
0164 }
0165
0166 template <typename T>
0167 std::enable_if_t<cms::is_bounded_array_v<T> and not std::is_array_v<std::remove_extent_t<T>>, host_view<T>>
0168 make_host_view(T& data) {
0169 return alpaka::ViewPlainPtr<DevHost, std::remove_extent_t<T>, Dim1D, Idx>(data, host(), Vec1D{std::extent_v<T>});
0170 }
0171
0172
0173
0174 template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
0175 using device_buffer = typename detail::buffer_type<TDev, T>::type;
0176
0177 template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
0178 using const_device_buffer = alpaka::ViewConst<device_buffer<TDev, T>>;
0179
0180
0181
0182 template <typename T, typename TDev>
0183 std::enable_if_t<alpaka::isDevice<TDev> and not std::is_array_v<T>, device_buffer<TDev, T>> make_device_buffer(
0184 TDev const& device) {
0185 return alpaka::allocBuf<T, Idx>(device, Scalar{});
0186 }
0187
0188 template <typename T, typename TDev>
0189 std::enable_if_t<alpaka::isDevice<TDev> and cms::is_unbounded_array_v<T> and
0190 not std::is_array_v<std::remove_extent_t<T>>,
0191 device_buffer<TDev, T>>
0192 make_device_buffer(TDev const& device, Extent extent) {
0193 return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(device, Vec1D{extent});
0194 }
0195
0196 template <typename T, typename TDev>
0197 std::enable_if_t<alpaka::isDevice<TDev> and cms::is_bounded_array_v<T> and
0198 not std::is_array_v<std::remove_extent_t<T>>,
0199 device_buffer<TDev, T>>
0200 make_device_buffer(TDev const& device) {
0201 return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(device, Vec1D{std::extent_v<T>});
0202 }
0203
0204
0205
0206 template <typename T, typename TQueue>
0207 std::enable_if_t<alpaka::isQueue<TQueue> and not std::is_array_v<T>, device_buffer<alpaka::Dev<TQueue>, T>>
0208 make_device_buffer(TQueue const& queue) {
0209 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0210 return allocCachedBuf<T, Idx>(alpaka::getDev(queue), queue, Scalar{});
0211 }
0212 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Asynchronous) {
0213 return alpaka::allocAsyncBuf<T, Idx>(queue, Scalar{});
0214 }
0215 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Synchronous) {
0216 return alpaka::allocBuf<T, Idx>(alpaka::getDev(queue), Scalar{});
0217 }
0218 }
0219
0220 template <typename T, typename TQueue>
0221 std::enable_if_t<alpaka::isQueue<TQueue> and cms::is_unbounded_array_v<T> and
0222 not std::is_array_v<std::remove_extent_t<T>>,
0223 device_buffer<alpaka::Dev<TQueue>, T>>
0224 make_device_buffer(TQueue const& queue, Extent extent) {
0225 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0226 return allocCachedBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), queue, Vec1D{extent});
0227 }
0228 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Asynchronous) {
0229 return alpaka::allocAsyncBuf<std::remove_extent_t<T>, Idx>(queue, Vec1D{extent});
0230 }
0231 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Synchronous) {
0232 return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), Vec1D{extent});
0233 }
0234 }
0235
0236 template <typename T, typename TQueue>
0237 std::enable_if_t<alpaka::isQueue<TQueue> and cms::is_bounded_array_v<T> and
0238 not std::is_array_v<std::remove_extent_t<T>>,
0239 device_buffer<alpaka::Dev<TQueue>, T>>
0240 make_device_buffer(TQueue const& queue) {
0241 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Caching) {
0242 return allocCachedBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), queue, Vec1D{std::extent_v<T>});
0243 }
0244 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Asynchronous) {
0245 return alpaka::allocAsyncBuf<std::remove_extent_t<T>, Idx>(queue, Vec1D{std::extent_v<T>});
0246 }
0247 if constexpr (allocator_policy<alpaka::Dev<TQueue>> == AllocatorPolicy::Synchronous) {
0248 return alpaka::allocBuf<std::remove_extent_t<T>, Idx>(alpaka::getDev(queue), Vec1D{std::extent_v<T>});
0249 }
0250 }
0251
0252
0253
0254 template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
0255 using device_view = typename detail::view_type<TDev, T>::type;
0256
0257 template <typename T, typename TDev>
0258 std::enable_if_t<alpaka::isDevice<TDev> and not std::is_array_v<T>, device_view<TDev, T>> make_device_view(
0259 TDev const& device, T& data) {
0260 return alpaka::ViewPlainPtr<TDev, T, Dim0D, Idx>(&data, device, Scalar{});
0261 }
0262
0263 template <typename T, typename TDev>
0264 std::enable_if_t<alpaka::isDevice<TDev>, device_view<TDev, T[]>> make_device_view(TDev const& device,
0265 T* data,
0266 Extent extent) {
0267 return alpaka::ViewPlainPtr<TDev, T, Dim1D, Idx>(data, device, Vec1D{extent});
0268 }
0269
0270 template <typename T, typename TDev>
0271 std::enable_if_t<alpaka::isDevice<TDev> and cms::is_unbounded_array_v<T> and
0272 not std::is_array_v<std::remove_extent_t<T>>,
0273 device_view<TDev, T>>
0274 make_device_view(TDev const& device, T& data, Extent extent) {
0275 return alpaka::ViewPlainPtr<TDev, std::remove_extent_t<T>, Dim1D, Idx>(data, device, Vec1D{extent});
0276 }
0277
0278 template <typename T, typename TDev>
0279 std::enable_if_t<alpaka::isDevice<TDev> and cms::is_bounded_array_v<T> and
0280 not std::is_array_v<std::remove_extent_t<T>>,
0281 device_view<TDev, T>>
0282 make_device_view(TDev const& device, T& data) {
0283 return alpaka::ViewPlainPtr<TDev, std::remove_extent_t<T>, Dim1D, Idx>(data, device, Vec1D{std::extent_v<T>});
0284 }
0285
0286 template <typename T, typename TQueue>
0287 std::enable_if_t<alpaka::isQueue<TQueue> and not std::is_array_v<T>, device_view<alpaka::Dev<TQueue>, T>>
0288 make_device_view(TQueue const& queue, T& data) {
0289 return alpaka::ViewPlainPtr<alpaka::Dev<TQueue>, T, Dim0D, Idx>(&data, alpaka::getDev(queue), Scalar{});
0290 }
0291
0292 template <typename T, typename TQueue>
0293 std::enable_if_t<alpaka::isQueue<TQueue>, device_view<alpaka::Dev<TQueue>, T[]>> make_device_view(TQueue const& queue,
0294 T* data,
0295 Extent extent) {
0296 return alpaka::ViewPlainPtr<alpaka::Dev<TQueue>, T, Dim1D, Idx>(data, alpaka::getDev(queue), Vec1D{extent});
0297 }
0298
0299 template <typename T, typename TQueue>
0300 std::enable_if_t<alpaka::isQueue<TQueue> and cms::is_unbounded_array_v<T> and
0301 not std::is_array_v<std::remove_extent_t<T>>,
0302 device_view<alpaka::Dev<TQueue>, T>>
0303 make_device_view(TQueue const& queue, T& data, Extent extent) {
0304 return alpaka::ViewPlainPtr<alpaka::Dev<TQueue>, std::remove_extent_t<T>, Dim1D, Idx>(
0305 data, alpaka::getDev(queue), Vec1D{extent});
0306 }
0307
0308 template <typename T, typename TQueue>
0309 std::enable_if_t<alpaka::isQueue<TQueue> and cms::is_bounded_array_v<T> and
0310 not std::is_array_v<std::remove_extent_t<T>>,
0311 device_view<alpaka::Dev<TQueue>, T>>
0312 make_device_view(TQueue const& queue, T& data) {
0313 return alpaka::ViewPlainPtr<alpaka::Dev<TQueue>, std::remove_extent_t<T>, Dim1D, Idx>(
0314 data, alpaka::getDev(queue), Vec1D{std::extent_v<T>});
0315 }
0316
0317 }
0318
0319 #endif