diff options
author | Aria Shrimpton <me@aria.rip> | 2024-01-19 22:26:02 +0000 |
---|---|---|
committer | Aria Shrimpton <me@aria.rip> | 2024-01-19 22:26:02 +0000 |
commit | 9c68abb682d3543aad0a89a9807300b2220d2db5 (patch) | |
tree | 8f434a0b9fe1e091c2117f92333174e1e20c0b77 /src | |
parent | 7fe644c89f6f359c5d2da11bd6e1e942e142bee1 (diff) |
feat(cli): show estimated cost of each option
Diffstat (limited to 'src')
-rw-r--r-- | src/crates/candelabra/src/cost/benchmark.rs | 5 | ||||
-rw-r--r-- | src/crates/candelabra/src/cost/mod.rs | 2 | ||||
-rw-r--r-- | src/crates/candelabra/src/select.rs | 77 | ||||
-rw-r--r-- | src/crates/cli/src/select.rs | 17 |
4 files changed, 55 insertions, 46 deletions
diff --git a/src/crates/candelabra/src/cost/benchmark.rs b/src/crates/candelabra/src/cost/benchmark.rs index 65addd2..25d0d37 100644 --- a/src/crates/candelabra/src/cost/benchmark.rs +++ b/src/crates/candelabra/src/cost/benchmark.rs @@ -23,7 +23,10 @@ use crate::paths::Paths; pub const ELEM_TYPE: &str = "usize"; /// String representation of the array of N values we use for benchmarking -pub const NS: &str = "[8, 256, 1024]"; +pub const NS: &str = "[ + 64, 128, 256, 512, 1024, 2048, 3072, 4096, 5120, 6144, 7168, 8192, 16384, 24576, 32768, + 40960, 49152, 57344, 65536, +]"; /// Results for a whole suite of benchmarks #[derive(Serialize, Deserialize, Debug, Clone)] diff --git a/src/crates/candelabra/src/cost/mod.rs b/src/crates/candelabra/src/cost/mod.rs index 99bdc7c..f29227f 100644 --- a/src/crates/candelabra/src/cost/mod.rs +++ b/src/crates/candelabra/src/cost/mod.rs @@ -3,7 +3,7 @@ mod benchmark; mod fit; pub use benchmark::{BenchmarkResult, Results as BenchmarkResults}; -pub use fit::Estimator; +pub use fit::{Cost, Estimator}; use std::collections::HashMap; diff --git a/src/crates/candelabra/src/select.rs b/src/crates/candelabra/src/select.rs index 28bea1e..1146040 100644 --- a/src/crates/candelabra/src/select.rs +++ b/src/crates/candelabra/src/select.rs @@ -2,63 +2,54 @@ use std::collections::HashMap; use crate::{ candidates::{ConTypeName, ImplName}, + cost::Cost, Project, State, }; use anyhow::Result; -use log::debug; impl State { /// Select a container implementation for each container type in the given project pub fn select(&self, project: &Project) -> Result<HashMap<ConTypeName, ImplName>> { - // get all candidates - let all_candidates = self.project_candidate_list(project)?; - - // get profiling information - let profiles = self.profiler_info(project)?; - - // generate estimates - // TODO: hacky stuff that panics too easy! - Ok(profiles - .iter() - .map(|(con_type, profile)| { - let candidates = &all_candidates - .iter() - .flat_map(|(_, cs)| cs.iter()) - .find(|(name, _)| name == con_type) - .unwrap() - .1; - - ( - con_type, - candidates.iter().map(move |candidate| -> (&str, f64) { - let cost_model = self.cost_model(candidate).unwrap(); - let cost = profile.estimate_cost(&cost_model); - - debug!("cost of {} being {} = {}", con_type, candidate, cost); - - (candidate, cost) - }), - ) - }) - .map(|(con_type, costs)| { + Ok(self + .rank_candidates(project)? + .into_iter() + .map(|(name, cs)| { ( - con_type.to_string(), - costs + name, + cs.into_iter() .reduce( - |acc @ (_, lowest_cost), new @ (_, cost)| { - if lowest_cost < cost { - acc - } else { - new - } - }, + |acc @ (_, min), new @ (_, cost)| if min < cost { acc } else { new }, ) .unwrap() - .0 - .to_string(), + .0, ) }) .collect()) } + + pub fn rank_candidates( + &self, + project: &Project, + ) -> Result<HashMap<ConTypeName, Vec<(ImplName, Cost)>>> { + // get all candidates + let all_candidates = self.project_candidate_list(project)?; + + // get profiling information + let profiles = self.profiler_info(project)?; + + let mut acc = HashMap::new(); + let con_type_names = all_candidates.iter().flat_map(|(_, cs)| cs.iter()); + for (con_type_name, candidates) in con_type_names { + let mut costs = vec![]; + let profile_info = profiles.get(con_type_name).unwrap(); + for candidate in candidates { + let model = self.cost_model(candidate)?; + costs.push((candidate.clone(), profile_info.estimate_cost(&model))); + } + acc.insert(con_type_name.to_string(), costs); + } + + Ok(acc) + } } diff --git a/src/crates/cli/src/select.rs b/src/crates/cli/src/select.rs index ab3e4aa..3ef43cd 100644 --- a/src/crates/cli/src/select.rs +++ b/src/crates/cli/src/select.rs @@ -1,6 +1,7 @@ use anyhow::Result; use argh::FromArgs; use log::info; +use tabled::{builder::Builder, settings::Style}; use crate::State; @@ -14,7 +15,21 @@ impl State { for proj in self.projects.iter() { info!("Processing project {}", &proj.name); - dbg!(self.inner.select(proj).unwrap()); + let costs = self.inner.rank_candidates(proj).unwrap(); + + let mut builder = Builder::default(); + builder.set_header(["name", "implementation", "estimated cost"]); + for (con_type_name, candidates) in costs.iter() { + for (candidate, cost) in candidates.iter() { + builder.push_record([ + con_type_name.as_str(), + candidate.as_str(), + cost.to_string().as_str(), + ]); + } + } + + println!("{}", builder.build().with(Style::sharp())) } Ok(()) } |