-
Couldn't load subscription status.
- Fork 60
[fud2] Json Parser for Serialized Plans #2564
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
629aad0
fe8940d
7204d27
a5cdb02
9dfef18
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| use cranelift_entity::PrimaryMap; | ||
| use std::{collections::HashMap, ops}; | ||
|
|
||
| use crate::{ | ||
| exec::{IO, OpRef, Operation}, | ||
| flang::ast::{ | ||
| Assignment, AssignmentList, Op, Visitable, Visitor, VisitorResult, | ||
| }, | ||
| }; | ||
|
|
||
| pub fn steps_to_ast( | ||
| plan: &Vec<(OpRef, Vec<IO>, Vec<IO>)>, | ||
| ops: &PrimaryMap<OpRef, Operation>, | ||
| ) -> AssignmentList { | ||
| let mut ast = AssignmentList { assigns: vec![] }; | ||
| for step in plan { | ||
| let vars = step | ||
| .1 | ||
| .iter() | ||
| .map(|v| match v { | ||
| IO::StdIO(utf8_path_buf) => utf8_path_buf, | ||
| IO::File(utf8_path_buf) => utf8_path_buf, | ||
| }) | ||
| .cloned() | ||
| .collect(); | ||
| let args = step | ||
| .2 | ||
| .iter() | ||
| .map(|v| match v { | ||
| IO::StdIO(utf8_path_buf) => utf8_path_buf, | ||
| IO::File(utf8_path_buf) => utf8_path_buf, | ||
| }) | ||
| .cloned() | ||
| .collect(); | ||
|
|
||
| let fun = Op { | ||
| name: ops[step.0].name.clone(), | ||
| args, | ||
| }; | ||
|
|
||
| let assignment = Assignment { vars, value: fun }; | ||
| ast.assigns.push(assignment); | ||
| } | ||
|
|
||
| ast | ||
| } | ||
|
|
||
| /// A struct to convert a flang AST into the steps of a `Plan`. | ||
| struct ASTToStepList { | ||
| step_list: Vec<(OpRef, Vec<IO>, Vec<IO>)>, | ||
| name_to_op_ref: HashMap<String, OpRef>, | ||
| } | ||
|
|
||
| impl ASTToStepList { | ||
| fn from_ops(ops: &PrimaryMap<OpRef, Operation>) -> Self { | ||
| let name_to_op_ref = | ||
| ops.iter().map(|(k, v)| (v.name.clone(), k)).collect(); | ||
| ASTToStepList { | ||
| step_list: vec![], | ||
| name_to_op_ref, | ||
| } | ||
| } | ||
|
|
||
| fn step_list_from_ast( | ||
| &mut self, | ||
| ast: &AssignmentList, | ||
| ) -> Vec<(OpRef, Vec<IO>, Vec<IO>)> { | ||
| self.step_list = vec![]; | ||
| let _ = ast.visit(self); | ||
| self.step_list.clone() | ||
| } | ||
| } | ||
|
|
||
| impl Visitor for ASTToStepList { | ||
| type Result = ops::ControlFlow<()>; | ||
|
|
||
| fn visit_assignment(&mut self, a: &Assignment) -> Self::Result { | ||
| let vars = a.vars.iter().map(|s| IO::File(s.clone())).collect(); | ||
| let args = a.value.args.iter().map(|s| IO::File(s.clone())).collect(); | ||
| let op_ref = self.name_to_op_ref[&a.value.name]; | ||
|
|
||
| self.step_list.push((op_ref, vars, args)); | ||
| Self::Result::output() | ||
| } | ||
| } | ||
|
|
||
| /// Given a flang AST and a set of ops, returns the steps of a `Plan` which the flang AST | ||
| /// represents. | ||
| pub fn ast_to_steps( | ||
| ast: &AssignmentList, | ||
| ops: &PrimaryMap<OpRef, Operation>, | ||
| ) -> Vec<(OpRef, Vec<IO>, Vec<IO>)> { | ||
| ASTToStepList::from_ops(ops).step_list_from_ast(ast) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,18 @@ | ||
| use super::{OpRef, Operation, Request, Setup, SetupRef, State, StateRef}; | ||
| use crate::{run, script, utils}; | ||
| use super::{ | ||
| OpRef, Operation, Request, Setup, SetupRef, State, StateRef, | ||
| plan::PlannerType, | ||
| }; | ||
| use crate::{ast_converter::ast_to_steps, run, script, utils}; | ||
| use camino::{Utf8Path, Utf8PathBuf}; | ||
| use cranelift_entity::PrimaryMap; | ||
| use rand::distributions::{Alphanumeric, DistString}; | ||
| use std::{collections::HashMap, error::Error, ffi::OsStr, fmt::Display}; | ||
| use std::{ | ||
| collections::HashMap, | ||
| error::Error, | ||
| ffi::OsStr, | ||
| fmt::Display, | ||
| io::{self, Read}, | ||
| }; | ||
|
|
||
| type FileData = HashMap<&'static str, &'static [u8]>; | ||
|
|
||
|
|
@@ -168,6 +177,47 @@ impl Driver { | |
| /// This works by searching for a path through the available operations from the input state | ||
| /// to the output state. If no such path exists in the operation graph, we return None. | ||
| pub fn plan(&self, req: &Request) -> Option<Plan> { | ||
| // Special case if the planner is the one which reads from stdin. | ||
jku20 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| let planner_ty = req.planner.ty(); | ||
| if let PlannerType::FromJson = planner_ty { | ||
| let mut stdin = io::stdin().lock(); | ||
| let mut input = String::new(); | ||
| let res = stdin.read_to_string(&mut input); | ||
| if let Err(e) = res { | ||
| eprintln!("error: {e}"); | ||
| return None; | ||
| } | ||
|
|
||
| let ast = serde_json::from_str(&input); | ||
| match ast { | ||
| Err(e) => { | ||
| eprintln!("error: {e}"); | ||
|
||
| return None; | ||
| } | ||
| Ok(ast) => { | ||
| let steps = ast_to_steps(&ast, &self.ops); | ||
| let results = self.gen_names( | ||
| &req.end_states, | ||
| req, | ||
| false, | ||
| &req.end_states, | ||
| ); | ||
| let inputs = self.gen_names( | ||
| &req.start_states, | ||
| req, | ||
| true, | ||
| &req.start_states, | ||
| ); | ||
| return Some(Plan { | ||
| steps, | ||
| inputs, | ||
| results, | ||
| workdir: req.workdir.clone(), | ||
| }); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Find a plan through the states. | ||
| let path = req.planner.find_plan( | ||
| &req.start_states, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| //! A planner which is predetermined by input from stdin. This always returns `None` for the plan | ||
| //! and must be special cased by the logic later. Currently planners only emit states with file | ||
| //! assignment done later. | ||
jku20 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| use super::{FindPlan, PlannerType}; | ||
|
|
||
| #[derive(Debug)] | ||
| pub struct JsonPlanner {} | ||
|
|
||
| impl FindPlan for JsonPlanner { | ||
| fn find_plan( | ||
| &self, | ||
| _start: &[crate::exec::StateRef], | ||
| _end: &[crate::exec::StateRef], | ||
| _through: &[crate::exec::OpRef], | ||
| _ops: &cranelift_entity::PrimaryMap< | ||
| crate::exec::OpRef, | ||
| crate::exec::Operation, | ||
| >, | ||
| _states: &cranelift_entity::PrimaryMap< | ||
| crate::exec::StateRef, | ||
| crate::exec::State, | ||
| >, | ||
| ) -> Option<Vec<super::Step>> { | ||
| None | ||
| } | ||
|
|
||
| fn ty(&self) -> PlannerType { | ||
| PlannerType::FromJson | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,14 @@ | ||
| #[cfg(feature = "egg_planner")] | ||
| mod egg_planner; | ||
| mod enumerative_planner; | ||
| mod json_planner; | ||
| mod legacy_planner; | ||
| mod planner; | ||
|
|
||
| #[cfg(feature = "egg_planner")] | ||
| pub use egg_planner::EggPlanner; | ||
|
|
||
| pub use enumerative_planner::EnumeratePlanner; | ||
| pub use json_planner::JsonPlanner; | ||
| pub use legacy_planner::LegacyPlanner; | ||
| pub use planner::{FindPlan, Step}; | ||
| pub use planner::{FindPlan, PlannerType, Step}; |
Uh oh!
There was an error while loading. Please reload this page.