Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-23 22:56:17

0001 #include <alpaka/alpaka.hpp>
0002 
0003 #define CATCH_CONFIG_MAIN
0004 #include <catch.hpp>
0005 
0006 #include "FWCore/Utilities/interface/stringize.h"
0007 #include "HeterogeneousCore/AlpakaInterface/interface/config.h"
0008 #include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
0009 #include "HeterogeneousCore/AlpakaInterface/interface/workdivision.h"
0010 
0011 // each test binary is built for a single Alpaka backend
0012 using namespace ALPAKA_ACCELERATOR_NAMESPACE;
0013 
0014 namespace {
0015   constexpr size_t SIZE = 32;
0016 
0017   void testDeviceSideError(Device const& device) {
0018     auto queue = Queue(device);
0019     auto buf_h = cms::alpakatools::make_host_buffer<int[]>(queue, SIZE);
0020     auto buf_d = cms::alpakatools::make_device_buffer<int[]>(queue, SIZE);
0021     alpaka::memset(queue, buf_h, 0);
0022     alpaka::memcpy(queue, buf_d, buf_h);
0023     // On the host device I don't know how to fabricate a device-side
0024     // error for which the Alpaka API calls would then throw an
0025     // exception. Therefore I just throw the std::runtime_error to
0026     // keep the caller side the same for all backends. At least the
0027     // test ensures the buffer destructors won't throw exceptions
0028     // during the stack unwinding of the thrown runtime_error.
0029     if constexpr (std::is_same_v<Device, alpaka::DevCpu>) {
0030       throw std::runtime_error("assert");
0031     } else {
0032       auto div = cms::alpakatools::make_workdiv<Acc1D>(1, 1);
0033       alpaka::exec<Acc1D>(
0034           queue,
0035           div,
0036           [] ALPAKA_FN_ACC(Acc1D const& acc, int* data, size_t size) {
0037             for (auto index : cms::alpakatools::uniform_elements(acc, size)) {
0038               ALPAKA_ASSERT_ACC(data[index] != 0);
0039             }
0040           },
0041           buf_d.data(),
0042           SIZE);
0043       alpaka::wait(queue);
0044     }
0045   }
0046 }  // namespace
0047 
0048 TEST_CASE("Test alpaka buffers for the " EDM_STRINGIZE(ALPAKA_ACCELERATOR_NAMESPACE) " backend",
0049           "[" EDM_STRINGIZE(ALPAKA_ACCELERATOR_NAMESPACE) "]") {
0050   // get the list of devices on the current platform
0051   auto const& devices = cms::alpakatools::devices<Platform>();
0052   if (devices.empty()) {
0053     FAIL("No devices available for the " EDM_STRINGIZE(ALPAKA_ACCELERATOR_NAMESPACE) " backend, "
0054          "the test will be skipped.");
0055   }
0056 
0057   SECTION("Single device buffer") {
0058     for (auto const& device : devices) {
0059       auto queue = Queue(device);
0060       auto buf = cms::alpakatools::make_device_buffer<int[]>(queue, SIZE);
0061       alpaka::memset(queue, buf, 0);
0062       alpaka::wait(queue);
0063     }
0064   }
0065 
0066   SECTION("Single host buffer") {
0067     for (auto const& device : devices) {
0068       auto queue = Queue(device);
0069       auto buf = cms::alpakatools::make_host_buffer<int[]>(queue, SIZE);
0070       buf[0] = 0;
0071       alpaka::wait(queue);
0072     }
0073   }
0074 
0075   SECTION("Host and device buffers") {
0076     for (auto const& device : devices) {
0077       auto queue = Queue(device);
0078       auto buf_h = cms::alpakatools::make_host_buffer<int[]>(queue, SIZE);
0079       auto buf_d = cms::alpakatools::make_device_buffer<int[]>(queue, SIZE);
0080       alpaka::memset(queue, buf_h, 0);
0081       alpaka::memcpy(queue, buf_d, buf_h);
0082       alpaka::wait(queue);
0083     }
0084   }
0085 
0086   SECTION("Buffer destruction after a device-side error") {
0087     for (auto const& device : devices) {
0088       REQUIRE_THROWS_AS(testDeviceSideError(device), std::runtime_error);
0089     }
0090   }
0091 }