mirror of
https://github.com/intel/llvm.git
synced 2026-01-21 04:14:03 +08:00
In the future, we want `ol_symbol_handle_t` to represent both kernels and global variables The first step in this process is a rename and promotion to a "typed handle".
173 lines
5.9 KiB
C++
173 lines
5.9 KiB
C++
//===------- Offload API tests - gtest fixtures --==-----------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include <OffloadAPI.h>
|
|
#include <OffloadPrint.hpp>
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "Environment.hpp"
|
|
|
|
#pragma once
|
|
|
|
#ifndef ASSERT_SUCCESS
|
|
#define ASSERT_SUCCESS(ACTUAL) \
|
|
do { \
|
|
ol_result_t Res = ACTUAL; \
|
|
if (Res && Res->Code != OL_ERRC_SUCCESS) { \
|
|
GTEST_FAIL() << #ACTUAL " returned " << Res->Code << ": " \
|
|
<< Res->Details; \
|
|
} \
|
|
} while (0)
|
|
#endif
|
|
|
|
// TODO: rework this so the EXPECTED/ACTUAL results are readable
|
|
#ifndef ASSERT_ERROR
|
|
#define ASSERT_ERROR(EXPECTED, ACTUAL) \
|
|
do { \
|
|
ol_result_t Res = ACTUAL; \
|
|
ASSERT_TRUE(Res && (Res->Code == EXPECTED)); \
|
|
} while (0)
|
|
#endif
|
|
|
|
#ifndef ASSERT_ANY_ERROR
|
|
#define ASSERT_ANY_ERROR(ACTUAL) \
|
|
do { \
|
|
ol_result_t Res = ACTUAL; \
|
|
ASSERT_TRUE(Res); \
|
|
} while (0)
|
|
#endif
|
|
|
|
#define RETURN_ON_FATAL_FAILURE(...) \
|
|
__VA_ARGS__; \
|
|
if (this->HasFatalFailure() || this->IsSkipped()) { \
|
|
return; \
|
|
} \
|
|
(void)0
|
|
|
|
inline std::string SanitizeString(const std::string &Str) {
|
|
auto NewStr = Str;
|
|
std::replace_if(
|
|
NewStr.begin(), NewStr.end(), [](char C) { return !std::isalnum(C); },
|
|
'_');
|
|
return NewStr;
|
|
}
|
|
|
|
struct OffloadTest : ::testing::Test {
|
|
ol_device_handle_t Host = TestEnvironment::getHostDevice();
|
|
};
|
|
|
|
struct OffloadDeviceTest
|
|
: OffloadTest,
|
|
::testing::WithParamInterface<TestEnvironment::Device> {
|
|
void SetUp() override {
|
|
RETURN_ON_FATAL_FAILURE(OffloadTest::SetUp());
|
|
|
|
auto DeviceParam = GetParam();
|
|
Device = DeviceParam.Handle;
|
|
if (Device == nullptr)
|
|
GTEST_SKIP() << "No available devices.";
|
|
}
|
|
|
|
ol_device_handle_t Device = nullptr;
|
|
};
|
|
|
|
struct OffloadPlatformTest : OffloadDeviceTest {
|
|
void SetUp() override {
|
|
RETURN_ON_FATAL_FAILURE(OffloadDeviceTest::SetUp());
|
|
|
|
ASSERT_SUCCESS(olGetDeviceInfo(Device, OL_DEVICE_INFO_PLATFORM,
|
|
sizeof(Platform), &Platform));
|
|
ASSERT_NE(Platform, nullptr);
|
|
}
|
|
|
|
ol_platform_handle_t Platform = nullptr;
|
|
};
|
|
|
|
// Fixture for a generic program test. If you want a different program, use
|
|
// offloadQueueTest and create your own program handle with the binary you want.
|
|
struct OffloadProgramTest : OffloadDeviceTest {
|
|
void SetUp() override {
|
|
RETURN_ON_FATAL_FAILURE(OffloadDeviceTest::SetUp());
|
|
ASSERT_TRUE(TestEnvironment::loadDeviceBinary("foo", Device, DeviceBin));
|
|
ASSERT_GE(DeviceBin->getBufferSize(), 0lu);
|
|
ASSERT_SUCCESS(olCreateProgram(Device, DeviceBin->getBufferStart(),
|
|
DeviceBin->getBufferSize(), &Program));
|
|
}
|
|
|
|
void TearDown() override {
|
|
if (Program) {
|
|
olDestroyProgram(Program);
|
|
}
|
|
RETURN_ON_FATAL_FAILURE(OffloadDeviceTest::TearDown());
|
|
}
|
|
|
|
ol_program_handle_t Program = nullptr;
|
|
std::unique_ptr<llvm::MemoryBuffer> DeviceBin;
|
|
};
|
|
|
|
struct OffloadKernelTest : OffloadProgramTest {
|
|
void SetUp() override {
|
|
RETURN_ON_FATAL_FAILURE(OffloadProgramTest::SetUp());
|
|
ASSERT_SUCCESS(olGetKernel(Program, "foo", &Kernel));
|
|
}
|
|
|
|
void TearDown() override {
|
|
RETURN_ON_FATAL_FAILURE(OffloadProgramTest::TearDown());
|
|
}
|
|
|
|
ol_symbol_handle_t Kernel = nullptr;
|
|
};
|
|
|
|
struct OffloadQueueTest : OffloadDeviceTest {
|
|
void SetUp() override {
|
|
RETURN_ON_FATAL_FAILURE(OffloadDeviceTest::SetUp());
|
|
ASSERT_SUCCESS(olCreateQueue(Device, &Queue));
|
|
}
|
|
|
|
void TearDown() override {
|
|
if (Queue) {
|
|
olDestroyQueue(Queue);
|
|
}
|
|
RETURN_ON_FATAL_FAILURE(OffloadDeviceTest::TearDown());
|
|
}
|
|
|
|
ol_queue_handle_t Queue = nullptr;
|
|
};
|
|
|
|
struct OffloadEventTest : OffloadQueueTest {
|
|
void SetUp() override {
|
|
RETURN_ON_FATAL_FAILURE(OffloadQueueTest::SetUp());
|
|
|
|
// Get an event from a memcpy. We can still use it in olGetEventInfo etc
|
|
// after it has been waited on.
|
|
void *Alloc;
|
|
uint32_t Value = 42;
|
|
ASSERT_SUCCESS(
|
|
olMemAlloc(Device, OL_ALLOC_TYPE_DEVICE, sizeof(Value), &Alloc));
|
|
ASSERT_SUCCESS(
|
|
olMemcpy(Queue, Alloc, Device, &Value, Host, sizeof(Value), &Event));
|
|
ASSERT_SUCCESS(olWaitEvent(Event));
|
|
ASSERT_SUCCESS(olMemFree(Alloc));
|
|
}
|
|
|
|
void TearDown() override {
|
|
if (Event)
|
|
olDestroyEvent(Event);
|
|
RETURN_ON_FATAL_FAILURE(OffloadQueueTest::TearDown());
|
|
}
|
|
|
|
ol_event_handle_t Event = nullptr;
|
|
};
|
|
|
|
#define OFFLOAD_TESTS_INSTANTIATE_DEVICE_FIXTURE(FIXTURE) \
|
|
INSTANTIATE_TEST_SUITE_P( \
|
|
, FIXTURE, ::testing::ValuesIn(TestEnvironment::getDevices()), \
|
|
[](const ::testing::TestParamInfo<TestEnvironment::Device> &info) { \
|
|
return SanitizeString(info.param.Name); \
|
|
})
|