Skip to content

Feature: Improved rust bindings #642

@jbrummack

Description

@jbrummack

Describe what you are looking for

Hello,
while using the Rust bindings to Usearch I have come across several possible improvements, which I have implemented in an experimental fork.

  1. Add the scalar type, metric type, dimensionality as generic argument to the Index type because they dont change much / cant be changed anyway:
//something like this
pub struct HighLevel<T: VectorType, const D: usize, M: MetricType> {
    _t: PhantomData<T>,
    _m: PhantomData<M>,
    pub(crate) index: Index,
}
impl<T,D,M> HighLevel<T,D,M> {
   pub fn try_default() -> Result<Self, cxx::Exception> {
        let mut options = IndexOptions::default();
        options.dimensions = D;
        options.metric = M::get_kind();
        options.quantization = T::quant_type();
        Self::make_index(&options)
    }
}
//so that you could just do this to initialize an index with default expansion etc.
let index = HighLevel::<f32,4,Cos>::try_default().expect("Failed to create index.");
  1. Add support for the half crate instead of custom f16
    Adding support for the half crate allows for better support and interoperability with the rest of the rust ecosystem, like serialisation.

  2. Remove openmp/replace openmp with rayon
    The OpenMP feature doesnt seem to do anything, and there is no Rust support for OpenMP because Rayon roughly takes that spot.

impl<T: VectorType + Sync, const D: usize, M: MetricType + Sync> HighLevel<T, D, M> {
    /// Adds a batch of vectors with multithreading
    /// Faster when inserting large amounts of vectors;
    /// Slower when inserting smaller batches because spinning up the thread pool adds latency.
    /// # Parameters
    /// - `batch`

    ///
    /// # Returns
    /// - `Ok(())` if the batch was inserted successfully
    /// - `Err(cxx::Exception)` if an error occurred during the operation.
    pub fn batch_insert(&self, batch: &[(Key, &[T])]) -> Result<(), cxx::Exception> {
        let len = batch.len();
        self.reserve(len)?;
        batch
            .par_iter()
            .try_for_each(|(key, value)| self.index.add(*key, &value))?;
        Ok(())
    }
}

If any of these changes are interesting to you; I could fix up my implementation and provide it.

Can you contribute to the implementation?

  • I can contribute

Is your feature request specific to a certain interface?

Other bindings

Contact Details

No response

Is there an existing issue for this?

  • I have searched the existing issues

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions