File indexing completed on 2024-12-19 04:04:41
0001 #include <optional>
0002 #include <type_traits>
0003
0004 #include <alpaka/alpaka.hpp>
0005
0006 #define CATCH_CONFIG_MAIN
0007 #include <catch.hpp>
0008
0009 #include "HeterogeneousCore/AlpakaInterface/interface/config.h"
0010 #include "HeterogeneousCore/AlpakaInterface/interface/CopyToDevice.h"
0011 #include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
0012 #include "HeterogeneousCore/AlpakaInterface/interface/moveToDeviceAsync.h"
0013 #include "HeterogeneousCore/AlpakaInterface/interface/workdivision.h"
0014
0015
0016 using namespace ALPAKA_ACCELERATOR_NAMESPACE;
0017
0018 namespace {
0019 template <typename T>
0020 class TestHostBuffer {
0021 public:
0022 using Buffer = cms::alpakatools::host_buffer<T[]>;
0023 using ConstBuffer = cms::alpakatools::const_host_buffer<T[]>;
0024
0025 template <typename TQueue>
0026 TestHostBuffer(TQueue const& queue, int size) : buffer_(cms::alpakatools::make_host_buffer<T[]>(queue, size)) {}
0027
0028 TestHostBuffer(TestHostBuffer const&) = delete;
0029 TestHostBuffer& operator=(TestHostBuffer const&) = delete;
0030 ;
0031 TestHostBuffer(TestHostBuffer&& other) {
0032 buffer_ = std::move(*other.buffer_);
0033 other.buffer_.reset();
0034 }
0035 TestHostBuffer& operator=(TestHostBuffer& other) {
0036 buffer_ = std::move(*other.buffer_);
0037 other.buffer_.reset();
0038 return this;
0039 }
0040
0041 bool has_value() const { return buffer_.has_value(); }
0042
0043 T* data() { return buffer_->data(); }
0044
0045 Buffer buffer() { return *buffer_; }
0046 ConstBuffer buffer() const { return *buffer_; }
0047
0048 private:
0049 std::optional<Buffer> buffer_;
0050 };
0051
0052 template <typename T, typename TDev>
0053 class TestDeviceBuffer {
0054 public:
0055 using Buffer = cms::alpakatools::device_buffer<TDev, T[]>;
0056
0057 template <typename TQueue>
0058 TestDeviceBuffer(TQueue const& queue, int size) : buffer_(cms::alpakatools::make_device_buffer<T[]>(queue, size)) {}
0059
0060 T* data() { return buffer_.data(); }
0061
0062 Buffer buffer() { return buffer_; }
0063
0064 private:
0065 Buffer buffer_;
0066 };
0067
0068 template <typename T>
0069 void fillBuffer(TestHostBuffer<T>& buffer) {
0070 for (int i = 0, size = alpaka::getExtentProduct(buffer.buffer()); i < size; ++i) {
0071 buffer.data()[i] = i;
0072 }
0073 }
0074 }
0075
0076 namespace cms::alpakatools {
0077 template <typename T>
0078 struct CopyToDevice<TestHostBuffer<T>> {
0079 template <typename TQueue>
0080 static auto copyAsync(TQueue& queue, TestHostBuffer<T> const& hostBuffer) {
0081 TestDeviceBuffer<T, alpaka::Dev<TQueue>> deviceBuffer(queue, alpaka::getExtentProduct(hostBuffer.buffer()));
0082 alpaka::memcpy(queue, deviceBuffer.buffer(), hostBuffer.buffer());
0083 return deviceBuffer;
0084 }
0085 };
0086 }
0087
0088 TEST_CASE("Test moveToDeviceAsync() for the " EDM_STRINGIZE(ALPAKA_ACCELERATOR_NAMESPACE) " backend",
0089 "[" EDM_STRINGIZE(ALPAKA_ACCELERATOR_NAMESPACE) "]") {
0090
0091 for (auto const& device : cms::alpakatools::devices<Platform>()) {
0092 auto queue = Queue(device);
0093 constexpr int size = 32;
0094 TestHostBuffer<int> buffer_host(queue, size);
0095 fillBuffer(buffer_host);
0096 auto const* ptr_host = buffer_host.data();
0097
0098 auto buffer_device = cms::alpakatools::moveToDeviceAsync(queue, std::move(buffer_host));
0099 REQUIRE(not buffer_host.has_value());
0100 if constexpr (std::is_same_v<Device, alpaka_common::DevHost>) {
0101 REQUIRE(buffer_device.data() == ptr_host);
0102 } else {
0103 REQUIRE(buffer_device.data() != ptr_host);
0104 }
0105 alpaka::exec<Acc1D>(
0106 queue,
0107 cms::alpakatools::make_workdiv<Acc1D>(1, size),
0108 [] ALPAKA_FN_ACC(Acc1D const& acc, int const* data) {
0109 for (int i : cms::alpakatools::uniform_elements(acc)) {
0110 assert(data[i] == i);
0111 }
0112 },
0113 buffer_device.data());
0114 alpaka::wait(queue);
0115
0116
0117
0118
0119
0120 }
0121 }