mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-07-08 00:05:00 +00:00
Remove type from NodeInput::Network
This commit is contained in:
parent
9eeefaad90
commit
45fd24650a
14 changed files with 53 additions and 54 deletions
|
@ -3421,10 +3421,7 @@ impl NodeNetworkInterface {
|
|||
pub fn create_wire(&mut self, output_connector: &OutputConnector, input_connector: &InputConnector, network_path: &[NodeId]) {
|
||||
let input = match output_connector {
|
||||
OutputConnector::Node { node_id, output_index } => NodeInput::node(*node_id, *output_index),
|
||||
OutputConnector::Import(import_index) => NodeInput::Network {
|
||||
import_type: graph_craft::generic!(T),
|
||||
import_index: *import_index,
|
||||
},
|
||||
OutputConnector::Import(import_index) => NodeInput::Network { import_index: *import_index },
|
||||
};
|
||||
|
||||
self.set_input(input_connector, input, network_path);
|
||||
|
|
|
@ -229,7 +229,7 @@ impl NodeRuntime {
|
|||
// We assume only one output
|
||||
assert_eq!(scoped_network.exports.len(), 1, "Graph with multiple outputs not yet handled");
|
||||
let c = Compiler {};
|
||||
let proto_network = match c.compile_single(scoped_network) {
|
||||
let proto_network = match c.compile_single(scoped_network, &[concrete!(RenderConfig)]) {
|
||||
Ok(network) => network,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
// Number presentation
|
||||
export let displayDecimalPlaces = 2;
|
||||
export let unit = "";
|
||||
$: console.info("new unit", unit);
|
||||
export let unitIsHiddenWhenEditing = true;
|
||||
|
||||
// Mode behavior
|
||||
|
|
|
@ -13,7 +13,8 @@ fn main() {
|
|||
|
||||
let network = add_network();
|
||||
let compiler = graph_craft::graphene_compiler::Compiler {};
|
||||
let proto_network = compiler.compile_single(network).unwrap();
|
||||
let input_types = vec![concrete!(Color), concrete!(Color), concrete!(u32)];
|
||||
let proto_network = compiler.compile_single(network, &input_types).unwrap();
|
||||
|
||||
let io = ShaderIO {
|
||||
inputs: vec![
|
||||
|
@ -25,7 +26,7 @@ fn main() {
|
|||
output: ShaderInput::OutputBuffer((), concrete!(Color)),
|
||||
};
|
||||
|
||||
let compile_request = CompileRequest::new(vec![proto_network], vec![concrete!(Color), concrete!(Color), concrete!(u32)], vec![concrete!(Color)], io);
|
||||
let compile_request = CompileRequest::new(vec![proto_network], input_types, vec![concrete!(Color)], io);
|
||||
let response = client
|
||||
.post("http://localhost:3000/compile/spirv")
|
||||
.timeout(Duration::from_secs(30))
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
use graph_craft::util::DEMO_ART;
|
||||
fn compile_to_proto(c: &mut Criterion) {
|
||||
use graph_craft::util::{compile, load_from_name};
|
||||
use graph_craft::util::{compile_with_render_config, load_from_name};
|
||||
let mut c = c.benchmark_group("Compile Network cold");
|
||||
|
||||
for name in DEMO_ART {
|
||||
let network = load_from_name(name);
|
||||
c.bench_function(name, |b| b.iter_batched(|| network.clone(), |network| compile(black_box(network)), criterion::BatchSize::SmallInput));
|
||||
c.bench_function(name, |b| {
|
||||
b.iter_batched(|| network.clone(), |network| compile_with_render_config(black_box(network)), criterion::BatchSize::SmallInput)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use iai_callgrind::{black_box, library_benchmark, library_benchmark_group, main}
|
|||
#[library_benchmark]
|
||||
#[benches::with_setup(args = ["isometric-fountain", "painted-dreams", "procedural-string-lights", "red-dress", "valley-of-spires"], setup = load_from_name)]
|
||||
pub fn compile_to_proto(_input: NodeNetwork) {
|
||||
black_box(compile(_input));
|
||||
black_box(compile_with_render_config(_input));
|
||||
}
|
||||
|
||||
library_benchmark_group!(name = compile_group; benchmarks = compile_to_proto);
|
||||
|
|
|
@ -286,7 +286,7 @@ impl DocumentNode {
|
|||
}
|
||||
}
|
||||
|
||||
fn resolve_proto_node(mut self) -> ProtoNode {
|
||||
fn resolve_proto_node(mut self, global_import_types: &[Type]) -> ProtoNode {
|
||||
assert!(!self.inputs.is_empty() || self.manual_composition.is_some(), "Resolving document node {self:#?} with no inputs");
|
||||
let DocumentNodeImplementation::ProtoNode(fqn) = self.implementation else {
|
||||
unreachable!("tried to resolve not flattened node on resolved node {self:?}");
|
||||
|
@ -311,7 +311,10 @@ impl DocumentNode {
|
|||
let node = if lambda { ProtoNodeInput::NodeLambda(node_id) } else { ProtoNodeInput::Node(node_id) };
|
||||
(node, ConstructionArgs::Nodes(vec![]))
|
||||
}
|
||||
NodeInput::Network { import_type, .. } => (ProtoNodeInput::ManualComposition(import_type), ConstructionArgs::Nodes(vec![])),
|
||||
NodeInput::Network { import_index } => {
|
||||
let ty = global_import_types.get(import_index).expect("import index in global_import_types").clone();
|
||||
(ProtoNodeInput::ManualComposition(ty), ConstructionArgs::Nodes(vec![]))
|
||||
}
|
||||
NodeInput::Inline(inline) => (ProtoNodeInput::None, ConstructionArgs::Inline(inline)),
|
||||
NodeInput::Scope(_) => unreachable!("Scope input was not resolved"),
|
||||
NodeInput::Reflection(_) => unreachable!("Reflection input was not resolved"),
|
||||
|
@ -355,9 +358,8 @@ pub enum NodeInput {
|
|||
/// A hardcoded value that can't change after the graph is compiled. Gets converted into a value node during graph compilation.
|
||||
Value { tagged_value: MemoHash<TaggedValue>, exposed: bool },
|
||||
|
||||
// TODO: Remove import_type and get type from parent node input
|
||||
/// Input that is provided by the parent network to this document node, instead of from a hardcoded value or another node within the same network.
|
||||
Network { import_type: Type, import_index: usize },
|
||||
Network { import_index: usize },
|
||||
|
||||
/// Input that is extracted from the parent scopes the node resides in. The string argument is the key.
|
||||
Scope(Cow<'static, str>),
|
||||
|
@ -403,8 +405,8 @@ impl NodeInput {
|
|||
Self::Value { tagged_value, exposed }
|
||||
}
|
||||
|
||||
pub const fn network(import_type: Type, import_index: usize) -> Self {
|
||||
Self::Network { import_type, import_index }
|
||||
pub fn network(_import_type: Type, import_index: usize) -> Self {
|
||||
Self::Network { import_index }
|
||||
}
|
||||
|
||||
pub fn scope(key: impl Into<Cow<'static, str>>) -> Self {
|
||||
|
@ -447,7 +449,7 @@ impl NodeInput {
|
|||
match self {
|
||||
NodeInput::Node { .. } => unreachable!("ty() called on NodeInput::Node"),
|
||||
NodeInput::Value { tagged_value, .. } => tagged_value.ty(),
|
||||
NodeInput::Network { import_type, .. } => import_type.clone(),
|
||||
NodeInput::Network { .. } => unreachable!("ty() called on NodeInput::Network"),
|
||||
NodeInput::Inline(_) => panic!("ty() called on NodeInput::Inline"),
|
||||
NodeInput::Scope(_) => unreachable!("ty() called on NodeInput::Scope"),
|
||||
NodeInput::Reflection(_) => concrete!(Metadata),
|
||||
|
@ -1312,8 +1314,8 @@ impl NodeNetwork {
|
|||
}
|
||||
|
||||
/// Creates a proto network for evaluating each output of this network.
|
||||
pub fn into_proto_networks(self) -> impl Iterator<Item = ProtoNetwork> {
|
||||
let nodes: Vec<_> = self.nodes.into_iter().map(|(id, node)| (id, node.resolve_proto_node())).collect();
|
||||
pub fn into_proto_networks(self, global_import_types: &[Type]) -> impl Iterator<Item = ProtoNetwork> {
|
||||
let nodes: Vec<_> = self.nodes.into_iter().map(|(id, node)| (id, node.resolve_proto_node(global_import_types))).collect();
|
||||
|
||||
// Create a network to evaluate each output
|
||||
if self.exports.len() == 1 {
|
||||
|
@ -1507,7 +1509,7 @@ mod test {
|
|||
..Default::default()
|
||||
};
|
||||
|
||||
let proto_node = document_node.resolve_proto_node();
|
||||
let proto_node = document_node.resolve_proto_node(&[concrete!(u32)]);
|
||||
let reference = ProtoNode {
|
||||
identifier: "graphene_core::structural::ConsNode".into(),
|
||||
input: ProtoNodeInput::ManualComposition(concrete!(u32)),
|
||||
|
@ -1577,7 +1579,7 @@ mod test {
|
|||
.collect(),
|
||||
};
|
||||
let network = flat_network();
|
||||
let mut resolved_network = network.into_proto_networks().collect::<Vec<_>>();
|
||||
let mut resolved_network = network.into_proto_networks(&[concrete!(u32)]).collect::<Vec<_>>();
|
||||
resolved_network[0].nodes.sort_unstable_by_key(|(id, _)| *id);
|
||||
|
||||
println!("{:#?}", resolved_network[0]);
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::proto::{LocalFuture, ProtoNetwork};
|
|||
pub struct Compiler {}
|
||||
|
||||
impl Compiler {
|
||||
pub fn compile(&self, mut network: NodeNetwork) -> impl Iterator<Item = Result<ProtoNetwork, String>> {
|
||||
pub fn compile(&self, mut network: NodeNetwork, global_import_types: &[crate::Type]) -> impl Iterator<Item = Result<ProtoNetwork, String>> {
|
||||
let node_ids = network.nodes.keys().copied().collect::<Vec<_>>();
|
||||
network.populate_dependants();
|
||||
for id in node_ids {
|
||||
|
@ -15,7 +15,7 @@ impl Compiler {
|
|||
network.resolve_scope_inputs();
|
||||
network.remove_redundant_id_nodes();
|
||||
// network.remove_dead_nodes(0);
|
||||
let proto_networks = network.into_proto_networks();
|
||||
let proto_networks = network.into_proto_networks(global_import_types);
|
||||
|
||||
proto_networks.map(move |mut proto_network| {
|
||||
proto_network.resolve_inputs()?;
|
||||
|
@ -23,9 +23,9 @@ impl Compiler {
|
|||
Ok(proto_network)
|
||||
})
|
||||
}
|
||||
pub fn compile_single(&self, network: NodeNetwork) -> Result<ProtoNetwork, String> {
|
||||
pub fn compile_single(&self, network: NodeNetwork, global_import_types: &[crate::Type]) -> Result<ProtoNetwork, String> {
|
||||
assert_eq!(network.exports.len(), 1, "Graph with multiple outputs not yet handled");
|
||||
let Some(proto_network) = self.compile(network).next() else {
|
||||
let Some(proto_network) = self.compile(network, global_import_types).next() else {
|
||||
return Err("Failed to convert graph into proto graph".to_string());
|
||||
};
|
||||
proto_network
|
||||
|
|
|
@ -7,9 +7,9 @@ pub fn load_network(document_string: &str) -> NodeNetwork {
|
|||
serde_json::from_value::<NodeNetwork>(document["network_interface"]["network"].clone()).expect("Failed to parse document")
|
||||
}
|
||||
|
||||
pub fn compile(network: NodeNetwork) -> ProtoNetwork {
|
||||
pub fn compile_with_render_config(network: NodeNetwork) -> ProtoNetwork {
|
||||
let compiler = Compiler {};
|
||||
compiler.compile_single(network).unwrap()
|
||||
compiler.compile_single(network, &[concrete!(graphene_core::application_io::RenderConfig)]).unwrap()
|
||||
}
|
||||
|
||||
pub fn load_from_name(name: &str) -> NodeNetwork {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use graph_craft::document::*;
|
||||
use graph_craft::graphene_compiler::{Compiler, Executor};
|
||||
use graph_craft::util::load_network;
|
||||
use graph_craft::wasm_application_io::EditorPreferences;
|
||||
use graph_craft::{concrete, document::*};
|
||||
use graphene_core::application_io::{ApplicationIo, NodeGraphUpdateSender};
|
||||
use graphene_core::text::FontCache;
|
||||
use graphene_std::wasm_application_io::{WasmApplicationIo, WasmEditorApi};
|
||||
|
@ -105,7 +105,7 @@ fn create_executor(document_string: String, editor_api: Arc<WasmEditorApi>) -> R
|
|||
|
||||
let wrapped_network = wrap_network_in_scope(network.clone(), editor_api);
|
||||
let compiler = Compiler {};
|
||||
let protograph = compiler.compile_single(wrapped_network)?;
|
||||
let protograph = compiler.compile_single(wrapped_network, &[concrete!(graphene_core::application_io::RenderConfig)])?;
|
||||
let executor = block_on(DynamicExecutor::new(protograph)).unwrap();
|
||||
Ok(executor)
|
||||
}
|
||||
|
|
|
@ -18,23 +18,17 @@ use crate::wasm_application_io::WasmApplicationIo;
|
|||
|
||||
// TODO: Move to graph-craft
|
||||
#[node_macro::node(category("Debug: GPU"))]
|
||||
async fn compile_gpu<'a: 'n>(_: (), node: &'a DocumentNode, typing_context: TypingContext, io: ShaderIO) -> Result<compilation_client::Shader, String> {
|
||||
async fn compile_gpu<'a: 'n>(_: (), node: &'a DocumentNode, typing_context: TypingContext, input_types: Vec<Type>, io: ShaderIO) -> Result<compilation_client::Shader, String> {
|
||||
let mut typing_context = typing_context;
|
||||
let compiler = graph_craft::graphene_compiler::Compiler {};
|
||||
let DocumentNodeImplementation::Network(ref network) = node.implementation else { panic!() };
|
||||
let proto_networks: Result<Vec<_>, _> = compiler.compile(network.clone()).collect();
|
||||
let proto_networks: Result<Vec<_>, _> = compiler.compile(network.clone(), &input_types).collect();
|
||||
let proto_networks = proto_networks?;
|
||||
|
||||
for network in proto_networks.iter() {
|
||||
typing_context.update(network).expect("Failed to type check network");
|
||||
}
|
||||
// TODO: do a proper union
|
||||
let input_types = proto_networks[0]
|
||||
.inputs
|
||||
.iter()
|
||||
.map(|id| typing_context.type_of(*id).unwrap())
|
||||
.map(|node_io| node_io.return_value.clone())
|
||||
.collect();
|
||||
let output_types = proto_networks.iter().map(|network| typing_context.type_of(network.output).unwrap().return_value.clone()).collect();
|
||||
|
||||
Ok(compilation_client::compile(proto_networks, input_types, output_types, io).await.unwrap())
|
||||
|
@ -187,11 +181,12 @@ async fn create_compute_pass_descriptor<T: Clone + Pixel + StaticTypeSized>(node
|
|||
..Default::default()
|
||||
};
|
||||
log::debug!("compiling network");
|
||||
let proto_networks: Result<Vec<_>, _> = compiler.compile(network.clone()).collect();
|
||||
let global_input_types = vec![concrete!(u32), concrete!(Color)];
|
||||
let proto_networks: Result<Vec<_>, _> = compiler.compile(network.clone(), &global_input_types).collect();
|
||||
log::debug!("compiling shader");
|
||||
let shader = compilation_client::compile(
|
||||
proto_networks?,
|
||||
vec![concrete!(u32), concrete!(Color)],
|
||||
global_input_types,
|
||||
vec![concrete!(Color)],
|
||||
ShaderIO {
|
||||
inputs: vec![
|
||||
|
@ -317,7 +312,15 @@ async fn blend_gpu_image(_: (), foreground: ImageFrame<Color>, background: Image
|
|||
..Default::default()
|
||||
};
|
||||
log::debug!("compiling network");
|
||||
let proto_networks: Result<Vec<_>, _> = compiler.compile(network.clone()).collect();
|
||||
let global_input_types = vec![
|
||||
concrete!(u32),
|
||||
concrete!(Color),
|
||||
concrete!(Color),
|
||||
concrete!(u32),
|
||||
concrete_with_name!(Mat2, "Mat2"),
|
||||
concrete_with_name!(Vec2, "Vec2"),
|
||||
];
|
||||
let proto_networks: Result<Vec<_>, _> = compiler.compile(network.clone(), &global_input_types).collect();
|
||||
let Ok(proto_networks_result) = proto_networks else {
|
||||
log::error!("Error compiling network in 'blend_gpu_image()");
|
||||
return ImageFrame::empty();
|
||||
|
@ -327,14 +330,7 @@ async fn blend_gpu_image(_: (), foreground: ImageFrame<Color>, background: Image
|
|||
|
||||
let shader = compilation_client::compile(
|
||||
proto_networks,
|
||||
vec![
|
||||
concrete!(u32),
|
||||
concrete!(Color),
|
||||
concrete!(Color),
|
||||
concrete!(u32),
|
||||
concrete_with_name!(Mat2, "Mat2"),
|
||||
concrete_with_name!(Vec2, "Vec2"),
|
||||
],
|
||||
global_input_types,
|
||||
vec![concrete!(Color)],
|
||||
ShaderIO {
|
||||
inputs: vec![
|
||||
|
|
|
@ -2,13 +2,13 @@ use criterion::{measurement::Measurement, BenchmarkGroup};
|
|||
use futures::executor::block_on;
|
||||
use graph_craft::{
|
||||
proto::ProtoNetwork,
|
||||
util::{compile, load_from_name, DEMO_ART},
|
||||
util::{compile_with_render_config, load_from_name, DEMO_ART},
|
||||
};
|
||||
use interpreted_executor::dynamic_executor::DynamicExecutor;
|
||||
|
||||
pub fn setup_network(name: &str) -> (DynamicExecutor, ProtoNetwork) {
|
||||
let network = load_from_name(name);
|
||||
let proto_network = compile(network);
|
||||
let proto_network = compile_with_render_config(network);
|
||||
let executor = block_on(DynamicExecutor::new(proto_network.clone())).unwrap();
|
||||
(executor, proto_network)
|
||||
}
|
||||
|
|
|
@ -2,14 +2,14 @@ use criterion::{black_box, criterion_group, criterion_main, measurement::Measure
|
|||
use graph_craft::{
|
||||
graphene_compiler::Executor,
|
||||
proto::ProtoNetwork,
|
||||
util::{compile, load_from_name, DEMO_ART},
|
||||
util::{compile_with_render_config, load_from_name, DEMO_ART},
|
||||
};
|
||||
use graphene_std::transform::Footprint;
|
||||
use interpreted_executor::dynamic_executor::DynamicExecutor;
|
||||
|
||||
fn update_executor<M: Measurement>(name: &str, c: &mut BenchmarkGroup<M>) {
|
||||
let network = load_from_name(name);
|
||||
let proto_network = compile(network);
|
||||
let proto_network = compile_with_render_config(network);
|
||||
let empty = ProtoNetwork::default();
|
||||
|
||||
let executor = futures::executor::block_on(DynamicExecutor::new(empty)).unwrap();
|
||||
|
@ -32,7 +32,7 @@ fn update_executor_demo(c: &mut Criterion) {
|
|||
|
||||
fn run_once<M: Measurement>(name: &str, c: &mut BenchmarkGroup<M>) {
|
||||
let network = load_from_name(name);
|
||||
let proto_network = compile(network);
|
||||
let proto_network = compile_with_render_config(network);
|
||||
|
||||
let executor = futures::executor::block_on(DynamicExecutor::new(proto_network)).unwrap();
|
||||
let footprint = Footprint::default();
|
||||
|
|
|
@ -44,7 +44,7 @@ mod tests {
|
|||
use graph_craft::graphene_compiler::Compiler;
|
||||
|
||||
let compiler = Compiler {};
|
||||
let protograph = compiler.compile_single(network).expect("Graph should be generated");
|
||||
let protograph = compiler.compile_single(network, &[concrete!(u32)]).expect("Graph should be generated");
|
||||
|
||||
let _exec = block_on(DynamicExecutor::new(protograph)).map(|_e| panic!("The network should not type check ")).unwrap_err();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue