Skip to content

Commit

Permalink
change: Move Braket-specific pragma, instruction, and result logic ou…
Browse files Browse the repository at this point in the history
…t of parser (#53)

* change: Add parsing for delay

* change: Add Reset, Barrier, Delay instructions and tests

* change: Test for Barrier

* change: Tests for other no-ops and reorg

* change: More tests for no-ops

* change: Move BraketSimulator.Instruction logic out of Quasar
  • Loading branch information
kshyatt-aws authored Sep 27, 2024
1 parent 4780fdf commit 98ee205
Show file tree
Hide file tree
Showing 18 changed files with 811 additions and 666 deletions.
2 changes: 1 addition & 1 deletion docs/src/gates.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ BraketSimulator.Si
BraketSimulator.U
BraketSimulator.Unitary
BraketSimulator.PhaseShift
BraketSimulator.MultiQubitPhaseShift
BraketSimulator.GPhase
BraketSimulator.PRx
BraketSimulator.GPi
BraketSimulator.GPi2
Expand Down
15 changes: 8 additions & 7 deletions src/BraketSimulator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,21 @@ complex_matrix_to_ir(m) = m
include("raw_schema.jl")
include("qubit_set.jl")
include("operators.jl")
include("gates.jl")
include("noises.jl")
include("schemas.jl")
include("observables.jl")
using .Observables
include("results.jl")
include("Quasar.jl")
using .Quasar
include("pragmas.jl")
include("gates.jl")
include("noises.jl")
include("schemas.jl")
include("circuit.jl")
include("validation.jl")
include("custom_gates.jl")
include("pow_gates.jl")
include("gate_kernels.jl")
include("noise_kernels.jl")
include("Quasar.jl")
using .Quasar

const LOG2_CHUNK_SIZE = 10
const CHUNK_SIZE = 2^LOG2_CHUNK_SIZE
Expand Down Expand Up @@ -201,7 +202,7 @@ function _prepare_program(circuit_ir::OpenQasmProgram, inputs::Dict{String, <:An
ir_inputs = isnothing(circuit_ir.inputs) ? Dict{String, Float64}() : circuit_ir.inputs
merged_inputs = merge(ir_inputs, inputs)
src = circuit_ir.source::String
circuit = Quasar.to_circuit(src, merged_inputs)
circuit = to_circuit(src, merged_inputs)
n_qubits = qubit_count(circuit)
if shots > 0
_verify_openqasm_shots_observables(circuit, n_qubits)
Expand Down Expand Up @@ -820,8 +821,8 @@ include("dm_simulator.jl")
sv_oq3_program = OpenQasmProgram(braketSchemaHeader("braket.ir.openqasm.program", "1"), sv_exact_results_qasm, nothing)
dm_oq3_program = OpenQasmProgram(braketSchemaHeader("braket.ir.openqasm.program", "1"), dm_exact_results_qasm, nothing)
simulate(sv_simulator, sv_oq3_program, 0)
simulate("braket_sv_v2", sv_exact_results_qasm, "{}", 0)
simulate(dm_simulator, dm_oq3_program, 0)
simulate("braket_sv_v2", sv_exact_results_qasm, "{}", 0)
simulate("braket_dm_v2", dm_exact_results_qasm, "{}", 0)
oq3_program = OpenQasmProgram(braketSchemaHeader("braket.ir.openqasm.program", "1"), shots_results_qasm, nothing)
simulate(sv_simulator, oq3_program, 10)
Expand Down
812 changes: 297 additions & 515 deletions src/Quasar.jl

Large diffs are not rendered by default.

91 changes: 39 additions & 52 deletions src/builtin_gates.jl
Original file line number Diff line number Diff line change
@@ -1,92 +1,79 @@
# OpenQASM 3 Braket Standard Gates
builtin_gates() = Dict{String, GateDefinition}(
builtin_gates() = Dict{String, BuiltinGateDefinition}(
# identity gate
"i"=>GateDefinition("i", String[], ["a"], Instruction(BraketSimulator.I(), 0)),
"i"=>BuiltinGateDefinition("i", String[], ["a"], (type="i", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# phase gate
"phaseshift"=>GateDefinition("phaseshift", ["λ"], ["a"], Instruction(BraketSimulator.PhaseShift(BraketSimulator.FreeParameter()), 0)),
"phaseshift"=>BuiltinGateDefinition("phaseshift", ["λ"], ["a"], (type="phaseshift", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# pauli X gate
"x"=>GateDefinition("x", String[], ["a"], Instruction(BraketSimulator.X(), 0)),
"x"=>BuiltinGateDefinition("x", String[], ["a"], (type="x", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# pauli Y gate
"y"=>GateDefinition("y", String[], ["a"], Instruction(BraketSimulator.Y(), 0)),
"y"=>BuiltinGateDefinition("y", String[], ["a"], (type="y", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# pauli Z gate
"z"=>GateDefinition("z", String[], ["a"], Instruction(BraketSimulator.Z(), 0)),
"z"=>BuiltinGateDefinition("z", String[], ["a"], (type="z", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# Hadamard gate
"h"=>GateDefinition("h", String[], ["a"], Instruction(BraketSimulator.H(), 0)),
"h"=>BuiltinGateDefinition("h", String[], ["a"], (type="h", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# S gate
"s"=>GateDefinition("s", String[], ["a"], Instruction(BraketSimulator.S(), 0)),
"s"=>BuiltinGateDefinition("s", String[], ["a"], (type="s", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# Si gate
"si"=>GateDefinition("si", String[], ["a"], Instruction(BraketSimulator.Si(), 0)),
"si"=>BuiltinGateDefinition("si", String[], ["a"], (type="si", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# T gate
"t"=>GateDefinition("t", String[], ["a"], Instruction(BraketSimulator.T(), 0)),
"t"=>BuiltinGateDefinition("t", String[], ["a"], (type="t", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# Ti gate
"ti"=>GateDefinition("ti", String[], ["a"], Instruction(BraketSimulator.Ti(), 0)),
"ti"=>BuiltinGateDefinition("ti", String[], ["a"], (type="ti", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# V gate
"v"=>GateDefinition("v", String[], ["a"], Instruction(BraketSimulator.V(), 0)),
"v"=>BuiltinGateDefinition("v", String[], ["a"], (type="v", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# Vi gate
"vi"=>GateDefinition("vi", String[], ["a"], Instruction(BraketSimulator.Vi(), 0)),
"vi"=>BuiltinGateDefinition("vi", String[], ["a"], (type="vi", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# RotX gate
"rx"=>GateDefinition("rx", ["θ"], ["a"], Instruction(BraketSimulator.Rx(BraketSimulator.FreeParameter()), 0)),
"rx"=>BuiltinGateDefinition("rx", ["θ"], ["a"], (type="rx", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# RotY gate
"ry"=>GateDefinition("ry", ["θ"], ["a"], Instruction(BraketSimulator.Ry(BraketSimulator.FreeParameter()), 0)),
"ry"=>BuiltinGateDefinition("ry", ["θ"], ["a"], (type="ry", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# RotZ gate
"rz"=>GateDefinition("rz", ["θ"], ["a"], Instruction(BraketSimulator.Rz(BraketSimulator.FreeParameter()), 0)),
"rz"=>BuiltinGateDefinition("rz", ["θ"], ["a"], (type="rz", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# CNot gate
"cnot"=>GateDefinition("cnot", String[], ["a", "b"], Instruction(BraketSimulator.CNot(), BraketSimulator.QubitSet(0, 1))),
"cnot"=>BuiltinGateDefinition("cnot", String[], ["a", "b"], (type="cnot", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# CY gate
"cy"=>GateDefinition("cy", String[], ["a", "b"], Instruction(BraketSimulator.CY(), BraketSimulator.QubitSet(0, 1))),
"cy"=>BuiltinGateDefinition("cy", String[], ["a", "b"], (type="cy", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# CZ gate
"cz"=>GateDefinition("cz", String[], ["a", "b"], Instruction(BraketSimulator.CZ(), BraketSimulator.QubitSet(0, 1))),
"cz"=>BuiltinGateDefinition("cz", String[], ["a", "b"], (type="cz", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# CV gate
"cv"=>GateDefinition("cv", String[], ["a", "b"], Instruction(BraketSimulator.CV(), BraketSimulator.QubitSet(0, 1))),
"cv"=>BuiltinGateDefinition("cv", String[], ["a", "b"], (type="cv", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# controlled-phase
"cphaseshift"=>GateDefinition("cphaseshift", ["λ"], ["a", "b"], Instruction(BraketSimulator.CPhaseShift(BraketSimulator.FreeParameter()), BraketSimulator.QubitSet(0, 1))),
"cphaseshift"=>BuiltinGateDefinition("cphaseshift", ["λ"], ["a", "b"], (type="cphaseshift", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# controlled-phase-00
"cphaseshift00"=>GateDefinition("cphaseshift00", ["λ"], ["a", "b"], Instruction(BraketSimulator.CPhaseShift00(BraketSimulator.FreeParameter()), BraketSimulator.QubitSet(0, 1))),
"cphaseshift00"=>BuiltinGateDefinition("cphaseshift00", ["λ"], ["a", "b"], (type="cphaseshift00", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# controlled-phase-01
"cphaseshift01"=>GateDefinition("cphaseshift01", ["λ"], ["a", "b"], Instruction(BraketSimulator.CPhaseShift01(BraketSimulator.FreeParameter()), BraketSimulator.QubitSet(0, 1))),
"cphaseshift01"=>BuiltinGateDefinition("cphaseshift01", ["λ"], ["a", "b"], (type="cphaseshift01", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# controlled-phase-10
"cphaseshift10"=>GateDefinition("cphaseshift10", ["λ"], ["a", "b"], Instruction(BraketSimulator.CPhaseShift10(BraketSimulator.FreeParameter()), BraketSimulator.QubitSet(0, 1))),
"cphaseshift10"=>BuiltinGateDefinition("cphaseshift10", ["λ"], ["a", "b"], (type="cphaseshift10", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# Swap gate
"swap"=>GateDefinition("swap", String[], ["a", "b"], Instruction(BraketSimulator.Swap(), BraketSimulator.QubitSet(0, 1))),
"swap"=>BuiltinGateDefinition("swap", String[], ["a", "b"], (type="swap", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# ISwap gate
"iswap"=>GateDefinition("iswap", String[], ["a", "b"], Instruction(BraketSimulator.ISwap(), BraketSimulator.QubitSet(0, 1))),
"iswap"=>BuiltinGateDefinition("iswap", String[], ["a", "b"], (type="iswap", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# ISwap gate
"pswap"=>GateDefinition("pswap", ["θ"], ["a", "b"], Instruction(BraketSimulator.PSwap(BraketSimulator.FreeParameter()), BraketSimulator.QubitSet(0, 1))),
"pswap"=>BuiltinGateDefinition("pswap", ["θ"], ["a", "b"], (type="pswap", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# controlled-swap gate
"cswap"=>GateDefinition("cswap", String[], ["a", "b", "c"], Instruction(BraketSimulator.CSwap(), BraketSimulator.QubitSet(0, 1, 2))),
"cswap"=>BuiltinGateDefinition("cswap", String[], ["a", "b", "c"], (type="cswap", arguments=InstructionArgument[], targets=[0, 1, 2], controls=Pair{Int,Int}[], exponent=1.0)),
# ccnot/Toffoli gate
"ccnot"=>GateDefinition("ccnot", String[], ["a", "b", "c"], Instruction(BraketSimulator.CCNot(), BraketSimulator.QubitSet(0, 1, 2))),
"ccnot"=>BuiltinGateDefinition("ccnot", String[], ["a", "b", "c"], (type="ccnot", arguments=InstructionArgument[], targets=[0, 1, 2], controls=Pair{Int,Int}[], exponent=1.0)),
# XX gate
"xx"=>GateDefinition("xx", ["θ"], ["a", "b"], Instruction(BraketSimulator.XX(BraketSimulator.FreeParameter()), BraketSimulator.QubitSet(0, 1))),
"xx"=>BuiltinGateDefinition("xx", ["θ"], ["a", "b"], (type="xx", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# XY gate
"xy"=>GateDefinition("xy", ["θ"], ["a", "b"], Instruction(BraketSimulator.XY(BraketSimulator.FreeParameter()), BraketSimulator.QubitSet(0, 1))),
"xy"=>BuiltinGateDefinition("xy", ["θ"], ["a", "b"], (type="xy", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# YY gate
"yy"=>GateDefinition("yy", ["θ"], ["a", "b"], Instruction(BraketSimulator.YY(BraketSimulator.FreeParameter()), BraketSimulator.QubitSet(0, 1))),
"yy"=>BuiltinGateDefinition("yy", ["θ"], ["a", "b"], (type="yy", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# ZZ gate
"zz"=>GateDefinition("zz", ["θ"], ["a", "b"], Instruction(BraketSimulator.ZZ(BraketSimulator.FreeParameter()), BraketSimulator.QubitSet(0, 1))),
"zz"=>BuiltinGateDefinition("zz", ["θ"], ["a", "b"], (type="zz", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# ECR gate
"ecr"=>GateDefinition("ecr", String[], ["a", "b"], Instruction(BraketSimulator.ECR(), BraketSimulator.QubitSet(0, 1))),
"ecr"=>BuiltinGateDefinition("ecr", String[], ["a", "b"], (type="ecr", arguments=InstructionArgument[], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# MS gate
"ms"=>GateDefinition("ms", ["ϕ", "θ", "λ"], ["a", "b"], Instruction(BraketSimulator.MS(BraketSimulator.FreeParameter(), BraketSimulator.FreeParameter(), BraketSimulator.FreeParameter()), BraketSimulator.QubitSet(0, 1))),
"ms"=>BuiltinGateDefinition("ms", ["ϕ", "θ", "λ"], ["a", "b"], (type="ms", arguments=InstructionArgument[, , ], targets=[0, 1], controls=Pair{Int,Int}[], exponent=1.0)),
# GPi gate
"gpi"=>GateDefinition("gpi", ["θ"], ["a"], Instruction(BraketSimulator.GPi(BraketSimulator.FreeParameter()), 0)),
"gpi"=>BuiltinGateDefinition("gpi", ["θ"], ["a"], (type="gpi", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# GPi2 gate
"gpi2"=>GateDefinition("gpi2", ["θ"], ["a"], Instruction(BraketSimulator.GPi2(BraketSimulator.FreeParameter()), 0)),
"gpi2"=>BuiltinGateDefinition("gpi2", ["θ"], ["a"], (type="gpi2", arguments=InstructionArgument[], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# PRx gate
"prx"=>GateDefinition("prx", ["θ", "ϕ"], ["a"], Instruction(BraketSimulator.PRx(BraketSimulator.FreeParameter(), BraketSimulator.FreeParameter()), 0)),
"prx"=>BuiltinGateDefinition("prx", ["θ", "ϕ"], ["a"], (type="prx", arguments=InstructionArgument[, ], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
# 3-angle U gate
"U"=>GateDefinition("U", ["θ", "ϕ", "λ"], ["a"], Instruction(BraketSimulator.U(BraketSimulator.FreeParameter(), BraketSimulator.FreeParameter(), BraketSimulator.FreeParameter()), 0)),
"U"=>BuiltinGateDefinition("U", ["θ", "ϕ", "λ"], ["a"], (type="u", arguments=InstructionArgument[, , ], targets=[0], controls=Pair{Int,Int}[], exponent=1.0)),
)

const noise_types = Dict{String, Type}(
"bit_flip"=>BraketSimulator.BitFlip,
"phase_flip"=>BraketSimulator.PhaseFlip,
"pauli_channel"=>BraketSimulator.PauliChannel,
"depolarizing"=>BraketSimulator.Depolarizing,
"two_qubit_depolarizing"=>BraketSimulator.TwoQubitDepolarizing,
"two_qubit_dephasing"=>BraketSimulator.TwoQubitDephasing,
"amplitude_damping"=>BraketSimulator.AmplitudeDamping,
"generalized_amplitude_damping"=>BraketSimulator.GeneralizedAmplitudeDamping,
"phase_damping"=>BraketSimulator.PhaseDamping,
"kraus"=>BraketSimulator.Kraus,
)
35 changes: 35 additions & 0 deletions src/circuit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,38 @@ function add_instruction!(c::Circuit, ix::Instruction{O}) where {O<:Operator}
push!(c.instructions, ix)
return c
end

function to_circuit(v::Quasar.QasmProgramVisitor)
c = Circuit()
foreach(v.instructions) do ix
sim_op = StructTypes.constructfrom(QuantumOperator, ix)
op = isempty(ix.controls) ? sim_op : Control(sim_op, tuple(map(c->getindex(c, 2), ix.controls)...))
sim_ix = Instruction(op, ix.targets)
add_instruction!(c, sim_ix)
end
for rt in v.results
sim_rt = StructTypes.constructfrom(Result, rt)
obs = extract_observable(sim_rt)
if !isnothing(obs) && c.observables_simultaneously_measureable && !(rt isa AdjointGradient)
add_to_qubit_observable_mapping!(c, obs, sim_rt.targets)
end
add_to_qubit_observable_set!(c, sim_rt)
push!(c.result_types, sim_rt)
end
return c
end

# semgrep rules can't handle this macro properly yet
function to_circuit(qasm_source::String, inputs)
input_qasm = if endswith(qasm_source, ".qasm") && isfile(qasm_source)
read(qasm_source, String)
else
qasm_source
end
endswith(input_qasm, "\n") || (input_qasm *= "\n")
parsed = parse_qasm(input_qasm)
visitor = QasmProgramVisitor(inputs)
visitor(parsed)
return to_circuit(visitor)
end
to_circuit(qasm_source::String) = to_circuit(qasm_source, Dict{String, Float64}())
19 changes: 10 additions & 9 deletions src/custom_gates.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,22 @@ end
qubit_count(g::MultiRZ) = 1

"""
MultiQubitPhaseShift{N}(angle)
GPhase{N}(angle)
Global phase shift on `N` qubits. Equivalent to
the OpenQASM3 built-in [`gphase` gate](https://openqasm.com/language/gates.html#gphase).
Controls/negative controls applied to this gate control
which states are rotated, so that `Control(g::MultiQubitPhaseShift{2})` will apply the rotation
which states are rotated, so that `Control(g::GPhase{2})` will apply the rotation
to the `|11>` state.
"""
mutable struct MultiQubitPhaseShift{N} <: AngledGate{1}
mutable struct GPhase{N} <: AngledGate{1}
angle::NTuple{1,Union{Real,FreeParameter}}
pow_exponent::Float64
MultiQubitPhaseShift{N}(angle::T, pow_exponent::Float64=1.0) where {N, T<:NTuple{1,Union{Real,FreeParameter}}} = new(angle, pow_exponent)
GPhase{N}(angle::T, pow_exponent::Float64=1.0) where {N, T<:NTuple{1,Union{Real,FreeParameter}}} = new(angle, pow_exponent)
end
matrix_rep_raw(g::MultiQubitPhaseShift{N}) where {N} = Diagonal(SVector{2^N, ComplexF64}(exp(im*g.angle[1]) for _ in 1:2^N))
qubit_count(g::MultiQubitPhaseShift{N}) where {N} = N
matrix_rep_raw(g::GPhase{N}) where {N} = Diagonal(SVector{2^N, ComplexF64}(exp(im*g.angle[1]) for _ in 1:2^N))
qubit_count(g::GPhase{N}) where {N} = N
StructTypes.constructfrom(::Type{GPhase}, nt::Quasar.CircuitInstruction) = GPhase{length(nt.targets)}(only(nt.arguments), nt.exponent)

function apply_gate!(
factor::ComplexF64,
Expand All @@ -75,7 +76,7 @@ for (V, f) in ((true, :conj), (false, :identity))
apply_gate!(::Val{$V}, g::MultiRZ, state_vec::AbstractStateVector{T}, t::Int) where {T<:Complex} = apply_gate!(Val($V), Rz(g.angle, g.pow_exponent), state_vec, t)
apply_gate!(::Val{$V}, g::MultiRZ, state_vec::AbstractStateVector{T}, t1::Int,t2::Int,) where {T<:Complex} = apply_gate!(Val($V), ZZ(g.angle, g.pow_exponent), state_vec, t1, t2)
apply_gate!(::Val{$V}, g::MultiRZ, state_vec::AbstractStateVector{T}, ts::Vararg{Int,N}) where {T<:Complex,N} = apply_gate!($f(-im * g.angle[1] / 2.0), PauliEigenvalues(Val(N)), state_vec, ts...)
apply_gate!(::Val{$V}, g::MultiQubitPhaseShift{N}, state_vec::AbstractStateVector{T}, ts::Vararg{Int,N}) where {T<:Complex, N} = apply_gate!($f(exp(im*g.angle[1]*g.pow_exponent)), state_vec, ts...)
apply_gate!(::Val{$V}, g::GPhase{N}, state_vec::AbstractStateVector{T}, ts::Vararg{Int,N}) where {T<:Complex, N} = apply_gate!($f(exp(im*g.angle[1]*g.pow_exponent)), state_vec, ts...)
end
end

Expand Down Expand Up @@ -119,7 +120,7 @@ Control(g::Control{G, BC}, bitvals::NTuple{0, Int}, pow_exponent::Float64=1.0) w
Control(g::G, bitvals::NTuple{0, Int}, pow_exponent::Float64=1.0) where {G<:Gate} = g
Base.copy(c::Control{G, B}) where {G<:Gate, B} = Control(copy(c.g), c.bitvals, c.pow_exponent)
qubit_count(c::Control{G, B}) where {G<:Gate, B} = qubit_count(c.g) + B
qubit_count(c::Control{MultiQubitPhaseShift{N}, B}) where {N, B} = N
qubit_count(c::Control{GPhase{N}, B}) where {N, B} = N
function matrix_rep_raw(c::Control{G, B}) where {G<:Gate, B}
inner_mat = matrix_rep(c.g)
inner_qc = qubit_count(c.g)
Expand All @@ -134,7 +135,7 @@ function matrix_rep_raw(c::Control{G, B}) where {G<:Gate, B}
end
return full_mat
end
function matrix_rep_raw(c::Control{MultiQubitPhaseShift{N}, B}) where {N, B}
function matrix_rep_raw(c::Control{GPhase{N}, B}) where {N, B}
g_mat = matrix_rep(c.g)
qc = N
ctrl_ix = 0
Expand Down
Loading

0 comments on commit 98ee205

Please sign in to comment.