calyx: Verilog backend overflows on large programs

As in the title, fud e --to interpreter-out -s verilog.data DRB1-3123.data DRB1-3123.futil produces the expected output, while fud e --to dat --through verilog -s verilog.data DRB1-3123.data DRB1-3123.futil and fud e --to dat --through icarus-verilog -s verilog.data DRB1-3123.data DRB1-3123.futil produce nearly identical error messages:

[fud] ERROR: `/scratch/susan/calyx/target/debug/futil -l /scratch/susan/calyx -b verilog' failed:
---
> [fud] ERROR: `/scratch/susan/calyx/target/debug/futil -l /scratch/susan/calyx -b verilog --disable-init --disable-verify' failed:

The details of verilator’s error message is in error.txt. I also uploaded the input files, in case anyone is interested in duplicating the error.

error.txt DRB1-3123.data.txt DRB1-3123.futil.txt

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 15 (15 by maintainers)

Most upvoted comments

@susan-garry are you building and running the compiler in release mode. You need to build the compiler using release mode:

cargo build --release

And then change fud to use the release binary:

fud e stages.futil.exec "<calyx repo>/target/release/futil

It should not get a overflow error anymore. If it does, open a new issue please

To get the overflow quicker, we can run the compiler with optimizations disabled using -p no-opt:

% ./target/release/futil -b verilog --log info -p no-opt pange.futil > /dev/null
[INFO  calyx::pass_manager] well-formed: 98ms
[INFO  calyx::pass_manager] papercut: 48ms
[INFO  calyx::pass_manager] canonicalize: 65ms
[INFO  calyx::pass_manager] compile-sync: 5ms
[INFO  calyx::pass_manager] compile-ref: 41ms
[INFO  calyx::pass_manager] remove-comb-groups: 0ms
[INFO  calyx::pass_manager] compile-invoke: 86ms
[INFO  calyx::pass_manager] tdcc: 6388ms
[INFO  calyx::pass_manager] go-insertion: 61ms
[INFO  calyx::pass_manager] wire-inliner: 2021ms
[INFO  calyx::pass_manager] clk-insertion: 93ms
[INFO  calyx::pass_manager] reset-insertion: 92ms
[INFO  calyx::pass_manager] merge-assigns: 979ms

thread 'main' has overflowed its stack
fatal runtime error: stack overflow
zsh: abort      ./target/release/futil -b verilog --log info -p no-opt pange.futil > /dev/nul

Running the compiler to just print out the Calyx program after compilation doesn’t overflow:

% ./target/release/futil --log info -p no-opt pange.futil > out.futil
[INFO  calyx::pass_manager] well-formed: 111ms
[INFO  calyx::pass_manager] papercut: 47ms
[INFO  calyx::pass_manager] canonicalize: 118ms
[INFO  calyx::pass_manager] compile-sync: 13ms
[INFO  calyx::pass_manager] compile-ref: 42ms
[INFO  calyx::pass_manager] remove-comb-groups: 1ms
[INFO  calyx::pass_manager] compile-invoke: 89ms
[INFO  calyx::pass_manager] tdcc: 6474ms
[INFO  calyx::pass_manager] go-insertion: 58ms
[INFO  calyx::pass_manager] wire-inliner: 2067ms
[INFO  calyx::pass_manager] clk-insertion: 83ms
[INFO  calyx::pass_manager] reset-insertion: 87ms
[INFO  calyx::pass_manager] merge-assigns: 957ms

Okay, according to @susan-garry, y’all previously had programs with the same number of PEs and memories and the only change is generating invoke statements which is curious. Some things to note:

  • This is probably the largest Calyx program the compiler has encountered! Congratulations!
  • You probably want run the compiler in release mode so its much faster. You can do this by building using cargo build --release and changing fud to use the release compiler (fud c futil.exec "$pwd/target/release/futil" in the Calyx repo)

Now onto sources of overflow:

  • By running the compiler with --log info (fud e -s futil.flags ' -p all --log info ...), you get the above log which shows none of the compiler passes overflow which is good
  • The problem is in the backend with the likely culprit being this recursive function: https://github.com/cucapra/calyx/blob/master/src/backend/verilog.rs#L483
  • The other, much worse possibility, is that the pretty printer in the Verilog library we use cannot print out the Verilog AST we’re generating. This would be much harder to fix unfortunately

Also, @calebmkim, got a new stress test for sharing pass for you (using DRB1-3123.futil.txt):

% ./target/release/futil -b verilog --log info pange.futil > /dev/null 
[INFO  calyx::pass_manager] well-formed: 111ms
[INFO  calyx::pass_manager] papercut: 49ms
[INFO  calyx::pass_manager] canonicalize: 55ms
[INFO  calyx::pass_manager] compile-sync: 5ms
[INFO  calyx::pass_manager] group2seq: 28ms
[INFO  calyx::pass_manager] group2invoke: 22ms
[INFO  calyx::pass_manager] inline: 44ms
[INFO  calyx::pass_manager] comb-prop: 43ms
[INFO  calyx::pass_manager] compile-ref: 37ms
[INFO  calyx::pass_manager] infer-share: 3ms
[INFO  calyx::pass_manager] cell-share: 153387ms // <- 2.5 minutes!
[INFO  calyx::pass_manager] remove-comb-groups: 0ms
[INFO  calyx::pass_manager] infer-static-timing: 330ms
[INFO  calyx::pass_manager] compile-invoke: 94ms
[INFO  calyx::pass_manager] merge-static-par: 68ms
[INFO  calyx::pass_manager] static-par-conv: 1630ms
[INFO  calyx::pass_manager] dead-group-removal: 40ms
[INFO  calyx::pass_manager] collapse-control: 16ms
[INFO  calyx::pass_manager] tdcc: 6399ms
[INFO  calyx::pass_manager] dead-group-removal: 11ms
[INFO  calyx::pass_manager] comb-prop: 9997ms              
[INFO  calyx::pass_manager] dead-cell-removal: 9044ms
[INFO  calyx::pass_manager] go-insertion: 33ms
[INFO  calyx::pass_manager] wire-inliner: 1789ms
[INFO  calyx::pass_manager] clk-insertion: 66ms
[INFO  calyx::pass_manager] reset-insertion: 54ms
[INFO  calyx::pass_manager] merge-assigns: 602ms