From b2207019936c044ff099b7578c695139f2ae6937 Mon Sep 17 00:00:00 2001 From: Basile Clement Date: Mon, 1 Apr 2019 11:47:32 +0200 Subject: [PATCH] Split the explorer in a separate crate This patch extracts the `telamon::explorer` module into a separate `telamon_explorer` crate, responsible for everything related to the search algorithms. This should help with compilation times since modifying the explorer will no longer require recompiling the rest of the `telamon` crate (and in particular not the generated `choices.rs`). --- Cargo.toml | 8 +--- backend/cuda/src/characterize/gen.rs | 5 +- backend/cuda/src/context.rs | 6 +-- backend/x86/src/context.rs | 11 ++--- kernels/Cargo.toml | 1 + kernels/benches/cuda_search.rs | 2 +- kernels/benches/cuda_variance.rs | 8 ++-- kernels/src/kernel.rs | 9 ++-- kernels/src/lib.rs | 6 +-- kernels/src/linalg.rs | 2 +- src/codegen/function.rs | 5 ++ src/device/context.rs | 2 +- src/device/fake.rs | 2 +- src/ir/dimension.rs | 6 +-- src/ir/function.rs | 2 +- src/lib.rs | 2 - src/{explorer => search_space}/candidate.rs | 46 +++++++++++++++---- src/search_space/mod.rs | 7 +++ telamon-capi/src/explorer.rs | 2 +- telamon-capi/src/lib.rs | 2 +- telamon-explorer/Cargo.toml | 32 +++++++++++++ .../src}/bandit_arm.rs | 34 +++++++------- .../src}/bin/expandconfig.rs | 4 +- .../src}/bin/parse_event_log.rs | 3 +- .../src}/choice.rs | 40 ++-------------- .../src}/config.rs | 4 +- .../src}/eventlog.rs | 0 .../src}/impact.rs | 0 .../mod.rs => telamon-explorer/src/lib.rs | 9 ++-- .../src}/local_selection.rs | 13 ++++-- .../src}/logger.rs | 5 +- .../explorer => telamon-explorer/src}/mcts.rs | 14 +++--- .../src}/monitor.rs | 19 ++++---- .../src}/offline_analysis/mod.rs | 0 .../src}/offline_analysis/tree.rs | 8 ++-- .../src}/parallel_list.rs | 22 ++++----- .../src}/store.rs | 6 +-- telamon-gen/src/print/template/store.rs | 11 +++++ 38 files changed, 201 insertions(+), 157 deletions(-) rename src/{explorer => search_space}/candidate.rs (77%) create mode 100644 telamon-explorer/Cargo.toml rename {src/explorer => telamon-explorer/src}/bandit_arm.rs (98%) rename {src => telamon-explorer/src}/bin/expandconfig.rs (96%) rename {src => telamon-explorer/src}/bin/parse_event_log.rs (98%) rename {src/explorer => telamon-explorer/src}/choice.rs (89%) rename {src/explorer => telamon-explorer/src}/config.rs (99%) rename {src/explorer => telamon-explorer/src}/eventlog.rs (100%) rename {src/explorer => telamon-explorer/src}/impact.rs (100%) rename src/explorer/mod.rs => telamon-explorer/src/lib.rs (98%) rename {src/explorer => telamon-explorer/src}/local_selection.rs (98%) rename {src/explorer => telamon-explorer/src}/logger.rs (97%) rename {src/explorer => telamon-explorer/src}/mcts.rs (99%) rename {src/explorer => telamon-explorer/src}/monitor.rs (97%) rename {src => telamon-explorer/src}/offline_analysis/mod.rs (100%) rename {src => telamon-explorer/src}/offline_analysis/tree.rs (99%) rename {src/explorer => telamon-explorer/src}/parallel_list.rs (94%) rename {src/explorer => telamon-explorer/src}/store.rs (90%) diff --git a/Cargo.toml b/Cargo.toml index 928680bf5..4c7aac974 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,12 +8,6 @@ edition = "2018" readme = "README.md" repository = "https://github.com/ulysseB/telamon/" -[[bin]] -name = "expandconfig" - -[[bin]] -name = "parse_event_log" - [[bench]] name = "descent" harness = false @@ -72,7 +66,6 @@ structopt = "0.2" bincode = "1.0" std-semaphore = "0.1.0" tempfile = "3.0.1" -toml = "0.4" flate2 = "1.0.2" dot = "0.1" csv = "1" @@ -106,4 +99,5 @@ members = [ "telamon-utils", "telamon-gen/cc_tests", "telamon-capi", + "telamon-explorer", ] diff --git a/backend/cuda/src/characterize/gen.rs b/backend/cuda/src/characterize/gen.rs index bbb038144..221d0e586 100644 --- a/backend/cuda/src/characterize/gen.rs +++ b/backend/cuda/src/characterize/gen.rs @@ -4,9 +4,9 @@ use crate::{Context, Gpu, Kernel, PerfCounterSet}; use itertools::Itertools; use log::*; use num::Zero; + use telamon::codegen; use telamon::device::{ArgMapExt, Device, ScalarArgument}; -use telamon::explorer; use telamon::helper::tensor::DimSize; use telamon::helper::{AutoOperand, Builder, Reduce}; use telamon::ir::{self, Signature}; @@ -498,9 +498,6 @@ pub fn run( result_prefix: &[u64], result: &mut Table, ) { - if let Some(choice) = explorer::choice::default_list(space).next() { - panic!("The benchmark is not completely scheduled: {:?}", choice); - } let dev_fun = codegen::Function::build(space); let kernel = Kernel::compile(&dev_fun, context.gpu(), context.executor(), 1); for &(arg, range) in args_range { diff --git a/backend/cuda/src/context.rs b/backend/cuda/src/context.rs index e0843ff67..ec0dc3017 100644 --- a/backend/cuda/src/context.rs +++ b/backend/cuda/src/context.rs @@ -8,7 +8,7 @@ use log::{debug, info}; use std::f64; use std::sync::{atomic, mpsc, Arc}; use telamon::device::{self, AsyncCallback, Device, EvalMode, ScalarArgument}; -use telamon::{codegen, explorer, ir}; +use telamon::{codegen, ir, search_space::Candidate}; use utils::*; /// Max number of candidates waiting to be evaluated. @@ -225,7 +225,7 @@ impl<'a> device::Context for Context<'a> { } } -type AsyncPayload<'a, 'b> = (explorer::Candidate<'a>, Thunk<'b>, AsyncCallback<'a, 'b>); +type AsyncPayload<'a, 'b> = (Candidate<'a>, Thunk<'b>, AsyncCallback<'a, 'b>); pub struct AsyncEvaluator<'a, 'b> where @@ -244,7 +244,7 @@ where { fn add_kernel( &mut self, - candidate: explorer::Candidate<'a>, + candidate: Candidate<'a>, callback: device::AsyncCallback<'a, 'c>, ) { let thunk = { diff --git a/backend/x86/src/context.rs b/backend/x86/src/context.rs index 2c3ffc174..a41ce0fd2 100644 --- a/backend/x86/src/context.rs +++ b/backend/x86/src/context.rs @@ -7,8 +7,8 @@ use telamon::codegen::ParamVal; use telamon::codegen; use telamon::device::{self, AsyncCallback, Device, EvalMode, ScalarArgument}; -use telamon::explorer; use telamon::ir; +use telamon::search_space::Candidate; use crossbeam; use itertools::Itertools; @@ -221,12 +221,7 @@ fn function_evaluate(fun_str: &str, args: &[ThunkArg]) -> Result { Ok(time) } -type AsyncPayload<'a, 'b> = ( - explorer::Candidate<'a>, - String, - Vec, - AsyncCallback<'a, 'b>, -); +type AsyncPayload<'a, 'b> = (Candidate<'a>, String, Vec, AsyncCallback<'a, 'b>); pub struct AsyncEvaluator<'a, 'b> where @@ -243,7 +238,7 @@ where { fn add_kernel( &mut self, - candidate: explorer::Candidate<'a>, + candidate: Candidate<'a>, callback: device::AsyncCallback<'a, 'c>, ) { let (fun_str, code_args); diff --git a/kernels/Cargo.toml b/kernels/Cargo.toml index bfc533a15..d74c21d0d 100644 --- a/kernels/Cargo.toml +++ b/kernels/Cargo.toml @@ -20,6 +20,7 @@ serde = { version = "1.0", features = ["derive"] } cuda-sys = { optional = true, version = "0.1.0" } telamon = { path = "../" } +telamon-explorer = { path = "../telamon-explorer" } telamon-cuda = { path = "../backend/cuda", optional=true } telamon-x86 = { path = "../backend/x86" } utils = { package = "telamon-utils", path = "../telamon-utils" } diff --git a/kernels/benches/cuda_search.rs b/kernels/benches/cuda_search.rs index 007377a85..d6cbe7137 100644 --- a/kernels/benches/cuda_search.rs +++ b/kernels/benches/cuda_search.rs @@ -1,8 +1,8 @@ //! Benchmarks the exploration on CUDA gpus. use cuda_sys::cublas::*; use cuda_sys::cuda::*; -use telamon::explorer::config::Config; use telamon_cuda as cuda; +use telamon_explorer::config::Config; use telamon_kernels::statistics::estimate_mean; use telamon_kernels::{linalg, Kernel}; diff --git a/kernels/benches/cuda_variance.rs b/kernels/benches/cuda_variance.rs index f9c246db6..3a909bc4a 100644 --- a/kernels/benches/cuda_variance.rs +++ b/kernels/benches/cuda_variance.rs @@ -6,9 +6,9 @@ use log::*; use std::sync::Mutex; use std::time::Duration; use telamon::device::Context; -use telamon::explorer::local_selection; -use telamon::{device, explorer, helper}; +use telamon::{device, helper, search_space::Candidate}; use telamon_cuda as cuda; +use telamon_explorer::{config, local_selection}; use telamon_kernels::{linalg, Kernel}; use utils::*; @@ -49,7 +49,7 @@ where let candidates = kernel.build_body(&signature, &context); let candidates = std::iter::repeat(()) .flat_map(|()| { - let order = explorer::config::NewNodeOrder::WeightedRandom; + let order = config::NewNodeOrder::WeightedRandom; let candidate_idx = order.pick_candidate(&candidates, CUT); let candidate = candidates[unwrap!(candidate_idx)].clone(); local_selection::descend(&Default::default(), order, &context, candidate, CUT) @@ -114,7 +114,7 @@ fn analyse_runtimes(mut runtimes: Vec, name: &str, bound: &str) -> (f64, f6 /// Runs a series of evaluation, sleeping the given duration betwen each evaluation. fn run_evaluations( - candidates: &[explorer::Candidate], + candidates: &[Candidate], context: &Context, num_samples: usize, sleep: Option, diff --git a/kernels/src/kernel.rs b/kernels/src/kernel.rs index dd3bcc314..e9161d60a 100644 --- a/kernels/src/kernel.rs +++ b/kernels/src/kernel.rs @@ -13,10 +13,13 @@ use rpds::list::List; use serde::{de::DeserializeOwned, Serialize}; use std::io::{Read, Write}; use std::sync::{atomic, Mutex}; -use telamon::explorer::{self, choice::ActionEx, local_selection, Candidate}; use telamon::helper::SignatureBuilder; use telamon::model::Bound; -use telamon::{codegen, device, ir}; +use telamon::{ + codegen, device, ir, + search_space::{ActionEx, Candidate}, +}; +use telamon_explorer::{self as explorer, local_selection}; use utils::*; /// Ignore candidates with a too big bound in tests. @@ -354,7 +357,7 @@ fn descend_check_bounds<'a>( /// A sample of the accuracy of bounds. pub struct BoundSample { - actions: Vec, + actions: Vec, bound: Bound, runtime: f64, } diff --git a/kernels/src/lib.rs b/kernels/src/lib.rs index 1a09ca056..6c3b6c852 100644 --- a/kernels/src/lib.rs +++ b/kernels/src/lib.rs @@ -9,15 +9,15 @@ pub use crate::kernel::{analyze_bounds, Kernel}; use telamon::device::{self, ArgMap, Context}; use telamon::helper::tensor::DimSize; use telamon::helper::{self, SignatureBuilder}; -use telamon::{explorer, model, search_space}; +use telamon::{model, search_space}; /// Creates a candidate from the search space and registers the tile sizes in it. fn build_candidate<'a>( space: search_space::SearchSpace<'a>, ctx: &device::Context, -) -> explorer::Candidate<'a> { +) -> search_space::Candidate<'a> { let bound = model::bound(&space, ctx); - explorer::Candidate::new(space, bound) + search_space::Candidate::new(space, bound) } /// Creates a `DimSize`. If the instantiate flag is true, it uses a constant size, diff --git a/kernels/src/linalg.rs b/kernels/src/linalg.rs index 9fe3604e7..b4bf1710a 100644 --- a/kernels/src/linalg.rs +++ b/kernels/src/linalg.rs @@ -8,10 +8,10 @@ use ::ndarray::{Array1, Array2, Array3, ArrayD}; use itertools::Itertools; use rand; use serde::{Deserialize, Serialize}; -use telamon::explorer::Candidate; use telamon::helper::tensor::*; use telamon::helper::{self, Builder, SignatureBuilder}; use telamon::ir::DimMapScope::Global as GlobalScope; +use telamon::search_space::Candidate; use telamon::search_space::*; use telamon::{device, ir}; use utils::*; diff --git a/src/codegen/function.rs b/src/codegen/function.rs index 29c12b0f2..bb280a759 100644 --- a/src/codegen/function.rs +++ b/src/codegen/function.rs @@ -30,6 +30,11 @@ pub struct Function<'a> { impl<'a> Function<'a> { /// Creates a device `Function` from an IR instance. pub fn build(space: &'a SearchSpace<'a>) -> Function<'a> { + assert!( + space.is_implementation(), + "impossible to generate code from partial implementations", + ); + let mut dims = dimension::group_merged_dimensions(space); let (induction_vars, init_induction_levels) = dimension::register_induction_vars(&mut dims, space); diff --git a/src/device/context.rs b/src/device/context.rs index 81d19db9a..8b778f044 100644 --- a/src/device/context.rs +++ b/src/device/context.rs @@ -1,8 +1,8 @@ //! Describes the context for which a function must be optimized. use crate::codegen::{self, Function}; use crate::device::{ArrayArgument, Device, ScalarArgument}; -use crate::explorer::Candidate; use crate::ir; +use crate::search_space::Candidate; use boxfnonce::SendBoxFnOnce; use num; use std::sync::Arc; diff --git a/src/device/fake.rs b/src/device/fake.rs index 58c95b7b3..345ae2569 100644 --- a/src/device/fake.rs +++ b/src/device/fake.rs @@ -3,8 +3,8 @@ use std::marker::PhantomData; use std::sync::Arc; use crate::codegen; -use crate::explorer::Candidate; use crate::ir; +use crate::search_space::Candidate; use super::{ ArgMap, ArrayArgument, AsyncCallback, AsyncEvaluator, Context, Device, EvalMode, diff --git a/src/ir/dimension.rs b/src/ir/dimension.rs index 19f08babf..0ec2e094f 100644 --- a/src/ir/dimension.rs +++ b/src/ir/dimension.rs @@ -17,9 +17,9 @@ impl fmt::Debug for DimId { } } -impl Into for DimId { - fn into(self) -> usize { - self.0 as usize +impl From for usize { + fn from(id: DimId) -> Self { + id.0 as usize } } diff --git a/src/ir/function.rs b/src/ir/function.rs index bde46599c..a4d99e936 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -380,7 +380,7 @@ impl<'a, L> Function<'a, L> { } /// Returns the list of layouts to lower. - pub(crate) fn layouts_to_lower(&self) -> &[ir::MemId] { + pub fn layouts_to_lower(&self) -> &[ir::MemId] { &self.layouts_to_lower } diff --git a/src/lib.rs b/src/lib.rs index f1fbf502d..5dbb7c178 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,8 +18,6 @@ pub mod codegen; #[macro_use] pub mod helper; pub mod device; -pub mod explorer; pub mod ir; pub mod model; -pub mod offline_analysis; pub mod search_space; diff --git a/src/explorer/candidate.rs b/src/search_space/candidate.rs similarity index 77% rename from src/explorer/candidate.rs rename to src/search_space/candidate.rs index 304bdcab8..d0d4e28d1 100644 --- a/src/explorer/candidate.rs +++ b/src/search_space/candidate.rs @@ -1,17 +1,47 @@ //! Exploration of the search space. -use crate::device::Context; -use crate::explorer::choice::ActionEx; -use crate::model::{bound, Bound}; -use crate::search_space::SearchSpace; - -use log::{debug, info, trace}; -use rpds::List; -use std; use std::cmp::{Ordering, PartialOrd}; +use std::{self, fmt}; use itertools::Itertools; +use log::{debug, info, trace}; +use rpds::List; +use serde::{Deserialize, Serialize}; use utils::unwrap; +use crate::device::Context; +use crate::ir; +use crate::model::{bound, Bound}; +use crate::search_space::{choices::Action, SearchSpace}; + +/// Either a regular action or a manually applied action. +#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum ActionEx { + Action(Action), + LowerLayout { + mem: ir::MemId, + st_dims: Vec, + ld_dims: Vec, + }, +} + +impl fmt::Debug for ActionEx { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + // Actions are already explicitely self-describing enough + ActionEx::Action(action) => write!(f, "{:?}", action), + ActionEx::LowerLayout { + mem, + st_dims, + ld_dims, + } => write!( + f, + "LowerLayout {{ mem: {:?}, st_dims: {:?}, ld_dims: {:?} }}", + mem, st_dims, ld_dims + ), + } + } +} + /// A node of the search tree. #[derive(Clone)] pub struct Candidate<'a> { diff --git a/src/search_space/mod.rs b/src/search_space/mod.rs index 3fdb15d2e..f9df2f229 100644 --- a/src/search_space/mod.rs +++ b/src/search_space/mod.rs @@ -7,11 +7,13 @@ use crate::device::Context; use crate::ir; use log::debug; +mod candidate; mod dim_map; mod operand; use utils::generated_file; generated_file!(choices); +pub use self::candidate::{ActionEx, Candidate}; pub use self::choices::{ Action, Bool, Choice, DimKind, Domain, DomainStore, InstFlag, MemSpace, NumSet, Order, ThreadMapping, @@ -111,6 +113,11 @@ impl<'a> SearchSpace<'a> { Ok(()) } + + /// Returns whether the candidate is a fully specified implementation. + pub fn is_implementation(&self) -> bool { + self.ir_instance.layouts_to_lower().is_empty() && self.domain.is_constrained() + } } /// Update the domain after a lowering. diff --git a/telamon-capi/src/explorer.rs b/telamon-capi/src/explorer.rs index 1c4228a84..623bb1fb0 100644 --- a/telamon-capi/src/explorer.rs +++ b/telamon-capi/src/explorer.rs @@ -2,7 +2,7 @@ use std; use std::ffi::CStr; use libc::c_char; -use telamon::explorer::{self, Config}; +use telamon_explorer::{self, Config}; use super::error::TelamonStatus; use super::search_space::SearchSpace; diff --git a/telamon-capi/src/lib.rs b/telamon-capi/src/lib.rs index 0983c7e6f..ba3d9af57 100644 --- a/telamon-capi/src/lib.rs +++ b/telamon-capi/src/lib.rs @@ -13,8 +13,8 @@ pub mod search_space; use libc::{c_char, c_int, c_uint, size_t, uint32_t}; use telamon::device; -use telamon::explorer::config::Config; use telamon::helper::TilingPattern; +use telamon_explorer::config::Config; pub use telamon_kernels::{linalg, Kernel}; use telamon_x86 as x86; diff --git a/telamon-explorer/Cargo.toml b/telamon-explorer/Cargo.toml new file mode 100644 index 000000000..8628b0689 --- /dev/null +++ b/telamon-explorer/Cargo.toml @@ -0,0 +1,32 @@ +[package] +authors = ["Ulysse Beaugnon ", "Nicolas Tollenaere ", "Basile Clement "] +name = "telamon-explorer" +version = "1.0.0" +edition = "2018" + +[dependencies] +bincode = "1.0" +boxfnonce = "0.1.0" +config = "0.8.0" +crossbeam = "0.3.2" +csv = "1" +dot = "0.1" +failure = "0.1.1" +flate2 = "1.0.2" +futures-preview = "0.2" +getopts = "0.2.17" +interval-heap = "0.0.5" +itertools = "0.7.8" +log = "0.4.1" +num_cpus = "1.8.0" +rand = "0.5.5" +rpds = { version = "0.5.0", features = ["serde"] } +serde = { version = "1.0", features = ["derive"] } +serde_yaml = "0.8" +structopt = "0.2" +telamon = {path = "../"} +tokio-timer = { git = "https://github.com/ulysseB/tokio-timer.git" } +toml = "0.4" +utils = {package = "telamon-utils", path = "../telamon-utils"} + +[dev-dependencies] diff --git a/src/explorer/bandit_arm.rs b/telamon-explorer/src/bandit_arm.rs similarity index 98% rename from src/explorer/bandit_arm.rs rename to telamon-explorer/src/bandit_arm.rs index cb45e98ae..93b78d679 100644 --- a/src/explorer/bandit_arm.rs +++ b/telamon-explorer/src/bandit_arm.rs @@ -1,10 +1,4 @@ ///! Exploration of the search space. -use crate::device::Context; -use crate::explorer::candidate::Candidate; -use crate::explorer::config::{self, BanditConfig, NewNodeOrder}; -use crate::explorer::logger::LogMessage; -use crate::explorer::store::Store; -use crate::explorer::{choice, local_selection}; use log::{debug, info, trace, warn}; use rpds::List; use serde::{Deserialize, Serialize}; @@ -14,6 +8,13 @@ use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::{Arc, RwLock, Weak}; use utils::*; +use crate::config::{self, BanditConfig, NewNodeOrder}; +use crate::logger::LogMessage; +use crate::store::Store; +use crate::{choice, local_selection}; +use telamon::device::Context; +use telamon::search_space::{ActionEx, Candidate}; + /// An environment in which candidates can be refined. pub struct Env<'a> { config: &'a BanditConfig, @@ -25,10 +26,7 @@ impl<'a> Env<'a> { /// List the available actions for a given candidate. /// /// If `list_actions` return `None`, the candidate is a fully-specified implementation. - pub fn list_actions( - &self, - candidate: &Candidate<'_>, - ) -> Option> { + pub fn list_actions(&self, candidate: &Candidate<'_>) -> Option> { choice::list(&self.config.choice_ordering, &candidate.space).next() } @@ -41,7 +39,7 @@ impl<'a> Env<'a> { pub fn apply_choice<'c>( &self, candidate: &Candidate<'c>, - actions: Vec, + actions: Vec, ) -> Vec> { candidate .apply_choice(self.context, actions) @@ -88,12 +86,12 @@ pub enum DeadEndSource { /// Dead-end encountered in the tree Tree { /// List of actions defining the dead-end candidate - actions: List, + actions: List, }, /// Dead-end encountered in the rollout phase Rollout { /// List of actions defining the dead-end candidate - actions: List, + actions: List, /// Depth in the tree. The remaining actions were selected during rollout. depth: usize, /// Performance model bound @@ -109,14 +107,14 @@ pub enum DeadEndSource { #[derive(Serialize, Deserialize)] pub enum TreeEvent { Evaluation { - actions: List, + actions: List, score: f64, }, /// A fully-specified implementation was found and evaluated EvaluationV2 { /// List of actions defining the implementation - actions: List, + actions: List, /// Depth in the tree. The remaining actions were selected during rollout. depth: usize, /// Execution time @@ -304,7 +302,7 @@ where fn commit_evaluation( &self, - actions: &List, + actions: &List, mut info: Self::PayLoad, eval: f64, ) { @@ -498,7 +496,7 @@ struct Edge<'a, E> { bound: RwLock, /// The action associated with this edge - action: Option, + action: Option, } impl<'a, E: Default> Edge<'a, E> { @@ -611,7 +609,7 @@ pub struct Node<'a, E> { impl<'a, E: Default> Node<'a, E> { /// Creates a new children containing the given candidates, if any. fn try_from_candidates( - candidates: Vec<(Option, Candidate<'a>)>, + candidates: Vec<(Option, Candidate<'a>)>, ) -> Option> { if candidates.is_empty() { None diff --git a/src/bin/expandconfig.rs b/telamon-explorer/src/bin/expandconfig.rs similarity index 96% rename from src/bin/expandconfig.rs rename to telamon-explorer/src/bin/expandconfig.rs index 191775e72..f0cf43103 100644 --- a/src/bin/expandconfig.rs +++ b/telamon-explorer/src/bin/expandconfig.rs @@ -58,7 +58,7 @@ impl Opt { } /// Parse the existing configuration - fn parse_config(&self) -> io::Result { + fn parse_config(&self) -> io::Result { let input_str = match self.open_input()? { Some(mut input) => { let mut input_str = String::new(); @@ -77,7 +77,7 @@ impl Opt { } /// Dump a configuration in the requested format - fn dump_config(&self, config: &telamon::explorer::config::Config) -> io::Result<()> { + fn dump_config(&self, config: &telamon_explorer::config::Config) -> io::Result<()> { let output_str = match self.format { Format::Toml => toml::to_string(config).map_err(|err| { io::Error::new( diff --git a/src/bin/parse_event_log.rs b/telamon-explorer/src/bin/parse_event_log.rs similarity index 98% rename from src/bin/parse_event_log.rs rename to telamon-explorer/src/bin/parse_event_log.rs index 9b070a395..f946813a7 100644 --- a/src/bin/parse_event_log.rs +++ b/telamon-explorer/src/bin/parse_event_log.rs @@ -5,7 +5,8 @@ use std::collections::HashMap; use std::fs::File; use std::io; use std::path::PathBuf; -use telamon::explorer::{bandit_arm::TreeEvent, choice::ActionEx, eventlog::EventLog}; +use telamon::search_space::ActionEx; +use telamon_explorer::{bandit_arm::TreeEvent, eventlog::EventLog}; use structopt::StructOpt; diff --git a/src/explorer/choice.rs b/telamon-explorer/src/choice.rs similarity index 89% rename from src/explorer/choice.rs rename to telamon-explorer/src/choice.rs index ccfba5f8d..001cf897b 100644 --- a/src/explorer/choice.rs +++ b/telamon-explorer/src/choice.rs @@ -1,42 +1,12 @@ //! Choices that can be applied to split the search space. -use std::fmt; - -use crate::explorer::config; -use crate::ir::{self, Statement}; -use crate::search_space::{Action, Domain, NumSet, Order, SearchSpace}; use itertools::Itertools; use log::trace; -use serde::{Deserialize, Serialize}; -use utils::unwrap; -/// Either a regular action or a manually applied action. -#[derive(Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub enum ActionEx { - Action(Action), - LowerLayout { - mem: ir::MemId, - st_dims: Vec, - ld_dims: Vec, - }, -} +use telamon::ir::{self, Statement}; +use telamon::search_space::{Action, ActionEx, Domain, NumSet, Order, SearchSpace}; +use utils::unwrap; -impl fmt::Debug for ActionEx { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self { - // Actions are already explicitely self-describing enough - ActionEx::Action(action) => write!(f, "{:?}", action), - ActionEx::LowerLayout { - mem, - st_dims, - ld_dims, - } => write!( - f, - "LowerLayout {{ mem: {:?}, st_dims: {:?}, ld_dims: {:?} }}", - mem, st_dims, ld_dims - ), - } - } -} +use crate::config; /// Represents a choice that splits a search space in multiple ones. // TODO(search_space): explore and lower loayouts directly from the regular actions. @@ -97,7 +67,7 @@ pub fn list<'a>( iter_choice: impl IntoIterator + 'a, space: &'a SearchSpace<'a>, ) -> impl Iterator + 'a { - use crate::explorer::config::ChoiceGroup::*; + use crate::config::ChoiceGroup::*; NestedIterator::new(iter_choice.into_iter().map( move |choice_grp| -> Box + 'a> { diff --git a/src/explorer/config.rs b/telamon-explorer/src/config.rs similarity index 99% rename from src/explorer/config.rs rename to telamon-explorer/src/config.rs index 5a63eecfd..484bd3414 100644 --- a/src/explorer/config.rs +++ b/telamon-explorer/src/config.rs @@ -2,8 +2,6 @@ //! is read from the `Setting.toml` file if it exists. Some parameters can be overridden //! from the command line. -extern crate toml; - use std::fs::File; use std::io::{self, BufWriter, Write}; use std::path::{Path, PathBuf}; @@ -16,7 +14,7 @@ use num_cpus; use serde::{Deserialize, Serialize}; use utils::{tfrecord, unwrap}; -use crate::explorer::eventlog::EventLog; +use crate::eventlog::EventLog; /// Stores the configuration of the exploration. #[derive(Clone, Serialize, Deserialize)] diff --git a/src/explorer/eventlog.rs b/telamon-explorer/src/eventlog.rs similarity index 100% rename from src/explorer/eventlog.rs rename to telamon-explorer/src/eventlog.rs diff --git a/src/explorer/impact.rs b/telamon-explorer/src/impact.rs similarity index 100% rename from src/explorer/impact.rs rename to telamon-explorer/src/impact.rs diff --git a/src/explorer/mod.rs b/telamon-explorer/src/lib.rs similarity index 98% rename from src/explorer/mod.rs rename to telamon-explorer/src/lib.rs index e5b0fe4a1..63a777a35 100644 --- a/src/explorer/mod.rs +++ b/telamon-explorer/src/lib.rs @@ -1,5 +1,4 @@ //! exploration of the search space. -mod candidate; mod logger; mod monitor; mod parallel_list; @@ -11,8 +10,8 @@ pub mod config; pub mod eventlog; pub mod local_selection; pub mod mcts; +pub mod offline_analysis; -pub use self::candidate::Candidate; pub use self::config::{BanditConfig, Config, SearchAlgorithm}; pub use self::logger::LogMessage; @@ -21,9 +20,9 @@ use self::monitor::{monitor, MonitorMessage}; use self::parallel_list::ParallelCandidateList; use self::store::Store; -use crate::device::{Context, EvalMode}; -use crate::model::bound; -use crate::search_space::SearchSpace; +use telamon::device::{Context, EvalMode}; +use telamon::model::bound; +use telamon::search_space::{Candidate, SearchSpace}; use boxfnonce::SendBoxFnOnce; use crossbeam; diff --git a/src/explorer/local_selection.rs b/telamon-explorer/src/local_selection.rs similarity index 98% rename from src/explorer/local_selection.rs rename to telamon-explorer/src/local_selection.rs index 957f4737d..454e98c9e 100644 --- a/src/explorer/local_selection.rs +++ b/telamon-explorer/src/local_selection.rs @@ -1,13 +1,16 @@ //! Provides different methods to select a candidate in a list. -use crate::device::Context; -use crate::explorer::candidate::Candidate; -use crate::explorer::choice; -use crate::explorer::config::{ChoiceOrdering, NewNodeOrder}; +use std; + use rand::distributions::{Weighted, WeightedChoice}; use rand::prelude::*; -use std; + +use telamon::device::Context; +use telamon::search_space::Candidate; use utils::*; +use crate::choice; +use crate::config::{ChoiceOrdering, NewNodeOrder}; + /// A random rollout configuration pub struct Rollout<'a> { /// The order in which choices should be considered during the rollout diff --git a/src/explorer/logger.rs b/telamon-explorer/src/logger.rs similarity index 97% rename from src/explorer/logger.rs rename to telamon-explorer/src/logger.rs index bbab4077d..4245d70b2 100644 --- a/src/explorer/logger.rs +++ b/telamon-explorer/src/logger.rs @@ -3,12 +3,13 @@ use std::io::{self, BufWriter, Write}; use std::sync::mpsc; use std::time::Duration; -use crate::explorer::config::Config; -use crate::explorer::monitor; use bincode; use failure::Fail; use serde::{Deserialize, Serialize}; +use crate::config::Config; +use crate::monitor; + #[derive(Serialize, Deserialize)] pub enum LogMessage { Event(E), diff --git a/src/explorer/mcts.rs b/telamon-explorer/src/mcts.rs similarity index 99% rename from src/explorer/mcts.rs rename to telamon-explorer/src/mcts.rs index def0493b0..6e1bde8b8 100644 --- a/src/explorer/mcts.rs +++ b/telamon-explorer/src/mcts.rs @@ -24,18 +24,18 @@ use rand::distributions::{Weighted, WeightedChoice}; use rand::prelude::*; use rpds::List; use serde::{Deserialize, Serialize}; + +use telamon::device::Context; +use telamon::model::{bound, Bound}; +use telamon::search_space::{ActionEx as Action, Candidate, SearchSpace}; use utils::cmp_f64; -use crate::device::Context; -use crate::explorer::{ - candidate::Candidate, - choice::{self, ActionEx as Action}, +use crate::{ + choice, config::{self, BanditConfig, ChoiceOrdering, NewNodeOrder}, logger::LogMessage, store::Store, }; -use crate::model::{bound, Bound}; -use crate::search_space::SearchSpace; /// Newtype wrapper to represent a node identifier. Node identifiers should be unique inside a /// tree. We use a fixed-size representation for consistency of the serialization format. @@ -1254,7 +1254,7 @@ where fn commit_evaluation( &self, - _actions: &List, + _actions: &List, trace: Self::PayLoad, eval: f64, ) { diff --git a/src/explorer/monitor.rs b/telamon-explorer/src/monitor.rs similarity index 97% rename from src/explorer/monitor.rs rename to telamon-explorer/src/monitor.rs index 99c5f6bc5..991e8606a 100644 --- a/src/explorer/monitor.rs +++ b/telamon-explorer/src/monitor.rs @@ -1,22 +1,25 @@ //! This file exposes a single function, monitor, that is launched in a special //! thread and pulls the evaluations results, store them and then updates the //! Store accordingly. -use crate::device::Context; -use crate::explorer::candidate::Candidate; -use crate::explorer::config::Config; -use crate::explorer::logger::LogMessage; -use crate::explorer::store::Store; +use std; +use std::sync; +use std::time::{Duration, Instant}; + use futures::channel; use futures::executor::block_on; use futures::prelude::*; use log::warn; use serde::{Deserialize, Serialize}; -use std; -use std::sync; -use std::time::{Duration, Instant}; use tokio_timer::*; + +use telamon::device::Context; +use telamon::search_space::Candidate; use utils::unwrap; +use crate::config::Config; +use crate::logger::LogMessage; +use crate::store::Store; + pub type MonitorMessage<'a, T> = (Candidate<'a>, f64, >::PayLoad); /// Indicates why the exploration was terminated. diff --git a/src/offline_analysis/mod.rs b/telamon-explorer/src/offline_analysis/mod.rs similarity index 100% rename from src/offline_analysis/mod.rs rename to telamon-explorer/src/offline_analysis/mod.rs diff --git a/src/offline_analysis/tree.rs b/telamon-explorer/src/offline_analysis/tree.rs similarity index 99% rename from src/offline_analysis/tree.rs rename to telamon-explorer/src/offline_analysis/tree.rs index 236684845..d0c22e806 100644 --- a/src/offline_analysis/tree.rs +++ b/telamon-explorer/src/offline_analysis/tree.rs @@ -1,14 +1,16 @@ ///! Data structures and function that allow for the recreation of a ///! candidate tree from a log file -use crate::explorer::choice::ActionEx as Action; -use crate::explorer::mcts::{EdgeIndex, NodeId}; -use crate::model::Bound; use core::ops::Deref; use std::cell::{Ref, RefCell}; use std::rc::{Rc, Weak}; use std::time::Duration; + +use telamon::model::Bound; +use telamon::search_space::ActionEx as Action; use utils::FnvHashMap; +use crate::mcts::{EdgeIndex, NodeId}; + /// Outgoing Edge to a child annotated with the action for the /// child. If `child` is None, the child node corresponding to the /// action has not been computed or hasn't been added to the tree, diff --git a/src/explorer/parallel_list.rs b/telamon-explorer/src/parallel_list.rs similarity index 94% rename from src/explorer/parallel_list.rs rename to telamon-explorer/src/parallel_list.rs index a2cb6fadb..dd7564061 100644 --- a/src/explorer/parallel_list.rs +++ b/telamon-explorer/src/parallel_list.rs @@ -1,16 +1,18 @@ //! Exploration of the search space. -pub use crate::explorer::candidate::Candidate; +use std; +use std::f64; -use crate::device::Context; -use crate::explorer::choice; -use crate::explorer::store::Store; use interval_heap::IntervalHeap; use log::{info, warn}; use rpds::List; -use std; -use std::f64; +use telamon::device::Context; use utils::unwrap; +use crate::choice; +use crate::store::Store; + +pub use telamon::search_space::{ActionEx, Candidate}; + impl<'a> Store<'a> for ParallelCandidateList<'a> { type PayLoad = (); @@ -20,13 +22,7 @@ impl<'a> Store<'a> for ParallelCandidateList<'a> { self.lock().0.update_cut(new_cut); } - fn commit_evaluation( - &self, - _actions: &List, - (): Self::PayLoad, - _: f64, - ) { - } + fn commit_evaluation(&self, _actions: &List, (): Self::PayLoad, _: f64) {} fn explore(&self, context: &Context) -> Option<(Candidate<'a>, Self::PayLoad)> { loop { diff --git a/src/explorer/store.rs b/telamon-explorer/src/store.rs similarity index 90% rename from src/explorer/store.rs rename to telamon-explorer/src/store.rs index 393e138f4..5c1c1bf47 100644 --- a/src/explorer/store.rs +++ b/telamon-explorer/src/store.rs @@ -1,9 +1,9 @@ -use crate::device::Context; -use crate::explorer::candidate::Candidate; -use crate::explorer::choice::ActionEx; use rpds::List; use serde::Serialize; +use telamon::device::Context; +use telamon::search_space::{ActionEx, Candidate}; + /// A Trait defining a structure containing the candidates, meant to explore the /// search space pub trait Store<'a>: Sync { diff --git a/telamon-gen/src/print/template/store.rs b/telamon-gen/src/print/template/store.rs index fc2e14e29..ae9dbe4d0 100644 --- a/telamon-gen/src/print/template/store.rs +++ b/telamon-gen/src/print/template/store.rs @@ -39,6 +39,17 @@ impl DomainStore { {{/each~}} } + /// Returns `true` when the domain is fully constrained. + #[allow(unused_variables, unused_mut)] + pub fn is_constrained(&self) -> bool { + {{~#if choices~}} + {{#each choices~}} + {{~#unless @first}} && {{/unless~}} + self.{{name}}.iter().all(|(_, value)| value.is_constrained()) + {{~/each}} + {{else}}true{{/if~}} + } + {{#each choices}}{{>getter this}}{{/each}} }