Do function objects have to be inline?

#1

Hi,
I’m just getting started with SYCL and I’m trying to integrate it into an existing application. I created a function object that uses another class internally. If I inline both classes it works fine, but trying to separate header and implementation (as commonly done in C++) fails at run time because the implementation is not found by the kernel.

According to the Integration Guide, any file containing a kernel will be parsed by the compute++ compiler to generate the integration header. But how do I tell it to also parse the other .cpp files for code that is relevant to the kernel? I am using CMake.

#2

Hi marek,
I’m afraid that is not possible, you need to have all your source in the same translation unit.

#3

To add some more information for this following some discussions about how this could be done.

Right now, the ComputeCpp compiler requires that all classes/functions used in the context of a kernel to be visible in the same translation unit (a.k.a .cpp file) however this is possible using unity builds. This SO question may give you some good information about unity builds.

#4

Thanks Rod! Looks like you are very serious about that “single source” thing :slight_smile:

I’ll have a look into whether a unity build might be feasible for my project but I assume it will create quite a few issues with namespaces and double definitions. As to how to integrate it into the compiler I guess the easiest solution would be to give it the .cpp files as additional input files and parse them for functions that appear in the kernels. Consider this a feature request. :slight_smile:

#5

Hi Marek,
The team is aware of the effort it might take to implement this feature - sadly, it is a really tough one to crack. If and when we do implement it, we’ll definitely be talking about it, so keep an eye on the patch notes.

It’s worth noting that having code inside the same TU shouldn’t be too onerous, unless your kernels are totally huge. We have designed libraries we write to work with this restriction rather than around it - for example, one library we maintain has its kernels written as templates in header files (roughly corresponding to one operation type per header). These templates are then instantiated inside different translation units for different types and so on.

Obviously though every code is different and it sounds like you are integrating SYCL into something that already exists - and such an approach might not be possible. Best of luck!

#6

Hi Duncan,
thanks for your detailed response. I know it would take a lot of effort, I didn’t mean to make it sound trivial - my apologies. The project I am working on is a fairly complex C++ application, and I opted for SYCL because porting it to plain OpenCL would be way too cumbersome - and from the descriptions on the Khronos and Codeplay websites it sounded like SYCL was made exactly for those cases. Maybe I was mistaken but it’s worth a try nonetheless. My code has a lot of type classes and data provider classes, and being able to use them inside compute kernels is a massive help. Many of these come from other libraries, and I’ve chosen a similar approach to what you are describing to get around that. Also the main application’s architecture is very modular so I might get away with several smaller translation units instead of a single massive one.

If something like this hasn’t been done before it might be worth a paper. I’ll make sure to document the process.

#7

That’s a great idea! Please, let us know how you get on, we’re always interested in how people get along with ComputeCpp.

Cheers,
Duncan.