FluxML / IRTools.jl

Mike's Little Intermediate Representation
MIT License
111 stars 35 forks source link

RFC: allow more general SSA IR type #59

Closed Roger-luo closed 4 years ago

Roger-luo commented 4 years ago

I'm wondering if it's possible to have a more general SSA Block type here since I currently need to define a modified SSA IR with the following extra nodes:

struct Measure # potentially should be an abstract statement
    operator::Any
    locations::Any
    reset_to::Any
    remove::Any
end

struct QuantumStatement
    routine::Any
    locations::Any
    ctrl_locations::Any
    configurations::Any
    line::Int
end

struct QuantumBlock
    stmts::Vector{Statement}
    measures::Vector{Measures}
end

Currently I have to define two extra things to make it work (which is exactly the same as IR and Block)

struct QuIR
    defs::Vector{Tuple{Int,Int}}
    blocks::Vector{Union{QuantumBlock, BasicBlock}}
    lines::Vector{LineInfoNode}
end

struct QuIRBlock
    ir::QuIR
    id::Int
end

the rest is the same as what's in this package, I find I have to copy-paste a bunch of code implemented for IR and Block since as defined here, they will contain BasicBlock specifically. In Julia's own AST Expr I can easily put my custom nodes in, but I'm wondering if this would cause some issue here? If not, I could open a PR for this, since it should be easy to add, I only need to change the Vector{BasicBlock} to Vector{Any} inside IR, and probably make some interface more general.

Thanks.

MikeInnes commented 4 years ago

Can't you just put Measures and QuantumStatements into the current BasicBlock data structure? A Statement's expr and type can be any Julia value, so it seems like you could just re-use that, and I don't think non-Exprs would cause issue with the vast majority of functionality in this package.

Roger-luo commented 4 years ago

I think I still need a block type, I need a special tagged block to mark that this part is quantum (which means I can swap it with other BasicBlock without changing the result of the program), e.g

%1 = sin(x)
%2 = %1 + pi
%3 = shift(%2)
         gate(%3, 2) # quantum
%4 = %2 + pi
%5 = shift(%4)
          ctrl(3, 2, %5) # quantum

then I can merge the two quantum routines into one quantum block and swap the positions of this quantum block with other BasicBlock as long as there is no conditional branches. the measurement is not the same as normal statements, it's like branches, it will cause a quantum block to jump into a classical block (BasicBlock).

Roger-luo commented 4 years ago

Maybe I'll just do a custom fork first and see what happens since the design of this new IR for quantum programs is quite new, maybe I'll find I don't need this or I need more on this.

MikeInnes commented 4 years ago

Might be a good idea. It sometimes takes a while to tease out the right abstraction from the specific case.

One other idea: perhaps QuantumBlock should actually just be one statement itself. Not sure if that allows the kind of operations you're looking for.

Roger-luo commented 4 years ago

OK, I think I have a better idea now. You are right, let it become one statement is way easier. Then I could mark the QuantumBlock using a wrapper around IR, so I can move quantum statements back and forth without changing IR now.

struct YaoIR
    # other fields
    ir::IR
    quantum::Vector{UnitRange}
end

by inserting new printers to Inner.printers this works great now

image

image

PS. one thing I'm not sure why is that I have to insert new printers inside __init__, I'm not sure why inserting new print to printers in the module's global scope doesn't work. But I think it's better to chat about this in another issue later.

I'll close this issue.

MikeInnes commented 4 years ago

Nice! It's very cool that you're using IRTools for this.

Adding printers in global scope is just tricky with precompilation. Yao can mutate IRTools at precompile time but at runtime a fresh copy of the package gets loaded. We could fix this by adding an API for this that uses dispatch.

Roger-luo commented 4 years ago

I'll show off this once this actually compiles on actual quantum hardware, like IBM's machine. But still working on it. I still need to have some features to enable partial evaluation on classical programs, but I'll look into that a bit later.