Provider Selection in the CSP Solver
The Spack CSP (Constraint Satisfaction Problem) solver determines the primary binding for a virtual dependency by treating the interface as a constraint that must be satisfied by at least one concrete package providing that interface. Unlike the legacy concretizer, which relied more heavily on a linear search and immediate backtracking, the CSP solver models the entire dependency DAG as a set of variables and constraints, seeking a valid assignment that satisfies all version and variant requirements simultaneously.
Binding Logic and Prioritization
When multiple compatible providers exist for a single interface (e.g., mpi provided by both openmpi and mpich), the solver follows these general behaviors:
- Constraint Satisfaction: The solver first filters for providers that meet the version constraints defined in the spec.
- Preference Heuristics: If multiple providers are valid, the solver typically defaults to the most recent version available in the repositories unless a specific preference is defined.
- Global Consistency: The CSP solver prioritizes a solution that allows the rest of the DAG to be satisfied. If
openmpi creates a version conflict with another dependency but mpich does not, the solver will select mpich even if openmpi is newer.
Influencing Selection Without Hard-Coding
To influence the provider selection without locking a specific version in the global spec, you can use preferences. This tells the solver which package to prefer when satisfying a virtual dependency across the entire environment.
Use the following command to set a preference for a specific provider:
spack config add preferences:mpi=openmpi
This approach is superior to hard-coding versions because it allows the solver to still pick the best version of openmpi that fits the rest of the DAG, rather than forcing a potentially incompatible version.
Verification and Diagnostics
To verify which provider the CSP solver has bound to your interface, use the internal spec view:
spack spec -i <your-spec>
To confirm which solver is currently active (builtin vs. clingo), run:
spack config get config:solver
Missing Diagnostic Detail: To provide a more precise explanation of the selection order, please specify if you are using the builtin Python solver or the clingo external solver, as the underlying search algorithms differ.