brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.6 KiB · c9eca36 Raw
288 lines · cpp
1//===------- Offload API tests - olLaunchKernel --------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "../common/Fixtures.hpp"10#include <OffloadAPI.h>11#include <gtest/gtest.h>12 13struct LaunchKernelTestBase : OffloadQueueTest {14  void SetUpProgram(const char *program) {15    RETURN_ON_FATAL_FAILURE(OffloadQueueTest::SetUp());16    ASSERT_TRUE(TestEnvironment::loadDeviceBinary(program, Device, DeviceBin));17    ASSERT_GE(DeviceBin->getBufferSize(), 0lu);18    ASSERT_SUCCESS(olCreateProgram(Device, DeviceBin->getBufferStart(),19                                   DeviceBin->getBufferSize(), &Program));20 21    LaunchArgs.Dimensions = 1;22    LaunchArgs.GroupSize = {64, 1, 1};23    LaunchArgs.NumGroups = {1, 1, 1};24 25    LaunchArgs.DynSharedMemory = 0;26  }27 28  void TearDown() override {29    if (Program) {30      olDestroyProgram(Program);31    }32    RETURN_ON_FATAL_FAILURE(OffloadQueueTest::TearDown());33  }34 35  std::unique_ptr<llvm::MemoryBuffer> DeviceBin;36  ol_program_handle_t Program = nullptr;37  ol_kernel_launch_size_args_t LaunchArgs{};38};39 40struct LaunchSingleKernelTestBase : LaunchKernelTestBase {41  void SetUpKernel(const char *kernel) {42    RETURN_ON_FATAL_FAILURE(SetUpProgram(kernel));43    ASSERT_SUCCESS(44        olGetSymbol(Program, kernel, OL_SYMBOL_KIND_KERNEL, &Kernel));45  }46 47  ol_symbol_handle_t Kernel = nullptr;48};49 50#define KERNEL_TEST(NAME, KERNEL)                                              \51  struct olLaunchKernel##NAME##Test : LaunchSingleKernelTestBase {             \52    void SetUp() override { SetUpKernel(#KERNEL); }                            \53  };                                                                           \54  OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olLaunchKernel##NAME##Test);55 56KERNEL_TEST(Foo, foo)57KERNEL_TEST(NoArgs, noargs)58KERNEL_TEST(Byte, byte)59KERNEL_TEST(LocalMem, localmem)60KERNEL_TEST(LocalMemReduction, localmem_reduction)61KERNEL_TEST(LocalMemStatic, localmem_static)62KERNEL_TEST(GlobalCtor, global_ctor)63KERNEL_TEST(GlobalDtor, global_dtor)64 65struct LaunchMultipleKernelTestBase : LaunchKernelTestBase {66  void SetUpKernels(const char *program, std::vector<const char *> kernels) {67    RETURN_ON_FATAL_FAILURE(SetUpProgram(program));68 69    Kernels.resize(kernels.size());70    size_t I = 0;71    for (auto K : kernels)72      ASSERT_SUCCESS(73          olGetSymbol(Program, K, OL_SYMBOL_KIND_KERNEL, &Kernels[I++]));74  }75 76  std::vector<ol_symbol_handle_t> Kernels;77};78 79#define KERNEL_MULTI_TEST(NAME, PROGRAM, ...)                                  \80  struct olLaunchKernel##NAME##Test : LaunchMultipleKernelTestBase {           \81    void SetUp() override { SetUpKernels(#PROGRAM, {__VA_ARGS__}); }           \82  };                                                                           \83  OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(olLaunchKernel##NAME##Test);84 85KERNEL_MULTI_TEST(Global, global, "write", "read")86 87TEST_P(olLaunchKernelFooTest, Success) {88  void *Mem;89  ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED,90                            LaunchArgs.GroupSize.x * sizeof(uint32_t), &Mem));91  struct {92    void *Mem;93  } Args{Mem};94 95  ASSERT_SUCCESS(96      olLaunchKernel(Queue, Device, Kernel, &Args, sizeof(Args), &LaunchArgs));97 98  ASSERT_SUCCESS(olSyncQueue(Queue));99 100  uint32_t *Data = (uint32_t *)Mem;101  for (uint32_t i = 0; i < 64; i++) {102    ASSERT_EQ(Data[i], i);103  }104 105  ASSERT_SUCCESS(olMemFree(Mem));106}107 108TEST_P(olLaunchKernelFooTest, SuccessThreaded) {109  threadify([&](size_t) {110    void *Mem;111    ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED,112                              LaunchArgs.GroupSize.x * sizeof(uint32_t), &Mem));113    struct {114      void *Mem;115    } Args{Mem};116 117    ASSERT_SUCCESS(olLaunchKernel(Queue, Device, Kernel, &Args, sizeof(Args),118                                  &LaunchArgs));119 120    ASSERT_SUCCESS(olSyncQueue(Queue));121 122    uint32_t *Data = (uint32_t *)Mem;123    for (uint32_t i = 0; i < 64; i++) {124      ASSERT_EQ(Data[i], i);125    }126 127    ASSERT_SUCCESS(olMemFree(Mem));128  });129}130 131TEST_P(olLaunchKernelNoArgsTest, Success) {132  ASSERT_SUCCESS(133      olLaunchKernel(Queue, Device, Kernel, nullptr, 0, &LaunchArgs));134 135  ASSERT_SUCCESS(olSyncQueue(Queue));136}137 138TEST_P(olLaunchKernelFooTest, SuccessSynchronous) {139  void *Mem;140  ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED,141                            LaunchArgs.GroupSize.x * sizeof(uint32_t), &Mem));142 143  struct {144    void *Mem;145  } Args{Mem};146 147  ASSERT_SUCCESS(olLaunchKernel(nullptr, Device, Kernel, &Args, sizeof(Args),148                                &LaunchArgs));149 150  uint32_t *Data = (uint32_t *)Mem;151  for (uint32_t i = 0; i < 64; i++) {152    ASSERT_EQ(Data[i], i);153  }154 155  ASSERT_SUCCESS(olMemFree(Mem));156}157 158TEST_P(olLaunchKernelLocalMemTest, Success) {159  LaunchArgs.NumGroups.x = 4;160  LaunchArgs.DynSharedMemory = 64 * sizeof(uint32_t);161 162  void *Mem;163  ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED,164                            LaunchArgs.GroupSize.x * LaunchArgs.NumGroups.x *165                                sizeof(uint32_t),166                            &Mem));167  struct {168    void *Mem;169  } Args{Mem};170 171  ASSERT_SUCCESS(172      olLaunchKernel(Queue, Device, Kernel, &Args, sizeof(Args), &LaunchArgs));173 174  ASSERT_SUCCESS(olSyncQueue(Queue));175 176  uint32_t *Data = (uint32_t *)Mem;177  for (uint32_t i = 0; i < LaunchArgs.GroupSize.x * LaunchArgs.NumGroups.x; i++)178    ASSERT_EQ(Data[i], (i % 64) * 2);179 180  ASSERT_SUCCESS(olMemFree(Mem));181}182 183TEST_P(olLaunchKernelLocalMemReductionTest, Success) {184  LaunchArgs.NumGroups.x = 4;185  LaunchArgs.DynSharedMemory = 64 * sizeof(uint32_t);186 187  void *Mem;188  ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED,189                            LaunchArgs.NumGroups.x * sizeof(uint32_t), &Mem));190  struct {191    void *Mem;192  } Args{Mem};193 194  ASSERT_SUCCESS(195      olLaunchKernel(Queue, Device, Kernel, &Args, sizeof(Args), &LaunchArgs));196 197  ASSERT_SUCCESS(olSyncQueue(Queue));198 199  uint32_t *Data = (uint32_t *)Mem;200  for (uint32_t i = 0; i < LaunchArgs.NumGroups.x; i++)201    ASSERT_EQ(Data[i], 2 * LaunchArgs.GroupSize.x);202 203  ASSERT_SUCCESS(olMemFree(Mem));204}205 206TEST_P(olLaunchKernelLocalMemStaticTest, Success) {207  LaunchArgs.NumGroups.x = 4;208  LaunchArgs.DynSharedMemory = 0;209 210  void *Mem;211  ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED,212                            LaunchArgs.NumGroups.x * sizeof(uint32_t), &Mem));213  struct {214    void *Mem;215  } Args{Mem};216 217  ASSERT_SUCCESS(218      olLaunchKernel(Queue, Device, Kernel, &Args, sizeof(Args), &LaunchArgs));219 220  ASSERT_SUCCESS(olSyncQueue(Queue));221 222  uint32_t *Data = (uint32_t *)Mem;223  for (uint32_t i = 0; i < LaunchArgs.NumGroups.x; i++)224    ASSERT_EQ(Data[i], 2 * LaunchArgs.GroupSize.x);225 226  ASSERT_SUCCESS(olMemFree(Mem));227}228 229TEST_P(olLaunchKernelGlobalTest, Success) {230  void *Mem;231  ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED,232                            LaunchArgs.GroupSize.x * sizeof(uint32_t), &Mem));233  struct {234    void *Mem;235  } Args{Mem};236 237  ASSERT_SUCCESS(238      olLaunchKernel(Queue, Device, Kernels[0], nullptr, 0, &LaunchArgs));239  ASSERT_SUCCESS(olSyncQueue(Queue));240  ASSERT_SUCCESS(olLaunchKernel(Queue, Device, Kernels[1], &Args, sizeof(Args),241                                &LaunchArgs));242  ASSERT_SUCCESS(olSyncQueue(Queue));243 244  uint32_t *Data = (uint32_t *)Mem;245  for (uint32_t i = 0; i < 64; i++) {246    ASSERT_EQ(Data[i], i * 2);247  }248 249  ASSERT_SUCCESS(olMemFree(Mem));250}251 252TEST_P(olLaunchKernelGlobalTest, InvalidNotAKernel) {253  ol_symbol_handle_t Global = nullptr;254  ASSERT_SUCCESS(255      olGetSymbol(Program, "global", OL_SYMBOL_KIND_GLOBAL_VARIABLE, &Global));256  ASSERT_ERROR(OL_ERRC_SYMBOL_KIND,257               olLaunchKernel(Queue, Device, Global, nullptr, 0, &LaunchArgs));258}259 260TEST_P(olLaunchKernelGlobalCtorTest, Success) {261  void *Mem;262  ASSERT_SUCCESS(olMemAlloc(Device, OL_ALLOC_TYPE_MANAGED,263                            LaunchArgs.GroupSize.x * sizeof(uint32_t), &Mem));264  struct {265    void *Mem;266  } Args{Mem};267 268  ASSERT_SUCCESS(269      olLaunchKernel(Queue, Device, Kernel, &Args, sizeof(Args), &LaunchArgs));270  ASSERT_SUCCESS(olSyncQueue(Queue));271 272  uint32_t *Data = (uint32_t *)Mem;273  for (uint32_t i = 0; i < 64; i++) {274    ASSERT_EQ(Data[i], i + 100);275  }276 277  ASSERT_SUCCESS(olMemFree(Mem));278}279 280TEST_P(olLaunchKernelGlobalDtorTest, Success) {281  // TODO: We can't inspect the result of a destructor yet, once we282  // find/implement a way, update this test. For now we just check that nothing283  // crashes284  ASSERT_SUCCESS(285      olLaunchKernel(Queue, Device, Kernel, nullptr, 0, &LaunchArgs));286  ASSERT_SUCCESS(olSyncQueue(Queue));287}288