Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
2d425b6
test: update sparse bf16 validation status
yiliu30 Jul 29, 2026
ddaad53
feat: add bf16 sparse mode to flux example
yiliu30 Jul 30, 2026
2e2ecb5
feat: add bf16 sparse kernel sources
yiliu30 Aug 5, 2026
0850714
chore: ignore XPU build artifact directories
yiliu30 Aug 6, 2026
95f2c06
feat: wire native BF16 sparse SDPA kernel and launchers
yiliu30 Aug 6, 2026
f96ec41
fix: BF16 sparse native kernel element-aware MMA and softmax scale
yiliu30 Aug 6, 2026
f9e8612
fix: sparse BF16 LUT crash, lossless round-trip, and preprocess speed
yiliu30 Aug 6, 2026
c94a1b8
feat: BF16 sparse SDPA benchmark support and repro script
yiliu30 Aug 6, 2026
e34327a
test: BF16 sparse preprocess and LUT regression tests
yiliu30 Aug 6, 2026
9c86dda
feat: include ark-xbuild in wan sparse binding search roots
yiliu30 Aug 6, 2026
743cece
refactor: remove dense-mask fallback from sage_sparse_bf16
yiliu30 Aug 6, 2026
c6bd14a
docs: add documented BF16 sparse benchmark runner script
yiliu30 Aug 6, 2026
625d483
fix: work around triton SPV_INTEL_predicated_io on Intel XPU
yiliu30 Aug 6, 2026
cf191c4
docs: add sparse SAGE v1 benchmark runner script
yiliu30 Aug 6, 2026
de2eca0
fix: work around triton SPV_INTEL_predicated_io on Intel XPU
yiliu30 Aug 6, 2026
31fad6e
docs: default BF16 benchmark runner to triton preprocess backend
yiliu30 Aug 6, 2026
2e635bc
feat: add independent native-precision sparse SDPA kernel path
yiliu30 Aug 6, 2026
2127635
feat: sparse-SDPA Python wrappers, switch sage_sparse_bf16, benchmark…
yiliu30 Aug 6, 2026
952ef64
test: sparse-SDPA correctness tests; fix XPU softmax reference
yiliu30 Aug 6, 2026
1da474b
refactor: separate native-precision sparse SDPA from INT8 sparse SAGE…
yiliu30 Aug 6, 2026
333e242
docs: refresh sparse BF16 handoff after int8/bf16 path separation
yiliu30 Aug 6, 2026
e39a2ac
chore: add bf16-sparse FLUX.1-dev output image reference
yiliu30 Aug 10, 2026
18ef86f
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 11, 2026
0ca035f
clean
yiliu30 Aug 11, 2026
a559dc8
chore: drop dev handoff and generated images from bf16 sparse branch
yiliu30 Aug 11, 2026
97ce5c7
Merge branch 'feat/sparse-bf16-prefill-v2' of https://github.com/inte…
yiliu30 Aug 13, 2026
cecc8a1
fix: use k32 sparse sdpa tiles
yiliu30 Aug 14, 2026
79bef55
bench: add ark sdpa baseline
yiliu30 Aug 14, 2026
ee565a1
tools: add sparse bf16 sweep helpers
yiliu30 Aug 14, 2026
9b1a951
docs: record sparse bf16 profiling results
yiliu30 Aug 14, 2026
7e82ad5
docs: record BF16 Flux sweep and offload fix
yiliu30 Aug 14, 2026
58105f7
fix: support causal qtile256 sparse attention
yiliu30 Aug 17, 2026
1d0040e
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 18, 2026
fbf26b5
add shape analysis
yiliu30 Aug 18, 2026
c42450e
Merge branch 'main' of https://github.com/intel/auto-round
yiliu30 Aug 18, 2026
4e62a6f
Merge branch 'main' into feat/sparse-bf16-prefill-v2
yiliu30 Aug 18, 2026
cbda4c4
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Aug 18, 2026
c762034
chore: stop tracking ark benchmark results
yiliu30 Aug 18, 2026
1aa4c03
Merge remote-tracking branch 'origin/feat/sparse-bf16-prefill-v2' int…
yiliu30 Aug 18, 2026
b47dbe4
fix
yiliu30 Aug 18, 2026
b3d03c7
Merge branch 'feat/sparse-bf16-prefill-v2' of https://github.com/inte…
yiliu30 Aug 18, 2026
5a5a97d
revert
yiliu30 Aug 18, 2026
4e29701
fix: consolidate xpu triton workaround
yiliu30 Aug 18, 2026
b131143
clean
yiliu30 Aug 18, 2026
308ba36
update
yiliu30 Aug 18, 2026
7d400d4
refactor: rename sparse sdpa api
yiliu30 Aug 18, 2026
ace6cdf
update
yiliu30 Aug 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions auto_round_extension/ark/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
build
xbuild
ark-xbuild*
ark-xbuild-builtin*
xbuild_bf16*
*.csv
*.so
*.pyc
benchmarks/results/
21 changes: 21 additions & 0 deletions auto_round_extension/ark/auto_round_kernel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,18 @@ if(ARK_XPU AND ARK_SYCL_TLA)
target_compile_definitions(${PY_NAME} PRIVATE ARK_SYCL_TLA=1 CUTLASS_ENABLE_SYCL=1 SYCL_INTEL_TARGET=1)
target_include_directories(${PY_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/wrapper/include)
target_include_directories(${PY_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated/sdpa)
# sycl-tla may provision oneMKL through an ExternalProject. Wire its staged
# headers into this module directly so parallel builds do not compile before
# oneMKL has been downloaded and installed.
if(TARGET onemkl_project)
add_dependencies(${PY_NAME} onemkl_project)
target_include_directories(${PY_NAME} SYSTEM PRIVATE ${CMAKE_BINARY_DIR}/deps/oneMKL/include)
elseif(TARGET MKL::MKL)
target_link_libraries(${PY_NAME} PRIVATE MKL::MKL)
if(DEFINED ENV{MKLROOT} AND EXISTS "$ENV{MKLROOT}/include")
target_include_directories(${PY_NAME} SYSTEM PRIVATE "$ENV{MKLROOT}/include")
endif()
endif()
# Use SYSTEM include directories for sycl-tla to suppress warnings/errors from third-party headers
# (e.g., std::common_type specialization issues in traits.hpp)
foreach(_inc_dir IN LISTS _sycl_tla_include_dirs)
Expand All @@ -208,6 +220,15 @@ if(ARK_UT)
if(ARK_XPU AND ARK_SYCL_TLA)
target_compile_definitions(${TEST_NAME} PRIVATE ARK_SYCL_TLA=1 CUTLASS_ENABLE_SYCL=1 SYCL_INTEL_TARGET=1)
target_include_directories(${TEST_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated/sdpa)
if(TARGET onemkl_project)
add_dependencies(${TEST_NAME} onemkl_project)
target_include_directories(${TEST_NAME} SYSTEM PRIVATE ${CMAKE_BINARY_DIR}/deps/oneMKL/include)
elseif(TARGET MKL::MKL)
target_link_libraries(${TEST_NAME} PRIVATE MKL::MKL)
if(DEFINED ENV{MKLROOT} AND EXISTS "$ENV{MKLROOT}/include")
target_include_directories(${TEST_NAME} SYSTEM PRIVATE "$ENV{MKLROOT}/include")
endif()
endif()
foreach(_inc_dir IN LISTS _sycl_tla_include_dirs)
if(EXISTS "${_inc_dir}")
target_include_directories(${TEST_NAME} SYSTEM PRIVATE "${_inc_dir}")
Expand Down
2 changes: 2 additions & 0 deletions auto_round_extension/ark/auto_round_kernel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2146,10 +2146,12 @@ def sageattn(
_sequence_mean_native_layout,
_slice_sequence_native_layout,
_to_hnd,
block_sparse_sdpa,
sage_sparse,
sparge_block_map_to_mask,
sparge_preprocess_topk,
sparge_sage2_attn_meansim_topk_xpu,
sparge_sage2_attn_meansim_topk_xpu_sdpa,
)


Expand Down
93 changes: 93 additions & 0 deletions auto_round_extension/ark/auto_round_kernel/ark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,98 @@ static void sage_sparse(torch_ptr stream, torch_ptr Q, torch_ptr K, torch_ptr V,
throw std::invalid_argument("ark::sage_sparse: unsupported head_dim; supported values are 64 and 128");
}

static void block_sparse_sdpa(torch_ptr stream, torch_ptr Q, torch_ptr K, torch_ptr V, torch_ptr O, torch_ptr mask,
torch_ptr lut, torch_ptr valid_block_num, int num_q_blocks, int num_k_blocks,
int q_tile_override, int q_stride_s, int q_stride_d, int q_stride_h, int q_stride_b,
int k_stride_s, int k_stride_d, int k_stride_h, int k_stride_b, int v_stride_d,
int v_stride_s, int v_stride_h, int v_stride_b, int o_stride_s, int o_stride_d,
int o_stride_h, int o_stride_b, int q_dtype, int batch, int num_heads_q,
int num_heads_kv, int seq_len_q, int seq_len_kv, int head_dim, float softmax_scale,
bool is_causal) {
if (q_dtype != (int)FlashAttnDtype::FP16 && q_dtype != (int)FlashAttnDtype::BF16) {
throw std::invalid_argument("ark::block_sparse_sdpa: q_dtype must be FP16 or BF16");
}
if (mask && is_causal) {
throw std::invalid_argument("ark::block_sparse_sdpa: mask and is_causal cannot both be set");
}
if (!lut || !valid_block_num) {
throw std::invalid_argument("ark::block_sparse_sdpa: lut and valid_block_num must be provided");
}
auto matches_block_size = [](int seq_len, int num_blocks, int block_size) {
return block_size > 0 && num_blocks == ((seq_len + block_size - 1) / block_size);
};
const bool key_block_is_64 = matches_block_size(seq_len_kv, num_k_blocks, 64);
if (!key_block_is_64) {
throw std::invalid_argument("ark::block_sparse_sdpa: only key block size 64 is supported");
}
const bool is_bf16 = (q_dtype == (int)FlashAttnDtype::BF16);
if (head_dim == 64) {
if (!matches_block_size(seq_len_q, num_q_blocks, 64)) {
throw std::invalid_argument("ark::block_sparse_sdpa: head_dim=64 requires query block size 64");
}
if (is_bf16) {
ark::sdpa_impl_bf16_sparse_sdpa_d64(
(sycl::queue*)stream, (void*)Q, (void*)K, (void*)V, (void*)O, (void*)mask, (void*)lut,
(void*)valid_block_num, num_q_blocks, num_k_blocks, q_tile_override, q_stride_s, q_stride_d, q_stride_h,
q_stride_b, k_stride_s, k_stride_d, k_stride_h, k_stride_b, v_stride_d, v_stride_s, v_stride_h,
v_stride_b, o_stride_s, o_stride_d, o_stride_h, o_stride_b, batch, num_heads_q, num_heads_kv, seq_len_q,
seq_len_kv, head_dim, softmax_scale, is_causal);
} else {
ark::sdpa_impl_fp16_sparse_sdpa_d64(
(sycl::queue*)stream, (void*)Q, (void*)K, (void*)V, (void*)O, (void*)mask, (void*)lut,
(void*)valid_block_num, num_q_blocks, num_k_blocks, q_tile_override, q_stride_s, q_stride_d, q_stride_h,
q_stride_b, k_stride_s, k_stride_d, k_stride_h, k_stride_b, v_stride_d, v_stride_s, v_stride_h,
v_stride_b, o_stride_s, o_stride_d, o_stride_h, o_stride_b, batch, num_heads_q, num_heads_kv, seq_len_q,
seq_len_kv, head_dim, softmax_scale, is_causal);
}
return;
}
if (head_dim == 128) {
if (matches_block_size(seq_len_q, num_q_blocks, 256)) {
if (q_tile_override != 256) {
throw std::invalid_argument(
"ark::block_sparse_sdpa: head_dim=128 query block size 256 requires q_tile_override=256");
}
if (is_bf16) {
ark::sdpa_impl_bf16_sparse_sdpa_qtile256_row64k(
(sycl::queue*)stream, (void*)Q, (void*)K, (void*)V, (void*)O, (void*)mask, (void*)lut,
(void*)valid_block_num, num_q_blocks, num_k_blocks, q_tile_override, q_stride_s, q_stride_d, q_stride_h,
q_stride_b, k_stride_s, k_stride_d, k_stride_h, k_stride_b, v_stride_d, v_stride_s, v_stride_h,
v_stride_b, o_stride_s, o_stride_d, o_stride_h, o_stride_b, batch, num_heads_q, num_heads_kv, seq_len_q,
seq_len_kv, head_dim, softmax_scale, is_causal);
} else {
ark::sdpa_impl_fp16_sparse_sdpa_qtile256_row64k(
(sycl::queue*)stream, (void*)Q, (void*)K, (void*)V, (void*)O, (void*)mask, (void*)lut,
(void*)valid_block_num, num_q_blocks, num_k_blocks, q_tile_override, q_stride_s, q_stride_d, q_stride_h,
q_stride_b, k_stride_s, k_stride_d, k_stride_h, k_stride_b, v_stride_d, v_stride_s, v_stride_h,
v_stride_b, o_stride_s, o_stride_d, o_stride_h, o_stride_b, batch, num_heads_q, num_heads_kv, seq_len_q,
seq_len_kv, head_dim, softmax_scale, is_causal);
}
return;
}
if (matches_block_size(seq_len_q, num_q_blocks, 64)) {
if (is_bf16) {
ark::sdpa_impl_bf16_sparse_sdpa_row_linear(
(sycl::queue*)stream, (void*)Q, (void*)K, (void*)V, (void*)O, (void*)mask, (void*)lut,
(void*)valid_block_num, num_q_blocks, num_k_blocks, q_tile_override, q_stride_s, q_stride_d, q_stride_h,
q_stride_b, k_stride_s, k_stride_d, k_stride_h, k_stride_b, v_stride_d, v_stride_s, v_stride_h,
v_stride_b, o_stride_s, o_stride_d, o_stride_h, o_stride_b, batch, num_heads_q, num_heads_kv, seq_len_q,
seq_len_kv, head_dim, softmax_scale, is_causal);
} else {
ark::sdpa_impl_fp16_sparse_sdpa_row_linear(
(sycl::queue*)stream, (void*)Q, (void*)K, (void*)V, (void*)O, (void*)mask, (void*)lut,
(void*)valid_block_num, num_q_blocks, num_k_blocks, q_tile_override, q_stride_s, q_stride_d, q_stride_h,
q_stride_b, k_stride_s, k_stride_d, k_stride_h, k_stride_b, v_stride_d, v_stride_s, v_stride_h,
v_stride_b, o_stride_s, o_stride_d, o_stride_h, o_stride_b, batch, num_heads_q, num_heads_kv, seq_len_q,
seq_len_kv, head_dim, softmax_scale, is_causal);
}
return;
}
throw std::invalid_argument("ark::block_sparse_sdpa: head_dim=128 supports query block sizes 64 and 256 only");
}
throw std::invalid_argument("ark::block_sparse_sdpa: unsupported head_dim; supported values are 64 and 128");
}

static void moe_gemm_wrapper(torch_ptr stream, torch_ptr activations, torch_ptr weights, torch_ptr scales,
torch_ptr outputs, int dtype, int N, int K, torch_ptr num_tokens_per_expert,
int num_experts) {
Expand Down Expand Up @@ -1379,6 +1471,7 @@ PYBIND11_MODULE(PY_NAME, m) {
pybind11::arg("head_dim"), pybind11::arg("softmax_scale"), pybind11::arg("is_causal"),
pybind11::arg("tensor_layout"), pybind11::arg("lse") = 0);
m.def("sage_sparse", &ark::sage_sparse);
m.def("block_sparse_sdpa", &ark::block_sparse_sdpa);
// Low-level SAGE PVi8 API: input Q/K/V are pre-quantized int8 with qscale/kscale/vscale.
m.def("sage_pvi8", &ark::sage_pvi8, pybind11::arg("stream"), pybind11::arg("Q"), pybind11::arg("K"),
pybind11::arg("V"), pybind11::arg("O"), pybind11::arg("mask"),
Expand Down
Loading