lerouxrgd / ngt-rs

Rust wrappers for NGT approximate nearest neighbor search
Apache License 2.0
36 stars 6 forks source link

feat: add openmp-sys to support static linking to openmp #9

Closed cjrh closed 2 years ago

cjrh commented 2 years ago

As you suggested here, I've made an attempt at introducing openmp-sys to restore openmp support with static linking.

The changes in this PR appear to work. cargo build and cargo test succeed without error.

I also created a local temporary --bin project, using the changes in this PR:

# Cargo.toml
[package]
name = "ngttester"
version = "0.1.0"
edition = "2021"

[dependencies]
ngt = { path = "/home/caleb/Documents/repos/ngt-rs/" }

The main.rs (the code is from the README tutorial):

use ngt::{Index, Properties, EPSILON};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("Hello, world!");

    // Create a new index
    let prop = Properties::dimension(3)?;
    let index = Index::create("db/", prop)?;

    // Open an existing index
    let mut index = Index::open("db/")?;

    // Insert two vectors and get their id
    let vec1 = vec![1.0, 2.0, 3.0];
    let vec2 = vec![4.0, 5.0, 6.0];
    let id1 = index.insert(vec1)?;
    let id2 = index.insert(vec2)?;

    // Actually build the index (not yet persisted on disk)
    // This is required in order to be able to search vectors
    index.build(2)?;

    // Perform a vector search (with 1 result)
    let res = index.search(&vec![1.1, 2.1, 3.1], 1, EPSILON)?;
    assert_eq!(res[0].id, id1);
    assert_eq!(index.get_vec(id1)?, vec![1.0, 2.0, 3.0]);

    // Remove a vector and check that it is not present anymore
    index.remove(id1)?;
    let res = index.get_vec(id1);
    assert!(matches!(res, Result::Err(_)));

    // Verify that now our search result is different
    let res = index.search(&vec![1.1, 2.1, 3.1], 1, EPSILON)?;
    assert_eq!(res[0].id, id2);
    assert_eq!(index.get_vec(id2)?, vec![4.0, 5.0, 6.0]);

    // Persist index on disk
    index.persist()?;
    Ok(())
}

$ cargo run works, and the assets created by ngt show up correctly:

~/tmp/ngttester  ±master|…8 
$ ls -lah
Permissions Size User  Date Modified Name
.rw-rw-r--     8 caleb  6 Sep 21:42  .gitignore
drwxrwxr-x     - caleb  6 Sep 21:42  target
.rw-rw-r--   233 caleb  6 Sep 21:43  Cargo.toml
.rw-rw-r--   13k caleb  6 Sep 21:45  Cargo.lock
drwxrwxr-x     - caleb  6 Sep 21:52  src
.rw-rw-r--   657 caleb  6 Sep 21:52  tags
drwxr-xr-x     - caleb  6 Sep 21:52  db
drwxrwxr-x     - caleb  6 Sep 21:52  .git
~/tmp/ngttester  ±master|…8 
$ ls db
grp  obj  prf  tre

And, finally, the link table for the produced executable:

$ ldd target/debug/ngttester
    linux-vdso.so.1 (0x00007ffd1c0b1000)
    libngt.so.1 => not found
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2b04600000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f2b04a08000)

No dynamic links to libngt or libgomp 🎉

lerouxrgd commented 2 years ago

Thanks ! I will release it as part of a bigger update for NGT 2.