# "Compiling" HIR produced by \`ZXCalculus.jl\`

**URL:** https://discourse.julialang.org/t/compiling-hir-produced-by-zxcalculus-jl/119221
**Category:** Quantum
**Tags:** quantum, quantum-circuits, ir
**Created:** [September 9, 2024, 6:02pm UTC](https://discourse.julialang.org/t/compiling-hir-produced-by-zxcalculus-jl/119221 "2024-09-09T18:02:03Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![bremez](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bremez/32/38777_2.png) [@bremez](https://discourse.julialang.org/u/bremez)
#### Post date: [September 9, 2024, 6:02pm UTC](https://discourse.julialang.org/t/compiling-hir-produced-by-zxcalculus-jl/119221/1 "2024-09-09T18:02:03Z")

</div>

I would like to explore the affects of [ZX calculus](https://zxcalculus.com/) on the synthesis of certain quantum circuits. Thankfully, I saw that Yao has a native Julia implementation in [ZXCalculus.jl](https://github.com/QuantumBFS/ZXCalculus.jl)! However, it seems to me its documentation might be outdated, and/or the package itself is out of lockstep with `Yao.jl`. My use case is as follows:

```julia
using ZXCalculus: ZX
zxd = ZXDiagram(N) # N number of qubits
# push gates onto the circuit, e.g. for some gate list
map(push_gate!(zxd, Val(:CNOT), g[1], g[2]), gates)
circuit = circuit_extraction(clifford_simplification(zxd))

```

The type produces is `typeof(circuit) == YaoHIR.Chain`, which I am not sure how to manipulate (`YaoHIR.jl` documentation link is broken). How can I proceed further with this output? In particular, I’d like to find the depth of the circuit specificed by this IR (do I need to pick some compilation backend), and preferably also visualize the circuit.

---

<div class="post-metadata">

### Author: ![Roger-luo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/roger-luo/32/3399_2.png) [@Roger-luo](https://discourse.julialang.org/u/Roger-luo)
#### Post date: [September 10, 2024, 3:23pm UTC](https://discourse.julialang.org/t/compiling-hir-produced-by-zxcalculus-jl/119221/2 "2024-09-10T15:23:50Z")

</div>

Hi, thanks for trying out. The package YaoHIR is not maintained in a good state. We cannot convert it to YaoBlocks because there is insufficient support for the ZX calculus-generated circuit. I’m (slowly) updating the IR to the next-gen with a refactor of Yao, but this is not done yet.

---

<div class="post-metadata">

### Author: ![bremez](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bremez/32/38777_2.png) [@bremez](https://discourse.julialang.org/u/bremez)
#### Post date: [September 10, 2024, 3:35pm UTC](https://discourse.julialang.org/t/compiling-hir-produced-by-zxcalculus-jl/119221/3 "2024-09-10T15:35:46Z")

</div>

Thanks for your response. I am dealing with a rather small “gateset”, so the outputs I receive in `circuit`, as far as I can read it, contain only very few gate types (Zs, Xs, Hadamards, CNOTs). Is there a way for me to hack together a solution that manually translates this into some supported IR / circuit specification that I could then compile?

---

<div class="post-metadata">

### Author: ![Roger-luo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/roger-luo/32/3399_2.png) [@Roger-luo](https://discourse.julialang.org/u/Roger-luo)
#### Post date: [September 10, 2024, 4:37pm UTC](https://discourse.julialang.org/t/compiling-hir-produced-by-zxcalculus-jl/119221/4 "2024-09-10T16:37:27Z")

</div>

YaoHIR itself is only a straightforward IR definition (if you are willing to look at the implementation)

> <https://github.com/QuantumBFS/YaoHIR.jl/blob/master/src/types.jl>

YaoCompiler infras should still work with 1.6 and they are tested, and you can find a lot of examples in the tests. I’m just not developing it, e.g you can start with a circuit defined via `@device` in Julia

```julia
using MLStyle
using YaoLocations
using YaoCompiler
using YaoCompiler.Intrinsics
using OpenQASM
using YaoTargetQASM
using YaoTargetQASM.QASM

@device function test_cir()
    5 => H
    @ctrl 4 5 => X
    5 => shift(7 / 4 * π)
    @ctrl 1 5 => X
    5 => T
    @ctrl 4 5 => X
    5 => shift(7 / 4 * π)
    @ctrl 1 5 => X
    4 => T
    5 => T
    @ctrl 1 4 => X
    4 => shift(7 / 4 * π)
    1 => T
    @ctrl 1 4 => X
    @ctrl 4 5 => X
    5 => shift(7 / 4 * π)
    @ctrl 3 5 => X
    5 => T
    @ctrl 4 5 => X
    5 => shift(7 / 4 * π)
    @ctrl 3 5 => X
    4 => T
    5 => T
    @ctrl 3 4 => X
    4 => shift(7 / 4 * π)
    5 => H
    3 => T
    @ctrl 3 4 => X
    @ctrl 4 5 => X
    5 => H
    @ctrl 3 5 => X
    5 => shift(7 / 4 * π)
    @ctrl 2 5 => X
    5 => T
    @ctrl 3 5 => X
    5 => shift(7 / 4 * π)
    @ctrl 2 5 => X
    3 => T
    5 => T
    @ctrl 2 3 => X
    3 => shift(7 / 4 * π)
    5 => H
    2 => T
    @ctrl 2 3 => X
    @ctrl 3 5 => X
    5 => H
    @ctrl 2 5 => X
    5 => shift(7 / 4 * π)
    @ctrl 1 5 => X
    5 => T
    @ctrl 2 5 => X
    5 => shift(7 / 4 * π)
    @ctrl 1 5 => X
    2 => T
    5 => T
    @ctrl 1 2 => X
    2 => shift(7 / 4 * π)
    5 => H
    1 => T
    @ctrl 1 2 => X
    @ctrl 2 5 => X
    @ctrl 1 5 => X
end

qasm = YaoCompiler.compile(OpenQASMTarget(), Intrinsics.apply, Tuple{AnyReg,Operation{typeof(test_cir), Tuple{}}}, HardwareFreeOptions(clifford_simplification=true))

```

which outputs the QASM 2.0 AST defined by OpenQASM, and you can copy that as a string and output it somewhere else. It supports all the basic control flows thus it can understand things like `if else` and thus can generate things like conditional measurement.

It has been a lot of maintenance burden to keep up with Julia compiler development (which is a good thing for Julia) for me, so YaoCompiler is broken in later Julia versions, I don’t gain much from reusing Julia internals. So I decide not to rely on Julia’s `Core.Compiler`.

---

<div class="post-metadata">

### Author: ![Roger-luo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/roger-luo/32/3399_2.png) [@Roger-luo](https://discourse.julialang.org/u/Roger-luo)
#### Post date: [September 10, 2024, 4:38pm UTC](https://discourse.julialang.org/t/compiling-hir-produced-by-zxcalculus-jl/119221/5 "2024-09-10T16:38:07Z")

</div>

This is what the output should work like to save you some time

 ![image](https://global.discourse-cdn.com/julialang/original/3X/0/1/0149c12b7cde968bbbdd0bd045c3a9e519084832.png)

---

<div class="post-metadata">

### Author: ![bremez](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bremez/32/38777_2.png) [@bremez](https://discourse.julialang.org/u/bremez)
#### Post date: [September 10, 2024, 5:12pm UTC](https://discourse.julialang.org/t/compiling-hir-produced-by-zxcalculus-jl/119221/6 "2024-09-10T17:12:13Z")

</div>

Of course! An extra-special thank you for maintaining YaoCompiler.

From your answer: Can I infer that `clifford_simplification = true` in the arguments to `compile` uses `ZXCalculus.jl` to do the simplification?

I am a bit foreign to the whole quantum description languages scene, so I’m not sure if a QASM representation is what I need. So I’ll describe my complete use case:

1. I generate some random quantum circuits programmatically.
2. I want to use ZX calculus to simplify them. (So far, I used the `push_gate!` method from my original post to do this; I’m not sure I know how to generalize the macro-based example you gave to receive a list of gates as parameters)
3. I want to compile the resulting IR, given a specific gate set. In particular, I want to enforce qubit nearest-neighbor connectivity only.
4. See what the resulting circuit depth is, and compare the depth to the case of no ZX simplification.

If it helps: I have no wish to actually execute any circuit on simulated or real hardware. I only care about the circuit schematic that is produced, assuming it is compliant with the connectivity constraint.
