Replies: 7 comments 3 replies
-
Nice write-up @doug-q :). We might wish to note there are several distinct reasons why nodes might be "never-dce" - it's probably OK to combine these but there might be reasons to distinguish
While the "linear state token" allows rewriting in the opposite impure->pure direction, even there one wants to do a lot more tidying up. Side comment, but I'd like to unify treatment of "never-dce" ops/nodes with unbounded TailLoops somehow. |
Beta Was this translation helpful? Give feedback.
-
Isn't a major design point of HUGR that it uses "value semantics", i.e. data dependencies are all there is? The "never-dce" and order edge approaches feel like hacks in that light while the "linear state token" expresses precisely what we want, both conceptually and pragmatically. It makes control dependencies into data dependencies where we want it, and so requires no additional attention to corner cases regarding ordering or effects. It marks effectfulness directly in the type of an operation. It is immediately clear how it interacts with control flow. This is also a solution that some people in PL semantics research have arrived at (see e.g. Universal Properties of Impure Programming Languages or Promonads and String Diagrams for Effectful Categories).
These should definitely be dead.
Can you explain what you mean here? |
Beta Was this translation helpful? Give feedback.
-
So at present we have two mechanisms for forcing evaluation of things.
The latter means that, given e.g. DFG_1 depends on DFG_2 where DFG_2 contains an infinite loop but doesn't use the result of that loop, we cannot execute DFG_1 (because DFG_2 never terminates). Thus, the "InlineDFG" rewrite is looking dangerous....we should probably insert StateOrder edges from all nodes not connected to the inlined DFG's Output node, to all successors of the DFG, and from all predecessors of the DFG to all nodes not connected from the inlined DFG's Input. Is there a better way? Passing tokens is one way, although I think this can work, I fear it may be quite painful if we use that to handle all the cases. Might we have a better mechanism? I wonder if some notion of "effect system" might address both this and #1894. |
Beta Was this translation helpful? Give feedback.
-
Could we remove the idea that executing a DFG requires executing everything in it, and require order edges to express this constraint? This is a bit like reintroducing the "causal cone" although we do not require every op be in the cone - only that if ops are not in the cone, they may be removed by DCE ?
And/or, can we replace order edges by linear types?
|
Beta Was this translation helpful? Give feedback.
-
Some thoughts on the rewriting when state is encoded via a linear type that is passed through:
When you start with a pure program and replace it with an impure one for efficiency, you'd probably want the effects to be local. For instance for memory allocation and mutation, you could create a local heap, pass around that heap as a linear value, and then deallocate the heap in the end. Overall the program's interface is not changed. This would be similar to using a Rewriting a pure program into an impure one that has effects which do not commute with the outside world in this way would have chaotic consequences anyway. For instance, take a program with pure ops
This case touches on what I meant with linear effect types not needing anything special: You can end up in the same situation with conditionals or loops where any kind of data is passed into the conditional/loop needlessly. An optimisation pass that detects this and makes the data bypass the cond/loop would then give you a "purification" optimisation for free. |
Beta Was this translation helpful? Give feedback.
-
I'm wondering about some kind of effect system for "impure" ops but I'm not clear whether this is the same or separate from just having value edges to restrict ordering. We can have value edges that are "splittable", enabling parallelism, something like:
However, this is not very flexible - e.g. we cannot have the DAG with edges There is also the question of whether we can really know in advance all the reasons why a particular op might have an ordering requirement (so we can put the appropriate linear input/output ports on it). At the least, I suspect these reasons will change at different stages of compilation (as we start to track more things), requiring "lowering" ops to similar-but-different ops with more/different ports. |
Beta Was this translation helpful? Give feedback.
-
Current thinking at https://github.com/quantinuum-dev/hugrverse/issues/116 |
Beta Was this translation helpful? Give feedback.
-
Dead code elimination is a well known concept in compilers. https://en.wikipedia.org/wiki/Dead-code_elimination
See #1807 for issues with our existing dead-code-elimination, which at time of writing lives in and around
ConstFoldPass::find_needed_nodes
.By dead, we mean "it's outputs aren't used". This is similar but different to "unreachable" which means "no dynamic trace of the program executes that basic block". It's always safe to remove unreachable basic blocks.
Our dead code elimination must eliminate "dead" ops, for which we need a definition of "dead". Some examples of ops that are surely dead:
int.iadd
whose outputs are not usedSome ops that are surely not dead:
int.add
whose outputs are wired to the Output node of a public FuncDefnint.iadd
whose outputs are wired to the Output node of that DFGAre the following ops dead?
Does the addition of order edges between the input and output nodes and the panic nodes affect the above?
Focusing now on the panic case, I assume that we want all panics in a live DFG to be live, irrespective of their connections.
Options:
Put a "never-dce" flag on
OpDef
. (maybe inmisc
?).Ops connected (perhaps through order edges) to the output node of their parent dataflow block are never dead unless their parent is.
Create a linear "state token" and thread it through all impure ops
My view is we should move forward with a "never-dce" flag.
Beta Was this translation helpful? Give feedback.
All reactions