Skip to content
Open
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ examples/**/main
examples/**/*.c
examples/**/*.cu
.out.hvm
dots.js
profile.csv

# nix-direnv
/.direnv/
Expand Down
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,28 @@ don't worry, it isn't meant to. [Bend](https://github.com/HigherOrderCO/Bend) is
the human-readable language and should be used both by end users and by languages
aiming to target the HVM. If you're looking to learn more about the core
syntax and tech, though, please check the [PAPER](./paper/HVM2.pdf).

Interaction Net graph dumping and visualization
-----------------------------------------------

With the rust interpreter (`hvm run`), every evaluation step can be dumped with
the `--dump` command line option. You can dump in sequential mode (only one
redex is evaluated in each step) or, with the `--parallel` option,
in parallel mode (all redexes are evaluated in each step).

The dump will be written to the file `dots.js` in the current directory.

You can view the graph dump as follows: Copy the file `dots.js` to the HVM
directory, then open `index.html` in your browser. You can step through
the graph with the wasd keys.

How parallel is my Bend/HVM program?
------------------------------------

With the `--parallel` option, HVM also calculates the average number of regexes
in each step, thus giving a measurement of how parallel a given bend program is.

You can use the `--parallel` option without the `--dump` option as well.

With the `--profile` option, a parallelization profile will be written to
`profile.csv`. This file contains the number of regexes per step.
97 changes: 97 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<style type="text/css">
html, body {
margin: 0;
padding: 0;
}
#graph {
position: absolute;
display: block;
width: 100%;
height: 100%;
}
</style>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script src="https://unpkg.com/@hpcc-js/wasm@2.20.0/dist/graphviz.umd.js"></script>
<script src="https://unpkg.com/d3-graphviz@5.6.0/build/d3-graphviz.js"></script>
<script src="./dots.js"></script>
<div id="graph"></div>
<script>

const div = document.getElementById("graph");
var offset = 0;
var dotIndex = 0;
readHash();
var graphviz = d3.select("#graph").graphviz()
.transition(function () {
return d3.transition("main")
.ease(d3.easeLinear)
.duration(200);
})
.logEvents(false)
.width(div.clientWidth)
.height(div.clientHeight)
.fit(false)
.tweenPaths(false)
.tweenShapes(false)
.growEnteringEdges(false)
.fade(true)
.on("initEnd", render);

window.addEventListener("keydown", function (e) {
old = offset;
if (e.code === "KeyW") {
offset = 10;
} else if (e.code === "KeyS") {
offset = -10;
} else if (e.code === "KeyA") {
offset = -1;
} else if (e.code === "KeyD") {
offset = 1;
}
if (old === 0) {
update();
}
});

window.addEventListener("keyup", function (e) {
offset = 0;
});

window.addEventListener("hashchange", function (e) {
readHash();
render();
});

function readHash() {
if (window.location.hash) {
dotIndex = parseInt(window.location.hash.slice(1), 10);
if (isNaN(dotIndex)) {
dotIndex = 0;
}
}
}

function render() {
graphviz.renderDot(dots[dotIndex]);
graphviz.on("end", update);
}

function update() {
if (offset === 0) {
return;
}

dotIndex += offset;
if (dotIndex < 0) {
dotIndex += dots.length;
} else if (dotIndex >= dots.length) {
dotIndex -= dots.length;
}
window.location.hash = "#" + dotIndex;
render();
}

</script>
Loading