Skip to content
Merged
21 changes: 20 additions & 1 deletion kernel-builder/src/pyproject/deps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,28 @@ pub fn render_deps(env: &Environment, build: &Build, write: &mut impl Write) ->
.wrap_err("Cannot render CUTLASS dependency template")?;
}
Dependency::SyclTla => {
// An Xe35-only TU puts MXFP code that ocloc rejects elsewhere into the
// generic image, so that image can only lower to cri and pvc/bmg need
// alias targets. Otherwise one image serves all three, halving the
// device compilations per TU.
let cri_isolated_image = build.kernels.values().any(|kernel| {
kernel.sycl_flags().is_some_and(|flags| {
flags
.iter()
.any(|flag| flag.contains("__SYCL_TARGET_INTEL_GPU_CRI__"))
})
});
let (sycl_aot_devices, sycl_offload_targets) = if cri_isolated_image {
("cri", "intel_gpu_pvc,intel_gpu_bmg_g21,spir64_gen,spir64")
} else {
("pvc,bmg-g21,cri", "spir64_gen,spir64")
};
env.get_template("xpu/dep-sycl-tla.cmake")
.wrap_err("Cannot get SYCL TLA dependency template")?
.render_captured_to(context! {}, &mut *write)
.render_captured_to(
context! { sycl_aot_devices, sycl_offload_targets },
&mut *write,
)
.wrap_err("Cannot render SYCL TLA dependency template")?;
}
Dependency::MetalCpp => {
Expand Down
49 changes: 47 additions & 2 deletions kernel-builder/src/pyproject/templates/torch/preamble.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,55 @@ elseif(GPU_LANG STREQUAL "SYCL")
endif()


# --- SYCL fat-binary flags ------------------------------------------------
# One .so carries an AOT image per GPU in SYCL_AOT_DEVICES plus a spir64 JIT
# fallback; the runtime picks the matching image at load time.
# These variables are the single source of truth: a dependency may change them
# and call xpu_compose_sycl_flags() again to rebuild the flags.
set(SYCL_OFFLOAD_TARGETS "spir64_gen,spir64")
set(SYCL_AOT_DEVICES "pvc,xe-lpg,ats-m150")
set(SYCL_AOT_BACKEND_OPTIONS " -cl-intel-enable-auto-large-GRF-mode -cl-poison-unsupported-fp64-kernels -cl-intel-greater-than-4GB-buffer-required")
set(SYCL_SPIRV_EXT "")

# Rebuild sycl_flags (compile) and sycl_link_flags (link) from the variables
# above. A macro so it runs in the including scope and can be re-invoked.
#
# -foffload-fp32-prec-* keeps fp32 division and sqrt IEEE correctly rounded,
# matching PyTorch; both the compile and the link step need them.
set(sycl_link_flags "-Wl,-z,noexecstack;-fsycl;--offload-compress;-foffload-fp32-prec-div;-foffload-fp32-prec-sqrt;-fsycl-targets=spir64_gen,spir64;-Xs;-device pvc,xe-lpg,ats-m150 -options ' -cl-intel-enable-auto-large-GRF-mode -cl-poison-unsupported-fp64-kernels -cl-intel-greater-than-4GB-buffer-required';")
set(sycl_flags "-fPIC;-fsycl;-fhonor-nans;-fhonor-infinities;-fno-associative-math;-fno-approx-func;-foffload-fp32-prec-div;-foffload-fp32-prec-sqrt;-fno-sycl-instrument-device-code;--offload-compress;-fsycl-targets=spir64_gen,spir64;")
macro(xpu_compose_sycl_flags)
set(sycl_flags
"-fPIC;-fsycl;-fhonor-nans;-fhonor-infinities;-fno-associative-math;-fno-approx-func;-foffload-fp32-prec-div;-foffload-fp32-prec-sqrt;-fno-sycl-instrument-device-code;--offload-compress;-fsycl-targets=${SYCL_OFFLOAD_TARGETS}")

set(sycl_link_flags
"-Wl,-z,noexecstack;-fsycl;--offload-compress;-foffload-fp32-prec-div;-foffload-fp32-prec-sqrt;-fsycl-targets=${SYCL_OFFLOAD_TARGETS}")

# Backend options reach one target each: spir64_gen takes -device, the
# intel_gpu_* aliases imply theirs. SHELL: stops CMake from deduplicating
# the identical -options and silently dropping all but the first target.
string(REPLACE "," ";" _sycl_aot_targets "${SYCL_OFFLOAD_TARGETS}")
foreach(_tgt IN LISTS _sycl_aot_targets)
if(_tgt STREQUAL "spir64_gen")
string(APPEND sycl_link_flags
";SHELL:-Xsycl-target-backend=spir64_gen \"-device ${SYCL_AOT_DEVICES} -options '${SYCL_AOT_BACKEND_OPTIONS}'\"")
elseif(_tgt MATCHES "^intel_gpu_")
string(APPEND sycl_link_flags
";SHELL:-Xsycl-target-backend=${_tgt} \"-options '${SYCL_AOT_BACKEND_OPTIONS}'\"")
endif()
endforeach()

# SYCL_SPIRV_EXT must be a COMPLETE list (translator replaces, not merges).
# A custom -spirv-ext only reaches an image whose triple matches the exact
# fsycl-targets alias, so emit one -Xspirv-translator=<alias> per target.
if(SYCL_SPIRV_EXT)
string(REPLACE "," ";" _sycl_ext_targets "${SYCL_OFFLOAD_TARGETS}")
foreach(_tgt IN LISTS _sycl_ext_targets)
string(APPEND sycl_link_flags
";SHELL:-Xspirv-translator=${_tgt} -spirv-ext=${SYCL_SPIRV_EXT}")
endforeach()
endif()
endmacro()

xpu_compose_sycl_flags()
set(GPU_FLAGS "${sycl_flags}")


Expand Down
50 changes: 48 additions & 2 deletions kernel-builder/src/pyproject/templates/tvm_ffi/preamble.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,56 @@ elseif(GPU_LANG STREQUAL "SYCL")
message(STATUS "Using Intel SYCL C++ compiler: ${ICPX_COMPILER} and C compiler: ${ICX_COMPILER} Version: ${DPCPP_VERSION}")
endif()

# --- SYCL fat-binary flags ------------------------------------------------
# One .so carries an AOT image per GPU in SYCL_AOT_DEVICES plus a spir64 JIT
# fallback; the runtime picks the matching image at load time.
# These variables are the single source of truth: a dependency may change them
# and call xpu_compose_sycl_flags() again to rebuild the flags.
set(SYCL_OFFLOAD_TARGETS "spir64_gen,spir64")
set(SYCL_AOT_DEVICES "pvc,xe-lpg,ats-m150")
set(SYCL_AOT_BACKEND_OPTIONS " -cl-intel-enable-auto-large-GRF-mode -cl-poison-unsupported-fp64-kernels -cl-intel-greater-than-4GB-buffer-required")
set(SYCL_SPIRV_EXT "")

# Rebuild sycl_flags (compile) and sycl_link_flags (link) from the variables
# above. A macro so it runs in the including scope and can be re-invoked.
#
# -foffload-fp32-prec-* keeps fp32 division and sqrt IEEE correctly rounded,
# matching PyTorch; both the compile and the link step need them.
set(sycl_link_flags "-Wl,-z,noexecstack;-fsycl;--offload-compress;-foffload-fp32-prec-div;-foffload-fp32-prec-sqrt;-fsycl-targets=spir64_gen,spir64;-Xs;-device pvc,xe-lpg,ats-m150 -options ' -cl-intel-enable-auto-large-GRF-mode -cl-poison-unsupported-fp64-kernels -cl-intel-greater-than-4GB-buffer-required';")
set(sycl_flags "-fPIC;-fsycl;-fhonor-nans;-fhonor-infinities;-fno-associative-math;-fno-approx-func;-foffload-fp32-prec-div;-foffload-fp32-prec-sqrt;-fno-sycl-instrument-device-code;--offload-compress;-fsycl-targets=spir64_gen,spir64;")
macro(xpu_compose_sycl_flags)
set(sycl_flags
"-fPIC;-fsycl;-fhonor-nans;-fhonor-infinities;-fno-associative-math;-fno-approx-func;-foffload-fp32-prec-div;-foffload-fp32-prec-sqrt;-fno-sycl-instrument-device-code;--offload-compress;-fsycl-targets=${SYCL_OFFLOAD_TARGETS}")

# spir64_gen bakes the per-device AOT images; -device selects the GPUs.
set(sycl_link_flags
"-Wl,-z,noexecstack;-fsycl;--offload-compress;-foffload-fp32-prec-div;-foffload-fp32-prec-sqrt;-fsycl-targets=${SYCL_OFFLOAD_TARGETS}")

# Backend options reach one target each: spir64_gen takes -device, the
# intel_gpu_* aliases imply theirs. SHELL: stops CMake from deduplicating
# the identical -options and silently dropping all but the first target.
string(REPLACE "," ";" _sycl_aot_targets "${SYCL_OFFLOAD_TARGETS}")
foreach(_tgt IN LISTS _sycl_aot_targets)
if(_tgt STREQUAL "spir64_gen")
string(APPEND sycl_link_flags
";SHELL:-Xsycl-target-backend=spir64_gen \"-device ${SYCL_AOT_DEVICES} -options '${SYCL_AOT_BACKEND_OPTIONS}'\"")
elseif(_tgt MATCHES "^intel_gpu_")
string(APPEND sycl_link_flags
";SHELL:-Xsycl-target-backend=${_tgt} \"-options '${SYCL_AOT_BACKEND_OPTIONS}'\"")
endif()
endforeach()

# SYCL_SPIRV_EXT must be a COMPLETE list (translator replaces, not merges).
# A custom -spirv-ext only reaches an image whose triple matches the exact
# fsycl-targets alias, so emit one -Xspirv-translator=<alias> per target.
if(SYCL_SPIRV_EXT)
string(REPLACE "," ";" _sycl_ext_targets "${SYCL_OFFLOAD_TARGETS}")
foreach(_tgt IN LISTS _sycl_ext_targets)
string(APPEND sycl_link_flags
";SHELL:-Xspirv-translator=${_tgt} -spirv-ext=${SYCL_SPIRV_EXT}")
endforeach()
endif()
endmacro()

xpu_compose_sycl_flags()
set(GPU_FLAGS "${sycl_flags}")

add_compile_definitions(XPU_KERNEL)
Expand Down
44 changes: 38 additions & 6 deletions kernel-builder/src/pyproject/templates/xpu/dep-sycl-tla.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ find_package(SyclTla)
if(DPCPP_VERSION STREQUAL "2025.3")
set(SYCL_TLA_REVISION "v0.8" CACHE STRING "sycl-tla revision to use")
elseif(DPCPP_VERSION STREQUAL "2026.0")
set(SYCL_TLA_REVISION "v0.9.1" CACHE STRING "sycl-tla revision to use")
# v0.9.2 == the rev pinned in nix-builder; v0.9.1 has no cri kernel support.
set(SYCL_TLA_REVISION "v0.9.2" CACHE STRING "sycl-tla revision to use")
else()
message(FATAL_ERROR "Unknown DPCPP_VERSION: ${DPCPP_VERSION}")
endif()
Expand Down Expand Up @@ -68,12 +69,43 @@ if(SYCL_TLA_REVISION MATCHES "^v3\\.9")
add_compile_definitions(OLD_API=1)
endif()

string(REPLACE "-fsycl-targets=spir64_gen,spir64" "-fsycl-targets=spir64" sycl_link_flags "${sycl_link_flags}")
string(REPLACE "-device pvc,xe-lpg,ats-m150" "-device bmg_g21,pvc" sycl_link_flags "${sycl_link_flags}")
string(APPEND sycl_link_flags "-Xspirv-translator;-spirv-ext=+SPV_INTEL_split_barrier")
# Fat binary: AOT images for SYCL_AOT_DEVICES plus a spir64 JIT fallback.
# cri needs sycl-tla v0.9.2 and ocloc >= 26.22, so only 2026.0 gets AOT images.
if(DPCPP_VERSION STREQUAL "2026.0")
set(SYCL_AOT_DEVICES "{{ sycl_aot_devices }}")
set(SYCL_OFFLOAD_TARGETS "{{ sycl_offload_targets }}")
else()
set(SYCL_OFFLOAD_TARGETS "spir64")
endif()

# sycl-tla needs extra extensions (split-barrier always; block-IO and
# matrix-multiply on newer DPCPP). Since the translator replaces the whole
# -spirv-ext list, we query the driver's defaults and append the extras.
set(_sycl_tla_extra_ext "+SPV_INTEL_split_barrier")
if(DPCPP_VERSION STREQUAL "2025.2" OR DPCPP_VERSION STREQUAL "2025.3" OR DPCPP_VERSION STREQUAL "2026.0" OR SYCL_TLA_REVISION STREQUAL "v0.5")
string(APPEND sycl_link_flags ",+SPV_INTEL_2d_block_io,+SPV_INTEL_subgroup_matrix_multiply_accumulate")
string(APPEND _sycl_tla_extra_ext ",+SPV_INTEL_2d_block_io,+SPV_INTEL_subgroup_matrix_multiply_accumulate")
endif()
string(REPLACE "-fsycl-targets=spir64_gen,spir64" "-fsycl-targets=spir64" sycl_flags "${sycl_flags}")

set(_sycl_ext_probe "${CMAKE_CURRENT_BINARY_DIR}/_sycl_spirv_ext_probe.cpp")
file(WRITE "${_sycl_ext_probe}" "int main() { return 0; }\n")
# "-###" MUST be quoted: an unquoted # starts a CMake comment and would drop the
# rest of the COMMAND, making icpx read from stdin instead of dumping its flags.
execute_process(
COMMAND ${ICPX_COMPILER} -fsycl -fsycl-targets=spir64_gen "-###" "${_sycl_ext_probe}"
RESULT_VARIABLE _sycl_ext_probe_rc
OUTPUT_VARIABLE _sycl_ext_probe_out
ERROR_VARIABLE _sycl_ext_probe_err)
string(REGEX MATCH "-spirv-ext=[^\" ]+" _sycl_default_ext "${_sycl_ext_probe_out}${_sycl_ext_probe_err}")
if(_sycl_ext_probe_rc EQUAL 0 AND _sycl_default_ext)
# Strip the "-spirv-ext=-all," prefix, leaving the "+ext,+ext,..." default set.
string(REGEX REPLACE "^-spirv-ext=(-all,)?" "" _sycl_default_ext "${_sycl_default_ext}")
set(SYCL_SPIRV_EXT "${_sycl_default_ext},${_sycl_tla_extra_ext}")
else()
# Silently dropping the compiler defaults would ship a miscompiled kernel.
message(FATAL_ERROR "Could not determine default SPIR-V extensions from ${ICPX_COMPILER} "
"(exit ${_sycl_ext_probe_rc}): ${_sycl_ext_probe_err}")
endif()

xpu_compose_sycl_flags()

endif(GPU_LANG STREQUAL "SYCL")
7 changes: 7 additions & 0 deletions kernels-data/src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,13 @@ impl Kernel {
}
}

pub fn sycl_flags(&self) -> Option<&[String]> {
match self {
Kernel::Xpu { sycl_flags, .. } => sycl_flags.as_deref(),
_ => None,
}
}

pub fn backend(&self) -> Backend {
match self {
Kernel::Cpu { .. } => Backend::Cpu,
Expand Down
26 changes: 13 additions & 13 deletions nix-builder/pkgs/xpu-packages/ocloc.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,32 @@

stdenv.mkDerivation (finalAttrs: {
pname = "ocloc";
version = "25.35";
version = "26.22";

srcs = [
(fetchurl {
url = "https://github.com/intel/compute-runtime/releases/download/25.35.35096.9/intel-ocloc_25.35.35096.9-0_amd64.deb";
hash = "sha256-AjzPj9iRKVi7PwCXcFbC+o3bzvjstLvHK9357LDuxvs=";
url = "https://github.com/intel/compute-runtime/releases/download/26.22.38646.4/intel-ocloc_26.22.38646.4-0_amd64.deb";
hash = "sha256-JXRYQeZiecf/H/bC1NqeyRFoXBLhycVgnZnk1Uo2TcA=";
})
(fetchurl {
url = "https://github.com/intel/intel-graphics-compiler/releases/download/v2.18.5/intel-igc-core-2_2.18.5+19820_amd64.deb";
hash = "sha256-fDQPRcTylOyjqXgKGz7ObUtpn9xR59yf+MXWMjxdjWQ=";
url = "https://github.com/intel/intel-graphics-compiler/releases/download/v2.36.3/intel-igc-core-2_2.36.3+21719_amd64.deb";
hash = "sha256-ngl1rHUBW0Meuy2oGoArn9HiijwnAxOpdWnNHmpsYEg=";
})
(fetchurl {
url = "https://github.com/intel/intel-graphics-compiler/releases/download/v2.18.5/intel-igc-opencl-2_2.18.5+19820_amd64.deb";
hash = "sha256-vLFDVIYXVnPxSxgO+4/Dn/MbdsYl4JsSU6B6cF78+cM=";
url = "https://github.com/intel/intel-graphics-compiler/releases/download/v2.36.3/intel-igc-opencl-2_2.36.3+21719_amd64.deb";
hash = "sha256-NQpSMx54S7f7ntQumTtcRLfmVi/HTSzzECsptqV2+oU=";
})
(fetchurl {
url = "https://github.com/intel/compute-runtime/releases/download/25.35.35096.9/intel-opencl-icd_25.35.35096.9-0_amd64.deb";
hash = "sha256-ifJSVTyTeyRW7pkZhY/yq2Xcaw3L0hnHOVNUhGWt8yU=";
url = "https://github.com/intel/compute-runtime/releases/download/26.22.38646.4/intel-opencl-icd_26.22.38646.4-0_amd64.deb";
hash = "sha256-b9rC6KKqz4ROv9kFIb9xArPrtE9pwbztGpeFp86Wo8I=";
})
(fetchurl {
url = "https://github.com/intel/compute-runtime/releases/download/25.35.35096.9/libigdgmm12_22.8.1_amd64.deb";
hash = "sha256-gQEU7wX01ExchvvC8LNGiBAvQVlqQHcqH/ekj132ns0=";
url = "https://github.com/intel/compute-runtime/releases/download/26.22.38646.4/libigdgmm12_22.10.0_amd64.deb";
hash = "sha256-YDGmPW6KEs5hwU78FfLI5ycGEobjgguFlObQBhXgTVQ=";
})
(fetchurl {
url = "https://github.com/intel/compute-runtime/releases/download/25.35.35096.9/libze-intel-gpu1_25.35.35096.9-0_amd64.deb";
hash = "sha256-phfUqwNRqPJxdDi+QyXKARB1hFDhDrb6AtYUrtElIHo=";
url = "https://github.com/intel/compute-runtime/releases/download/26.22.38646.4/libze-intel-gpu1_26.22.38646.4-0_amd64.deb";
hash = "sha256-i++fJOA/gm+TwHYIG9oTxqw6+9nkK5+48pj6tlIzDi8=";
})
];
dontStrip = true;
Expand Down
4 changes: 2 additions & 2 deletions nix-builder/pkgs/xpu-packages/sycl-tla.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ let
hash = "sha256-xXAxIDBesjDDOIa6/YsGznyW+5+NpaO1L96lBuqRzrk=";
};
"2026.0" = {
version = "0.9.1";
hash = "sha256-c8ecf042tO9ChTiFav9vQvHhhVZyk1YH5govfWOxfF0=";
version = "0.9.2";
hash = "sha256-Hn51Ah1wEscOnrt9O/aXBW7IC6Mcl4gUWynAmDeAOlM=";
};
};
syclTlaVersion =
Expand Down
Loading