Skip to content

Commit 0387ac5

Browse files
committed
much better design (without circuit)
1 parent 7c2c394 commit 0387ac5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+670
-300
lines changed

CondaPkg.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[deps]
2-
qiskit-aer = "0.16.1.*"
3-
qiskit-ibm-runtime = "0.37.0.*"
4-
qiskit = "1.4.2.*"
2+
qiskit-aer = ""
3+
qiskit-ibm-runtime = ""
4+
qiskit = ""
55

66
[pip.deps]
77
stim = ""

src/Backends/Qiskit/IBMBackend.jl

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,24 @@ A Qiskit backend that runs on IBM's quantum computers.
66
"""
77
struct IBMBackend <: MQC.QuantumComputer
88
python_interface::PythonCall.Py
9+
circuit::Circuit
910

10-
function IBMBackend(backend::PythonCall.Py)
11+
function IBMBackend(backend::PythonCall.Py, nqubits::Integer)
1112
_checkinit_qiskit()
12-
new(backend)
13+
new(backend, Circuit(nqubits+1,nqubits+1))
1314
end
1415

15-
function IBMBackend(name::String)
16+
function IBMBackend(nqubits::Integer)
1617
_checkinit_qiskit()
1718
runtime = QiskitRuntimeService()
18-
backend = getBackend(runtime, name)
19-
new(backend)
19+
backend = least_buisy(runtime,nqubits)
20+
new(backend, Circuit(nqubits+1,nqubits+1))
2021
end
21-
function IBMBackend(name::String, api_key::String)
22+
function IBMBackend(nqubits::Integer, api_key::String)
2223
_checkinit_qiskit()
2324
runtime = QiskitRuntimeService(api_key)
24-
backend = runtime.get_backend(name)
25-
new(backend)
25+
backend = least_buisy(runtime,nqubits)
26+
new(backend,Circuit(nqubits+1,nqubits+1))
2627
end
2728
end
2829
function Base.getproperty(qc::IBMBackend, prop::Symbol)
@@ -33,10 +34,21 @@ function Base.getproperty(qc::IBMBackend, prop::Symbol)
3334
end
3435
end
3536

37+
function get_circuit(backend::IBMBackend)
38+
return getfield(backend,:circuit)
39+
end
40+
3641
function Base.show(io::IO, ::MIME"text/plain", obj::IBMBackend)
3742
println(io, "Name: $(obj.name)")
38-
println(io, "Qubits: $(obj.num_qubits)")
39-
println(io, "Max shots: $(obj.max_shots)")
43+
println(io, get_circuit(obj).python_interface)
44+
end
45+
46+
function MQC.execute(backend::IBMBackend; shots=1)
47+
qc = get_circuit(backend)
48+
transpile!(qc, backend)
49+
sampler = Sampler(backend)
50+
job = run(sampler, qc)
51+
println("Job ID: $(job.job_id())")
4052
end
4153

4254
function execute(circuit::MQC.Circuit, backend::IBMBackend; verbose::Bool=true)

src/Backends/Qiskit/Qiskit.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,5 +95,7 @@ include("operations/Weak_XX.jl")
9595
include("operations/Weak_YY.jl")
9696
include("operations/Pauli.jl")
9797
include("operations/I.jl")
98-
98+
include("operations/X.jl")
99+
include("operations/Y.jl")
100+
include("operations/Z.jl")
99101
end

src/Backends/Qiskit/QiskitRuntimeService.jl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@ struct QiskitRuntimeService
44
function QiskitRuntimeService()
55
_checkinit_qiskit()
66
try
7-
runtimeService = qiskit_ibm_runtime.QiskitRuntimeService(channel="ibm_quantum")
7+
runtimeService = qiskit_ibm_runtime.QiskitRuntimeService()
88
new(runtimeService)
99
catch
1010
throw(ArgumentError("Could not connect to IBM Quantum. Please provide an API key."))
1111
end
1212
end
1313
function QiskitRuntimeService(api_key::String)
1414
_checkinit_qiskit()
15-
runtimeService = qiskit_ibm_runtime.QiskitRuntimeService(token=api_key, channel="ibm_quantum")
16-
runtimeService.save_account(token=api_key, channel="ibm_quantum", overwrite=true)
15+
qiskit_ibm_runtime.QiskitRuntimeService.save_account(token=api_key, set_as_default=true)
16+
runtimeService = qiskit_ibm_runtime.QiskitRuntimeService()
17+
1718
new(runtimeService)
1819
end
1920
end
@@ -33,6 +34,11 @@ function getBackend(qc::QiskitRuntimeService, name::String)
3334
backend = qc.get_backend(name)
3435
return IBMBackend(backend)
3536
end
37+
function least_buisy(qc::QiskitRuntimeService,nqubits::Integer)
38+
qc.least_busy(
39+
operational=true, simulator=false, min_num_qubits=nqubits
40+
)
41+
end
3642

3743
function Base.show(io::IO, ::MIME"text/plain", obj::QiskitRuntimeService)
3844
account_info = activeAccount(obj)

src/Backends/Qiskit/QuantumCircuit.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Base.show(io::IO, ::MIME"text/plain", obj::Circuit) = print(io, obj.python_inter
2222

2323

2424
function nQubits(circuit::Circuit)
25-
return circuit.n_qubits
25+
return circuit.num_qubits
2626
end
2727

2828
function depth(operation::MQC.Operation, ::Type{Circuit})

src/Backends/Qiskit/Sampler.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ struct Sampler
22
python_interface::PythonCall.Py
33
function Sampler(backend::String)
44
_checkinit_qiskit()
5-
new(qiskit_ibm_runtime.SamplerV2(backend=backend))
5+
new(qiskit_ibm_runtime.SamplerV2(backend))
66
end
77
function Sampler(backend::IBMBackend)
88
_checkinit_qiskit()
9-
new(qiskit_ibm_runtime.SamplerV2(backend=backend.python_interface))
9+
new(qiskit_ibm_runtime.SamplerV2(backend.python_interface))
1010
end
1111
function Sampler(backend::AerSimulator)
1212
_checkinit_qiskit()

src/Backends/Qiskit/Simulation.jl

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,72 @@
11

22
struct AerSimulator <: MQC.Simulator
33
python_interface::PythonCall.Py
4+
circuit::Circuit
45
end
56
"""
67
GPUStateVectorSimulator()
78
89
A Qiskit Aer statevector simulator that runs on the GPU.
910
"""
10-
function GPUStateVectorSimulator()
11+
function GPUStateVectorSimulator(nqubits::Integer)
1112
_checkinit_qiskit_aer(; gpu=true)
1213
AerSimulator(qiskit_aer.AerSimulator(
1314
method="statevector",
1415
device="GPU",
1516
cuStateVec_enable=true,
1617
enable_truncation=false,
17-
target=[0]
18-
))
18+
target=[0]),
19+
Circuit(nqubits+1,nqubits+1))
1920
end
2021

2122
"""
2223
StateVectorSimulator()
2324
2425
A Qiskit Aer statevector simulator.
2526
"""
26-
function StateVectorSimulator()
27+
function StateVectorSimulator(nqubits::Integer)
2728
_checkinit_qiskit_aer()
28-
AerSimulator(qiskit_aer.AerSimulator(
29+
AerSimulator(
30+
qiskit_aer.AerSimulator(
2931
method="statevector",
30-
enable_truncation=false
31-
))
32+
enable_truncation=false),
33+
Circuit(nqubits+1,nqubits+1))
3234
end
3335

3436
"""
3537
CliffordSimulator()
3638
3739
A Qiskit Aer stabilizer simulator.
3840
"""
39-
function CliffordSimulator()
41+
function CliffordSimulator(nqubits::Integer)
4042
_checkinit_qiskit_aer()
41-
AerSimulator(qiskit_aer.AerSimulator(method="stabilizer"))
43+
AerSimulator(
44+
qiskit_aer.AerSimulator(method="stabilizer"),
45+
Circuit(nqubits+1,nqubits+1))
4246
end
4347

4448
"""
4549
GPUTensorNetworkSimulator()
4650
4751
A Qiskit Aer tensor network simulator that runs on the GPU.
4852
"""
49-
function GPUTensorNetworkSimulator()
53+
function GPUTensorNetworkSimulator(nqubits::Integer)
5054
_checkinit_qiskit_aer(; gpu=true)
5155
AerSimulator(qiskit_aer.AerSimulator(
5256
method="tensor_network",
5357
device="GPU",
5458
cuStateVec_enable=true,
5559
use_cuTensorNet_autotuning=true,
5660
enable_truncation=false,
57-
target=[0]
58-
))
61+
target=[0]),
62+
Circuit(nqubits+1,nqubits+1))
5963
end
6064
function isSimulator(::AerSimulator)
6165
return true
6266
end
6367

6468
function Base.show(io::IO, ::MIME"text/plain", obj::AerSimulator)
65-
println(io, "Name: $(obj.name)")
66-
println(io, "Qubits: $(obj.num_qubits)")
69+
println(io, get_circuit(obj).python_interface)
6770
end
6871

6972
function Base.getproperty(qc::AerSimulator, prop::Symbol)
@@ -74,6 +77,24 @@ function Base.getproperty(qc::AerSimulator, prop::Symbol)
7477
end
7578
end
7679

80+
function get_circuit(qc::AerSimulator)
81+
return getfield(qc, :circuit)
82+
end
83+
84+
function aux(backend::Union{AerSimulator,IBMBackend})
85+
# Ancilla qubit is the last qubit in the circuit
86+
return nQubits(get_circuit(backend))
87+
end
88+
89+
function MQC.execute(backend::AerSimulator; shots=1)
90+
qc = get_circuit(backend)
91+
transpile!(qc, backend)
92+
sampler = Sampler(backend)
93+
job = run(sampler, qc; shots)
94+
nativeResult = job.result()[0]
95+
return nativeResult
96+
end
97+
7798
function MQC.execute(circuit::MQC.CompiledCircuit, backend::AerSimulator; shots=1024)
7899
verbose = false
79100
verbose && print("Transpiling circuit to Qiskit...")

src/Backends/Qiskit/Transpiler.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,11 @@ function transpile!(circuit::Circuit, backend::AerSimulator; optimization::Integ
88
0 <= optimization <= 3 || throw(ArgumentError("Degree must be between 0 and 3"))
99
circuit.python_interface = qiskit.compiler.transpile(circuit.python_interface, backend.python_interface, optimization_level=optimization)
1010
end
11+
12+
13+
function transpile!(backend::Union{AerSimulator,IBMBackend}; optimization::Integer=3)
14+
0 <= optimization <= 3 || throw(ArgumentError("Degree must be between 0 and 3"))
15+
qc = circuit(backend)
16+
qc.python_interface = qiskit.compiler.transpile(qc.python_interface, backend.python_interface, optimization_level=optimization)
17+
return qc
18+
end
Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
1-
function apply!(qc::Circuit, ::MQC.CNOT, p::SubArray, ::Integer)
2-
p1 = p[1]
3-
p2 = p[2]
1+
# function apply!(qc::Circuit, ::MQC.CNOT, p::SubArray, ::Integer)
2+
# p1 = p[1]
3+
# p2 = p[2]
4+
# qc.cx(p1 - 1, p2 - 1)
5+
# end
6+
7+
function MQC.apply!(
8+
backend::Union{AerSimulator,IBMBackend},
9+
::MQC.CNOT,
10+
p1::Integer,
11+
p2::Integer)
12+
qc = get_circuit(backend)
413
qc.cx(p1 - 1, p2 - 1)
14+
return qc
515
end
Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1-
function apply!(qc::Circuit, ::MQC.H, p::SubArray, ::Integer)
2-
p1 = p[1]
3-
qc.h(p1 - 1)
1+
# function apply!(qc::Circuit, ::MQC.H, p::SubArray, ::Integer)
2+
# p1 = p[1]
3+
# qc.h(p1 - 1)
4+
# end
5+
6+
function MQC.apply!(
7+
backend::Union{AerSimulator,IBMBackend},
8+
::MQC.H,
9+
p::Integer)
10+
qc = get_circuit(backend)
11+
qc.h(p - 1)
12+
return qc
413
end

0 commit comments

Comments
 (0)