-
Notifications
You must be signed in to change notification settings - Fork 826
fix(linalg): stop FP16 hosts falling to scalar when the AVX-512 f16 kernel is absent #8868
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -153,6 +153,16 @@ impl Dot for bf16 { | |
| SimdSupport::Avx512FP16 => unsafe { | ||
| bf16_kernel::dot_bf16_avx512(x.as_ptr(), y.as_ptr(), x.len() as u32) | ||
| }, | ||
| #[cfg(all( | ||
| feature = "fp16kernels", | ||
| not(kernel_support = "avx512_bf16"), | ||
| target_arch = "x86_64" | ||
| ))] | ||
| // `Avx512*` tier detection does not check FMA, and these kernels are | ||
| // compiled `-march=haswell`, which enables it. | ||
| SimdSupport::Avx512FP16 if std::is_x86_feature_detected!("fma") => unsafe { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Checking only Verification run on this headcc -std=c17 -O3 -ffast-math -funroll-loops -DSUFFIX=_gate -march=haswell -S -o - rust/lance-linalg/src/simd/f16.c | rg 'vcvtph2ps|vfmadd'
cc -std=c17 -O3 -ffast-math -funroll-loops -DSUFFIX=_gate -march=haswell -S -o - rust/lance-linalg/src/simd/bf16.c | rg 'vpmovzxwd|vfmadd'Both commands produced the named instructions; |
||
| bf16_kernel::dot_bf16_avx2(x.as_ptr(), y.as_ptr(), x.len() as u32) | ||
| }, | ||
| #[cfg(all(feature = "fp16kernels", target_arch = "x86_64"))] | ||
| SimdSupport::Avx2 | SimdSupport::Avx512 => unsafe { | ||
| bf16_kernel::dot_bf16_avx2(x.as_ptr(), y.as_ptr(), x.len() as u32) | ||
|
|
@@ -210,6 +220,16 @@ impl Dot for f16 { | |
| SimdSupport::Avx512FP16 => unsafe { | ||
| kernel::dot_f16_avx512(x.as_ptr(), y.as_ptr(), x.len() as u32) | ||
| }, | ||
| #[cfg(all( | ||
| feature = "fp16kernels", | ||
| not(kernel_support = "avx512_f16"), | ||
| target_arch = "x86_64" | ||
| ))] | ||
| // `Avx512*` tier detection does not check FMA, and these kernels are | ||
| // compiled `-march=haswell`, which enables it. | ||
| SimdSupport::Avx512FP16 if std::is_x86_feature_detected!("fma") => unsafe { | ||
| kernel::dot_f16_avx2(x.as_ptr(), y.as_ptr(), x.len() as u32) | ||
| }, | ||
| #[cfg(all(feature = "fp16kernels", target_arch = "x86_64"))] | ||
| SimdSupport::Avx2 | SimdSupport::Avx512 => unsafe { | ||
| kernel::dot_f16_avx2(x.as_ptr(), y.as_ptr(), x.len() as u32) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -61,6 +61,16 @@ impl Normalize for f16 { | |
| SimdSupport::Avx512FP16 => unsafe { | ||
| kernel::norm_l2_f16_avx512(vector.as_ptr(), vector.len() as u32) | ||
| }, | ||
| #[cfg(all( | ||
| feature = "fp16kernels", | ||
| not(kernel_support = "avx512_f16"), | ||
| target_arch = "x86_64" | ||
| ))] | ||
| // `Avx512*` tier detection does not check FMA, and these kernels are | ||
| // compiled `-march=haswell`, which enables it. | ||
| SimdSupport::Avx512FP16 if std::is_x86_feature_detected!("fma") => unsafe { | ||
| kernel::norm_l2_f16_avx2(vector.as_ptr(), vector.len() as u32) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The newly selected f16 AVX2 path does not satisfy the repository's existing numerical tests on the exact target configuration. On this Sapphire Rapids host, forcing the AVX-512 builds to fail made the full library suite execute these cfg-unset arms: ReproducerThe wrapper delegates to CC=/path/to/cc-no-spr CARGO_TARGET_DIR=/home/agent/tmp/gate-8868-target cargo test --profile ci -p lance-linalg --lib --features fp16kernelsObserved examples were L2 |
||
| }, | ||
| #[cfg(all(feature = "fp16kernels", target_arch = "x86_64"))] | ||
| SimdSupport::Avx2 | SimdSupport::Avx512 => unsafe { | ||
| kernel::norm_l2_f16_avx2(vector.as_ptr(), vector.len() as u32) | ||
|
|
@@ -115,6 +125,16 @@ impl Normalize for bf16 { | |
| SimdSupport::Avx512FP16 => unsafe { | ||
| bf16_kernel::norm_l2_bf16_avx512(vector.as_ptr(), vector.len() as u32) | ||
| }, | ||
| #[cfg(all( | ||
| feature = "fp16kernels", | ||
| not(kernel_support = "avx512_bf16"), | ||
| target_arch = "x86_64" | ||
| ))] | ||
| // `Avx512*` tier detection does not check FMA, and these kernels are | ||
| // compiled `-march=haswell`, which enables it. | ||
| SimdSupport::Avx512FP16 if std::is_x86_feature_detected!("fma") => unsafe { | ||
| bf16_kernel::norm_l2_bf16_avx2(vector.as_ptr(), vector.len() as u32) | ||
| }, | ||
| #[cfg(all(feature = "fp16kernels", target_arch = "x86_64"))] | ||
| SimdSupport::Avx2 | SimdSupport::Avx512 => unsafe { | ||
| bf16_kernel::norm_l2_bf16_avx2(vector.as_ptr(), vector.len() as u32) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This new branch can read past
xfrom safe Rust.Cosine::cosine_fastdoes not validate equal lengths, butcosine_f16_avx2receivesy.len()and its C loop reads bothx[i]andy[i]. In the base cfg-unset path,cosine_scalarinstead reaches the checkedDot::dotand panics. Please validate the lengths before dispatch in both the f16 and bf16 implementations so every unsafe C arm inherits the boundary check.Reproducer run on this head
I forced both AVX-512 builds to fail with a
CCwrapper that rejects-march=sapphirerapids, then added a test which mmaps two pages, protects the second withPROT_NONE, places a one-element f16xat the end of the first page, and calls<f16 as Cosine>::cosine_fast(x, 1.0, &[1.0, 2.0]).