At the 13th IWOCL International Workshop on OpenCL* and SYCL, Alexey Sachkov of Intel reported on several experimental proposals for increasing the reach and applicability of SYCL as a common cross-architecture framework for accelerated computing for different verticals and use cases, from AI PC to supercomputer and from edge to cloud.
In this article, we provide a glimpse into two of those ideas that expand SYCL in different directions.
First, we cover virtual functions. SYCL is designed to be a natural, comprehensive extension of C++ into the realm of multiarchitecture computing. As such, it is only consistent to expand the idea of virtual functions, which can be redefined in derived classes to offload kernels. Alexey discusses a proposed approach to achieving that.
The second idea is also about abstraction, not about the abstraction of functions within a base class, though. It is about expanding SPIR-V backend abstraction support to make it even easier for SYCL’s low-level implementation to interface with the rich ecosystem of available hardware architecture and specialized custom accelerators. It is about making LLVM* and SPIR-V work even better together in a SYCL context.
SYCL and its wide universal applicability are growing in many dimensions. Looking at its ongoing expansion, let us talk about abstraction with SYCL, from C++ virtual function objects to low-level hardware abstraction.
Virtual Functions in SYCL
Virtual functions are a standard staple of modern C++ software development since the language’s inception. Common backend abstractions like the Kokkos* C++ performance portability interface, widely used in high-performance scientific computing, rely on it.
Although the SYCL specification allows the one-definition rule (ODR) use of virtual inheritance, virtual member functions cannot be called within a device function, leading to complications when porting some code bases.
Beginning [1min 50sec] into his presentation, Alexey sets up a basic reference example of a base class with a couple of virtual methods, and direct classes with overrides for those virtual classes and some offload kernels.
Figure 1: Basic virtual class inheritance setup with oneAPI kernel property extension.
First, he adds the experimental indirectly callable function properties described in the sycl_ext_oneapi_kernel_properties GitHub sandbox (highlighted in yellow in Figure 1). With this, a function or offload kernel can be tagged as an indirectly callable device function.
Why is this needed for virtual functions?
A program object contains a virtual table of pointers to class overrides. Every time a virtual function is called, a specific pointer from this table is loaded to call the correct derived function. The table references all virtual functions you have in your class.
However, in the Base{}function in Figure 1, for example, foo{} throws an exception and new memory is allocated, violating SYCL device code restrictions.
You can think of the indirectly_callable property as analogous to the SYCL_EXTERNAL macro, declaring the virtual function to be a device function with all its restrictions.
The assume_indirect_calls properties_tag is needed for the same reason. Doing a virtual call from a kernel without this property will trigger an error.
Note: An object can only be used to make virtual function calls on the same device where it was constructed—no switching back and forth between host and device for virtual function construction and call.
From there, Alexey discusses advanced topics and possible future work, such as reqd_sub_group_size support and optional kernel feature support.
Figure 2: Full Presentation Recording
⇒ Dive into the details of virtual function support with SYCL. Check out the slides and recording of the
“Virtual Functions in SYCL” presentation at the 13th IWOCL International Workshop on OpenCL* and SYCL this past April.
Implementation Considerations
There are a few high-level items to consider when building an application with this new feature:
- When building your application using virtual function support with SYCL, put every virtual function set into a separate device image. If any optional kernel features are in use, create a copy with empty functions. This helps to avoid speculative compilation but still provides all symbols for the link stage.
- For any such device image with a kernel, link all device images containing the same virtual function sets.
- When targeting SPIR-V, the above happens at runtime. Otherwise, it happens during the build link step
If you are looking for more technical implementation details, check out the
- ext_intel_virtual_functions specification on Intel’s LLVM GitHub and
- the sycl_ext_oneapi_virtual_functions extension test cases
in the same source code tree.
Take your SYCL Code to the Next Level with Virtual Functions
The proposed virtual function support is continually evolving and experimentally available with the Intel® oneAPI DPC++/C++ Compiler and Intel® DPC++ Compatibility Tool 2025.1 or newer releases.
Give it a go with your codebase and let us know what you think.
SPIR-V Backend Use with SYCL
SPIR-V is a binary intermediate language for representing graphical-shader stages and compute kernels, with a specification defined by the Khronos* Group, the same governing body that manages SYCL. It provides a portable format serving as a programming interface and unifying intermediate representation for heterogeneous accelerators.
There is a rich ecosystem of languages and APIs that support it.
For LLVM and LLVM Intermediate Representation (LLVM IR) based C++ compilers, like all compilers in the CLANG* project family, this raises the issue of a duality of intermediate abstracted hardware backend representation.
There is a SPIR-V to LLVM Translator for bi-directional translation, but it is not maintained as part of the LLVM project tree itself, making it prone to disconnects and intermittent incompatibilities.
To address this, Intel’s compiler development team proposes SPIR-V as a regular LLVM code generation target akin to other hardware target runtimes. As such, a SPIR-V backend becomes part of the LLVM project, ensuring full comprehensive integration testing and opening it up for not just heterogeneous computing with OpenCL or SYCL, but also for use with OpenAI Triton backends or graphics-oriented programming models like high-level shader language (HLSL) or Vulkan.
The SPIR-V Backend is now supported and maintained by an active and growing LLVM SPIR-V working group with comprehensive documentation:
Following Intel’s committed support for the open source community, our compiler developers are active and engaged contributors, helping to address challenges related to mapping LLVM IR semantics and specifications to SPIR-V.
Alexey Sachkov, in his presentation, discusses them and Intel’s approach to resolving them in detail.
Figure 3: Full Presentation Recording
⇒ Dive into the details of LLVM SPIR-V Backend support with SYCL. Check out the slides and recording of the
“Virtual Functions in SYCL” presentation at the 13th IWOCL International Workshop on OpenCL* and SYCL this past April.
Use SPIR-V as a Compilation Target with your SYCL Code
The development of the SPIR-V Backend for LLVM is ongoing, but it has been available as an official target with the LLVM project since January 2025. Give it a try and follow up by commenting on its LLVM project RFC page.
Get Started with SYCL, oneAPI, and SPIR-V Today
Find out more about how to use these and other latest features in LLVM-based C++ compilers and toolchains with SYCL support at the Intel® oneAPI DPC++ C++ Compiler and oneAPI Overview landing page.
Additional Resources
Virtual Functions
- sycl_ext_oneapi_kernel_properties on GitHub
- sycl_ext_oneapi_enqueue_functions on GitHub
- sycl_ext_oneapi_named_sub_group_sizes on GitHub
- SYCL 2020 Specification
- SPIR-V Function Pointers
- Intel Virtual Function Pointer Specification
- Virtual Function Example Tests
SPIR-V with LLVM and SYCL