Skip to content

v6.5: Half-Precision `f16` & `bf16` Numbers in Rust πŸ¦€

Choose a tag to compare

@ashvardanian ashvardanian released this 07 Jul 12:46
· 1498 commits to main since this release

SimSIMD has historically been one of the largest collections of mixed-precision kernels, but f32 to/from f16 and bf16 conversion operators have never been exposed to bindings. This release is the first step in that direction. I look forward to everyone's suggestions on how to further improve the Rust API. Thanks πŸ€—


Here's an example:

use simsimd::{SpatialSimilarity, f16, bf16};

// Process embeddings at different precisions for speed vs accuracy trade-offs
let embeddings_f32 = vec![1.0, 2.0, 3.0, 4.0];
let query_f32 = vec![0.5, 1.5, 2.5, 3.5];

// Convert to f16 for memory efficiency (2x compression)
let embeddings_f16: Vec<f16> = embeddings_f32.iter()
    .map(|&x| f16::from_f32(x))
    .collect();
let query_f16: Vec<f16> = query_f32.iter()
    .map(|&x| f16::from_f32(x))
    .collect();

// Convert to bf16 for ML workloads (better range than f16)
let embeddings_bf16: Vec<bf16> = embeddings_f32.iter()
    .map(|&x| bf16::from_f32(x))
    .collect();
let query_bf16: Vec<bf16> = query_f32.iter()
    .map(|&x| bf16::from_f32(x))
    .collect();

// Hardware-accelerated similarity at different precisions
let similarity_f32 = f32::cosine(&embeddings_f32, &query_f32).unwrap();
let similarity_f16 = f16::cosine(&embeddings_f16, &query_f16).unwrap();
let similarity_bf16 = bf16::cosine(&embeddings_bf16, &query_bf16).unwrap();

println!("Cosine similarities:");
println!("f32:  {:.6}", similarity_f32);   // Full precision
println!("f16:  {:.6}", similarity_f16);   // 2x memory savings
println!("bf16: {:.6}", similarity_bf16);  // ML-optimized range

// Natural arithmetic operations work seamlessly
let scaled_f16 = embeddings_f16.iter()
    .map(|&x| x * f16::from_f32(2.0) + f16::ONE)
    .collect::<Vec<_>>();

// Direct bit manipulation when needed
let raw_bits = embeddings_f16[0].0; // Access underlying u16
let reconstructed = f16(raw_bits);

Minor

  • Add: Half-precision converters for C/Rust (bf5a7d2)

Patch

  • Improve: Support more numeric operators in Rust (1d7b2b8)
  • Improve: Rust nostd builds (c6c0698)
  • Make: Bump dependencies (3667313)
  • Fix: Expose Distance in Rust (e0c69c7)