Skip to content

Commit

Permalink
made sure that exploration also has strict messages
Browse files Browse the repository at this point in the history
  • Loading branch information
Rojods committed Aug 10, 2023
1 parent bb912bf commit 8e335d4
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 70 deletions.
40 changes: 37 additions & 3 deletions rust-blueprints/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
pub mod macros;

use std::{
collections::HashSet,
collections::{HashMap, HashSet},
path::{Path, PathBuf},
sync::Arc,
};

use clap::Parser;
use idesyde_core::{
headers::{load_decision_model_headers_from_binary, DecisionModelHeader, ExplorationBid},
DecisionModel, DesignModel, ExplorationModule, Explorer, IdentificationModule,
MarkedIdentificationRule, ReverseIdentificationRule,
DecisionModel, DesignModel, ExplorationModule, ExplorationSolution, Explorer,
IdentificationModule, MarkedIdentificationRule, ReverseIdentificationRule,
};
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -65,6 +65,18 @@ impl DecisionModelMessage {
}
}

#[derive(Clone, PartialEq, Serialize, Deserialize)]
pub struct ExplorationSolutionMessage {
pub objectives: HashMap<String, f64>,
pub solved: DecisionModelMessage,
}

impl ExplorationSolutionMessage {
pub fn from_json_str(s: &str) -> Option<ExplorationSolutionMessage> {
serde_json::from_str(s).ok()
}
}

pub struct StandaloneExplorationModule {
unique_identifier: String,
explorers: Vec<Box<dyn Explorer>>,
Expand Down Expand Up @@ -102,6 +114,28 @@ impl ExplorationModule for StandaloneExplorationModule {
})
.unwrap_or(Box::new(std::iter::empty::<Arc<dyn DecisionModel>>()))
}

fn iter_explore(
&self,
m: Arc<dyn DecisionModel>,
explorer_id: &str,
currrent_solutions: Vec<idesyde_core::ExplorationSolution>,
exploration_configuration: idesyde_core::ExplorationConfiguration,
solution_iter: fn(ExplorationSolution) -> (),
) -> Vec<idesyde_core::ExplorationSolution> {
self.explorers
.iter()
.find(|e| e.unique_identifier() == explorer_id)
.map(|e| {
e.iter_explore(
m,
currrent_solutions,
solution_iter,
exploration_configuration,
)
})
.unwrap_or(vec![])
}
}

pub struct StandaloneIdentificationModule {
Expand Down
58 changes: 57 additions & 1 deletion rust-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pub mod headers;
pub mod macros;

use std::{hash::Hash, path::Path, sync::Arc};
use std::{collections::HashMap, hash::Hash, path::Path, sync::Arc};

use downcast_rs::{impl_downcast, Downcast, DowncastSync};
use headers::{DecisionModelHeader, DesignModelHeader, ExplorationBid};
Expand Down Expand Up @@ -160,6 +160,28 @@ impl Hash for dyn IdentificationModule {
self.unique_identifier().hash(state);
}
}

#[derive(Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct ExplorationConfiguration {
pub max_sols: u64,
pub total_timeout: u64,
pub time_resolution: u64,
pub memory_resolution: u64,
}

impl ExplorationConfiguration {
pub fn default() -> ExplorationConfiguration {
ExplorationConfiguration {
max_sols: 0,
total_timeout: 0,
time_resolution: 0,
memory_resolution: 0,
}
}
}

pub type ExplorationSolution = (Arc<dyn DecisionModel>, HashMap<String, f64>);

/// This trait is the root for all possible explorers within IDeSyDe. A real explorer should
/// implement this trait by dispatching the real exploration from 'explore'.
///
Expand Down Expand Up @@ -191,6 +213,13 @@ pub trait Explorer: Downcast + Send + Sync {
time_resolution: i64,
memory_resolution: i64,
) -> Box<dyn Iterator<Item = Arc<dyn DecisionModel>>>;
fn iter_explore(
&self,
m: Arc<dyn DecisionModel>,
currrent_solutions: Vec<ExplorationSolution>,
solution_iter: fn(ExplorationSolution) -> (),
exploration_configuration: ExplorationConfiguration,
) -> Vec<ExplorationSolution>;
}
impl_downcast!(Explorer);

Expand Down Expand Up @@ -233,6 +262,33 @@ pub trait ExplorationModule: Send + Sync {
None => Box::new(std::iter::empty()),
}
}
fn iter_explore(
&self,
m: Arc<dyn DecisionModel>,
explorer_id: &str,
currrent_solutions: Vec<ExplorationSolution>,
exploration_configuration: ExplorationConfiguration,
solution_iter: fn(ExplorationSolution) -> (),
) -> Vec<ExplorationSolution>;
fn iter_explore_best(
&self,
m: Arc<dyn DecisionModel>,
currrent_solutions: Vec<ExplorationSolution>,
exploration_configuration: ExplorationConfiguration,
solution_iter: fn(ExplorationSolution) -> (),
) -> Vec<ExplorationSolution> {
let bids = self.bid(m.clone());
match compute_dominant_biddings(bids.iter()) {
Some((_, bid)) => self.iter_explore(
m,
bid.explorer_unique_identifier.as_str(),
currrent_solutions,
exploration_configuration,
solution_iter,
),
None => vec![],
}
}
}

impl PartialEq<dyn ExplorationModule> for dyn ExplorationModule {
Expand Down
120 changes: 87 additions & 33 deletions rust-orchestration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ use std::sync::Arc;
use std::sync::Mutex;

use idesyde_blueprints::DecisionModelMessage;
use idesyde_blueprints::ExplorationSolutionMessage;
use idesyde_core::headers::load_decision_model_header_from_path;
use idesyde_core::headers::load_decision_model_headers_from_binary;
use idesyde_core::ExplorationSolution;

use idesyde_core::headers::DecisionModelHeader;
use idesyde_core::headers::DesignModelHeader;
Expand Down Expand Up @@ -485,6 +487,17 @@ impl ExplorationModule for ExternalExplorationModule {
.map(|m| Arc::new(m) as Arc<dyn DecisionModel>),
)
}

fn iter_explore(
&self,
m: Arc<dyn DecisionModel>,
explorer_id: &str,
currrent_solutions: Vec<ExplorationSolution>,
exploration_configuration: idesyde_core::ExplorationConfiguration,
solution_iter: fn(ExplorationSolution) -> (),
) -> Vec<ExplorationSolution> {
vec![]
}
}

pub struct ExternalServerExplorationModule {
Expand Down Expand Up @@ -609,19 +622,6 @@ impl ExplorationModule for ExternalServerExplorationModule {
.collect()
})
.unwrap_or(Vec::new());
// return std::iter::repeat_with(|| self.read_line_from_output())
// .flatten()
// .map(|line| {
// if line.starts_with("RESULT") {
// return ExplorationBid::from_json_str(&line[6..].trim());
// } else if line.eq_ignore_ascii_case("FINISHED") {
// return None;
// }
// None
// })
// .take_while(|x| x.is_some())
// .flatten()
// .collect();
}
Vec::new()
}
Expand Down Expand Up @@ -676,28 +676,82 @@ impl ExplorationModule for ExternalServerExplorationModule {
.collect()
})
.unwrap_or(Vec::new());
// let explored: Vec<Arc<dyn DecisionModel>> =
// std::iter::repeat_with(|| self.read_line_from_output())
// .flatten()
// .map(|line| {
// if line.contains("RESULT") {
// let mut payload = line[6..].trim().split(" ");
// let _objs_ = payload.next();
// return payload
// .next()
// .and_then(|m_str| DecisionModelMessage::from_json_str(m_str.trim()))
// .map(|x| OpaqueDecisionModel::from_decision_message(&x))
// .map(|m| Arc::new(m) as Arc<dyn DecisionModel>);
// } else if line.contains("FINISHED") {
// return None;
// }
// None
// })
// .take_while(|x| x.is_some())
// .flatten()
// .collect();
Box::new(explored.into_iter())
}

fn iter_explore(
&self,
m: Arc<dyn DecisionModel>,
explorer_id: &str,
currrent_solutions: Vec<idesyde_core::ExplorationSolution>,
exploration_configuration: idesyde_core::ExplorationConfiguration,
solution_iter: fn(ExplorationSolution) -> (),
) -> Vec<idesyde_core::ExplorationSolution> {
self.write_line_to_input(
format!("SET identified-path {}", self.identified_path.display()).as_str(),
);
self.write_line_to_input(
format!("SET solved-path {}", self.solved_path.display()).as_str(),
);
self.write_line_to_input(
format!("SET max-sols {}", exploration_configuration.max_sols).as_str(),
);
self.write_line_to_input(
format!(
"SET total-timeout {}",
exploration_configuration.total_timeout
)
.as_str(),
);
self.write_line_to_input(
format!(
"SET time-resolution {}",
exploration_configuration.time_resolution
)
.as_str(),
);
self.write_line_to_input(
format!(
"SET memory-resolution {}",
exploration_configuration.memory_resolution
)
.as_str(),
);
self.write_line_to_input(
format!(
"EXPLORE {} {}",
explorer_id,
DecisionModelMessage::from_dyn_decision_model(m.as_ref()).to_json_str()
)
.as_str(),
);
self.map_output(|buf| {
buf.lines()
.flatten()
.map(|line| {
if line.contains("RESULT") {
let payload = line[6..].trim();
if let Some(message) = ExplorationSolutionMessage::from_json_str(payload) {
let solution = (
Arc::new(OpaqueDecisionModel::from_decision_message(
&message.solved,
)) as Arc<dyn DecisionModel>,
message.objectives.to_owned(),
);
solution_iter(solution.clone());
return Some(solution);
}
} else if line.contains("FINISHED") {
return None;
}
None
})
.take_while(|x| x.is_some())
.flatten()
.collect()
})
.unwrap_or(Vec::new())
}
}

pub fn find_identification_modules(
Expand Down
44 changes: 24 additions & 20 deletions rust-orchestration/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use idesyde_core::{
load_decision_model_headers_from_binary, load_design_model_headers_from_binary,
DesignModelHeader, ExplorationBid,
},
DecisionModel, DesignModel, ExplorationModule, IdentificationModule,
DecisionModel, DesignModel, ExplorationConfiguration, ExplorationModule, IdentificationModule,
};
use idesyde_orchestration::OpaqueDecisionModel;
use log::{debug, error, info, warn, Level};
Expand Down Expand Up @@ -56,26 +56,26 @@ struct Args {
help = "Sets the desired maximum number of solutions. \nIf non-positive, there is no litmit",
long_help = "Sets the desired maximum number of solutions. \nIf non-positive, there is no litmit. \nThe identification and integration stages are unnafected."
)]
x_max_solutions: Option<i64>,
x_max_solutions: Option<u64>,

#[arg(
long,
help = "Sets the _total exploration_ time-out in seconds. \nIf non-positive, there is no time-out.",
long_help = "Sets the _total exploration_ time-out in seconds. \nIf non-positive, there is no time-out. \nThe identification and integration stages are unnafected."
)]
x_total_time_out: Option<i64>,
x_total_time_out: Option<u64>,

#[arg(
long,
help = "For explorer with mandatory discretization, this factor is used for the time upsizing resolution."
)]
x_time_resolution: Option<i64>,
x_time_resolution: Option<u64>,

#[arg(
long,
help = "For explorer with mandatory discretization, this factor is used for the memory downsizing resolution."
)]
x_memory_resolution: Option<i64>,
x_memory_resolution: Option<u64>,
}

fn main() {
Expand Down Expand Up @@ -360,29 +360,33 @@ fn main() {
}
// let (mut tx, rx) = spmc::channel();
let (chosen_exploration_module, chosen_decision_model, _) = &biddings[idx];
let sols_found: Vec<Arc<dyn DecisionModel>> = chosen_exploration_module
.explore(
chosen_decision_model.clone(),
&dominant_bid.explorer_unique_identifier,
args.x_max_solutions.unwrap_or(0),
args.x_total_time_out.unwrap_or(0),
args.x_time_resolution.unwrap_or(-1),
args.x_memory_resolution.unwrap_or(-1),
)
.enumerate()
// .par_bridge()
.inspect(|(i, _)| debug!("Found a new solution. Total count is {}", i + 1))
.map(|(_, sol)| sol)
.collect();
let sols_found = chosen_exploration_module.iter_explore(
chosen_decision_model.clone(),
&dominant_bid.explorer_unique_identifier,
vec![],
ExplorationConfiguration {
max_sols: args.x_max_solutions.unwrap_or(0),
total_timeout: args.x_total_time_out.unwrap_or(0),
time_resolution: args.x_time_resolution.unwrap_or(0),
memory_resolution: args.x_memory_resolution.unwrap_or(0),
},
|_| {
debug!("Found a new solution.");
},
);
info!("Finished exploration with {} solution(s)", sols_found.len());
let solved_models: Vec<Arc<dyn DecisionModel>> =
sols_found.iter().map(|(x, _)| x.clone()).collect();
if !sols_found.is_empty() {
info!("Starting integration");
let total_reversed: usize = imodules
.par_iter()
.enumerate()
.map(|(_, imodule)| {
let mut n_reversed = 0;
for reverse in imodule.reverse_identification(&sols_found, &design_models) {
for reverse in
imodule.reverse_identification(&solved_models, &design_models)
{
let reverse_header = reverse.header();
reverse_header.write_to_dir(
&reverse_path,
Expand Down
Loading

0 comments on commit 8e335d4

Please sign in to comment.