chore: rename executor -> evaluator and integrate into app
This commit is contained in:
parent
de9ca81b65
commit
3c529c3a1a
16 changed files with 229 additions and 115 deletions
|
@ -9,6 +9,7 @@ edition = "2021"
|
|||
clap = { workspace = true, features = [ "derive" ] }
|
||||
image = "0.24"
|
||||
ir = { path = "../ir" }
|
||||
serde = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
pub(crate) struct CpuExecutor;
|
|
@ -1,37 +0,0 @@
|
|||
use ir::instruction::{Filter, Kind};
|
||||
|
||||
use crate::value::Dynamic;
|
||||
mod instructions;
|
||||
|
||||
pub struct Executor;
|
||||
|
||||
impl crate::Executor for Executor {
|
||||
fn execute(instruction: Kind, input: Option<Dynamic>) -> Option<Dynamic> {
|
||||
match instruction {
|
||||
Kind::Read(read_instruction) => {
|
||||
Some(Dynamic::Image(instructions::read::read(read_instruction)))
|
||||
}
|
||||
Kind::Write(write_instruction) => {
|
||||
instructions::write::write(
|
||||
write_instruction,
|
||||
match input {
|
||||
Some(Dynamic::Image(ref img)) => img,
|
||||
_ => panic!("awawwawwa"),
|
||||
},
|
||||
);
|
||||
None
|
||||
}
|
||||
Kind::Math(_) => todo!(),
|
||||
Kind::Blend(_) => todo!(),
|
||||
Kind::Noise(_) => todo!(),
|
||||
Kind::Filter(filter_instruction) => match filter_instruction {
|
||||
Filter::Invert => Some(Dynamic::Image(instructions::filters::invert::invert(
|
||||
match input {
|
||||
Some(Dynamic::Image(img)) => img,
|
||||
_ => panic!("invalid value type for invert"),
|
||||
},
|
||||
))),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
57
crates/eval/src/kind/debug/mod.rs
Normal file
57
crates/eval/src/kind/debug/mod.rs
Normal file
|
@ -0,0 +1,57 @@
|
|||
use std::mem;
|
||||
|
||||
use ir::{
|
||||
instruction::{Filter, Kind},
|
||||
GraphIr, Instruction, InstructionRef,
|
||||
};
|
||||
|
||||
use crate::value::Dynamic;
|
||||
mod instr;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Evaluator {
|
||||
ir: GraphIr,
|
||||
}
|
||||
|
||||
impl crate::Evaluator for Evaluator {
|
||||
fn feed(&mut self, ir: GraphIr) {
|
||||
// TODO: should add instead of replace, see note in Evaluator trait above this method
|
||||
self.ir = ir;
|
||||
}
|
||||
|
||||
fn eval_full(&mut self) {
|
||||
let queue: Vec<Instruction> = self
|
||||
.ir
|
||||
.topological_sort()
|
||||
.into_iter()
|
||||
.map(Into::into)
|
||||
.collect();
|
||||
for instr in queue {
|
||||
self.step(instr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Evaluator {
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
fn step(&mut self, instr: Instruction) {
|
||||
let _ = match instr.kind {
|
||||
Kind::Read(details) => Some(Dynamic::Image(instr::read::read(details))),
|
||||
Kind::Write(details) => {
|
||||
instr::write::write(details, todo!());
|
||||
None
|
||||
}
|
||||
Kind::Math(_) => todo!(),
|
||||
Kind::Blend(_) => todo!(),
|
||||
Kind::Noise(_) => todo!(),
|
||||
Kind::Filter(filter_instruction) => match filter_instruction {
|
||||
Filter::Invert => Some(Dynamic::Image(instr::filters::invert::invert(
|
||||
match todo!() {
|
||||
Some(Dynamic::Image(img)) => img,
|
||||
_ => panic!("invalid value type for invert"),
|
||||
},
|
||||
))),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
1
crates/eval/src/kind/mod.rs
Normal file
1
crates/eval/src/kind/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod debug;
|
|
@ -1,34 +1,43 @@
|
|||
use ir::instruction::Kind;
|
||||
use value::Dynamic;
|
||||
use ir::GraphIr;
|
||||
|
||||
mod debug;
|
||||
mod kind;
|
||||
mod value;
|
||||
|
||||
/// The available executors
|
||||
/// unused in early dev.
|
||||
#[derive(Debug, Clone, Copy, clap::ValueEnum)]
|
||||
pub enum RegisteredExecutor {
|
||||
/// the debug executor is single threaded and really, *really* slow. And unstable. Don't use. Unless you're a dev working on this.
|
||||
/// Can collapse a [`GraphIr`] in meaningful ways and do interesting work on it.
|
||||
///
|
||||
/// It's surprisingly difficult to find a fitting description for this.
|
||||
pub trait Evaluator {
|
||||
/// Take some [`GraphIr`] which will then be processed later.
|
||||
/// May be called multiple times, in which the [`GraphIr`]s should add up.
|
||||
// TODO: atm they definitely don't add up -- add some functionality to GraphIr to
|
||||
// make it combine two graphs into one
|
||||
fn feed(&mut self, ir: GraphIr);
|
||||
|
||||
/// Walk through the _whole_ [`GraphIr`] and run through each instruction.
|
||||
fn eval_full(&mut self);
|
||||
|
||||
// TODO: for an LSP or the like, eval_single which starts at a given instr
|
||||
}
|
||||
|
||||
/// The available [`Evaluator`]s.
|
||||
///
|
||||
/// Checklist for adding new ones:
|
||||
///
|
||||
/// 1. Create a new module under the [`kind`] module.
|
||||
/// 2. Add a struct and implement [`Evaluator`] for it.
|
||||
#[derive(Clone, Copy, Debug, Default, clap::ValueEnum, serde::Deserialize, serde::Serialize)]
|
||||
pub enum Available {
|
||||
/// Runs fully on the CPU. Single-threaded, debug-friendly and quick to implement.
|
||||
#[default]
|
||||
Debug,
|
||||
}
|
||||
|
||||
trait Executor {
|
||||
fn execute(instruction: Kind, input: Option<Dynamic>) -> Option<Dynamic>;
|
||||
}
|
||||
|
||||
pub fn execute_all(instructions: Vec<Kind>) {
|
||||
let mut tmp = None;
|
||||
|
||||
for instruction in instructions {
|
||||
tmp = debug::Executor::execute(instruction, tmp);
|
||||
impl Available {
|
||||
/// Selects the [`Evaluator`] corresponding to this label.
|
||||
#[must_use]
|
||||
pub fn pick(&self) -> Box<dyn Evaluator> {
|
||||
match self {
|
||||
Self::Debug => Box::new(kind::debug::Evaluator::default()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// scratchpad lol:
|
||||
// execution structure:
|
||||
// 1. take in rpl
|
||||
// 2. analyse/validate structure against allowed executors
|
||||
// 3. assign executors to instructions
|
||||
// 4. optimize
|
||||
// 5. prepare memory management patterns
|
||||
// 6. run
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue