Skip to content

Commit

Permalink
Rust Dynamic Dispatch (#462)
Browse files Browse the repository at this point in the history
  • Loading branch information
ashvardanian authored Aug 15, 2024
1 parent 5ad2053 commit a0901a0
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 36 deletions.
1 change: 1 addition & 0 deletions .github/workflows/prerelease.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ jobs:
package.json:"version": "(\d+\.\d+\.\d+)"
CITATION.cff:^version: (\d+\.\d+\.\d+)
Cargo.toml:^version = "(\d+\.\d+\.\d+)"
Cargo.lock:name = "usearch"\nversion = "(\d+\.\d+\.\d+)"
wasmer.toml:^version = "(\d+\.\d+\.\d+)"
conanfile.py:version = "(\d+\.\d+\.\d+)"
java/README.md:<version>(\d+\.\d+\.\d+)</version>
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
package.json:"version": "(\d+\.\d+\.\d+)"
CITATION.cff:^version: (\d+\.\d+\.\d+)
Cargo.toml:^version = "(\d+\.\d+\.\d+)"
Cargo.lock:^version = "(\d+\.\d+\.\d+)"
Cargo.lock:name = "usearch"\nversion = "(\d+\.\d+\.\d+)"
wasmer.toml:^version = "(\d+\.\d+\.\d+)"
conanfile.py:version = "(\d+\.\d+\.\d+)"
java/README.md:<version>(\d+\.\d+\.\d+)</version>
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ include = [
]

[features]
default = ["simsimd"] # SimSIMD is enabled by default
simsimd = [] # No need to do anything to enable SimSIMD by default
openmp = [] # Optional: Users can enable OpenMP
fp16lib = [] # Optional: Users can enable FP16 support
default = ["simsimd", "fp16lib"] # SimSIMD is enabled by default
simsimd = [] # No need to do anything to enable SimSIMD by default
fp16lib = [] # Without this FP16 we lose precision downcasting
openmp = [] # Optional: Users can enable OpenMP

[lib]
name = "usearch"
Expand Down
58 changes: 31 additions & 27 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,41 @@ fn main() {
build.define("USEARCH_USE_FP16LIB", "0");
}

// Define all possible SIMD targets as 1
let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default();
let flags_to_try = match target_arch.as_str() {
"arm" | "aarch64" => vec![
"SIMSIMD_TARGET_SVE_BF16",
"SIMSIMD_TARGET_SVE_F16",
"SIMSIMD_TARGET_SVE_I8",
"SIMSIMD_TARGET_SVE",
"SIMSIMD_TARGET_NEON_BF16",
"SIMSIMD_TARGET_NEON_F16",
"SIMSIMD_TARGET_NEON_I8",
"SIMSIMD_TARGET_NEON",
],
_ => vec![
"SIMSIMD_TARGET_SAPPHIRE",
"SIMSIMD_TARGET_GENOA",
"SIMSIMD_TARGET_ICE",
"SIMSIMD_TARGET_SKYLAKE",
"SIMSIMD_TARGET_HASWELL",
],
};

if cfg!(feature = "simsimd") {
build
.define("USEARCH_USE_SIMSIMD", "1")
.define("SIMSIMD_DYNAMIC_DISPATCH", "1")
.define("SIMSIMD_NATIVE_BF16", "0")
.define("SIMSIMD_NATIVE_F16", "0");
build.define("USEARCH_USE_SIMSIMD", "1")
.define("SIMSIMD_DYNAMIC_DISPATCH", "1")
.define("SIMSIMD_NATIVE_BF16", "0")
.define("SIMSIMD_NATIVE_F16", "0");

for flag in &flags_to_try {
build.define(flag, "1");
}
} else {
build.define("USEARCH_USE_SIMSIMD", "0");
}


// Conditional compilation depending on the target operating system.
if cfg!(target_os = "linux") {
Expand Down Expand Up @@ -60,28 +86,6 @@ fn main() {
let mut result = build.try_compile("usearch");
if result.is_err() {
print!("cargo:warning=Failed to compile with all SIMD backends...");

let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default();
let flags_to_try = match target_arch.as_str() {
"arm" | "aarch64" => vec![
"SIMSIMD_TARGET_SVE_BF16",
"SIMSIMD_TARGET_SVE_F16",
"SIMSIMD_TARGET_SVE_I8",
"SIMSIMD_TARGET_SVE",
"SIMSIMD_TARGET_NEON_BF16",
"SIMSIMD_TARGET_NEON_F16",
"SIMSIMD_TARGET_NEON_I8",
"SIMSIMD_TARGET_NEON",
],
_ => vec![
"SIMSIMD_TARGET_SAPPHIRE",
"SIMSIMD_TARGET_GENOA",
"SIMSIMD_TARGET_ICE",
"SIMSIMD_TARGET_SKYLAKE",
"SIMSIMD_TARGET_HASWELL",
],
};

for flag in flags_to_try {
build.define(flag, "0");
result = build.try_compile("usearch");
Expand Down
22 changes: 22 additions & 0 deletions rust/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1639,6 +1639,28 @@ mod tests {
}

#[test]
fn test_zero_distances() {
let options = IndexOptions {
dimensions: 8,
metric: MetricKind::L2sq,
quantization: ScalarKind::F16,
..Default::default()
};

let index = new_index(&options).unwrap();
index.reserve(10).unwrap();
index.add(0, &[0.4, 0.1, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0]).unwrap();
index.add(1, &[0.5, 0.1, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0]).unwrap();
index.add(2, &[0.6, 0.1, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0]).unwrap();

// Make sure non of the distances are zeros
let matches = index.search(&[0.05, 0.1, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0], 2).unwrap();
for distance in matches.distances.iter() {
assert_ne!(*distance, 0.0);
}
}

#[test]
fn test_change_distance_function() {
let mut options = IndexOptions::default();
options.dimensions = 2; // Adjusted for simplicity in creating test vectors
Expand Down

0 comments on commit a0901a0

Please sign in to comment.