Skip to content
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

Piecemaker #159

Draft
wants to merge 12 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add this file to .gitignore

Binary file not shown.
6 changes: 5 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
name = "QuantumSavory"
uuid = "2de2e421-972c-4cb5-a0c3-999c85908079"
authors = ["Stefan Krastanov <[email protected]>"]
version = "0.6"
version = "0.6.0"

[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
ConcurrentSim = "6ed1e86c-fcaf-46a9-97e0-2b26a2cdb499"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
Expand All @@ -22,7 +24,9 @@ QuantumSymbolics = "efa7fd63-0460-4890-beb7-be1bbdfbaeae"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
ResumableFunctions = "c5292f4c-5179-55e1-98c5-05642aab7184"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These do not seem to be library dependencies, rather just example dependencies. They can go in an example Project.toml or just be left out.

SumTypes = "8e1ec7a9-0e02-4297-b0fe-6433085c89f2"

[weakdeps]
Expand Down
52 changes: 52 additions & 0 deletions examples/piecemakerswitch/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# System Overview
A central switch node connects to **n** clients. The switch possesses **m = n + 1** qubit slots, while each client has a single qubit slot.

# Entanglement Initiation
At each clock tick, the switch initiates entanglement attempts with each of the **n** clients, resulting in **n** entanglement processes per cycle. Successful entanglement links are then merged into a GHZ (Greenberger–Horne–Zeilinger) state using an additional "piecemaker" qubit located in the \((n + 1)\)th slot of the switch node. This fusion process is assumed to occur instantaneously. Once all clients went through the fusion operation, the piecemaker qubit is measured out. This completes the fusing process and all nodes are sharing an n-GHZ state.

# Fusion Operation
The fusion operation consists of applying a **CNOT** gate followed by a measurement in the computational basis. This procedure allows the merging of two GHZ states into a single GHZ state, modulo any required Pauli corrections. We iterate over all existing entangled states with the switch node: in each iteration, the piecemaker qubit (initialized in the state \(|+\rangle\)) is fused with one of the existing entangled states.

# Noise
The memories residing the nodes' `Register`s suffer from depolarizing noise. The latter is modelled via Kraus operators applied to the current state's density matrix.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the nodes

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of Kraus operators is just the default due to using state vectors. The simulator might decide to not use Kraus operators if it defaults to a different representation (e.g. tableaux)


### Protocol flow

```mermaid
sequenceDiagram
participant Client1
participant ClientN

participant SwitchNode
participant Log

Note over Client1,SwitchNode: Round 1 (1 unit time)
par Entanglement Generation
Client1->>+SwitchNode: Try to generate entanglement
ClientN->>+SwitchNode: Try to generate entanglement
end

SwitchNode->>SwitchNode: Run fusions with successful clients

par Send Measurement Outcomes
SwitchNode-->>-Client1: Send measurement outcomes
SwitchNode-->>-ClientN: Send measurement outcomes
end

par Apply Corrections (No time cost)
Client1->>Client1: Apply correction gates
ClientN->>ClientN: Apply correction gates
end

loop Check Fusion Status (No time cost)
SwitchNode->>SwitchNode: Check if all clients are fused
alt All clients fused
SwitchNode->>SwitchNode: Measure piecemaker
SwitchNode->>SwitchNode: Compute fidelity to GHZ state
SwitchNode->>Log: Log fidelity and time
SwitchNode->>SwitchNode: Trigger STOP
else
SwitchNode->>SwitchNode: Keep checking
end
end
```
45 changes: 45 additions & 0 deletions examples/piecemakerswitch/setup.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using QuantumSavory
using QuantumSavory.ProtocolZoo
using Graphs
using ConcurrentSim
using ResumableFunctions
using Distributions
using DataFrames
using CSV
using StatsPlots


function prepare_simulation(nclients=2, mem_depolar_prob = 0.1, link_success_prob = 0.5)

m = nclients+1 # memory slots in switch is equal to the number of clients + 1 slot for piecemaker qubit
r_depol = - log(1 - mem_depolar_prob) # depolarization rate

# The graph of network connectivity. Index 1 corresponds to the switch.
graph = star_graph(nclients+1)

switch_register = Register(m, Depolarization(1/r_depol)) # the first slot is reserved for the 'piecemaker' qubit used as fusion qubit
client_registers = [Register(1, Depolarization(1/r_depol)) for _ in 1:nclients] #Depolarization(1/r_depol)
net = RegisterNet(graph, [switch_register, client_registers...])
sim = get_time_tracker(net)

# Set up the initial |+> state of the piecemaker qubit
initialize!(net[1][m], X1)

event_ghz_state = Event(sim)

# Set up the entanglement trackers at each client
trackers = [EntanglementTracker(sim, net, k) for k in 2:nclients+1]
for tracker in trackers
@process tracker()
end

# Finally, set up the switch without assignments
switch_protocol = FusionSwitchDiscreteProt(net, 1, 2:nclients+1, fill(link_success_prob, nclients); ticktock=1)
@process switch_protocol()

# Set up an entanglement consumer between each unordered pair of clients
consumer = FusionConsumer(net, net[1][m], event_ghz_state; period=1)
@process consumer()

return sim, consumer
end
57 changes: 57 additions & 0 deletions examples/piecemakerswitch/simple_run.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
include("setup.jl")
using DataFrames
using CSV

name = "qs_piecemeal"
nruns = 1000
mem_depolar_prob = 0.1
link_success_prob = 0.5

results_per_client = DataFrame[]
for nclients in 2:3
# Prepare simulation components
distribution_times = Float64[]
fidelities = Float64[]
elapsed_times = Float64[]

for i in 1:nruns
sim, consumer = prepare_simulation(nclients, mem_depolar_prob, link_success_prob)
elapsed_time = @elapsed run(sim)

# Extract data from consumer.log
distribution_time, fidelity = consumer.log[1]
append!(distribution_times, distribution_time)
append!(fidelities, fidelity)
append!(elapsed_times, elapsed_time)
@info "Run $i completed"
end

# Initialize results DataFrame
results = DataFrame(
distribution_times = distribution_times,
fidelities = fidelities,
elapsed_times = elapsed_times
)
results.num_remote_nodes .= nclients
results.link_success_prob .= link_success_prob
results.mem_depolar_prob .= mem_depolar_prob
results.type .= name

push!(results_per_client, results)
@info "Clients $nclients completed"
end
results_total = vcat(results_per_client...)

# Group and summarize the data
grouped_df = groupby(results_total, [:num_remote_nodes, :distribution_times])
summary_df = combine(
grouped_df,
:fidelities => mean => :mean_fidelities,
:fidelities => std => :std_fidelities
)

@info summary_df

# Write results to CSV
# CSV.write("examples/piecemakerswitch/output/piecemaker2-9.csv", results_total)
# CSV.write("examples/piecemakerswitch/output/piecemaker2-9_summary.csv", summary_df)
12 changes: 11 additions & 1 deletion src/CircuitZoo/CircuitZoo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module CircuitZoo
using QuantumSavory
using DocStringExtensions

export EntanglementSwap, LocalEntanglementSwap,
export EntanglementFusion, EntanglementSwap, LocalEntanglementSwap,
Purify2to1, Purify2to1Node, Purify3to1, Purify3to1Node,
PurifyStringent, PurifyStringentNode, PurifyExpedient, PurifyExpedientNode,
SDDecode, SDEncode
Expand Down Expand Up @@ -46,6 +46,16 @@ end

inputqubits(::LocalEntanglementSwap) = 2

struct EntanglementFusion <: AbstractCircuit
end

function (::EntanglementFusion)(localq, piecemaker)
apply!((piecemaker, localq), CNOT)
zmeas = project_traceout!(localq, σᶻ)
zmeas
end

inputqubits(::EntanglementFusion) = 2
Comment on lines +49 to +58
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add tests for the correctness of this circuit?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and a docstring


"""
$TYPEDEF
Expand Down
Loading