Skip to content

[SYCL] Add tests that submit kernels from shared library #9626

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 2 commits into from
May 30, 2023
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
61 changes: 61 additions & 0 deletions sycl/test-e2e/SharedLib/use_when_link.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// REQUIRES: linux
//
// RUN: %{build} -DBUILD_LIB -fPIC -shared -o %T/lib%basename_t.so

// RUN: %{build} -DFOO_FIRST -L%T -o %t.out -l%basename_t -Wl,-rpath=%T
// RUN: %{run} %t.out

// RUN: %{build} -L%T -o %t.out -l%basename_t -Wl,-rpath=%T
// RUN: %{run} %t.out

#include <sycl/sycl.hpp>

#include <iostream>

#ifdef BUILD_LIB
int foo() {
sycl::queue q;
sycl::buffer<int, 1> b(1);
q.submit([&](sycl::handler &cgh) {
sycl::accessor acc(b, cgh);
using AccTy = decltype(acc);
struct Kernel {
void operator()() const { acc[0] = 1; }
AccTy acc;
} k = {acc};
cgh.single_task(k);
}).wait();
auto val = sycl::host_accessor(b)[0];
std::cout << "Foo: " << val << std::endl;
return val;
}
#else
int foo();
void run() {
sycl::queue q;
sycl::buffer<int, 1> b(1);
q.submit([&](sycl::handler &cgh) {
sycl::accessor acc(b, cgh);
using AccTy = decltype(acc);
// Use different name to avoid ODR-violation.
struct Kernel2 {
void operator()() const { acc[0] = 2; }
AccTy acc;
} k = {acc};
cgh.single_task(k);
}).wait();
auto val = sycl::host_accessor(b)[0];
std::cout << "Main: " << val << std::endl;
assert(val == 2);
}
int main() {
#ifdef FOO_FIRST
assert(foo() == 1);
#endif
run();
#ifndef FOO_FIRST
assert(foo() == 1);
#endif
return 0;
}
#endif
73 changes: 73 additions & 0 deletions sycl/test-e2e/SharedLib/use_when_link_verify_cache.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// REQUIRES: linux
//
// RUN: %{build} -DBUILD_LIB -fPIC -shared -o %T/lib%basename_t.so

// RUN: %{build} -DFOO_FIRST -L%T -o %t.out -l%basename_t -Wl,-rpath=%T
// RUN: env SYCL_PI_TRACE=-1 %{run} %t.out 2>&1 | FileCheck %s --check-prefixes=CHECK-FIRST,CHECK --implicit-check-not=piProgramBuild

// RUN: %{build} -L%T -o %t.out -l%basename_t -Wl,-rpath=%T
// RUN: env SYCL_PI_TRACE=-1 %{run} %t.out 2>&1 | FileCheck %s --check-prefixes=CHECK-LAST,CHECK --implicit-check-not=piProgramBuild

#include <sycl/sycl.hpp>

#include <iostream>

#ifdef BUILD_LIB
int foo() {
sycl::queue q;
sycl::buffer<int, 1> b(1);
q.submit([&](sycl::handler &cgh) {
sycl::accessor acc(b, cgh);
using AccTy = decltype(acc);
struct Kernel {
void operator()() const { acc[0] = 1; }
AccTy acc;
} k = {acc};
cgh.single_task(k);
}).wait();
auto val = sycl::host_accessor(b)[0];
std::cout << "Foo: " << val << std::endl;
return val;
}
#else
int foo();
void run() {
sycl::queue q;
sycl::buffer<int, 1> b(1);
q.submit([&](sycl::handler &cgh) {
sycl::accessor acc(b, cgh);
using AccTy = decltype(acc);
// Use different name to avoid ODR-violation.
struct Kernel2 {
void operator()() const { acc[0] = 2; }
AccTy acc;
} k = {acc};
cgh.single_task(k);
}).wait();
auto val = sycl::host_accessor(b)[0];
std::cout << "Main: " << val << std::endl;
assert(val == 2);
}
int main() {
#ifdef FOO_FIRST
// CHECK-FIRST: piProgramBuild
// CHECK-FIRST: Foo: 1
// CHECK-FIRST: Foo: 1
assert(foo() == 1);
assert(foo() == 1);
#endif
// CHECK: piProgramBuild
// CHECK: Main: 2
// CHECK: Main: 2
run();
run();
#ifndef FOO_FIRST
// CHECK-LAST: piProgramBuild
// CHECK-LAST: Foo: 1
// CHECK-LAST: Foo: 1
assert(foo() == 1);
assert(foo() == 1);
#endif
return 0;
}
#endif
91 changes: 91 additions & 0 deletions sycl/test-e2e/SharedLib/use_with_dlopen.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
// REQUIRES: linux
//
// RUN: %{build} -DBUILD_LIB -fPIC -shared -o %T/lib%basename_t.so

// DEFINE: %{compile} = %{build} -DFNAME=%basename_t -o %t.out -ldl -Wl,-rpath=%T

// RUN: %{compile} -DRUN_FIRST
// RUN: %{run} %t.out

// RUN: %{compile} -DRUN_MIDDLE_BEFORE
// RUN: %{run} %t.out

// RUN: %{compile} -DRUN_MIDDLE_AFTER
// RUN: %{run} %t.out

// This causes SEG. FAULT.
// RUNx: %{compile} -DRUN_LAST
// RUNx: %{run} %t.out

#include <sycl/sycl.hpp>

#include <dlfcn.h>
#include <iostream>

#ifdef BUILD_LIB
int foo() {
sycl::queue q;
sycl::buffer<int, 1> b(1);
q.submit([&](sycl::handler &cgh) {
sycl::accessor acc(b, cgh);
using AccTy = decltype(acc);
struct Kernel {
void operator()() const { acc[0] = 1; }
AccTy acc;
} k = {acc};
cgh.single_task(k);
}).wait();
auto val = sycl::host_accessor(b)[0];
std::cout << "Foo: " << val << std::endl;
return val;
}
#else
void run() {
sycl::queue q;
sycl::buffer<int, 1> b(1);
q.submit([&](sycl::handler &cgh) {
sycl::accessor acc(b, cgh);
using AccTy = decltype(acc);
// Same Kernel name as in the shared library.
struct Kernel {
void operator()() const { acc[0] = 2; }
AccTy acc;
} k = {acc};
cgh.single_task(k);
}).wait();
auto val = sycl::host_accessor(b)[0];
std::cout << "Main: " << val << std::endl;
assert(val == 2);
}
int main() {
#ifdef RUN_FIRST
run();
#endif

#define STRINGIFY_HELPER(A) #A
#define STRINGIFY(A) STRINGIFY_HELPER(A)
#define SO_FNAME "lib" STRINGIFY(FNAME) ".so"

void *handle = dlopen(SO_FNAME, RTLD_LAZY);
int (*func)();
*(void **)(&func) = dlsym(handle, "_Z3foov");

#ifdef RUN_MIDDLE_BEFORE
run();
#endif

assert(func() == 1);

#ifdef RUN_MIDDLE_AFTER
run();
#endif

dlclose(handle);

#ifdef RUN_LAST
run();
#endif

return 0;
}
#endif
113 changes: 113 additions & 0 deletions sycl/test-e2e/SharedLib/use_with_dlopen_verify_cache.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// REQUIRES: linux
//
// RUN: %{build} -DBUILD_LIB -fPIC -shared -o %T/lib%basename_t.so

// DEFINE: %{compile} = %{build} -DFNAME=%basename_t -o %t.out -ldl -Wl,-rpath=%T

// RUN: %{compile} -DRUN_FIRST
// RUN: env SYCL_PI_TRACE=-1 %{run} %t.out 2>&1 | FileCheck %s --check-prefixes=CHECK-FIRST,CHECK --implicit-check-not=piProgramBuild

// RUN: %{compile} -DRUN_MIDDLE_BEFORE
// RUN: env SYCL_PI_TRACE=-1 %{run} %t.out 2>&1 | FileCheck %s --check-prefixes=CHECK-MIDDLE-BEFORE,CHECK --implicit-check-not=piProgramBuild

// RUN: %{compile} -DRUN_MIDDLE_AFTER
// RUN: env SYCL_PI_TRACE=-1 %{run} %t.out 2>&1 | FileCheck %s --check-prefixes=CHECK-MIDDLE-AFTER,CHECK --implicit-check-not=piProgramBuild

// clang-format off
// This causes SEG. FAULT.
// RUNx: %{compile} -DRUN_LAST
// RUNx: env SYCL_PI_TRACE=-1 %{run} %t.out 2>&1 | FileCheck %s --check-prefixes=CHECK-LAST,CHECK --implicit-check-not=piProgramBuild
// clang-format on

#include <sycl/sycl.hpp>

#include <dlfcn.h>
#include <iostream>

#ifdef BUILD_LIB
int foo() {
sycl::queue q;
sycl::buffer<int, 1> b(1);
q.submit([&](sycl::handler &cgh) {
sycl::accessor acc(b, cgh);
using AccTy = decltype(acc);
struct Kernel {
void operator()() const { acc[0] = 1; }
AccTy acc;
} k = {acc};
cgh.single_task(k);
}).wait();
auto val = sycl::host_accessor(b)[0];
std::cout << "Foo: " << val << std::endl;
return val;
}
#else
void run() {
sycl::queue q;
sycl::buffer<int, 1> b(1);
q.submit([&](sycl::handler &cgh) {
sycl::accessor acc(b, cgh);
using AccTy = decltype(acc);
// Same Kernel name as in the shared library.
struct Kernel {
void operator()() const { acc[0] = 2; }
AccTy acc;
} k = {acc};
cgh.single_task(k);
}).wait();
auto val = sycl::host_accessor(b)[0];
std::cout << "Main: " << val << std::endl;
assert(val == 2);
}
int main() {
#ifdef RUN_FIRST
// CHECK-FIRST: piProgramBuild
// CHECK-FIRST: Main: 2
// CHECK-FIRST: Main: 2
run();
run();
#endif

#define STRINGIFY_HELPER(A) #A
#define STRINGIFY(A) STRINGIFY_HELPER(A)
#define SO_FNAME "lib" STRINGIFY(FNAME) ".so"

void *handle = dlopen(SO_FNAME, RTLD_LAZY);
int (*func)();
*(void **)(&func) = dlsym(handle, "_Z3foov");

#ifdef RUN_MIDDLE_BEFORE
// CHECK-MIDDLE-BEFORE: piProgramBuild
// CHECK-MIDDLE-BEFORE: Main: 2
// CHECK-MIDDLE-BEFORE: Main: 2
run();
run();
#endif

// CHECK: piProgramBuild
// CHECK: Foo: 1
// CHECK: Foo: 1
assert(func() == 1);
assert(func() == 1);

#ifdef RUN_MIDDLE_AFTER
// CHECK-MIDDLE-AFTER: piProgramBuild
// CHECK-MIDDLE-AFTER: Main: 2
// CHECK-MIDDLE-AFTER: Main: 2
run();
run();
#endif

dlclose(handle);

#ifdef RUN_LAST
// CHECK-LAST: piProgramBuild
// CHECK-LAST: Main: 2
// CHECK-LAST: Main: 2
run();
run();
#endif

return 0;
}
#endif