-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reducing CNOT count during circuit extraction #70
Conversation
Codecov Report
@@ Coverage Diff @@
## master #70 +/- ##
==========================================
+ Coverage 82.18% 83.59% +1.41%
==========================================
Files 11 11
Lines 1532 1652 +120
==========================================
+ Hits 1259 1381 +122
+ Misses 273 271 -2
Continue to review full report at Codecov.
|
@Roger-luo it's ready to be merged now. |
can we chat about this in the next meeting? I'll merge it after that. |
@Roger-luo CI failed because the SWAP PR of YaoHIR is not merged. |
@Roger-luo Naive simplification methods (e.g. |
Yeah I think there are a few better ways of doing SWAP simplification. let's do that in the exact match package later. |
src/simplify.jl
Outdated
g = pop!(qc.args) | ||
if g isa Gate | ||
if g.operation === SWAP | ||
loc1, loc2 = g.locations.storage[1:2] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use plain
here to get the plain old data
continue | ||
end | ||
end | ||
pushfirst!(chain_after_swap.args, map_locations(loc_map, g)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel SWAP should be simplified by looking at qubit dependency etc. but let's prob go with this simple one first.
src/simplify.jl
Outdated
j += 1 | ||
g isa Ctrl || continue | ||
if g.gate === X && length(g.gate.locations) == 1 && length(g.ctrl) == 1 | ||
loc = g.gate.locations.storage[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
loc = g.gate.locations.storage[] | |
loc = plain(g.gate.locations)[] |
src/simplify.jl
Outdated
j += 1 | ||
g isa Ctrl || continue | ||
if g.gate === X && length(g.gate.locations) == 1 && length(g.ctrl) == 1 | ||
loc = g.gate.locations.storage[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
loc = g.gate.locations.storage[] | |
loc = plain(g.gate.locations)[] |
src/simplify.jl
Outdated
g isa Ctrl || continue | ||
if g.gate === X && length(g.gate.locations) == 1 && length(g.ctrl) == 1 | ||
loc = g.gate.locations.storage[] | ||
ctrl = g.ctrl.storage.storage[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ctrl = g.ctrl.storage.storage[] | |
ctrl = plain(g.ctrl.storage)[] |
src/simplify.jl
Outdated
g = qc_after_swap[j] | ||
j += 1 | ||
g isa Ctrl || continue | ||
if g.gate === X && length(g.gate.locations) == 1 && length(g.ctrl) == 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you use MLStyle
, this can just be
@switch gate begin
@case Ctrl(Gate(X, locs::Locations), ctrl::Locations)
length(locs) == 1 && length(ctrl) == 1 || continue # or we should use a Guard pattern here
plain_loc = plain(locs)[]
plain_ctrl = plain(ctrl)[]
@case _ # other case
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this pattern asserts the location type since in HIR we allow locations
to be a SSAValue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried but it seems it doesn't work well because we have a break
here.
src/simplify.jl
Outdated
loc = g.gate.locations.storage[] | ||
ctrl = g.ctrl.storage.storage[] | ||
if haskey(qmap, loc) && haskey(qmap, ctrl) | ||
insert!(qc, j, convert_to_gate(Val(:CNOT), ctrl, loc)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm actually thinking maybe should just use the intrinsic type and pattern match in convert_to_gate
function too.
@@ -1,3 +1,46 @@ | |||
using YaoHIR: X, Z, S, T, SWAP, Rz, Rx, shift | |||
|
|||
convert_to_gate(::Val{:X}, loc) = Gate(X, Locations(loc)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we just XGate
type over Val{:X}
we can prob get rid of these functions in this package.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will simplify for most gates except for CNOT
and CZ
. For consistency, make it's better to use the old one.
r0 += i - 1 | ||
r0 == i && break | ||
M[i,:] = M[i,:] .⊻ M[r0,:] | ||
step = GEStep(:addto, r0, i) | ||
M_r0 = M[r0,:] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe should use @views
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will swap two rows. So we have to record one of the rows. Hence, @view
is not the right way.
I use SWAP gates to reduce CNOT counts.
More tests are needed. Please do not merge until tests are added.