Skip to content

ruvector-core: avx512f intrinsics force nightly toolchain on all dependents #438

@jatin4614

Description

@jatin4614

Summary

ruvector-core uses target_feature(enable = "avx512f") unconditionally on x86_64 in src/simd_intrinsics.rs. Because avx512f and the target_feature attribute on functions are nightly-only Rust features (rust-lang/rust#44839, rust-lang/rust#111137), any crate that depends on ruvector-core — directly or transitively — requires a nightly Rust toolchain to build.

Reproduction

Discovered while auditing the RuVector workspace as foundation crates for an external project (Kairos, an agentic RAG built on RuVector). Three independent audit harnesses depending on ruvector-graph, ruvector-server, and rvAgent/{rvagent-core, rvagent-mcp} all hit the same compile failure:

$ cargo +1.88 build  # stable
error[E0658]: the `#[target_feature]` attribute is an experimental feature
   --> ruvector-core/src/simd_intrinsics.rs:196:5
    |
196 |     #[target_feature(enable = "avx512f")]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: see issue #44839 <https://github.com/rust-lang/rust/issues/44839> for more information

(33 similar errors at simd_intrinsics.rs:196, 227, 253, 288, ...)

Pinning to nightly via rust-toolchain.toml is the only way to compile downstream crates today. Workspace-internal builds presumably already use nightly, but external consumers don't expect this requirement.

Effect

  • All RuVector workspace consumers have to opt into nightly Rust (more breaking changes, more CI fragility, fewer supported edition combos).
  • The simd = ["simsimd"] feature flag in ruvector-core/Cargo.toml:99 exists but does NOT actually gate the target_feature(avx512f) annotations — the SIMD module compiles unconditionally on x86_64.
  • Build hosts that lack AVX-512 support at runtime will compile a binary that traps on those intrinsics (the runtime check happens via the function dispatch, but the symbols still need to compile).

Proposed fix

Gate every function that uses target_feature(enable = "avx512f") behind #[cfg(target_feature = "avx512f")] (compile-time check) AND/OR move them behind a simd-avx512 Cargo feature that consumers opt into explicitly:

// Current (unconditional):
#[target_feature(enable = "avx512f")]
unsafe fn simd_dot_512(a: &[f32], b: &[f32]) -> f32 { ... }

// Proposed (gated):
#[cfg(any(target_feature = "avx512f", feature = "simd-avx512"))]
#[target_feature(enable = "avx512f")]
unsafe fn simd_dot_512(a: &[f32], b: &[f32]) -> f32 { ... }

With a corresponding Cargo feature in ruvector-core/Cargo.toml:

[features]
default = []
simd-avx512 = []   # opt-in; requires nightly + AVX-512 host

Consumers without AVX-512 (or stuck on stable) get a scalar/SSE fallback path; AVX-512 users opt in.

Why I'm filing this from outside the workspace

I'm building Kairos against your crates and hit this in three separate audit harnesses (graph, server, rvAgent). Filing the issue now so it's visible. I'd be happy to submit a PR with the fix in 1-2 weeks once we close the rest of our Phase 0 audit milestones — let me know if you'd prefer to handle it internally or want me to take a swing.

References

cc @ruvnet

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions