I am trying to create a static or shared library from a sycl program and use it from a main application build using gcc/g++/clang++. Everything is fine if I use dpcpp to build my main application, but I need to use g++.
For example, my sample sycl_lib.cpp and the main program are as follows.
//sycl_lib.cpp
#include<CL/sycl.hpp>
int func() {
q.submit([&](sycl::handler &h) {
sycl::stream os(1024, 768, h);
h.parallel_for(32, [=](sycl::id<1> i) {
os<<i<<"\n";
});
});
}
//main.cpp
void func();
int main() {
func();
return 0;
}
To create a static library and use it:
dpcpp -c sycl_lib.cpp -fPIC
ar rvs sycl_lib.a sycl_lib.o
dpcpp main.cpp sycl_lib.a
./a.out
This works fine. But I want to use g++ to build main.cpp, it is causing runtime error.
g++ main.cpp sycl_lib.a -L$SYSL_DIR/lib -lsycl
./a.out
which is giving the following error
terminate called after throwing an instance of 'cl::sycl::runtime_error'
what(): No kernel named _ZTSZZ4funcvENKUlRN2cl4sycl7handlerEE6_12clES2_EUlNS0_2idILi1EEEE8_24 was found -46 (CL_INVALID_KERNEL_NAME)
Aborted
Is it possible for an executable created with g++ to use a sycl library created using dpc++?
Thank you
The short answer is: while any compiler can be used for the host code, dpcpp must be used to create the final binary (do the link) because only dpcpp knows this is a SYCL program.
We do this by replacing:
$ g++ main.cpp sycl_lib.a -L$SYSL_DIR/lib -lsycl
with
$ g++ -c main.cpp
$ dpcpp main.o sycl_lib.a -L$SYSL_DIR/lib -lsycl
We definitely need to document this better - sorry about that. I'll see what we can do there (suggestions would be appreciated).
Here is why: You can compile any host code with g++, but there is finalization required to finish the SYCL program and create the final binary (to bring together host and non-host code) that g++ knows nothing about. dpcpp invokes “sycl-post-link” - which we get by just using dpcpp to build the final binary
Here are the files and Makefile to illustrate:
//main.cpp
void func();
int main() {
func();
return 0;
}
//sycl_lib.cpp
#include<CL/sycl.hpp>
using namespace sycl;
void func() {
queue q;
q.submit([&](sycl::handler &h) {
sycl::stream os(1024, 768, h);
h.parallel_for(32, [=](sycl::id<1> i) {
os<<i<<"\n";
});
});
}
# Makefile
runG: sycl_lib.a
g++ -c main.cpp
dpcpp -o runG main.o sycl_lib.a -L$SYSL_DIR/lib -lsycl
./runG
FAILrunG: sycl_lib.a
g++ -o runG main.cpp sycl_lib.a -L$SYSL_DIR/lib -lsycl
./runG
sycl_lib.a: sycl_lib.cpp
dpcpp -c sycl_lib.cpp -fPIC
ar rvs sycl_lib.a sycl_lib.o
dpcpp -o runD main.cpp sycl_lib.a
./runD
Thank you for pointing this out. I've added a general note to the book errata, and I'll talk with the dpcpp compiler documentation team about how we can document this clearly.