Skip to content

Commit

Permalink
Merge pull request #737 from vladimirkhashev/cover_gaps_for_use_kerne…
Browse files Browse the repository at this point in the history
…l_bundle

Cover gaps for use_kernel_bunde()
  • Loading branch information
bader authored Jun 29, 2023
2 parents 9552084 + 06edf5d commit b3c7519
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 41 deletions.
29 changes: 23 additions & 6 deletions tests/kernel_bundle/use_kernel_bundle.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,29 @@ static const std::string skip_test_for_builtin_kernels_msg{
"Test for built-in kernels will be skipped due to kernel bundle is "
"empty."};

inline auto user_def_kernels =
named_type_pack<kernels::kernel_cpu_descriptor,
kernels::kernel_gpu_descriptor,
kernels::kernel_accelerator_descriptor>::
generate("kernel_cpu_descriptor", "kernel_gpu_descriptor",
"kernel_accelerator_descriptor");
inline auto user_def_kernels = named_type_pack<
kernels::kernel_fp16_descriptor, kernels::kernel_fp64_descriptor,
kernels::kernel_atomic64_descriptor, kernels::kernel_image_descriptor,
kernels::kernel_online_compiler_descriptor,
kernels::kernel_online_linker_descriptor,
kernels::kernel_queue_profiling_descriptor,
kernels::kernel_usm_device_allocations_descriptor,
kernels::kernel_usm_host_allocations_descriptor,
kernels::kernel_usm_atomic_host_allocations_descriptor,
kernels::kernel_usm_shared_allocations_descriptor,
kernels::kernel_usm_atomic_shared_allocations_descriptor,
kernels::kernel_usm_system_allocations_descriptor>::
generate("kernel_fp16_descriptor", "kernel_fp64_descriptor",
"kernel_atomic64_descriptor", "kernel_image_descriptor",
"kernel_online_compiler_descriptor",
"kernel_online_linker_descriptor",
"kernel_queue_profiling_descriptor",
"kernel_usm_device_allocations_descriptor",
"kernel_usm_host_allocations_descriptor",
"kernel_usm_atomic_host_allocations_descriptor",
"kernel_usm_shared_allocations_descriptor",
"kernel_usm_atomic_shared_allocations_descriptor",
"kernel_usm_system_allocations_descriptor");

template <sycl::bundle_state BundleState>
class TestCaseDescription
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ using namespace sycl_cts::tests::use_kernel_bundle;

/** @brief Struct with overloaded call operator for using in "for_all_types"
* function to be able run this test with different user-defined kernels
* @tparam KernelDescriptorT Detepminated user-defined structs with kernels and
* @tparam KernelDescriptorT Determined user-defined structs with kernels and
* restrictions for this kernels
*/
template <typename KernelDescriptorT>
struct run_verification {
/** @brief Call sycl::handler::use_kernel_bundle with used-defined kernel for
/** @brief Call sycl::handler::use_kernel_bundle with user-defined kernel for
* incompatible device and verify that exceptions with
* sycl::errc::kernel_not_supported code was thrown with using
* sycl::errc::kernel_not_supported code was thrown without using
* secondary queue
* @param log sycl_cts::util::logger class object
* @param ctx Context that will used for sycl::queue and kernel bundle
Expand All @@ -39,17 +39,32 @@ struct run_verification {
void operator()(util::logger &log, const sycl::context &ctx,
const std::string &kernel_name) {
auto restrictions{KernelDescriptorT::get_restrictions()};
if (!restrictions.is_compatible(ctx.get_devices()[0])) {

bool there_is_compat_dev{false};
std::vector<sycl::device> incompatible_devs;

for (auto& dev : ctx.get_devices()) {
if (restrictions.is_compatible(dev))
there_is_compat_dev = true;
else
incompatible_devs.push_back(dev);
}

if (there_is_compat_dev && !incompatible_devs.empty()) {
using kernel_functor = typename KernelDescriptorT::type;
sycl::kernel_bundle<sycl::bundle_state::executable> kernel_bundle =
get_non_empty_bundle<kernel_functor>(ctx);
bool ex_was_thrown = false;

sycl::queue queue(ctx, ctx.get_devices()[0]);
sycl::queue queue(ctx, incompatible_devs[0]);
unsigned long long data;
try {
queue.submit([&](sycl::handler &cgh) {
sycl::buffer<unsigned long long, 1> data_buf(&data, 1);
queue.submit([&](sycl::handler& cgh) {
auto data_acc =
data_buf.get_access<sycl::access_mode::read_write>(cgh);
cgh.use_kernel_bundle(kernel_bundle);
cgh.single_task<kernel_functor>([=]() {});
cgh.parallel_for(sycl::range(1), kernel_functor{data_acc});
});
} catch (const sycl::exception &e) {
if (e.code() != sycl::errc::kernel_not_supported) {
Expand Down Expand Up @@ -78,6 +93,18 @@ class TEST_NAME : public sycl_cts::util::test_base {
*/
void run(util::logger &log) override {
sycl::device dev = util::get_cts_object::device();

if (dev.get_platform().get_devices().size() < 2) {
SKIP(
"Not enough devices on the platform used. Required at least two "
"devices to test kernel"
"on not compatible device. In case of single available device a "
"kernel_bundle with incompatible"
"kernel for available device can't be gotten as there is no devices "
"which support the kernel,"
"only device that is not compatible");
}

sycl::context ctx(dev.get_platform().get_devices());

for_all_types<run_verification>(user_def_kernels, log, ctx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,46 @@ using namespace sycl_cts::tests::use_kernel_bundle;

/** @brief Struct with overloaded call operator for using in "for_all_types"
* function to be able run this test with different user-defined kernels
* @tparam KernelDescriptorT Detepminated user-defined structs with kernels and
* @tparam KernelDescriptorT Determined user-defined structs with kernels and
* restrictions for this kernels
*/
template <typename KernelDescriptorT>
struct run_verification {
/** @brief Call sycl::handler::use_kernel_bundle with used-defined kernel for
* incompatible device and verify that exceptions with
std::string kernel_name;
util::logger* log;

void check_exception(sycl::queue& primary_queue,
sycl::queue& secondary_queue) {
using kernel_functor = typename KernelDescriptorT::type;
sycl::kernel_bundle<sycl::bundle_state::executable> kernel_bundle =
get_non_empty_bundle<kernel_functor>(primary_queue.get_context());
bool ex_was_thrown = false;

unsigned long long data;
try {
sycl::buffer<unsigned long long, 1> data_buf(&data, 1);
primary_queue.submit(
[&](sycl::handler& cgh) {
auto data_acc =
data_buf.get_access<sycl::access_mode::read_write>(cgh);
cgh.use_kernel_bundle(kernel_bundle);
cgh.parallel_for(sycl::range(1), kernel_functor{data_acc});
},
secondary_queue);
} catch (const sycl::exception& e) {
if (e.code() != sycl::errc::kernel_not_supported) {
FAIL(*log, unexpected_exception_msg);
throw;
}
ex_was_thrown = true;
}

if (!ex_was_thrown) {
FAIL(*log, "Exception was not thrown for kernel name: " + kernel_name);
}
}
/** @brief Call sycl::handler::use_kernel_bundle with user-defined kernel for
* incompatible device and verify that exception with
* sycl::errc::kernel_not_supported code was thrown with using
* secondary queue
* @param log sycl_cts::util::logger class object
Expand All @@ -38,33 +71,34 @@ struct run_verification {
*/
void operator()(util::logger &log, const sycl::context &ctx,
const std::string &kernel_name) {
this->kernel_name = kernel_name;
this->log = &log;

auto restrictions{KernelDescriptorT::get_restrictions()};
if (!restrictions.is_compatible(ctx.get_devices()[0])) {
using kernel_functor = typename KernelDescriptorT::type;
sycl::kernel_bundle<sycl::bundle_state::executable> kernel_bundle =
get_non_empty_bundle<kernel_functor>(ctx);
bool ex_was_thrown = false;

sycl::queue first_queue(ctx, ctx.get_devices()[0]);
sycl::queue second_queue(ctx, ctx.get_devices()[0]);
try {
first_queue.submit(
[&](sycl::handler &cgh) {
cgh.use_kernel_bundle(kernel_bundle);
cgh.single_task<kernel_functor>([=]() {});
},
second_queue);
} catch (const sycl::exception &e) {
if (e.code() != sycl::errc::kernel_not_supported) {
FAIL(log, unexpected_exception_msg);
throw;
}
ex_was_thrown = true;
}
std::vector<sycl::device> compatible_devs;
std::vector<sycl::device> incompatible_devs;

if (!ex_was_thrown) {
FAIL(log, "Exception was not thrown for kernel name: " + kernel_name);
}
for (auto& dev : ctx.get_devices()) {
if (restrictions.is_compatible(dev))
compatible_devs.push_back(dev);
else
incompatible_devs.push_back(dev);
}

if (!compatible_devs.empty() && !incompatible_devs.empty()) {
sycl::queue first_queue_incompat_dev(ctx, incompatible_devs[0]);
sycl::queue second_queue_incompat_dev(ctx, incompatible_devs[0]);

sycl::queue first_queue_compat_dev(ctx, compatible_devs[0]);
sycl::queue second_queue_compat_dev(ctx, compatible_devs[0]);

// Check when devices of both queues are not compatible with kernel bundle
check_exception(first_queue_incompat_dev, second_queue_incompat_dev);
// Check when device of secondary queue is not compatible with kernel
// bundle
check_exception(first_queue_compat_dev, second_queue_incompat_dev);
// Check when device of primary queue is not compatible with kernel bundle
check_exception(first_queue_incompat_dev, second_queue_compat_dev);
}
}
};
Expand All @@ -81,6 +115,18 @@ class TEST_NAME : public sycl_cts::util::test_base {
*/
void run(util::logger &log) override {
sycl::device dev = util::get_cts_object::device();

if (dev.get_platform().get_devices().size() < 2) {
SKIP(
"Not enough devices on the platform used. Required at least two "
"devices to test kernel"
"on not compatible device. In case of single available device a "
"kernel_bundle with incompatible"
"kernel for available device can't be gotten as there is no devices "
"which support the kernel,"
"only device that is not compatible");
}

sycl::context ctx(dev.get_platform().get_devices());

for_all_types<run_verification>(user_def_kernels, log, ctx);
Expand Down

0 comments on commit b3c7519

Please sign in to comment.