bend/hvm/
check_net_size.rs1use super::tree_children;
2use crate::{diagnostics::Diagnostics, fun::Name, CompilerTarget};
3use hvm::ast::{Book, Net, Tree};
4
5pub const MAX_NET_SIZE_C: usize = 4095;
6pub const MAX_NET_SIZE_CUDA: usize = 64;
7
8pub fn check_net_sizes(
9 book: &Book,
10 diagnostics: &mut Diagnostics,
11 target: &CompilerTarget,
12) -> Result<(), Diagnostics> {
13 let (net_size_bound, target_lang) = match target {
14 CompilerTarget::Cuda => (MAX_NET_SIZE_CUDA, "Cuda"),
15 _ => (MAX_NET_SIZE_C, "C"),
16 };
17 for (name, net) in &book.defs {
18 let nodes = count_nodes(net);
19 if nodes > net_size_bound {
20 diagnostics.add_function_error(
21 format!("Definition is too large for HVM {target_lang} (size={nodes}, max size={net_size_bound}). Please break it into smaller pieces."),
22 Name::new(name),
23 Default::default()
24 );
25 }
26 }
27
28 diagnostics.fatal(())
29}
30
31pub fn count_nodes(net: &Net) -> usize {
33 let mut visit: Vec<&Tree> = vec![&net.root];
34 let mut count = 0usize;
35 for (_, l, r) in &net.rbag {
36 visit.push(l);
37 visit.push(r);
38 }
39 while let Some(tree) = visit.pop() {
40 if tree_children(tree).next().is_some() {
42 count += 1;
43 }
44 for subtree in tree_children(tree) {
45 visit.push(subtree);
46 }
47 }
48 count
49}