- 
                Notifications
    You must be signed in to change notification settings 
- Fork 24
Implement electron-nuclear spin register for MBQC distillation protocol #285
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
base: master
Are you sure you want to change the base?
Changes from 2 commits
a03356a
              feac4b0
              d7124c1
              47ae3a5
              69bcd9d
              92cda31
              cda8962
              673e66f
              c494885
              84eccf9
              5ec634e
              6a4f6e0
              f11fb92
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,235 @@ | ||||||
| using ResumableFunctions | ||||||
| using ConcurrentSim | ||||||
| using Revise | ||||||
| using Graphs | ||||||
| using QuantumSavory | ||||||
| using QuantumSavory.ProtocolZoo | ||||||
| import QuantumSavory: Tag | ||||||
|  | ||||||
| include("../graphstate/graph_preparer.jl") | ||||||
|  | ||||||
| using Logging | ||||||
| global_logger(ConsoleLogger(stderr, Logging.Debug)) | ||||||
|  | ||||||
|  | ||||||
| # let's just assume that the overall xor of the measurement results is all we need (maybe wrong) to decide if purification succeeded | ||||||
|  | ||||||
| @kwdef struct FusionMeasurement | ||||||
| node::Int | ||||||
| measurement::Int | ||||||
| end | ||||||
| Base.show(io::IO, tag::FusionMeasurement) = print(io, "Measurement for register $(tag.node) is $(tag.measurement).") | ||||||
| Tag(tag::FusionMeasurement) = Tag(FusionMeasurement, tag.node, tag.measurement) | ||||||
|  | ||||||
| @kwdef struct MBQCMeasurement | ||||||
| node::Int | ||||||
| measurement::Int | ||||||
| end | ||||||
| Base.show(io::IO, tag::MBQCMeasurement) = print(io, "Measurement for register $(tag.node) is $(tag.measurement).") | ||||||
| Tag(tag::MBQCMeasurement) = Tag(MBQCMeasurement, tag.node, tag.measurement) | ||||||
|  | ||||||
| @kwdef struct XORMeasurements | ||||||
| node::Int | ||||||
| xor_result::Int | ||||||
| end | ||||||
| Base.show(io::IO, tag::XORMeasurements) = print(io, "XOR measurement for register $(tag.node) is $(tag.xor_result).") | ||||||
| Tag(tag::XORMeasurements) = Tag(XORMeasurements, tag.node, tag.xor_result) | ||||||
|  | ||||||
| @kwdef struct PurifiedEntalgementCounterpart | ||||||
| remote_node::Int | ||||||
| remote_slot::Int | ||||||
| end | ||||||
| Base.show(io::IO, tag::PurifiedEntalgementCounterpart) = print(io, "Entangled to $(tag.remote_node).$(tag.remote_slot)") | ||||||
| Tag(tag::PurifiedEntalgementCounterpart) = Tag(PurifiedEntalgementCounterpart, tag.remote_node, tag.remote_slot) | ||||||
|  | ||||||
|  | ||||||
| # TODO: hardcoded for now | ||||||
| function graph_generator(initial_entanglements_nodes, purified_nodes) | ||||||
| g = Graph(4) | ||||||
| for ij in [(1,3), (2,3), (3,4)] | ||||||
| add_edge!(g, ij...) | ||||||
| end | ||||||
| return g | ||||||
| end | ||||||
|  | ||||||
| # TODO: right now, it just measures all but purified nodes | ||||||
| @resumable function measure(sim, net, side, purified_nodes, storage_slot) | ||||||
|          | ||||||
| graph = net.graph | ||||||
| n = nv(graph) | ||||||
| offset = side == 1 ? 0 : n÷2 | ||||||
| side_nodes = (1:n÷2) .+ offset | ||||||
| local_purified_nodes = purified_nodes .+ offset | ||||||
|  | ||||||
| xor_result = 0 | ||||||
| for node in side_nodes | ||||||
| if !(node in local_purified_nodes) | ||||||
| reg = net[node] | ||||||
| m = project_traceout!(reg[storage_slot], X) # TODO: fixed basis for now | ||||||
| tag!(reg[storage_slot], MBQCMeasurement, node, m) # storing the results for now, in case we need to something more sophisticated with them | ||||||
|          | ||||||
| xor_result = xor(xor_result, m - 1) | ||||||
| end | ||||||
| end | ||||||
|  | ||||||
| local_purified = purified_nodes[1] + offset # save XOR result in the first purified node | ||||||
| reg = net[local_purified] | ||||||
| tag!(reg[storage_slot], XORMeasurements, local_purified, xor_result) | ||||||
| remote_purified = purified_nodes[1] + (side == 1 ? n÷2 : 0) | ||||||
| put!(channel(net, local_purified=>remote_purified), Tag(XORMeasurements, local_purified, xor_result)) | ||||||
| # TODO: send the entangler fusion measurement info as well.. | ||||||
| end | ||||||
|  | ||||||
| @resumable function purification_tracker(sim, net, side, purified_nodes, storage_slot) | ||||||
|          | ||||||
| graph = net.graph | ||||||
| n = nv(graph) | ||||||
| offset = side == 1 ? 0 : n÷2 | ||||||
|  | ||||||
| # Local and remote purified nodes | ||||||
| local_purified = purified_nodes[1] + offset | ||||||
| remote_purified = purified_nodes[1] + (side == 1 ? n÷2 : 0) | ||||||
|  | ||||||
| nodereg = net[local_purified] | ||||||
| mb = messagebuffer(net, local_purified) | ||||||
|  | ||||||
| while true | ||||||
| # for local XOR measurement result | ||||||
| local_tag = query(nodereg, XORMeasurements, local_purified, ❓) | ||||||
|  | ||||||
| if isnothing(local_tag) | ||||||
| @yield onchange_tag(net[local_purified]) | ||||||
| continue | ||||||
| end | ||||||
|  | ||||||
| # for remote XOR measurement result | ||||||
| msg = query(mb, XORMeasurements, remote_purified, ❓) | ||||||
| if isnothing(msg) | ||||||
| @debug "Starting message wait at $(now(sim)) with MessageBuffer containing: $(mb.buffer)" | ||||||
| @yield wait(mb) | ||||||
| @debug "Done waiting for message at side $(side)" | ||||||
| continue | ||||||
| end | ||||||
|  | ||||||
| msg = querydelete!(mb, XORMeasurements, ❓, ❓) | ||||||
| local_xor = local_tag.tag.data[3] # it would be better if it can be local_tag.tag.measurement | ||||||
| src, (_, src_node, remote_xor) = msg | ||||||
|  | ||||||
| if remote_xor == local_xor | ||||||
| @debug "Purification was successful" | ||||||
| tag!(local_tag.slot, PurifiedEntalgementCounterpart, src_node, storage_slot) | ||||||
| else | ||||||
| @debug "Purification failed." | ||||||
| untag!(local_tag.slot, local_tag.id) | ||||||
|          | ||||||
| end | ||||||
| end | ||||||
| end | ||||||
|  | ||||||
|  | ||||||
|  | ||||||
| @resumable function entangler_fusion(sim, net, nodeA, nodeB, communication_slot, storage_slot, pairstate) | ||||||
|          | ||||||
| @resumable function entangler_fusion(sim, net, nodeA, nodeB, communication_slot, storage_slot, pairstate) | |
| @resumable function entangler_fusion(sim, net, nodeA, nodeB, communication_slot, storage_slot, pairstate) | 
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.
let's rename this to
purification_resource_graph(code)or something like this