unum-cloud / usearch

Fast Open-Source Search & Clustering engine × for Vectors & 🔜 Strings × in C++, C, Python, JavaScript, Rust, Java, Objective-C, Swift, C#, GoLang, and Wolfram 🔍
https://unum-cloud.github.io/usearch/
Apache License 2.0
2.27k stars 143 forks source link

Feature: Better Rust Concurrency support #482

Open jbrummack opened 2 months ago

jbrummack commented 2 months ago

Describe what you are looking for

The documentation says somewhere that the Usearch-Index is threadsafe, would it be possible to make it Send+Sync? For now I have to do this workaround:

struct SyncIndex {
    index: Index,
}
unsafe impl Send for SyncIndex {}
unsafe impl Sync for SyncIndex {}

I tried this with Rayon (index creation took 9 minutes instead of 96) and with Actix and it worked quite well with f32 in both. I tested making Index conform to Send + Sync in a stashed fork and it also worked. The workaround starts to not work as soon as more internal stuff comes to the surface like this:

let len = tensor.shape()[0];
(0..len).into_par_iter().for_each(|current_offset| {
        println!("{current_offset}");
        let calc_offset = current_offset * 128;
        let keypoint = &view[calc_offset..calc_offset + 128];
        let keypoint_b1 = b1x8::from_u8s(keypoint);
        index.add(current_offset as u64, keypoint_b1);
        bar.inc(1);
});

Which results in this:

error[E0277]: `*const cxx::void` cannot be shared between threads safely
   --> src/main.rs:73:43
    |
73  |           (0..len).into_par_iter().for_each(|current_offset| {
    |  __________________________________--------_^
    | |                                  |
    | |                                  required by a bound introduced by this call
74  | |             println!("{current_offset}");
75  | |             let calc_offset = current_offset * 128;
76  | |             let keypoint = &view[calc_offset..calc_offset + 128];
...   |
81  | |             bar.inc(1);
82  | |         });
    | |_________^ `*const cxx::void` cannot be shared between threads safely

PS: I tried to run OpenMP, however it looks like rust doesnt support OpenMP if im not mistaken

Can you contribute to the implementation?

Is your feature request specific to a certain interface?

Other bindings

Contact Details

No response

Is there an existing issue for this?

Code of Conduct

ashvardanian commented 2 months ago

Sure! If you know a better way to expose concurrency to Rust - feel free to open a PR 🤗