Skip to content

[SYCL][NFC] Refactor RT unit tests #4021

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions sycl/unittests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ endforeach()
include(AddSYCLUnitTest)

add_subdirectory(allowlist)
add_subdirectory(get_native_interop)
add_subdirectory(misc)
add_subdirectory(pi)
add_subdirectory(kernel-and-program)
add_subdirectory(queue)
add_subdirectory(scheduler)
add_subdirectory(spec_constants)
add_subdirectory(SYCL2020)
add_subdirectory(thread_safety)
add_subdirectory(program_manager)
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ set(CMAKE_CXX_EXTENSIONS OFF)

# Enable exception handling for these unit tests
set(LLVM_REQUIRES_EH 1)
add_sycl_unittest(SpecConstantsTests OBJECT
DefaultValues.cpp
add_sycl_unittest(SYCL2020Tests OBJECT
GetNativeOpenCL.cpp
SpecConstDefaultValues.cpp
)

Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
//==----------- test_get_native.cpp --- get_native interop unit test only for
// opencl
//-------------==//
//==----------- GetNativeOpenCL.cpp --- interop unit test only for opencl -==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
Expand All @@ -13,9 +11,12 @@
#include <CL/sycl.hpp>
#include <CL/sycl/backend/opencl.hpp>
#include <detail/context_impl.hpp>
#include <gtest/gtest.h>

#include <helpers/CommonRedefinitions.hpp>
#include <helpers/PiMock.hpp>

#include <gtest/gtest.h>

#include <iostream>
#include <memory>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For sycl::program usages.

Suggested change
#include <memory>
#include <memory>
#define SYCL2020_DISABLE_DEPRECATION_WARNINGS

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is SYCL2020 test, so there must be no sycl::program usages. Right?
I suggest we do not use deprecated API in our unittests and have dedicated set of tests to validate that deprecated API is supported until we decide to drop such support. Does it make sense?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's address both your comments in a separate PR, if that's okay.


Expand Down Expand Up @@ -48,27 +49,6 @@ static pi_result redefinedEventRetain(pi_event c) {
return PI_SUCCESS;
}

static pi_result redefinedProgramCreateWithSource(pi_context context,
pi_uint32 count,
const char **strings,
const size_t *lengths,
pi_program *ret_program) {
return PI_SUCCESS;
}

static pi_result
redefinedProgramBuild(pi_program program, pi_uint32 num_devices,
const pi_device *device_list, const char *options,
void (*pfn_notify)(pi_program program, void *user_data),
void *user_data) {
return PI_SUCCESS;
}

pi_result redefinedEventsWait(pi_uint32 num_events,
const pi_event *event_list) {
return PI_SUCCESS;
}

pi_result redefinedEventGetInfo(pi_event event, pi_event_info param_name,
size_t param_value_size, void *param_value,
size_t *param_value_size_ret) {
Expand All @@ -81,9 +61,7 @@ pi_result redefinedEventGetInfo(pi_event event, pi_event_info param_name,
return PI_SUCCESS;
}

pi_result redefinedEventRelease(pi_event event) { return PI_SUCCESS; }

TEST(GetNativeTest, GetNativeHandle) {
TEST(GetNative, GetNativeHandle) {
platform Plt{default_selector()};
if (Plt.get_backend() != backend::opencl) {
std::cout << "Test is created for opencl only" << std::endl;
Expand All @@ -97,14 +75,9 @@ TEST(GetNativeTest, GetNativeHandle) {
TestCounter = 0;

unittest::PiMock Mock{Plt};
Mock.redefine<detail::PiApiKind::piclProgramCreateWithSource>(
redefinedProgramCreateWithSource);
Mock.redefine<detail::PiApiKind::piProgramBuild>(redefinedProgramBuild);
setupDefaultMockAPIs(Mock);

Mock.redefine<detail::PiApiKind::piEventsWait>(redefinedEventsWait);
Mock.redefine<detail::PiApiKind::piEventGetInfo>(redefinedEventGetInfo);
Mock.redefine<detail::PiApiKind::piEventRelease>(redefinedEventRelease);

Mock.redefine<detail::PiApiKind::piContextRetain>(redefinedContextRetain);
Mock.redefine<detail::PiApiKind::piQueueRetain>(redefinedQueueRetain);
Mock.redefine<detail::PiApiKind::piDeviceRetain>(redefinedDeviceRetain);
Expand Down
156 changes: 156 additions & 0 deletions sycl/unittests/SYCL2020/SpecConstDefaultValues.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
//==---- DefaultValues.cpp --- Spec constants default values unit test -----==//
//
// 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
//
//===----------------------------------------------------------------------===//

#define SYCL2020_DISABLE_DEPRECATION_WARNINGS

#include <CL/sycl.hpp>

#include <helpers/CommonRedefinitions.hpp>
#include <helpers/PiImage.hpp>
#include <helpers/PiMock.hpp>

#include <gtest/gtest.h>

class TestKernel;
const static sycl::specialization_id<int> SpecConst1{42};

__SYCL_INLINE_NAMESPACE(cl) {
namespace sycl {
namespace detail {
template <> struct KernelInfo<TestKernel> {
static constexpr unsigned getNumParams() { return 0; }
static const kernel_param_desc_t &getParamDesc(int) {
static kernel_param_desc_t Dummy;
return Dummy;
}
static constexpr const char *getName() { return "TestKernel"; }
static constexpr bool isESIMD() { return false; }
static constexpr bool callsThisItem() { return false; }
static constexpr bool callsAnyThisFreeFunction() { return false; }
};

template <> const char *get_spec_constant_symbolic_ID<SpecConst1>() {
return "SC1";
}
} // namespace detail
} // namespace sycl
} // __SYCL_INLINE_NAMESPACE(cl)

int SpecConstVal0 = 0;
int SpecConstVal1 = 0;

static pi_result
redefinedProgramSetSpecializationConstant(pi_program prog, pi_uint32 spec_id,
size_t spec_size,
const void *spec_value) {
if (spec_id == 0)
SpecConstVal0 = *static_cast<const int *>(spec_value);
if (spec_id == 1)
SpecConstVal1 = *static_cast<const int *>(spec_value);

return PI_SUCCESS;
}

static sycl::unittest::PiImage generateImageWithSpecConsts() {
using namespace sycl::unittest;

std::vector<char> SpecConstData;
PiProperty SC1 = makeSpecConstant<int>(SpecConstData, "SC1", {0}, {0}, {42});
PiProperty SC2 = makeSpecConstant<int>(SpecConstData, "SC2", {1}, {0}, {8});

PiPropertySet PropSet;
addSpecConstants({SC1, SC2}, std::move(SpecConstData), PropSet);

std::vector<unsigned char> Bin{0, 1, 2, 3, 4, 5}; // Random data

PiArray<PiOffloadEntry> Entries = makeEmptyKernels({"TestKernel"});

PiImage Img{PI_DEVICE_BINARY_TYPE_SPIRV, // Format
__SYCL_PI_DEVICE_BINARY_TARGET_SPIRV64, // DeviceTargetSpec
"", // Compile options
"", // Link options
std::move(Bin),
std::move(Entries),
std::move(PropSet)};

return Img;
}

sycl::unittest::PiImage Img = generateImageWithSpecConsts();
sycl::unittest::PiImageArray ImgArray{Img};

TEST(SpecConstDefaultValues, DISABLED_DefaultValuesAreSet) {
sycl::platform Plt{sycl::default_selector()};
if (Plt.is_host()) {
std::cerr << "Test is not supported on host, skipping\n";
return; // test is not supported on host.
}

if (Plt.get_backend() == sycl::backend::cuda) {
std::cerr << "Test is not supported on CUDA platform, skipping\n";
return;
}

sycl::unittest::PiMock Mock{Plt};
setupDefaultMockAPIs(Mock);
Mock.redefine<sycl::detail::PiApiKind::piextProgramSetSpecializationConstant>(
redefinedProgramSetSpecializationConstant);

const sycl::device Dev = Plt.get_devices()[0];

sycl::queue Queue{Dev};

const sycl::context Ctx = Queue.get_context();

sycl::kernel_bundle KernelBundle =
sycl::get_kernel_bundle<sycl::bundle_state::input>(Ctx, {Dev});
auto ExecBundle = sycl::build(KernelBundle);
Queue.submit([&](sycl::handler &CGH) {
CGH.use_kernel_bundle(ExecBundle);
CGH.single_task<TestKernel>([] {}); // Actual kernel does not matter
});

EXPECT_EQ(SpecConstVal0, 42);
EXPECT_EQ(SpecConstVal1, 8);
}

TEST(SpecConstDefaultValues, DISABLED_DefaultValuesAreOverriden) {
sycl::platform Plt{sycl::default_selector()};
if (Plt.is_host()) {
std::cerr << "Test is not supported on host, skipping\n";
return; // test is not supported on host.
}

if (Plt.get_backend() == sycl::backend::cuda) {
std::cerr << "Test is not supported on CUDA platform, skipping\n";
return;
}

sycl::unittest::PiMock Mock{Plt};
setupDefaultMockAPIs(Mock);
Mock.redefine<sycl::detail::PiApiKind::piextProgramSetSpecializationConstant>(
redefinedProgramSetSpecializationConstant);

const sycl::device Dev = Plt.get_devices()[0];

sycl::queue Queue{Dev};

const sycl::context Ctx = Queue.get_context();

sycl::kernel_bundle KernelBundle =
sycl::get_kernel_bundle<sycl::bundle_state::input>(Ctx, {Dev});
KernelBundle.set_specialization_constant<SpecConst1>(80);
auto ExecBundle = sycl::build(KernelBundle);
Queue.submit([&](sycl::handler &CGH) {
CGH.use_kernel_bundle(ExecBundle);
CGH.single_task<TestKernel>([] {}); // Actual kernel does not matter
});

EXPECT_EQ(SpecConstVal0, 80);
EXPECT_EQ(SpecConstVal1, 8);
}
3 changes: 0 additions & 3 deletions sycl/unittests/get_native_interop/CMakeLists.txt

This file was deleted.

136 changes: 136 additions & 0 deletions sycl/unittests/helpers/CommonRedefinitions.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
//==---- CommonRedefinitions.hpp --- Header with common PI redefinitions ---==//
//
// 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 <CL/sycl.hpp>
#include <helpers/PiImage.hpp>
#include <helpers/PiMock.hpp>

inline pi_result redefinedProgramCreateCommon(pi_context, const void *, size_t,
pi_program *) {
return PI_SUCCESS;
}

Comment on lines +13 to +17
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit. I would allocate something like int * and release it just in case we test somewhere that the program is not null. This can be applied as a separate PR, though.

inline pi_result redefinedProgramBuildCommon(
pi_program prog, pi_uint32, const pi_device *, const char *,
void (*pfn_notify)(pi_program program, void *user_data), void *user_data) {
if (pfn_notify) {
pfn_notify(prog, user_data);
}
return PI_SUCCESS;
}

inline pi_result redefinedProgramCompileCommon(
pi_program, pi_uint32, const pi_device *, const char *, pi_uint32,
const pi_program *, const char **, void (*)(pi_program, void *), void *) {
return PI_SUCCESS;
}

inline pi_result redefinedProgramLinkCommon(pi_context, pi_uint32,
const pi_device *, const char *,
pi_uint32, const pi_program *,
void (*)(pi_program, void *),
void *, pi_program *) {
return PI_SUCCESS;
}

inline pi_result redefinedProgramGetInfoCommon(pi_program program,
pi_program_info param_name,
size_t param_value_size,
void *param_value,
size_t *param_value_size_ret) {
if (param_name == PI_PROGRAM_INFO_NUM_DEVICES) {
auto value = reinterpret_cast<unsigned int *>(param_value);
*value = 1;
}

if (param_name == PI_PROGRAM_INFO_BINARY_SIZES) {
auto value = reinterpret_cast<size_t *>(param_value);
value[0] = 1;
}

if (param_name == PI_PROGRAM_INFO_BINARIES) {
auto value = reinterpret_cast<unsigned char *>(param_value);
value[0] = 1;
}

return PI_SUCCESS;
}

inline pi_result redefinedProgramRetainCommon(pi_program program) {
return PI_SUCCESS;
}

inline pi_result redefinedProgramReleaseCommon(pi_program program) {
return PI_SUCCESS;
}

inline pi_result redefinedKernelCreateCommon(pi_program program,
const char *kernel_name,
pi_kernel *ret_kernel) {
*ret_kernel = reinterpret_cast<pi_kernel>(new int[1]);
return PI_SUCCESS;
}

inline pi_result redefinedKernelRetainCommon(pi_kernel kernel) {
return PI_SUCCESS;
}

inline pi_result redefinedKernelReleaseCommon(pi_kernel kernel) {
delete[] reinterpret_cast<int *>(kernel);
return PI_SUCCESS;
}

inline pi_result redefinedKernelGetInfoCommon(pi_kernel kernel,
pi_kernel_info param_name,
size_t param_value_size,
void *param_value,
size_t *param_value_size_ret) {
return PI_SUCCESS;
}

inline pi_result redefinedKernelSetExecInfoCommon(
pi_kernel kernel, pi_kernel_exec_info value_name, size_t param_value_size,
const void *param_value) {
return PI_SUCCESS;
}

inline pi_result redefinedEventsWaitCommon(pi_uint32 num_events,
const pi_event *event_list) {
return PI_SUCCESS;
}

inline pi_result redefinedEventReleaseCommon(pi_event event) {
return PI_SUCCESS;
}

inline pi_result redefinedEnqueueKernelLaunchCommon(
pi_queue, pi_kernel, pi_uint32, const size_t *, const size_t *,
const size_t *, pi_uint32, const pi_event *, pi_event *) {
return PI_SUCCESS;
}

inline void setupDefaultMockAPIs(sycl::unittest::PiMock &Mock) {
using namespace sycl::detail;
Mock.redefine<PiApiKind::piProgramCreate>(redefinedProgramCreateCommon);
Mock.redefine<PiApiKind::piProgramCompile>(redefinedProgramCompileCommon);
Mock.redefine<PiApiKind::piProgramLink>(redefinedProgramLinkCommon);
Mock.redefine<PiApiKind::piProgramBuild>(redefinedProgramBuildCommon);
Mock.redefine<PiApiKind::piProgramGetInfo>(redefinedProgramGetInfoCommon);
Mock.redefine<PiApiKind::piProgramRetain>(redefinedProgramRetainCommon);
Mock.redefine<PiApiKind::piProgramRelease>(redefinedProgramReleaseCommon);
Mock.redefine<PiApiKind::piKernelCreate>(redefinedKernelCreateCommon);
Mock.redefine<PiApiKind::piKernelRetain>(redefinedKernelRetainCommon);
Mock.redefine<PiApiKind::piKernelRelease>(redefinedKernelReleaseCommon);
Mock.redefine<PiApiKind::piKernelGetInfo>(redefinedKernelGetInfoCommon);
Mock.redefine<PiApiKind::piKernelSetExecInfo>(
redefinedKernelSetExecInfoCommon);
Mock.redefine<PiApiKind::piEventsWait>(redefinedEventsWaitCommon);
Mock.redefine<PiApiKind::piEventRelease>(redefinedEventReleaseCommon);
Mock.redefine<PiApiKind::piEnqueueKernelLaunch>(
redefinedEnqueueKernelLaunchCommon);
}
Loading