Skip to content

Add manually-runnable benchmarks for runtime profiling #2005

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

Merged
merged 7 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion demo-artwork/isometric-fountain.graphite

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion demo-artwork/procedural-string-lights.graphite

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion demo-artwork/red-dress.graphite

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use graphene_core::text::Font;
use graphene_core::transform::Footprint;
use graphene_core::vector::VectorData;
use graphene_core::*;
use graphene_std::application_io::RenderConfig;
use graphene_std::wasm_application_io::WasmEditorApi;

#[cfg(feature = "gpu")]
Expand Down Expand Up @@ -2735,78 +2734,6 @@ impl DocumentNodeDefinition {
}
}

pub fn wrap_network_in_scope(mut network: NodeNetwork, editor_api: Arc<WasmEditorApi>) -> NodeNetwork {
network.generate_node_paths(&[]);

let inner_network = DocumentNode {
implementation: DocumentNodeImplementation::Network(network),
inputs: vec![],
..Default::default()
};

// TODO: Replace with "Output" definition?
// let render_node = resolve_document_node_type("Output")
// .expect("Output node type not found")
// .node_template_input_override(vec![Some(NodeInput::node(NodeId(1), 0)), Some(NodeInput::node(NodeId(0), 1))])
// .document_node;

let render_node = graph_craft::document::DocumentNode {
inputs: vec![NodeInput::node(NodeId(0), 0), NodeInput::node(NodeId(2), 0)],
implementation: graph_craft::document::DocumentNodeImplementation::Network(NodeNetwork {
exports: vec![NodeInput::node(NodeId(2), 0)],
nodes: [
DocumentNode {
inputs: vec![NodeInput::scope("editor-api")],
manual_composition: Some(concrete!(())),
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("wgpu_executor::CreateGpuSurfaceNode")),
skip_deduplication: true,
..Default::default()
},
DocumentNode {
manual_composition: Some(concrete!(())),
inputs: vec![NodeInput::node(NodeId(0), 0)],
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::memo::MemoNode")),
..Default::default()
},
// TODO: Add conversion step
DocumentNode {
manual_composition: Some(concrete!(RenderConfig)),
inputs: vec![
NodeInput::scope("editor-api"),
NodeInput::network(graphene_core::Type::Fn(Box::new(concrete!(Footprint)), Box::new(generic!(T))), 0),
NodeInput::node(NodeId(1), 0),
],
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_std::wasm_application_io::RenderNode")),
..Default::default()
},
]
.into_iter()
.enumerate()
.map(|(id, node)| (NodeId(id as u64), node))
.collect(),
..Default::default()
}),
..Default::default()
};

// wrap the inner network in a scope
let nodes = vec![
inner_network,
render_node,
DocumentNode {
implementation: DocumentNodeImplementation::proto("graphene_core::ops::IdentityNode"),
inputs: vec![NodeInput::value(TaggedValue::EditorApi(editor_api), false)],
..Default::default()
},
];

NodeNetwork {
exports: vec![NodeInput::node(NodeId(1), 0)],
nodes: nodes.into_iter().enumerate().map(|(id, node)| (NodeId(id as u64), node)).collect(),
scope_injections: [("editor-api".to_string(), (NodeId(2), concrete!(&WasmEditorApi)))].into_iter().collect(),
}
}

// Previously used by the Imaginate node, but usage was commented out since it did nothing.
// pub fn new_image_network(output_offset: i32, output_node_id: NodeId) -> NodeNetwork {
// let mut network = NodeNetwork { ..Default::default() };
Expand Down
2 changes: 1 addition & 1 deletion editor/src/node_graph_executor.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::consts::FILE_SAVE_SUFFIX;
use crate::messages::frontend::utility_types::{ExportBounds, FileType};
use crate::messages::portfolio::document::node_graph::document_node_definitions::wrap_network_in_scope;
use crate::messages::prelude::*;

use graph_craft::concrete;
Expand All @@ -21,6 +20,7 @@ use graphene_std::wasm_application_io::{WasmApplicationIo, WasmEditorApi};
use interpreted_executor::dynamic_executor::{DynamicExecutor, IntrospectError, ResolvedDocumentNodeTypesDelta};

use glam::{DAffine2, DVec2, UVec2};
use interpreted_executor::util::wrap_network_in_scope;
use once_cell::sync::Lazy;
use spin::Mutex;
use std::sync::mpsc::{Receiver, Sender};
Expand Down
16 changes: 7 additions & 9 deletions node-graph/graph-craft/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ dealloc_nodes = ["graphene-core/dealloc_nodes"]
wgpu = []
tokio = ["dep:tokio"]
wayland = []
criterion = []
iai = []
loading = ["serde_json", "serde"]

[dependencies]
# Local dependencies
Expand Down Expand Up @@ -40,6 +39,7 @@ wgpu-executor = { workspace = true }
# Optional workspace dependencies
serde = { workspace = true, optional = true }
tokio = { workspace = true, optional = true }
serde_json = { workspace = true, optional = true }

# Workspace dependencies
[target.'cfg(target_arch = "wasm32")'.dependencies]
Expand All @@ -53,19 +53,17 @@ winit = { workspace = true }

[dev-dependencies]
# Workspace dependencies
serde_json = { workspace = true }
graph-craft = { workspace = true, features = ["serde"] }
graph-craft = { workspace = true, features = ["loading"] }

# Required dependencies
criterion = { version = "0.5", features = ["html_reports"]}
glob = "0.3"
iai-callgrind = { version = "0.12.3"}

# Benchmarks
[[bench]]
name = "compile_demo_art"
name = "compile_demo_art_criterion"
harness = false

# [[bench]]
# name = "exec_demo_art"
# harness = false
[[bench]]
name = "compile_demo_art_iai"
harness = false
64 changes: 0 additions & 64 deletions node-graph/graph-craft/benches/compile_demo_art.rs

This file was deleted.

14 changes: 14 additions & 0 deletions node-graph/graph-craft/benches/compile_demo_art_criterion.rs
Original file line number Diff line number Diff line change
@@ -0,0 +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};
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));
}
}

criterion_group!(benches, compile_to_proto);
criterion_main!(benches);
13 changes: 13 additions & 0 deletions node-graph/graph-craft/benches/compile_demo_art_iai.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use graph_craft::document::NodeNetwork;
use graph_craft::util::*;
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));
}

library_benchmark_group!(name = compile_group; benchmarks = compile_to_proto);

main!(library_benchmark_groups = compile_group);
Loading
Loading