Integrating SushiBLAS
How to consume SushiBLAS from another project, and the one fact that decides what you do and don’t need to set up.
1. The fact that shapes everything
SushiBLAS’s kernels are compiled into the library. They are not header templates instantiated in your translation units.
This is the opposite of SushiRuntime’s integration story, and it matters: when you write
engine.blas().gemm(A, B, C);
that call resolves to a function already compiled into libsushiblas.a —
your compiler does not see the GEMM kernel’s source, does not instantiate a
device lambda, and produces no device code of its own for it. Level3::gemm
is an ordinary (if asynchronous) library call.
What you do still need a SYCL-capable compiler for: the public headers
include <sycl/sycl.hpp> directly and use sycl::event/sycl::device in
their own signatures (Tensor::get_device(), every BLASOps/ElementwiseOps
method returns sycl::event). A translation unit that includes
<SushiBLAS/SushiBLAS.h> needs a compiler that can parse those types, even
though it never submits a kernel of its own. This is why linking
SushiBLAS::sushiblas still carries -fsycl as a PUBLIC compile/link
option (cmake/SyclTarget.cmake’s sushiblas_apply_sycl()) — not because
your code will be compiled as a kernel, but because the headers require a
SYCL-aware front end to compile at all.
The practical consequence: you do not need the two-lane build split
SushiRuntime’s own INTEGRATION.md
describes. There is no “SYCL lane vs. ordinary lane” decision to make for
SushiBLAS itself — every translation unit that touches SushiBLAS::sushiblas
needs the SYCL compiler regardless of whether it writes a kernel, because the
headers alone require it.
2. Consuming the package
From an installed prefix
# In SushiBLAS's tree
sb build
cmake --install build --prefix /opt/sushiblas
# In your project (CMAKE_PREFIX_PATH needs BOTH SushiBLAS and its
# SushiRuntime dependency's install prefixes)
cmake -S . -B build \
-DCMAKE_PREFIX_PATH="/opt/sushiblas;/opt/sushiruntime" \
-DCMAKE_CXX_COMPILER=<the same SYCL compiler SushiBLAS was built with>
find_package(SushiBLAS REQUIRED)
add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE SushiBLAS::sushiblas)
tests/package/ in this repository is a complete, working example of
exactly this — a two-file consumer with no access to SushiBLAS’s source
tree. It also runs the flag-hygiene assertion of §3.
From a sibling checkout
add_subdirectory(path/to/sushiblas) also works and gives you the same
SushiBLAS::sushiblas target — the D3 layered resolution
that SushiBLAS itself uses for its own SushiRuntime dependency applies
identically one level up.
Version compatibility
The package is written with SameMinorVersion compatibility while the
project is pre-1.0: find_package(SushiBLAS 0.1 REQUIRED) accepts 0.1.x and
rejects 0.2.0. At the v1.0.0 freeze this becomes SameMajorVersion.
3. What you inherit, and what you must supply
Linking SushiBLAS::sushiblas gives you:
| Inherited | Why |
|---|---|
| Include directories | Obviously. |
| The library itself | Obviously. |
-fsycl (on the intel-llvm toolchain) |
The public headers need a SYCL-aware compiler to parse sycl::event/sycl::device, even if you write no kernel of your own — see §1. |
| SushiRuntime’s floating-point contract, transitively | SushiBLAS links SushiRuntime::SushiRuntime PUBLIC, so its sushiruntime_deterministic_fp interface (-ffp-contract=off -fno-fast-math / /fp:precise) reaches you too. |
You do not inherit SushiBLAS’s own warnings, -Werror, sanitizer
selection, or -march — those are this project’s development choices, and a
dependency silently imposing them on you is a build failure whose cause is
invisible from your own source tree. tests/package/CMakeLists.txt asserts
this from the consumer side (checking INTERFACE_COMPILE_OPTIONS for
-Werror/-Wall/-march=/-fsanitize and INTERFACE_LINK_LIBRARIES for
the in-tree policy target names), which is the only side it is observable
from.
You must supply:
- The same SYCL compiler SushiBLAS itself was built with — mixing toolchains between the library and a consumer is not a supported configuration.
- C++17 or later. SushiBLAS is built at C++17, matching SushiRuntime; a
consumer on C++20 is equally supported and is what
tests/package/compiles as. What is not supported is a consumer whose standard disagrees with the SushiRuntime it links:SushiRuntime::spanisstd::spanat C++20 and SushiRuntime’s own shim below, and that difference is visible in mangled names across SushiRuntime’s compiled ABI. CMAKE_PREFIX_PATHnaming both install prefixes — SushiBLAS’s and its SushiRuntime dependency’s — unless both were installed to the same prefix.- SushiRuntime’s shared library on the loader path at run time (see SushiRuntime’s own README for the redistributable notes), plus whatever your SYCL implementation needs.
4. Checking the binary you actually linked
#include <SushiBLAS/version.hpp>
std::printf("Built against SushiBLAS headers %s\n", SUSHIBLAS_VERSION_STRING);
Unlike SushiRuntime (a SHARED library, where “the headers compiled against”
and “the .dll actually loaded” can legitimately disagree), SushiBLAS is
STATIC: there is no separately loaded artifact whose version could drift
from SUSHIBLAS_VERSION_STRING at run time, so the compile-time macro is the
whole story — there is no SushiBLAS::version_matches() runtime check to
make, because there is nothing for it to check against.
You can also branch at compile time:
#if SUSHIBLAS_VERSION >= SUSHIBLAS_VERSION_ENCODE(0, 2, 0)
// use something introduced in 0.2.0
#endif
5. Troubleshooting
A parse error inside <sycl/sycl.hpp> or <SushiBLAS/tensor.hpp>. Your
translation unit is being compiled by a non-SYCL compiler. Every file that
includes any SushiBLAS header needs the SYCL-aware compiler — see §1.
find_package(SushiBLAS) succeeds but find_package for SushiRuntime
fails downstream. CMAKE_PREFIX_PATH must name both install prefixes;
SushiBLASConfig.cmake calls find_dependency(SushiRuntime) internally, so
a missing SushiRuntime prefix surfaces as a SushiRuntime configure error, not
a SushiBLAS one.
A build failure mentioning -Werror, -march, or sushiblas_warnings.
That would be a leak of SushiBLAS’s private development flags into the
export set — a defect on our side, not yours. tests/package/ asserts
against it; please report it.
Link errors on a BLAS symbol. Confirm you’re linking
SushiBLAS::sushiblas (the namespaced alias), not a bare sushiblas target
name from an add_subdirectory that predates SB-6’s packaging work.

