Skip to content

Add compile-time dispatching examples for generic BLAS and portFFT backends - #752

Open
zjin-lcf wants to merge 2 commits into
uxlfoundation:developfrom
zjin-lcf:examples-generic-portfft
Open

Add compile-time dispatching examples for generic BLAS and portFFT backends#752
zjin-lcf wants to merge 2 commits into
uxlfoundation:developfrom
zjin-lcf:examples-generic-portfft

Conversation

@zjin-lcf

Copy link
Copy Markdown
Contributor

Summary

Closes #714.

The SYCL-only generic BLAS and portFFT backends cannot be combined with any other backend, so the existing compile-time dispatching examples (which pair mklcpu with a vendor GPU backend) do not cover them. This PR adds standalone, single-device compile-time dispatching examples so users can build and run something to validate these backends:

  • examples/blas/compile_time_dispatching/level3/gemm_usm_generic.cpp — GEMM via backend_selector<backend::generic>, built when ENABLE_GENERIC_BLAS_BACKEND is on (links onemath_blas_generic).
  • examples/dft/compile_time_dispatching/complex_fwd_usm_portfft.cpp — complex in-place forward DFT via backend_selector<backend::portfft>, built when ENABLE_PORTFFT_BACKEND is on (links onemath_dft_portfft). Only the COMPLEX domain is used since portFFT does not support REAL.

The BLAS and DFT compile-time CMakeLists.txt files are restructured to guard each backend combination independently (instead of an early return()), so the new SYCL-only examples build alongside the existing ones. Both examples are registered as ctests and documented in examples/README.md with sample output.

Test plan

Built and run on an Intel(R) Arc(TM) B580 Graphics GPU with the DPC++ (icpx 2025.3.1) compiler:

cmake -B build -G Ninja \
  -DCMAKE_CXX_COMPILER=icpx -DCMAKE_C_COMPILER=icx \
  -DENABLE_MKLGPU_BACKEND=OFF -DENABLE_MKLCPU_BACKEND=OFF \
  -DENABLE_GENERIC_BLAS_BACKEND=ON -DENABLE_PORTFFT_BACKEND=ON \
  -DTARGET_DOMAINS="blas;dft" \
  -DBUILD_EXAMPLES=ON -DBUILD_SHARED_LIBS=ON \
  -DGENERIC_BLAS_TUNING_TARGET=INTEL_GPU
cmake --build build -j

Results:

  • example_blas_gemm_usm_generic — ran OK, exit 0.
  • example_dft_complex_fwd_usm_portfft — ran OK, exit 0.

Note for the reporter: the first run of each example is slow because the kernels are JIT-compiled by IGC on the B580; this can look like a hang. Allowing it to finish (or building AOT with -fsycl-targets=spir64_gen -Xs "-device bmg") resolves it.

…ckends

The SYCL-only generic BLAS and portFFT backends cannot be combined with
any other backend, so the existing compile-time examples (which pair
mklcpu with a vendor GPU backend) do not cover them. Add standalone
single-device examples so users can validate these backends:

- blas: level3/gemm_usm_generic (built with ENABLE_GENERIC_BLAS_BACKEND)
- dft: complex_fwd_usm_portfft (built with ENABLE_PORTFFT_BACKEND, COMPLEX
  domain only)

The BLAS and DFT compile-time CMakeLists are restructured to guard each
backend combination independently instead of returning early. The
examples README documents both new examples with sample output.

Both examples were verified on an Intel Arc B580 GPU with the DPC++
compiler.

Addresses uxlfoundation#714

Co-authored-by: Cursor <cursoragent@cursor.com>
@zjin-lcf
zjin-lcf requested review from a team as code owners August 11, 2026 02:41

@melonakos melonakos left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a clean change and I'm happy to approve once the formatter is satisfied.

The CMake restructuring is the right call. Converting the early if(NOT ...) return() endif() guard into per-example if(...) blocks is what lets a second example live in the same directory without the first one's backend requirements gating it — and you did the same thing consistently in both the BLAS and DFT example directories. That's the kind of change that's easy to do halfway, so nice work keeping them symmetric.

Adding a generic-BLAS and a portFFT compile-time dispatching example is genuinely useful. The compile-time dispatch path is underdocumented, and the existing examples all assumed MKLCPU+cuBLAS, which meant anyone on a SYCL-only build had nothing to copy from. Registering each as a ctest is a good touch.

One thing to fix: clang-format check is failing, and this one is real — unlike the ArmPL failures elsewhere in your queue, this is your change. It'll be the two new sources (gemm_usm_generic.cpp and complex_fwd_usm_portfft.cpp). That's the only thing standing between this and my approval.

Rather than hand-formatting, the CI check is just pre-commit, so you can reproduce it exactly:

pip install pre-commit
pre-commit install     # sets up the git hook — do this once
pre-commit run --all-files

I'd particularly recommend the pre-commit install step. It formats on every commit from then on, and with the number of PRs you have open it'll save you a round trip on each one. Using pre-commit rather than a locally-installed clang-format also guarantees you get the exact version the hook pins, so you won't get a diff that still fails CI.

I offered to just push the formatting commit myself, but it's your branch and you may have local work on it — I'd rather not create a surprise non-fast-forward under you. Say the word if you'd like me to, though.

While you're pushing that commit, one optional thought: the README addition is helpful, but it might be worth a one-line note that these targets are only built when the corresponding backend is enabled — otherwise someone building with MKLCPU only will wonder why example_blas_gemm_usm_generic doesn't appear. Take it or leave it.

Zero risk on my side of the review: this touches only examples/ and no library code, so worst case is a broken example rather than a broken library.

@melonakos

Copy link
Copy Markdown
Contributor

Heads up: I'm about to close and immediately reopen this PR. Nothing is wrong with it and nothing about your branch changes — that's just the cleanest way for a maintainer to trigger a fresh CI run.

Why it needs one: the red unit tests ArmPL * jobs here are not caused by your change. Arm republished their apt repo package as arm-toolchains-repository_2-2~noble_all.deb around 2026-07-30, which broke the 2-1 URL pinned in .github/workflows/pr-arm.yml. Your aarch64 run executed on 2026-08-11 while that pin was still stale, so Install ArmPL failed before any test ran. #749 fixed the pin on develop at 2026-08-11 23:21 UTC, a few hours later.

A plain re-run doesn't help, because re-running replays the original commit's workflow file — I tried, and it fetched the old 2-1 URL again. A fresh pull_request run picks up current develop and should go green.

@melonakos melonakos closed this Aug 26, 2026
@melonakos melonakos reopened this Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Example code for SYCL generic BLAS and portFFT backends

2 participants