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

Add AnyBell distributor #9

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
37 changes: 37 additions & 0 deletions examples/stack/teleport/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
qdevice_cfg: &qdevice_cfg
num_qubits: 3
num_comm_qubits: 1
T1: 1.e+10
T2: 1.e+9
init_time: 1.e+4
single_qubit_gate_time: 1.e+3
two_qubit_gate_time: 1.e+5
measurement_time: 1.e+4
single_qubit_gate_depolar_prob: 0
two_qubit_gate_depolar_prob: 0.01

stacks:
- name: sender
qdevice_typ: nv
qdevice_cfg:
<<: *qdevice_cfg
classical_cfg:
host_qnos_latency: 1e5
- name: receiver
qdevice_typ: nv
qdevice_cfg:
<<: *qdevice_cfg
classical_cfg:
host_qnos_latency: 1e5

link_cfg: &link_cfg
fidelity: 0.8
prob_success: 0.01
t_cycle: 1.e+6

links:
- stack1: sender
stack2: receiver
typ: depolarise_any_bell
cfg:
<<: *link_cfg
86 changes: 50 additions & 36 deletions examples/stack/teleport/example_teleport.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
from __future__ import annotations

import math
from typing import Any, Dict, Generator
import os
from typing import Any, Dict, Generator, List

from netqasm.lang.ir import BreakpointAction, BreakpointRole
import netsquid as ns
from netqasm.lang.ir import BreakpointAction
from netqasm.sdk.qubit import Qubit
from netqasm.sdk.toolbox import set_qubit_state
from netsquid.qubits import operators, qubitapi

from pydynaa import EventExpression
from squidasm.run.stack.config import (
GenericQDeviceConfig,
LinkConfig,
StackConfig,
StackNetworkConfig,
)
from squidasm.run.stack.config import StackNetworkConfig
from squidasm.run.stack.run import run
from squidasm.sim.stack.common import LogManager
from squidasm.sim.stack.csocket import ClassicalSocket
from squidasm.sim.stack.globals import GlobalSimData
from squidasm.sim.stack.program import Program, ProgramContext, ProgramMeta


Expand Down Expand Up @@ -54,9 +53,6 @@ def run(
set_qubit_state(q, self._phi, self._theta)

e = epr_socket.create_keep()[0]
conn.insert_breakpoint(
BreakpointAction.DUMP_GLOBAL_STATE, BreakpointRole.CREATE
)
q.cnot(e)
q.H()
m1 = q.measure()
Expand Down Expand Up @@ -93,9 +89,6 @@ def run(
csocket: ClassicalSocket = context.csockets[self.PEER]

e = epr_socket.recv_keep()[0]
conn.insert_breakpoint(
BreakpointAction.DUMP_GLOBAL_STATE, BreakpointRole.RECEIVE
)
yield from conn.flush()

m1 = yield from csocket.recv_int()
Expand All @@ -106,33 +99,54 @@ def run(
if m1 == 1:
e.Z()

# conn.insert_breakpoint(BreakpointAction.DUMP_LOCAL_STATE)
conn.insert_breakpoint(BreakpointAction.DUMP_LOCAL_STATE)
e.measure()
yield from conn.flush()

all_states = GlobalSimData.get_last_breakpoint_state()
state = all_states["receiver"][0]
return state

if __name__ == "__main__":
# set_log_level("INFO")

sender_stack = StackConfig(
name="sender",
qdevice_typ="generic",
qdevice_cfg=GenericQDeviceConfig.perfect_config(),
)
receiver_stack = StackConfig(
name="receiver",
qdevice_typ="generic",
qdevice_cfg=GenericQDeviceConfig.perfect_config(),
def do_teleportation(
cfg: StackNetworkConfig,
num_times: int = 1,
theta: float = 0.0,
phi: float = 0.0,
log_level: str = "WARNING",
) -> List[float]:
LogManager.set_log_level(log_level)

sender_program = SenderProgram(theta=theta, phi=phi)
receiver_program = ReceiverProgram()

_, final_states = run(
cfg,
{"sender": sender_program, "receiver": receiver_program},
num_times=num_times,
)
link = LinkConfig(
stack1="sender",
stack2="receiver",
typ="perfect",

expected = qubitapi.create_qubits(1)[0]
rot_theta = operators.create_rotation_op(theta, rotation_axis=(0, 1, 0))
rot_phi = operators.create_rotation_op(phi, rotation_axis=(0, 0, 1))
qubitapi.operate(expected, rot_theta)
qubitapi.operate(expected, rot_phi)
fidelities = [qubitapi.fidelity(expected, f, squared=True) for f in final_states]

return fidelities


if __name__ == "__main__":
ns.set_qstate_formalism(ns.qubits.qformalism.QFormalism.DM)

cfg = StackNetworkConfig.from_file(
os.path.join(os.getcwd(), os.path.dirname(__file__), "config.yaml")
)

cfg = StackNetworkConfig(stacks=[sender_stack, receiver_stack], links=[link])
# link between sender and receiver
link = cfg.links[0]

sender_program = SenderProgram(theta=math.pi, phi=0)
receiver_program = ReceiverProgram()
link.cfg["fidelity"] = 0.8

results = run(cfg, {"sender": sender_program, "receiver": receiver_program})
print(results)
fidelities = do_teleportation(cfg, num_times=10, theta=0, phi=0)
print(fidelities)
10 changes: 10 additions & 0 deletions squidasm/run/stack/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,16 @@ def from_file(cls, path: str) -> DepolariseLinkConfig:
return _from_file(path, DepolariseLinkConfig) # type: ignore


class DepolariseAnyBellLinkConfig(BaseModel):
fidelity: float
prob_success: float
t_cycle: float

@classmethod
def from_file(cls, path: str) -> DepolariseAnyBellLinkConfig:
return _from_file(path, DepolariseAnyBellLinkConfig)


class NVLinkConfig(BaseModel):
length_A: float
length_B: float
Expand Down
94 changes: 94 additions & 0 deletions squidasm/run/stack/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
from typing import Any, Dict, List

import netsquid as ns
import numpy as np
from netsquid.qubits.ketstates import BellIndex
from netsquid.qubits.state_sampler import StateSampler
from netsquid_magic.link_layer import (
MagicLinkLayerProtocol,
MagicLinkLayerProtocolWithSignaling,
Expand All @@ -12,13 +15,16 @@
from netsquid_magic.magic_distributor import (
DepolariseWithFailureMagicDistributor,
DoubleClickMagicDistributor,
MagicDistributor,
PerfectStateMagicDistributor,
)
from netsquid_magic.state_delivery_sampler import HeraldedStateDeliverySamplerFactory
from netsquid_nv.magic_distributor import NVSingleClickMagicDistributor
from netsquid_physlayer.heralded_connection import MiddleHeraldedConnection

from squidasm.run.stack.build import build_generic_qdevice, build_nv_qdevice
from squidasm.run.stack.config import (
DepolariseAnyBellLinkConfig,
DepolariseLinkConfig,
GenericQDeviceConfig,
HeraldedLinkConfig,
Expand All @@ -32,6 +38,83 @@
from squidasm.sim.stack.stack import NodeStack, StackNetwork


class DepolariseWithFailureAnyBellStateSamplerFactory(
HeraldedStateDeliverySamplerFactory
):
"""State sampler that samples any of the 4 Bell states with equal probablity."""

def __init__(self):
super().__init__(func_delivery=self._delivery_func)

@staticmethod
def _delivery_func(prob_max_mixed, prob_success, **kwargs):
bell00 = np.array(
[[0.5, 0, 0, 0.5], [0, 0, 0, 0], [0, 0, 0, 0], [0.5, 0, 0, 0.5]],
dtype=np.complex,
)
bell01 = np.array(
[[0, 0, 0, 0], [0, 0.5, 0.5, 0], [0, 0.5, 0.5, 0], [0, 0, 0, 0]],
dtype=np.complex,
)
bell10 = np.array(
[[0, 0, 0, 0], [0, 0.5, -0.5, 0], [0, -0.5, 0.5, 0], [0, 0, 0, 0]],
dtype=np.complex,
)
bell11 = np.array(
[[0.5, 0, 0, -0.5], [0, 0, 0, 0], [0, 0, 0, 0], [-0.5, 0, 0, 0.5]],
dtype=np.complex,
)
maximally_mixed = np.array(
[[0.25, 0, 0, 0], [0, 0.25, 0, 0], [0, 0, 0.25, 0], [0, 0, 0, 0.25]],
dtype=np.complex,
)
bell00_noisy = (1 - prob_max_mixed) * bell00 + prob_max_mixed * maximally_mixed
bell01_noisy = (1 - prob_max_mixed) * bell01 + prob_max_mixed * maximally_mixed
bell10_noisy = (1 - prob_max_mixed) * bell10 + prob_max_mixed * maximally_mixed
bell11_noisy = (1 - prob_max_mixed) * bell11 + prob_max_mixed * maximally_mixed
return (
StateSampler(
qreprs=[bell00_noisy, bell01_noisy, bell10_noisy, bell11_noisy],
probabilities=[0.25, 0.25, 0.25, 0.25],
labels=[
BellIndex.PHI_PLUS,
BellIndex.PSI_PLUS,
BellIndex.PSI_MINUS,
BellIndex.PHI_MINUS,
],
),
prob_success,
)


class DepolariseWithFailureAnyBellMagicDistributor(MagicDistributor):
"""Distributor that creates any of the 4 Bell states with equal probablity."""

def __init__(self, nodes, prob_max_mixed, prob_success, **kwargs):
self.prob_max_mixed = prob_max_mixed
self.prob_success = prob_success
super().__init__(
delivery_sampler_factory=DepolariseWithFailureAnyBellStateSamplerFactory(),
nodes=nodes,
**kwargs,
)

def add_delivery(self, memory_positions, **kwargs):
return super().add_delivery(
memory_positions=memory_positions,
prob_max_mixed=self.prob_max_mixed,
prob_success=self.prob_success,
**kwargs,
)

def get_bell_state(self, midpoint_outcome):
try:
status, label = midpoint_outcome
except ValueError:
raise ValueError("Unknown midpoint outcome {}".format(midpoint_outcome))
return label


def fidelity_to_prob_max_mixed(fid: float) -> float:
return (1 - fid) * 4.0 / 3.0

Expand Down Expand Up @@ -80,6 +163,17 @@ def _setup_network(config: StackNetworkConfig) -> StackNetwork:
prob_success=link_cfg.prob_success,
t_cycle=link_cfg.t_cycle,
)
elif link.typ == "depolarise_any_bell":
link_cfg = link.cfg
if not isinstance(link_cfg, DepolariseAnyBellLinkConfig):
link_cfg = DepolariseAnyBellLinkConfig(**link.cfg)
prob_max_mixed = fidelity_to_prob_max_mixed(link_cfg.fidelity)
link_dist = DepolariseWithFailureAnyBellMagicDistributor(
nodes=[stack1.node, stack2.node],
prob_max_mixed=prob_max_mixed,
prob_success=link_cfg.prob_success,
t_cycle=link_cfg.t_cycle,
)
elif link.typ == "nv":
link_cfg = link.cfg
if not isinstance(link_cfg, NVLinkConfig):
Expand Down