🎊 rattler 0.6.0: A new rust based solver

Rattler 0.6.0 has been released, including a brand new conda package solver.

What is rattler?

Rattler is a library that provides common functionality used within the conda ecosystem. The goal of the library is to enable programs and other libraries to easily interact with the conda ecosystem without being dependent on Python. Its primary use case is as a library that you can use to provide conda related workflows in your own tools. Rattler is used in prefix.devs dependency and workflow management solution pixi and in the backend of prefix.dev.

rattler_libsolv_rs!

rattler_libsolv_rs is a rust crate that implements a port of libsolv. libsolv is a c library used by mamba, micromamba and conda-libmamba-solver to provide fast package resolution. Our port performs slightly better or similar to the original C code and does not contain any unsafe code, is well documented, and is thread-safe. A big difference at the moment is that our implementation is specific to solving conda packages by leveraging rattler_conda_types for matching and parsing whereas libsolv is able to resolve many different package formats.

Some performance benchmarks taken on Apple M2 Max.

libsolv-c libsolv-rs
python=3.9 7.3734 ms 4.5831 ms
xtensor, xsimd 5.7521 ms 2.7643 ms
tensorflow 654.38 ms 371.59 ms
quetz 1.2577 s 1.3807 s
tensorboard=2.1.1, grpc-cpp=1.39.1 474.76 ms 132.79 ms

You can try these benchmarks yourself by cloning the rattler repository and running cargo bench libsolv.

Besides the much-improved implementation, the new solver also provides much better error messages based on the work from Mamba. When a conflict is detected the incompatibilities are analyzed and displayed with a more user-friendly error message.

The following packages are incompatible
|-- asdf can be installed with any of the following options:
    |-- asdf 1.2.3 would require
        |-- C >1, which can be installed with any of the following options:
            |-- C 2.0.0
|-- C 1.0.0 is locked, but another version is required as reported above

rattler-solve has also been refactored to accommodate this change. rattler_solve is a crate that provides a generic interface to multiple solver implementations.

It is now more easily possible to switch between solvers at runtime by writing functions that are generic on the solver. Both solvers can be enabled with feature flags. The default features only select libsolv_c.

Here is a simple example that shows roughly what that would look like:

let solver_task = SolverTask {
    available_packages: &repodatas,
    locked_packages,
    virtual_packages,
    specs,
    pinned_packages,
};

let solution = if use_libsolv_rs {
    libsolv_rs::Solver.solve(solver_task)
} else {
    libsolv_c::Solver.solve(solver_task)
}

The new solver will be the default solver for pixi and will be enabled by default as the solver for prefix.dev environments in the near future.

What’s next?

Rattler is still actively developed! Expect more awesomeness in the future so keep your eyes open! :slight_smile:

3 Likes