0

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

sriraj
  • 93
  • 5

1 Answers1

3

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.