diff --git a/Cargo.toml b/Cargo.toml index 6b8da2477..7c114c4b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,7 @@ digest = "0.10.7" dirs = "5.0.1" dunce = "1.0.4" enum_dispatch = "0.3.13" -fs-err = { version = "2.11.0", features = ["tokio"] } +fs-err = { version = "2.11.0", features = ["tokio"] } fslock = "0.2.1" futures = "0.3.30" futures-util = "0.3.30" @@ -110,7 +110,7 @@ regex = "1.10.4" reqwest = { version = "0.12.3", default-features = false } reqwest-middleware = "0.3.0" reqwest-retry = "0.6.0" -resolvo = { version = "0.8.1" } +resolvo = { version = "0.8.2" } retry-policies = { version = "0.4.0", default-features = false } rmp-serde = { version = "1.2.0" } rstest = { version = "0.21.0" } @@ -150,7 +150,7 @@ tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", default-features = false } tracing-test = { version = "0.2.4" } trybuild = { version = "1.0.91" } -typed-path = { version = "0.9.0" } +typed-path = { version = "0.9.2" } url = { version = "2.5.0" } uuid = { version = "1.8.0", default-features = false } walkdir = "2.5.0" diff --git a/crates/rattler_conda_types/src/utils/serde.rs b/crates/rattler_conda_types/src/utils/serde.rs index 3a2788fc7..7b2a2b103 100644 --- a/crates/rattler_conda_types/src/utils/serde.rs +++ b/crates/rattler_conda_types/src/utils/serde.rs @@ -1,14 +1,10 @@ use chrono::{DateTime, Utc}; use fxhash::FxHashMap; -use itertools::Itertools; use serde::de::Error as _; use serde::ser::Error; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use serde_with::de::DeserializeAsWrap; -use serde_with::ser::SerializeAsWrap; use serde_with::{DeserializeAs, SerializeAs}; -use std::collections::{BTreeMap, HashSet}; -use std::hash::{BuildHasher, Hash}; +use std::collections::BTreeMap; use std::marker::PhantomData; use std::path::{Path, PathBuf}; use url::Url; @@ -143,62 +139,6 @@ impl SerializeAs> for Timestamp { } } -/// Used with `serde_with` to serialize a collection as a sorted collection. -#[derive(Default)] -pub(crate) struct Ordered(PhantomData); - -impl<'de, T: Eq + Hash, S: BuildHasher + Default, TAs> DeserializeAs<'de, HashSet> - for Ordered -where - TAs: DeserializeAs<'de, T>, -{ - fn deserialize_as(deserializer: D) -> Result, D::Error> - where - D: Deserializer<'de>, - { - let content = - DeserializeAsWrap::, Vec>::deserialize(deserializer)?.into_inner(); - Ok(content.into_iter().collect()) - } -} - -impl> SerializeAs> for Ordered { - fn serialize_as(source: &HashSet, serializer: S) -> Result - where - S: Serializer, - { - let mut elements = source.iter().collect_vec(); - elements.sort(); - SerializeAsWrap::, Vec<&TAs>>::new(&elements).serialize(serializer) - } -} - -impl<'de, T: Ord, TAs> DeserializeAs<'de, Vec> for Ordered -where - TAs: DeserializeAs<'de, T>, -{ - fn deserialize_as(deserializer: D) -> Result, D::Error> - where - D: Deserializer<'de>, - { - let mut content = - DeserializeAsWrap::, Vec>::deserialize(deserializer)?.into_inner(); - content.sort(); - Ok(content) - } -} - -impl> SerializeAs> for Ordered { - fn serialize_as(source: &Vec, serializer: S) -> Result - where - S: Serializer, - { - let mut elements = source.iter().collect_vec(); - elements.sort(); - SerializeAsWrap::, Vec<&TAs>>::new(&elements).serialize(serializer) - } -} - /// A helper struct to deserialize types from a string without checking the string. pub struct DeserializeFromStrUnchecked; diff --git a/crates/rattler_conda_types/src/version/mod.rs b/crates/rattler_conda_types/src/version/mod.rs index 52ab8daa8..37b65c104 100644 --- a/crates/rattler_conda_types/src/version/mod.rs +++ b/crates/rattler_conda_types/src/version/mod.rs @@ -1037,7 +1037,7 @@ mod test { use crate::version::StrictVersion; - use super::Version; + use super::{Component, Version}; // Tests are inspired by: https://github.com/conda/conda/blob/33a142c16530fcdada6c377486f1c1a385738a96/tests/models/test_version.py @@ -1049,7 +1049,7 @@ mod test { Restart, } - let versions = [ + let versions_str = [ " 0.4", "== 0.4.0", " < 0.4.1.rc", @@ -1079,13 +1079,13 @@ mod test { " < 2!0.4.1", // epoch increased again ]; - let ops = versions.iter().map(|&v| { - let (op, version) = if let Some((op, version)) = v.trim().split_once(' ') { + let ops = versions_str.iter().map(|&v| { + let (op, version_str) = if let Some((op, version)) = v.trim().split_once(' ') { (op, version.trim()) } else { ("", v.trim()) }; - let version: Version = version.parse().unwrap(); + let version: Version = version_str.parse().unwrap(); let op = match op { "<" => CmpOp::Less, "==" => CmpOp::Equal, @@ -1397,4 +1397,51 @@ mod test { expected ); } + + #[test] + fn test_component_total_order() { + // Create instances of each variant + let components = vec![ + Component::Dev, + Component::UnderscoreOrDash { is_dash: false }, + Component::Iden(Box::from("alpha")), + Component::Iden(Box::from("beta")), + Component::Numeral(1), + Component::Numeral(2), + Component::Post, + ]; + + // Check that each component equals itself + for a in &components { + assert_eq!(a.cmp(a), Ordering::Equal); + } + + for (i, a) in components.iter().enumerate() { + for b in components[i + 1..].iter() { + let ord = a.cmp(b); + assert_eq!( + ord, + Ordering::Less, + "Expected {:?} < {:?}, but found {:?}", + a, + b, + ord + ); + } + // Check the reverse ordering as well + // I think this should automatically check transitivity + // If a <= b and b <= c, then a <= c + for b in components[..i].iter() { + let ord = a.cmp(b); + assert_eq!( + ord, + Ordering::Greater, + "Expected {:?} > {:?}, but found {:?}", + a, + b, + ord + ); + } + } + } } diff --git a/crates/rattler_solve/src/resolvo/conda_sorting.rs b/crates/rattler_solve/src/resolvo/conda_sorting.rs new file mode 100644 index 000000000..0c68e87ea --- /dev/null +++ b/crates/rattler_solve/src/resolvo/conda_sorting.rs @@ -0,0 +1,387 @@ +use std::{ + cmp::Ordering, + collections::{hash_map::Entry, HashMap}, +}; + +use futures::future::FutureExt; +use itertools::Itertools; +use rattler_conda_types::Version; +use resolvo::{ + utils::Pool, Dependencies, NameId, Requirement, SolvableId, SolverCache, VersionSetId, +}; + +use super::{SolverMatchSpec, SolverPackageRecord}; +use crate::resolvo::CondaDependencyProvider; + +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub(super) enum CompareStrategy { + Default, + LowestVersion, +} + +/// Sort the candidates based on the dependencies. +/// This sorts in two steps: +/// 1. Sort by tracked features, version, and build number +/// 2. Sort by trying to sort the solvable that selects the highest versions of +/// the shared set of dependencies +pub struct SolvableSorter<'a, 'repo> { + solver: &'a SolverCache>, + strategy: CompareStrategy, + dependency_strategy: CompareStrategy, +} + +impl<'a, 'repo> SolvableSorter<'a, 'repo> { + pub fn new( + solver: &'a SolverCache>, + strategy: CompareStrategy, + dependency_strategy: CompareStrategy, + ) -> Self { + Self { + solver, + strategy, + dependency_strategy, + } + } + + /// Get a reference to the solvable record. + fn solvable_record(&self, id: SolvableId) -> &SolverPackageRecord<'repo> { + let pool = self.pool(); + let solvable = pool.resolve_solvable(id); + + &solvable.record + } + + /// Referece to the pool + fn pool(&self) -> &Pool> { + &self.solver.provider().pool + } + + /// Sort the candidates based on the dependencies. + /// This sorts in two steps: + /// 1. Sort by tracked features, version, and build number + /// 2. Sort by trying to find the candidate that selects the highest + /// versions of the shared set of dependencies + pub fn sort( + self, + solvables: &mut [SolvableId], + version_cache: &mut HashMap>, + ) { + self.sort_by_tracked_version_build(solvables); + self.sort_by_highest_dependency_versions(solvables, version_cache); + } + + /// This function can be used for the initial sorting of the candidates. + fn sort_by_tracked_version_build(&self, solvables: &mut [SolvableId]) { + solvables.sort_by(|a, b| self.simple_compare(*a, *b)); + } + + /// Sort the candidates based on: + /// 1. Whether the package has tracked features + /// 2. The version of the package + /// 3. The build number of the package + fn simple_compare(&self, a: SolvableId, b: SolvableId) -> Ordering { + let a_record = &self.solvable_record(a); + let b_record = &self.solvable_record(b); + + // First compare by "tracked_features". If one of the packages has a tracked + // feature it is sorted below the one that doesn't have the tracked feature. + let a_has_tracked_features = !a_record.track_features().is_empty(); + let b_has_tracked_features = !b_record.track_features().is_empty(); + match (a_has_tracked_features, b_has_tracked_features) { + (true, false) => return Ordering::Greater, + (false, true) => return Ordering::Less, + _ => {} + }; + + // Otherwise, select the variant with the highest version + match (self.strategy, a_record.version().cmp(b_record.version())) { + (CompareStrategy::Default, Ordering::Greater) + | (CompareStrategy::LowestVersion, Ordering::Less) => return Ordering::Less, + (CompareStrategy::Default, Ordering::Less) + | (CompareStrategy::LowestVersion, Ordering::Greater) => return Ordering::Greater, + (_, Ordering::Equal) => {} + }; + + // Otherwise, select the variant with the highest build number first + b_record.build_number().cmp(&a_record.build_number()) + } + + fn sort_by_highest_dependency_versions( + &self, + solvables: &mut [SolvableId], + version_cache: &mut HashMap>, + ) { + // Because the list can contain multiple versions, tracked features, and builds + // of the same package we need to create sub list of solvables that have + // the same version, build, and tracked features and sort these sub + // lists by the highest version of the dependencies shared by the solvables. + let mut start = 0usize; + let entire_len = solvables.len(); + while start < entire_len { + let mut end = start + 1; + + // Find the range of solvables with the same: version, build, tracked features + while end < entire_len + && self.simple_compare(solvables[start], solvables[end]) == Ordering::Equal + { + end += 1; + } + + // Take the sub list of solvables + let sub = &mut solvables[start..end]; + if sub.len() > 1 { + // Sort the sub list of solvables by the highest version of the dependencies + self.sort_subset_by_highest_dependency_versions(sub, version_cache); + } + + start = end; + } + } + + /// Sorts the solvables by the highest version of the dependencies shared by + /// the solvables. what this function does is: + /// 1. Find the first unsorted solvable in the list + /// 2. Get the dependencies for each solvable + /// 3. Get the known dependencies for each solvable, filter out the unknown + /// dependencies + /// 4. Retain the dependencies that are shared by all the solvables + /// 6. Calculate a total score by counting the position of the solvable in + /// the list with sorted dependencies + /// 7. Sort by the score per solvable and use timestamp of the record as a + /// tie breaker + fn sort_subset_by_highest_dependency_versions( + &self, + solvables: &mut [SolvableId], + version_cache: &mut HashMap>, + ) { + // Get the dependencies for each solvable + let dependencies = solvables + .iter() + .map(|id| { + self.solver + .get_or_cache_dependencies(*id) + .now_or_never() + .expect("get_or_cache_dependencies failed") + .map(|deps| (id, deps)) + }) + .collect::, _>>(); + + let dependencies = match dependencies { + Ok(dependencies) => dependencies, + // Solver cancelation, lets just return + Err(_) => return, + }; + + // Get the known dependencies for each solvable, filter out the unknown + // dependencies + let mut id_and_deps: HashMap<_, Vec<_>> = HashMap::with_capacity(dependencies.len()); + let mut name_count: HashMap = HashMap::new(); + for (solvable_idx, &solvable_id) in solvables.iter().enumerate() { + let dependencies = self + .solver + .get_or_cache_dependencies(solvable_id) + .now_or_never() + .expect("get_or_cache_dependencies failed"); + let known = match dependencies { + Ok(Dependencies::Known(known_dependencies)) => known_dependencies, + Ok(Dependencies::Unknown(_)) => { + unreachable!("Unknown dependencies should never happen in the conda ecosystem") + } + // Solver cancelation, lets just return + Err(_) => return, + }; + + for requirement in &known.requirements { + let version_set_id = match requirement { + // Ignore union requirements, these do not occur in the conda ecosystem + // currently + Requirement::Union(_) => { + unreachable!("Union requirements, are not implemented in the ordering") + } + Requirement::Single(version_set_id) => version_set_id, + }; + + // Get the name of the dependency and add the version set id to the list of + // version sets for a particular package. A single solvable can depend on a + // single package multiple times. + let dependency_name = self + .pool() + .resolve_version_set_package_name(*version_set_id); + + // Check how often we have seen this dependency name + let name_count = match name_count.entry(dependency_name) { + Entry::Occupied(entry) if entry.get() + 1 >= solvable_idx => entry.into_mut(), + Entry::Vacant(entry) if solvable_idx == 0 => entry.insert(0), + _ => { + // We have already not seen this dependency name for all solvables so there + // is no need to allocate additional memory to track + // it. + continue; + } + }; + + match id_and_deps.entry((solvable_id, dependency_name)) { + Entry::Occupied(mut entry) => entry.get_mut().push(*version_set_id), + Entry::Vacant(entry) => { + entry.insert(vec![*version_set_id]); + *name_count += 1; + } + } + } + } + + // Sort all the dependencies that the solvables have in common by their name. + let sorted_unique_names = name_count + .into_iter() + .filter_map(|(name, count)| { + if count == solvables.len() { + Some(name) + } else { + None + } + }) + .sorted_by_key(|name| self.pool().resolve_package_name(*name)) + .collect_vec(); + + // A closure that locates the highest version of a dependency for a solvable. + let mut find_highest_version_for_set = |version_set_ids: &Vec| { + version_set_ids + .iter() + .filter_map(|id| find_highest_version(*id, self.solver, version_cache)) + .map(|v| TrackedFeatureVersion::new(v.0, v.1)) + .fold(None, |init, version| { + if let Some(init) = init { + Some( + if version.compare_with_strategy(&init, CompareStrategy::Default) + == Ordering::Less + { + version + } else { + init + }, + ) + } else { + Some(version) + } + }) + }; + + // Sort the solvables by comparing the highest version of the shared + // dependencies in alphabetic order. + solvables.sort_by(|a, b| { + for &name in sorted_unique_names.iter() { + let a_version = id_and_deps + .get(&(*a, name)) + .and_then(&mut find_highest_version_for_set); + let b_version = id_and_deps + .get(&(*b, name)) + .and_then(&mut find_highest_version_for_set); + + // Deal with the case where resolving the version set doesn't actually select a + // version + let (a_version, b_version) = match (a_version, b_version) { + // If we have a version for either solvable, but not the other, the one with the + // version is better. + (Some(_), None) => return Ordering::Less, + (None, Some(_)) => return Ordering::Greater, + + // If for neither solvable the version set doesn't select a version for the + // dependency we skip it. + (None, None) => continue, + + (Some(a), Some(b)) => (a, b), + }; + + // Compare the versions + match a_version.compare_with_strategy(&b_version, self.dependency_strategy) { + Ordering::Equal => { + // If this version is equal, we continue with the next dependency + continue; + } + ordering => return ordering, + } + } + + // Otherwise sort by timestamp (in reverse, we want the highest timestamp first) + let a_record = self.solvable_record(*a); + let b_record = self.solvable_record(*b); + b_record.timestamp().cmp(&a_record.timestamp()) + }); + } +} + +/// Couples the version with the tracked features, for easier ordering +#[derive(PartialEq, Eq, Clone, Debug)] +struct TrackedFeatureVersion { + version: Version, + tracked_features: bool, +} + +impl TrackedFeatureVersion { + fn new(version: Version, tracked_features: bool) -> Self { + Self { + version, + tracked_features, + } + } + + fn compare_with_strategy(&self, other: &Self, compare_strategy: CompareStrategy) -> Ordering { + // First compare by "tracked_features". If one of the packages has a tracked + // feature it is sorted below the one that doesn't have the tracked feature. + match (self.tracked_features, other.tracked_features) { + (true, false) => Ordering::Greater, + (false, true) => Ordering::Less, + _ if compare_strategy == CompareStrategy::Default => other.version.cmp(&self.version), + _ => self.version.cmp(&other.version), + } + } +} + +pub(super) fn find_highest_version( + match_spec_id: VersionSetId, + solver: &SolverCache>, + highest_version_cache: &mut HashMap>, +) -> Option<(Version, bool)> { + highest_version_cache + .entry(match_spec_id) + .or_insert_with(|| { + let candidates = solver + .get_or_cache_matching_candidates(match_spec_id) + .now_or_never() + .expect("get_or_cache_matching_candidates failed"); + + // Err only happens on cancellation, so we will not continue anyways + let candidates = if let Ok(candidates) = candidates { + candidates + } else { + return None; + }; + + let pool = &solver.provider().pool; + + candidates + .iter() + .map(|id| &pool.resolve_solvable(*id).record) + .fold(None, |init, record| { + Some(init.map_or_else( + || { + ( + record.version().clone(), + !record.track_features().is_empty(), + ) + }, + |(version, has_tracked_features)| { + if &version < record.version() { + ( + record.version().clone(), + !record.track_features().is_empty(), + ) + } else { + (version, has_tracked_features) + } + }, + )) + }) + }) + .clone() +} diff --git a/crates/rattler_solve/src/resolvo/conda_util.rs b/crates/rattler_solve/src/resolvo/conda_util.rs deleted file mode 100644 index d10a1f529..000000000 --- a/crates/rattler_solve/src/resolvo/conda_util.rs +++ /dev/null @@ -1,212 +0,0 @@ -use std::{cmp::Ordering, collections::HashMap}; - -use futures::future::FutureExt; -use rattler_conda_types::Version; -use resolvo::{Dependencies, Requirement, SolvableId, SolverCache, VersionSetId}; - -use crate::resolvo::CondaDependencyProvider; - -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub(super) enum CompareStrategy { - Default, - LowestVersion, -} - -/// Returns the order of two candidates based on the order used by conda. -#[allow(clippy::too_many_arguments)] -pub(super) fn compare_candidates( - a: SolvableId, - b: SolvableId, - solver: &SolverCache>, - match_spec_highest_version: &mut HashMap< - VersionSetId, - Option<(rattler_conda_types::Version, bool)>, - >, - strategy: CompareStrategy, -) -> Ordering { - let pool = &solver.provider().pool; - - let a_solvable = pool.resolve_solvable(a); - let b_solvable = pool.resolve_solvable(b); - - let a_record = &a_solvable.record; - let b_record = &b_solvable.record; - - // First compare by "tracked_features". If one of the packages has a tracked - // feature it is sorted below the one that doesn't have the tracked feature. - let a_has_tracked_features = !a_record.track_features().is_empty(); - let b_has_tracked_features = !b_record.track_features().is_empty(); - match a_has_tracked_features.cmp(&b_has_tracked_features) { - Ordering::Less => return Ordering::Less, - Ordering::Greater => return Ordering::Greater, - Ordering::Equal => {} - }; - - // Otherwise, select the variant with the highest version - match (strategy, a_record.version().cmp(b_record.version())) { - (CompareStrategy::Default, Ordering::Greater) - | (CompareStrategy::LowestVersion, Ordering::Less) => return Ordering::Less, - (CompareStrategy::Default, Ordering::Less) - | (CompareStrategy::LowestVersion, Ordering::Greater) => return Ordering::Greater, - (_, Ordering::Equal) => {} - }; - - // Otherwise, select the variant with the highest build number - match a_record.build_number().cmp(&b_record.build_number()) { - Ordering::Less => return Ordering::Greater, - Ordering::Greater => return Ordering::Less, - Ordering::Equal => {} - }; - - // return Ordering::Equal; - - // Otherwise, compare the dependencies of the variants. If there are similar - // dependencies select the variant that selects the highest version of the - // dependency. - let (a_dependencies, b_dependencies) = match ( - solver - .get_or_cache_dependencies(a) - .now_or_never() - .expect("get_or_cache_dependencies failed"), - solver - .get_or_cache_dependencies(b) - .now_or_never() - .expect("get_or_cache_dependencies failed"), - ) { - (Ok(a_deps), Ok(b_deps)) => (a_deps, b_deps), - // If either call fails, it's likely due to solver cancellation; thus, we can't compare - // dependencies - _ => return Ordering::Equal, - }; - - // If the MatchSpecs are known use these - // map these into a HashMap - // for comparison later - let (a_specs_by_name, b_specs_by_name) = - if let (Dependencies::Known(a_known), Dependencies::Known(b_known)) = - (a_dependencies, b_dependencies) - { - let a_match_specs = a_known - .requirements - .iter() - .filter_map(|req| match req { - Requirement::Single(id) => Some((*id, pool.resolve_version_set(*id))), - Requirement::Union(_) => None, - }) - .map(|(spec_id, _)| (pool.resolve_version_set_package_name(spec_id), spec_id)) - .collect::>(); - - let b_match_specs = b_known - .requirements - .iter() - .filter_map(|req| match req { - Requirement::Single(id) => Some((*id, pool.resolve_version_set(*id))), - Requirement::Union(_) => None, - }) - .map(|(spec_id, _)| (pool.resolve_version_set_package_name(spec_id), spec_id)) - .collect::>(); - (a_match_specs, b_match_specs) - } else { - (HashMap::new(), HashMap::new()) - }; - - let mut total_score = 0; - for (a_dep_name, a_spec_id) in a_specs_by_name { - if let Some(b_spec_id) = b_specs_by_name.get(&a_dep_name) { - if &a_spec_id == b_spec_id { - continue; - } - - // Find which of the two specs selects the highest version - let highest_a = find_highest_version(a_spec_id, solver, match_spec_highest_version); - let highest_b = find_highest_version(*b_spec_id, solver, match_spec_highest_version); - - // Skip version if no package is selected by either spec - let (a_version, a_tracked_features, b_version, b_tracked_features) = if let ( - Some((a_version, a_tracked_features)), - Some((b_version, b_tracked_features)), - ) = - (highest_a, highest_b) - { - (a_version, a_tracked_features, b_version, b_tracked_features) - } else { - continue; - }; - - // If one of the dependencies only selects versions with tracked features, down- - // weigh that variant. - if let Some(score) = match a_tracked_features.cmp(&b_tracked_features) { - Ordering::Less => Some(-100), - Ordering::Greater => Some(100), - Ordering::Equal => None, - } { - total_score += score; - continue; - } - - // Otherwise, down-weigh the version with the lowest selected version. - total_score += match a_version.cmp(&b_version) { - Ordering::Less => 1, - Ordering::Equal => 0, - Ordering::Greater => -1, - }; - } - } - - // If ranking the dependencies provides a score, use that for the sorting. - match total_score.cmp(&0) { - Ordering::Equal => {} - ord => return ord, - }; - - // Otherwise, order by timestamp - b_record.timestamp().cmp(&a_record.timestamp()) -} - -pub(super) fn find_highest_version( - match_spec_id: VersionSetId, - solver: &SolverCache>, - match_spec_highest_version: &mut HashMap< - VersionSetId, - Option<(rattler_conda_types::Version, bool)>, - >, -) -> Option<(Version, bool)> { - match_spec_highest_version - .entry(match_spec_id) - .or_insert_with(|| { - let candidates = solver - .get_or_cache_matching_candidates(match_spec_id) - .now_or_never() - .expect("get_or_cache_matching_candidates failed"); - - // Err only happens on cancellation, so we will not continue anyways - let candidates = if let Ok(candidates) = candidates { - candidates - } else { - return None; - }; - - let pool = &solver.provider().pool; - - candidates - .iter() - .map(|id| &pool.resolve_solvable(*id).record) - .fold(None, |init, record| { - Some(init.map_or_else( - || { - ( - record.version().clone(), - !record.track_features().is_empty(), - ) - }, - |(version, has_tracked_features)| { - ( - version.max(record.version().clone()), - has_tracked_features && !record.track_features().is_empty(), - ) - }, - )) - }) - }) - .clone() -} diff --git a/crates/rattler_solve/src/resolvo/mod.rs b/crates/rattler_solve/src/resolvo/mod.rs index d278e4a8b..c26b44600 100644 --- a/crates/rattler_solve/src/resolvo/mod.rs +++ b/crates/rattler_solve/src/resolvo/mod.rs @@ -10,6 +10,7 @@ use std::{ }; use chrono::{DateTime, Utc}; +use conda_sorting::SolvableSorter; use itertools::Itertools; use rattler_conda_types::{ package::ArchiveType, GenericVirtualPackage, MatchSpec, Matches, NamelessMatchSpec, @@ -23,11 +24,11 @@ use resolvo::{ }; use crate::{ - resolvo::conda_util::CompareStrategy, ChannelPriority, IntoRepoData, SolveError, SolveStrategy, - SolverRepoData, SolverTask, + resolvo::conda_sorting::CompareStrategy, ChannelPriority, IntoRepoData, SolveError, + SolveStrategy, SolverRepoData, SolverTask, }; -mod conda_util; +mod conda_sorting; /// Represents the information required to load available packages into libsolv /// for a single channel and platform combination @@ -474,23 +475,29 @@ impl<'a> DependencyProvider for CondaDependencyProvider<'a> { let mut highest_version_spec = self.matchspec_to_highest_version.borrow_mut(); - let strategy = match self.strategy { - SolveStrategy::Highest => CompareStrategy::Default, - SolveStrategy::LowestVersion => CompareStrategy::LowestVersion, + let (strategy, dependency_strategy) = match self.strategy { + SolveStrategy::Highest => (CompareStrategy::Default, CompareStrategy::Default), + SolveStrategy::LowestVersion => ( + CompareStrategy::LowestVersion, + CompareStrategy::LowestVersion, + ), SolveStrategy::LowestVersionDirect => { if self .direct_dependencies .contains(&self.pool.resolve_solvable(solvables[0]).name) { - CompareStrategy::LowestVersion + (CompareStrategy::LowestVersion, CompareStrategy::Default) } else { - CompareStrategy::Default + (CompareStrategy::Default, CompareStrategy::Default) } } }; - solvables.sort_by(|&p1, &p2| { - conda_util::compare_candidates(p1, p2, solver, &mut highest_version_spec, strategy) - }); + + // Custom sorter that sorts by name, version, and build + // and then by the maximalization of dependency versions + // more information can be found at the struct location + SolvableSorter::new(solver, strategy, dependency_strategy) + .sort(solvables, &mut highest_version_spec); } async fn get_candidates(&self, name: NameId) -> Option { diff --git a/crates/rattler_solve/tests/snapshots/sorting__test_ordering_abess.snap b/crates/rattler_solve/tests/snapshots/sorting__test_ordering_abess.snap deleted file mode 100644 index e0aa48316..000000000 --- a/crates/rattler_solve/tests/snapshots/sorting__test_ordering_abess.snap +++ /dev/null @@ -1,17 +0,0 @@ ---- -source: crates/rattler_solve/tests/sorting.rs -expression: create_sorting_snapshot(spec) ---- -abess=0.4.5=py310hc4a4660_1 -abess=0.4.5=py39hac2352c_1 -abess=0.4.5=py38h514daf8_1 -abess=0.4.5=py37h48bf904_1 -abess=0.4.5=py39hac2352c_0 -abess=0.4.5=py38h514daf8_0 -abess=0.4.5=py37h48bf904_0 -abess=0.4.4=py39hac2352c_1 -abess=0.4.4=py38h514daf8_1 -abess=0.4.4=py37h48bf904_1 -abess=0.4.4=py39hac2352c_0 -abess=0.4.4=py38h514daf8_0 -abess=0.4.4=py37h48bf904_0 diff --git a/crates/rattler_solve/tests/snapshots/sorting__test_ordering_certifi_highest.snap b/crates/rattler_solve/tests/snapshots/sorting__test_ordering_certifi_highest.snap index 752c70756..969ced39d 100644 --- a/crates/rattler_solve/tests/snapshots/sorting__test_ordering_certifi_highest.snap +++ b/crates/rattler_solve/tests/snapshots/sorting__test_ordering_certifi_highest.snap @@ -4,28 +4,28 @@ expression: "create_sorting_snapshot(spec, solve_strategy)" --- certifi=2022.6.15=py310hff52083_0 certifi=2022.6.15=py39hf3d152e_0 -certifi=2022.6.15=py38h578d9bd_0 -certifi=2022.6.15=py37h89c1867_0 certifi=2022.6.15=py39h4162558_0 +certifi=2022.6.15=py38h578d9bd_0 certifi=2022.6.15=py38h373033e_0 +certifi=2022.6.15=py37h89c1867_0 certifi=2022.5.18.1=py310hff52083_0 certifi=2022.5.18.1=py39hf3d152e_0 -certifi=2022.5.18.1=py38h578d9bd_0 -certifi=2022.5.18.1=py37h89c1867_0 certifi=2022.5.18.1=py39h4162558_0 +certifi=2022.5.18.1=py38h578d9bd_0 certifi=2022.5.18.1=py38h373033e_0 +certifi=2022.5.18.1=py37h89c1867_0 certifi=2022.5.18=py310hff52083_0 certifi=2022.5.18=py39hf3d152e_0 -certifi=2022.5.18=py38h578d9bd_0 -certifi=2022.5.18=py37h89c1867_0 certifi=2022.5.18=py39h4162558_0 +certifi=2022.5.18=py38h578d9bd_0 certifi=2022.5.18=py38h373033e_0 +certifi=2022.5.18=py37h89c1867_0 certifi=2021.10.8=py310hff52083_2 certifi=2021.10.8=py39hf3d152e_2 -certifi=2021.10.8=py38h578d9bd_2 -certifi=2021.10.8=py37h89c1867_2 certifi=2021.10.8=py39h4162558_2 +certifi=2021.10.8=py38h578d9bd_2 certifi=2021.10.8=py38h373033e_2 +certifi=2021.10.8=py37h89c1867_2 certifi=2021.10.8=py310hff52083_1 certifi=2021.10.8=py39hf3d152e_1 certifi=2021.10.8=py38h578d9bd_1 @@ -36,85 +36,85 @@ certifi=2021.10.8=py38h578d9bd_0 certifi=2021.10.8=py37h89c1867_0 certifi=2021.10.8=py37h9c2f6ca_0 certifi=2021.5.30=py39hf3d152e_0 +certifi=2021.5.30=py36h5fab9bb_0 +certifi=2021.5.30=py36hd000896_0 certifi=2021.5.30=py38h578d9bd_0 certifi=2021.5.30=py37h89c1867_0 -certifi=2021.5.30=py36h5fab9bb_0 certifi=2021.5.30=py37h9c2f6ca_0 -certifi=2021.5.30=py36hd000896_0 certifi=2020.12.5=py39hf3d152e_1 +certifi=2020.12.5=py36h5fab9bb_1 +certifi=2020.12.5=py36hd000896_1 certifi=2020.12.5=py38h578d9bd_1 certifi=2020.12.5=py37h89c1867_1 -certifi=2020.12.5=py36h5fab9bb_1 certifi=2020.12.5=py37h9c2f6ca_1 -certifi=2020.12.5=py36hd000896_1 certifi=2020.12.5=py39hf3d152e_0 -certifi=2020.12.5=py38h578d9bd_0 -certifi=2020.12.5=py37h89c1867_0 certifi=2020.12.5=py36h5fab9bb_0 certifi=2020.12.5=py36hd000896_0 +certifi=2020.12.5=py38h578d9bd_0 +certifi=2020.12.5=py37h89c1867_0 certifi=2020.11.8=py39hf3d152e_0 -certifi=2020.11.8=py38h578d9bd_0 -certifi=2020.11.8=py37h89c1867_0 certifi=2020.11.8=py36h5fab9bb_0 certifi=2020.11.8=py36hd000896_0 +certifi=2020.11.8=py38h578d9bd_0 +certifi=2020.11.8=py37h89c1867_0 certifi=2020.6.20=py39h079e4ff_2 -certifi=2020.6.20=py38h924ce5b_2 -certifi=2020.6.20=py37he5f6b98_2 certifi=2020.6.20=py36h9880bd3_2 certifi=2020.6.20=py36ha6c21b1_2 -certifi=2020.6.20=py38h924ce5b_1 -certifi=2020.6.20=py37he5f6b98_1 +certifi=2020.6.20=py38h924ce5b_2 +certifi=2020.6.20=py37he5f6b98_2 certifi=2020.6.20=py36h9880bd3_1 certifi=2020.6.20=py36ha6c21b1_1 -certifi=2020.6.20=py38h32f6830_0 -certifi=2020.6.20=py37hc8dfbb8_0 +certifi=2020.6.20=py38h924ce5b_1 +certifi=2020.6.20=py37he5f6b98_1 certifi=2020.6.20=py36h9f0ad1d_0 certifi=2020.6.20=py36hc560c46_0 -certifi=2020.4.5.2=py38h32f6830_0 -certifi=2020.4.5.2=py37hc8dfbb8_0 +certifi=2020.6.20=py38h32f6830_0 +certifi=2020.6.20=py37hc8dfbb8_0 certifi=2020.4.5.2=py36h9f0ad1d_0 certifi=2020.4.5.2=py36hc560c46_0 -certifi=2020.4.5.1=py38h32f6830_0 -certifi=2020.4.5.1=py37hc8dfbb8_0 +certifi=2020.4.5.2=py38h32f6830_0 +certifi=2020.4.5.2=py37hc8dfbb8_0 certifi=2020.4.5.1=py36h9f0ad1d_0 certifi=2020.4.5.1=py36hc560c46_0 -certifi=2019.11.28=py38h32f6830_1 -certifi=2019.11.28=py37hc8dfbb8_1 +certifi=2020.4.5.1=py38h32f6830_0 +certifi=2020.4.5.1=py37hc8dfbb8_0 certifi=2019.11.28=py36h9f0ad1d_1 -certifi=2019.11.28=py27h8c360ce_1 certifi=2019.11.28=py36hc560c46_1 -certifi=2019.11.28=py38h32f6830_0 -certifi=2019.11.28=py38_0 -certifi=2019.11.28=py37hc8dfbb8_0 -certifi=2019.11.28=py37_0 -certifi=2019.11.28=py36h9f0ad1d_0 +certifi=2019.11.28=py27h8c360ce_1 +certifi=2019.11.28=py38h32f6830_1 +certifi=2019.11.28=py37hc8dfbb8_1 certifi=2019.11.28=py36hc560c46_0 +certifi=2019.11.28=py36h9f0ad1d_0 certifi=2019.11.28=py36_0 certifi=2019.11.28=py27h8c360ce_0 certifi=2019.11.28=py27_0 -certifi=2019.9.11=py38_0 -certifi=2019.9.11=py37_0 +certifi=2019.11.28=py38h32f6830_0 +certifi=2019.11.28=py38_0 +certifi=2019.11.28=py37hc8dfbb8_0 +certifi=2019.11.28=py37_0 certifi=2019.9.11=py36_0 certifi=2019.9.11=py27_0 -certifi=2019.6.16=py37_1 +certifi=2019.9.11=py38_0 +certifi=2019.9.11=py37_0 certifi=2019.6.16=py36_1 certifi=2019.6.16=py27_1 -certifi=2019.6.16=py37_0 +certifi=2019.6.16=py37_1 certifi=2019.6.16=py36_0 certifi=2019.6.16=py27_0 -certifi=2019.3.9=py37_0 +certifi=2019.6.16=py37_0 certifi=2019.3.9=py36_0 certifi=2019.3.9=py27_0 -certifi=2018.11.29=py37_1000 +certifi=2019.3.9=py37_0 certifi=2018.11.29=py36_1000 certifi=2018.11.29=py27_1000 -certifi=2018.10.15=py37_1000 +certifi=2018.11.29=py37_1000 certifi=2018.10.15=py36_1000 certifi=2018.10.15=py27_1000 -certifi=2018.8.24=py37_1001 +certifi=2018.10.15=py37_1000 certifi=2018.8.24=py36_1001 certifi=2018.8.24=py35_1001 certifi=2018.8.24=py27_1001 +certifi=2018.8.24=py37_1001 certifi=2018.8.24=py36_1 certifi=2018.8.24=py35_1 certifi=2018.8.24=py27_1 @@ -124,10 +124,10 @@ certifi=2018.8.24=py27_0 certifi=2018.8.13=py36_0 certifi=2018.8.13=py35_0 certifi=2018.8.13=py27_0 -certifi=2018.4.16=py37_0 certifi=2018.4.16=py36_0 certifi=2018.4.16=py35_0 certifi=2018.4.16=py27_0 +certifi=2018.4.16=py37_0 certifi=2018.1.18=py36_0 certifi=2018.1.18=py35_0 certifi=2018.1.18=py27_0 diff --git a/crates/rattler_solve/tests/snapshots/sorting__test_ordering_libuuid.snap b/crates/rattler_solve/tests/snapshots/sorting__test_ordering_libuuid.snap deleted file mode 100644 index 1b2aba728..000000000 --- a/crates/rattler_solve/tests/snapshots/sorting__test_ordering_libuuid.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: crates/rattler_solve/tests/sorting.rs -expression: create_sorting_snapshot(package_name) ---- -libuuid=2.32.1=h7f98852_1000 -libuuid=2.32.1=h14c3975_1000 diff --git a/crates/rattler_solve/tests/snapshots/sorting__test_ordering_python.snap b/crates/rattler_solve/tests/snapshots/sorting__test_ordering_python.snap deleted file mode 100644 index 16ab4128d..000000000 --- a/crates/rattler_solve/tests/snapshots/sorting__test_ordering_python.snap +++ /dev/null @@ -1,30 +0,0 @@ ---- -source: crates/rattler_solve/tests/sorting.rs -expression: create_sorting_snapshot(spec) ---- -python=3.10.5=ha86cf86_0_cpython -python=3.10.5=h582c2e5_0_cpython -python=3.10.4=h2660328_0_cpython -python=3.10.4=h9a8a25e_0_cpython -python=3.10.2=hc74c709_4_cpython -python=3.10.2=h85951f9_4_cpython -python=3.10.2=hc74c709_3_cpython -python=3.10.2=h85951f9_3_cpython -python=3.10.2=hc74c709_2_cpython -python=3.10.2=h85951f9_2_cpython -python=3.10.2=hc74c709_1_cpython -python=3.10.2=h85951f9_1_cpython -python=3.10.2=h543edf9_0_cpython -python=3.10.2=h62f1059_0_cpython -python=3.10.1=h543edf9_2_cpython -python=3.10.1=h62f1059_2_cpython -python=3.10.1=h543edf9_1_cpython -python=3.10.1=h62f1059_1_cpython -python=3.10.1=h543edf9_0_cpython -python=3.10.1=h62f1059_0_cpython -python=3.10.0=h543edf9_3_cpython -python=3.10.0=h62f1059_3_cpython -python=3.10.0=h543edf9_2_cpython -python=3.10.0=h62f1059_2_cpython -python=3.10.0=h543edf9_1_cpython -python=3.10.0=h62f1059_1_cpython diff --git a/crates/rattler_solve/tests/snapshots/sorting__test_ordering_pytorch.snap b/crates/rattler_solve/tests/snapshots/sorting__test_ordering_pytorch.snap deleted file mode 100644 index 35d65274f..000000000 --- a/crates/rattler_solve/tests/snapshots/sorting__test_ordering_pytorch.snap +++ /dev/null @@ -1,68 +0,0 @@ ---- -source: crates/rattler_solve/tests/sorting.rs -expression: create_sorting_snapshot(spec) ---- -pytorch=1.12.1=cuda112py310h51fe464_200 -pytorch=1.12.1=cuda111py310h385535d_200 -pytorch=1.12.1=cuda110py310hfdf97d1_200 -pytorch=1.12.1=cuda112py39ha0cca9b_200 -pytorch=1.12.1=cuda111py39h9f128c5_200 -pytorch=1.12.1=cuda110py39h0a9da28_200 -pytorch=1.12.1=cuda112py38habe9d5a_200 -pytorch=1.12.1=cuda111py38h2d04dd0_200 -pytorch=1.12.1=cuda110py38h386aa8f_200 -pytorch=1.12.1=cuda111py37hdb2541a_200 -pytorch=1.12.1=cuda110py37h0def887_200 -pytorch=1.12.1=cuda102py310hdf4a2db_200 -pytorch=1.12.1=cuda102py39hbbcd3cb_200 -pytorch=1.12.1=cuda102py38hfdb21e3_200 -pytorch=1.12.1=cuda112py37hfcfbd4c_200 -pytorch=1.12.1=cuda102py37haad9b4f_200 -pytorch=1.12.1=cpu_py310h75c9ab6_0 -pytorch=1.12.1=cpu_py39h5d22d69_0 -pytorch=1.12.1=cpu_py38h39c826d_0 -pytorch=1.12.1=cpu_py37h14e09b7_0 -pytorch=1.12.0=cuda112py310h51fe464_202 -pytorch=1.12.0=cuda111py310h385535d_202 -pytorch=1.12.0=cuda110py310hfdf97d1_202 -pytorch=1.12.0=cuda112py39ha0cca9b_202 -pytorch=1.12.0=cuda111py39h9f128c5_202 -pytorch=1.12.0=cuda110py39h0a9da28_202 -pytorch=1.12.0=cuda111py38h2d04dd0_202 -pytorch=1.12.0=cuda110py38h386aa8f_202 -pytorch=1.12.0=cuda112py37hfcfbd4c_202 -pytorch=1.12.0=cuda111py37hdb2541a_202 -pytorch=1.12.0=cuda110py37h0def887_202 -pytorch=1.12.0=cuda102py310hdf4a2db_202 -pytorch=1.12.0=cuda102py39hbbcd3cb_202 -pytorch=1.12.0=cuda112py38habe9d5a_202 -pytorch=1.12.0=cuda102py38hfdb21e3_202 -pytorch=1.12.0=cuda102py37haad9b4f_202 -pytorch=1.12.0=cuda112py310h51fe464_200 -pytorch=1.12.0=cuda111py310h385535d_200 -pytorch=1.12.0=cuda110py310hfdf97d1_200 -pytorch=1.12.0=cuda112py39ha0cca9b_200 -pytorch=1.12.0=cuda111py39h9f128c5_200 -pytorch=1.12.0=cuda110py39h0a9da28_200 -pytorch=1.12.0=cuda111py38h2d04dd0_200 -pytorch=1.12.0=cuda110py38h386aa8f_200 -pytorch=1.12.0=cuda112py37hfcfbd4c_200 -pytorch=1.12.0=cuda111py37hdb2541a_200 -pytorch=1.12.0=cuda110py37h0def887_200 -pytorch=1.12.0=cuda102py310hdf4a2db_200 -pytorch=1.12.0=cuda102py39hbbcd3cb_200 -pytorch=1.12.0=cuda112py38habe9d5a_200 -pytorch=1.12.0=cuda102py38hfdb21e3_200 -pytorch=1.12.0=cuda102py37haad9b4f_200 -pytorch=1.12.0=cpu_py310h75c9ab6_2 -pytorch=1.12.0=cpu_py39h5d22d69_2 -pytorch=1.12.0=cpu_py38h39c826d_2 -pytorch=1.12.0=cpu_py37h14e09b7_2 -pytorch=1.12.0=cpu_py310h75c9ab6_1 -pytorch=1.12.0=cpu_py39h5d22d69_1 -pytorch=1.12.0=cpu_py38h39c826d_1 -pytorch=1.12.0=cpu_py37h14e09b7_1 -pytorch=1.12.0=cpu_py310h75c9ab6_0 -pytorch=1.12.0=cpu_py39h5d22d69_0 -pytorch=1.12.0=cpu_py38h39c826d_0 -pytorch=1.12.0=cpu_py37h14e09b7_0 diff --git a/crates/rattler_solve/tests/snapshots/sorting__test_ordering_pytorch_highest.snap b/crates/rattler_solve/tests/snapshots/sorting__test_ordering_pytorch_highest.snap index 40691f62c..b46844316 100644 --- a/crates/rattler_solve/tests/snapshots/sorting__test_ordering_pytorch_highest.snap +++ b/crates/rattler_solve/tests/snapshots/sorting__test_ordering_pytorch_highest.snap @@ -3,55 +3,55 @@ source: crates/rattler_solve/tests/sorting.rs expression: "create_sorting_snapshot(spec, solve_strategy)" --- pytorch=1.12.1=cuda112py310h51fe464_200 -pytorch=1.12.1=cuda111py310h385535d_200 -pytorch=1.12.1=cuda110py310hfdf97d1_200 pytorch=1.12.1=cuda112py39ha0cca9b_200 -pytorch=1.12.1=cuda111py39h9f128c5_200 -pytorch=1.12.1=cuda110py39h0a9da28_200 pytorch=1.12.1=cuda112py38habe9d5a_200 +pytorch=1.12.1=cuda112py37hfcfbd4c_200 +pytorch=1.12.1=cuda111py310h385535d_200 +pytorch=1.12.1=cuda111py39h9f128c5_200 pytorch=1.12.1=cuda111py38h2d04dd0_200 -pytorch=1.12.1=cuda110py38h386aa8f_200 pytorch=1.12.1=cuda111py37hdb2541a_200 +pytorch=1.12.1=cuda110py310hfdf97d1_200 +pytorch=1.12.1=cuda110py39h0a9da28_200 +pytorch=1.12.1=cuda110py38h386aa8f_200 pytorch=1.12.1=cuda110py37h0def887_200 pytorch=1.12.1=cuda102py310hdf4a2db_200 pytorch=1.12.1=cuda102py39hbbcd3cb_200 pytorch=1.12.1=cuda102py38hfdb21e3_200 -pytorch=1.12.1=cuda112py37hfcfbd4c_200 pytorch=1.12.1=cuda102py37haad9b4f_200 pytorch=1.12.1=cpu_py310h75c9ab6_0 pytorch=1.12.1=cpu_py39h5d22d69_0 pytorch=1.12.1=cpu_py38h39c826d_0 pytorch=1.12.1=cpu_py37h14e09b7_0 pytorch=1.12.0=cuda112py310h51fe464_202 -pytorch=1.12.0=cuda111py310h385535d_202 -pytorch=1.12.0=cuda110py310hfdf97d1_202 pytorch=1.12.0=cuda112py39ha0cca9b_202 +pytorch=1.12.0=cuda112py38habe9d5a_202 +pytorch=1.12.0=cuda112py37hfcfbd4c_202 +pytorch=1.12.0=cuda111py310h385535d_202 pytorch=1.12.0=cuda111py39h9f128c5_202 -pytorch=1.12.0=cuda110py39h0a9da28_202 pytorch=1.12.0=cuda111py38h2d04dd0_202 -pytorch=1.12.0=cuda110py38h386aa8f_202 -pytorch=1.12.0=cuda112py37hfcfbd4c_202 pytorch=1.12.0=cuda111py37hdb2541a_202 +pytorch=1.12.0=cuda110py310hfdf97d1_202 +pytorch=1.12.0=cuda110py39h0a9da28_202 +pytorch=1.12.0=cuda110py38h386aa8f_202 pytorch=1.12.0=cuda110py37h0def887_202 pytorch=1.12.0=cuda102py310hdf4a2db_202 pytorch=1.12.0=cuda102py39hbbcd3cb_202 -pytorch=1.12.0=cuda112py38habe9d5a_202 pytorch=1.12.0=cuda102py38hfdb21e3_202 pytorch=1.12.0=cuda102py37haad9b4f_202 pytorch=1.12.0=cuda112py310h51fe464_200 -pytorch=1.12.0=cuda111py310h385535d_200 -pytorch=1.12.0=cuda110py310hfdf97d1_200 pytorch=1.12.0=cuda112py39ha0cca9b_200 +pytorch=1.12.0=cuda112py38habe9d5a_200 +pytorch=1.12.0=cuda112py37hfcfbd4c_200 +pytorch=1.12.0=cuda111py310h385535d_200 pytorch=1.12.0=cuda111py39h9f128c5_200 -pytorch=1.12.0=cuda110py39h0a9da28_200 pytorch=1.12.0=cuda111py38h2d04dd0_200 -pytorch=1.12.0=cuda110py38h386aa8f_200 -pytorch=1.12.0=cuda112py37hfcfbd4c_200 pytorch=1.12.0=cuda111py37hdb2541a_200 +pytorch=1.12.0=cuda110py310hfdf97d1_200 +pytorch=1.12.0=cuda110py39h0a9da28_200 +pytorch=1.12.0=cuda110py38h386aa8f_200 pytorch=1.12.0=cuda110py37h0def887_200 pytorch=1.12.0=cuda102py310hdf4a2db_200 pytorch=1.12.0=cuda102py39hbbcd3cb_200 -pytorch=1.12.0=cuda112py38habe9d5a_200 pytorch=1.12.0=cuda102py38hfdb21e3_200 pytorch=1.12.0=cuda102py37haad9b4f_200 pytorch=1.12.0=cpu_py310h75c9ab6_2 diff --git a/crates/rattler_solve/tests/snapshots/sorting__test_ordering_pytorch_lowest.snap b/crates/rattler_solve/tests/snapshots/sorting__test_ordering_pytorch_lowest.snap index b0e998e79..62426a299 100644 --- a/crates/rattler_solve/tests/snapshots/sorting__test_ordering_pytorch_lowest.snap +++ b/crates/rattler_solve/tests/snapshots/sorting__test_ordering_pytorch_lowest.snap @@ -2,67 +2,67 @@ source: crates/rattler_solve/tests/sorting.rs expression: "create_sorting_snapshot(spec, solve_strategy)" --- -pytorch=1.12.0=cuda112py310h51fe464_202 -pytorch=1.12.0=cuda111py310h385535d_202 +pytorch=1.12.0=cuda102py39hbbcd3cb_202 +pytorch=1.12.0=cuda102py310hdf4a2db_202 +pytorch=1.12.0=cuda102py37haad9b4f_202 +pytorch=1.12.0=cuda102py38hfdb21e3_202 +pytorch=1.12.0=cuda110py39h0a9da28_202 pytorch=1.12.0=cuda110py310hfdf97d1_202 -pytorch=1.12.0=cuda112py39ha0cca9b_202 +pytorch=1.12.0=cuda110py37h0def887_202 +pytorch=1.12.0=cuda110py38h386aa8f_202 pytorch=1.12.0=cuda111py39h9f128c5_202 -pytorch=1.12.0=cuda110py39h0a9da28_202 +pytorch=1.12.0=cuda111py310h385535d_202 +pytorch=1.12.0=cuda111py37hdb2541a_202 pytorch=1.12.0=cuda111py38h2d04dd0_202 -pytorch=1.12.0=cuda110py38h386aa8f_202 +pytorch=1.12.0=cuda112py39ha0cca9b_202 +pytorch=1.12.0=cuda112py310h51fe464_202 pytorch=1.12.0=cuda112py37hfcfbd4c_202 -pytorch=1.12.0=cuda111py37hdb2541a_202 -pytorch=1.12.0=cuda110py37h0def887_202 -pytorch=1.12.0=cuda102py310hdf4a2db_202 -pytorch=1.12.0=cuda102py39hbbcd3cb_202 pytorch=1.12.0=cuda112py38habe9d5a_202 -pytorch=1.12.0=cuda102py38hfdb21e3_202 -pytorch=1.12.0=cuda102py37haad9b4f_202 -pytorch=1.12.0=cuda112py310h51fe464_200 -pytorch=1.12.0=cuda111py310h385535d_200 +pytorch=1.12.0=cuda102py39hbbcd3cb_200 +pytorch=1.12.0=cuda102py310hdf4a2db_200 +pytorch=1.12.0=cuda102py37haad9b4f_200 +pytorch=1.12.0=cuda102py38hfdb21e3_200 +pytorch=1.12.0=cuda110py39h0a9da28_200 pytorch=1.12.0=cuda110py310hfdf97d1_200 -pytorch=1.12.0=cuda112py39ha0cca9b_200 +pytorch=1.12.0=cuda110py37h0def887_200 +pytorch=1.12.0=cuda110py38h386aa8f_200 pytorch=1.12.0=cuda111py39h9f128c5_200 -pytorch=1.12.0=cuda110py39h0a9da28_200 +pytorch=1.12.0=cuda111py310h385535d_200 +pytorch=1.12.0=cuda111py37hdb2541a_200 pytorch=1.12.0=cuda111py38h2d04dd0_200 -pytorch=1.12.0=cuda110py38h386aa8f_200 +pytorch=1.12.0=cuda112py39ha0cca9b_200 +pytorch=1.12.0=cuda112py310h51fe464_200 pytorch=1.12.0=cuda112py37hfcfbd4c_200 -pytorch=1.12.0=cuda111py37hdb2541a_200 -pytorch=1.12.0=cuda110py37h0def887_200 -pytorch=1.12.0=cuda102py310hdf4a2db_200 -pytorch=1.12.0=cuda102py39hbbcd3cb_200 pytorch=1.12.0=cuda112py38habe9d5a_200 -pytorch=1.12.0=cuda102py38hfdb21e3_200 -pytorch=1.12.0=cuda102py37haad9b4f_200 -pytorch=1.12.0=cpu_py310h75c9ab6_2 pytorch=1.12.0=cpu_py39h5d22d69_2 -pytorch=1.12.0=cpu_py38h39c826d_2 +pytorch=1.12.0=cpu_py310h75c9ab6_2 pytorch=1.12.0=cpu_py37h14e09b7_2 -pytorch=1.12.0=cpu_py310h75c9ab6_1 +pytorch=1.12.0=cpu_py38h39c826d_2 pytorch=1.12.0=cpu_py39h5d22d69_1 -pytorch=1.12.0=cpu_py38h39c826d_1 +pytorch=1.12.0=cpu_py310h75c9ab6_1 pytorch=1.12.0=cpu_py37h14e09b7_1 -pytorch=1.12.0=cpu_py310h75c9ab6_0 +pytorch=1.12.0=cpu_py38h39c826d_1 pytorch=1.12.0=cpu_py39h5d22d69_0 -pytorch=1.12.0=cpu_py38h39c826d_0 +pytorch=1.12.0=cpu_py310h75c9ab6_0 pytorch=1.12.0=cpu_py37h14e09b7_0 -pytorch=1.12.1=cuda112py310h51fe464_200 -pytorch=1.12.1=cuda111py310h385535d_200 -pytorch=1.12.1=cuda110py310hfdf97d1_200 -pytorch=1.12.1=cuda112py39ha0cca9b_200 -pytorch=1.12.1=cuda111py39h9f128c5_200 +pytorch=1.12.0=cpu_py38h39c826d_0 +pytorch=1.12.1=cuda102py39hbbcd3cb_200 +pytorch=1.12.1=cuda102py310hdf4a2db_200 +pytorch=1.12.1=cuda102py37haad9b4f_200 +pytorch=1.12.1=cuda102py38hfdb21e3_200 pytorch=1.12.1=cuda110py39h0a9da28_200 -pytorch=1.12.1=cuda112py38habe9d5a_200 -pytorch=1.12.1=cuda111py38h2d04dd0_200 +pytorch=1.12.1=cuda110py310hfdf97d1_200 +pytorch=1.12.1=cuda110py37h0def887_200 pytorch=1.12.1=cuda110py38h386aa8f_200 +pytorch=1.12.1=cuda111py39h9f128c5_200 +pytorch=1.12.1=cuda111py310h385535d_200 pytorch=1.12.1=cuda111py37hdb2541a_200 -pytorch=1.12.1=cuda110py37h0def887_200 -pytorch=1.12.1=cuda102py310hdf4a2db_200 -pytorch=1.12.1=cuda102py39hbbcd3cb_200 -pytorch=1.12.1=cuda102py38hfdb21e3_200 +pytorch=1.12.1=cuda111py38h2d04dd0_200 +pytorch=1.12.1=cuda112py39ha0cca9b_200 +pytorch=1.12.1=cuda112py310h51fe464_200 pytorch=1.12.1=cuda112py37hfcfbd4c_200 -pytorch=1.12.1=cuda102py37haad9b4f_200 -pytorch=1.12.1=cpu_py310h75c9ab6_0 +pytorch=1.12.1=cuda112py38habe9d5a_200 pytorch=1.12.1=cpu_py39h5d22d69_0 -pytorch=1.12.1=cpu_py38h39c826d_0 +pytorch=1.12.1=cpu_py310h75c9ab6_0 pytorch=1.12.1=cpu_py37h14e09b7_0 +pytorch=1.12.1=cpu_py38h39c826d_0 diff --git a/crates/rattler_solve/tests/snapshots/sorting__test_ordering_pytorch_lowest_direct.snap b/crates/rattler_solve/tests/snapshots/sorting__test_ordering_pytorch_lowest_direct.snap index b0e998e79..985c95813 100644 --- a/crates/rattler_solve/tests/snapshots/sorting__test_ordering_pytorch_lowest_direct.snap +++ b/crates/rattler_solve/tests/snapshots/sorting__test_ordering_pytorch_lowest_direct.snap @@ -3,35 +3,35 @@ source: crates/rattler_solve/tests/sorting.rs expression: "create_sorting_snapshot(spec, solve_strategy)" --- pytorch=1.12.0=cuda112py310h51fe464_202 -pytorch=1.12.0=cuda111py310h385535d_202 -pytorch=1.12.0=cuda110py310hfdf97d1_202 pytorch=1.12.0=cuda112py39ha0cca9b_202 +pytorch=1.12.0=cuda112py38habe9d5a_202 +pytorch=1.12.0=cuda112py37hfcfbd4c_202 +pytorch=1.12.0=cuda111py310h385535d_202 pytorch=1.12.0=cuda111py39h9f128c5_202 -pytorch=1.12.0=cuda110py39h0a9da28_202 pytorch=1.12.0=cuda111py38h2d04dd0_202 -pytorch=1.12.0=cuda110py38h386aa8f_202 -pytorch=1.12.0=cuda112py37hfcfbd4c_202 pytorch=1.12.0=cuda111py37hdb2541a_202 +pytorch=1.12.0=cuda110py310hfdf97d1_202 +pytorch=1.12.0=cuda110py39h0a9da28_202 +pytorch=1.12.0=cuda110py38h386aa8f_202 pytorch=1.12.0=cuda110py37h0def887_202 pytorch=1.12.0=cuda102py310hdf4a2db_202 pytorch=1.12.0=cuda102py39hbbcd3cb_202 -pytorch=1.12.0=cuda112py38habe9d5a_202 pytorch=1.12.0=cuda102py38hfdb21e3_202 pytorch=1.12.0=cuda102py37haad9b4f_202 pytorch=1.12.0=cuda112py310h51fe464_200 -pytorch=1.12.0=cuda111py310h385535d_200 -pytorch=1.12.0=cuda110py310hfdf97d1_200 pytorch=1.12.0=cuda112py39ha0cca9b_200 +pytorch=1.12.0=cuda112py38habe9d5a_200 +pytorch=1.12.0=cuda112py37hfcfbd4c_200 +pytorch=1.12.0=cuda111py310h385535d_200 pytorch=1.12.0=cuda111py39h9f128c5_200 -pytorch=1.12.0=cuda110py39h0a9da28_200 pytorch=1.12.0=cuda111py38h2d04dd0_200 -pytorch=1.12.0=cuda110py38h386aa8f_200 -pytorch=1.12.0=cuda112py37hfcfbd4c_200 pytorch=1.12.0=cuda111py37hdb2541a_200 +pytorch=1.12.0=cuda110py310hfdf97d1_200 +pytorch=1.12.0=cuda110py39h0a9da28_200 +pytorch=1.12.0=cuda110py38h386aa8f_200 pytorch=1.12.0=cuda110py37h0def887_200 pytorch=1.12.0=cuda102py310hdf4a2db_200 pytorch=1.12.0=cuda102py39hbbcd3cb_200 -pytorch=1.12.0=cuda112py38habe9d5a_200 pytorch=1.12.0=cuda102py38hfdb21e3_200 pytorch=1.12.0=cuda102py37haad9b4f_200 pytorch=1.12.0=cpu_py310h75c9ab6_2 @@ -47,20 +47,20 @@ pytorch=1.12.0=cpu_py39h5d22d69_0 pytorch=1.12.0=cpu_py38h39c826d_0 pytorch=1.12.0=cpu_py37h14e09b7_0 pytorch=1.12.1=cuda112py310h51fe464_200 -pytorch=1.12.1=cuda111py310h385535d_200 -pytorch=1.12.1=cuda110py310hfdf97d1_200 pytorch=1.12.1=cuda112py39ha0cca9b_200 -pytorch=1.12.1=cuda111py39h9f128c5_200 -pytorch=1.12.1=cuda110py39h0a9da28_200 pytorch=1.12.1=cuda112py38habe9d5a_200 +pytorch=1.12.1=cuda112py37hfcfbd4c_200 +pytorch=1.12.1=cuda111py310h385535d_200 +pytorch=1.12.1=cuda111py39h9f128c5_200 pytorch=1.12.1=cuda111py38h2d04dd0_200 -pytorch=1.12.1=cuda110py38h386aa8f_200 pytorch=1.12.1=cuda111py37hdb2541a_200 +pytorch=1.12.1=cuda110py310hfdf97d1_200 +pytorch=1.12.1=cuda110py39h0a9da28_200 +pytorch=1.12.1=cuda110py38h386aa8f_200 pytorch=1.12.1=cuda110py37h0def887_200 pytorch=1.12.1=cuda102py310hdf4a2db_200 pytorch=1.12.1=cuda102py39hbbcd3cb_200 pytorch=1.12.1=cuda102py38hfdb21e3_200 -pytorch=1.12.1=cuda112py37hfcfbd4c_200 pytorch=1.12.1=cuda102py37haad9b4f_200 pytorch=1.12.1=cpu_py310h75c9ab6_0 pytorch=1.12.1=cpu_py39h5d22d69_0 diff --git a/rust-toolchain b/rust-toolchain index aaceec04e..dbd41264a 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1 +1 @@ -1.80.0 +1.81.0