Skip to content

Commit

Permalink
Merge pull request #197 from sequence-toolbox/RnD
Browse files Browse the repository at this point in the history
Fix BUG: Path of scr -> dst could be different than dst -> src when edges are equal length
  • Loading branch information
caitaozhan authored Sep 26, 2024
2 parents 56d3b81 + 3badc4c commit 28f72e6
Show file tree
Hide file tree
Showing 30 changed files with 98 additions and 52 deletions.
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,15 @@
</picture>
</p>

<h3><p align="center">Quantum Networking in SeQUeNCe: Scalable, Customizable, Easy Debugging</p></h3>
<h3><p align="center">Quantum Networking in SeQUeNCe: Customizable, Scalable, Easy Debugging</p></h3>


[![Documentation](https://img.shields.io/readthedocs/sequence-rtd-tutorial)](https://sequence-rtd-tutorial.readthedocs.io/)
[![PyPi](https://img.shields.io/pypi/v/sequence)](https://pypi.org/project/sequence/)
[![Qutip](https://img.shields.io/badge/integration%20-Qutip-blue)](https://qutip.org/)
[![Paper](https://img.shields.io/badge/10.1088%2F2058-9565%2Fac22f6?label=DOI)](https://iopscience.iop.org/article/10.1088/2058-9565/ac22f6)



<br>

Expand Down Expand Up @@ -58,7 +66,7 @@ publisher = {IOP Publishing},
## Running the GUI
Once SeQUeNCe has been installed as described above, simply run the `gui.py` script found in the root of the project directory
```
$ python gui.py
python gui.py
```

## Usage Examples
Expand All @@ -70,12 +78,12 @@ Code for the experiments performed in our paper can be found in the file `starli
### Jupyter Notebook Examples
The example folder contains several scripts that can be run with jupyter notebook for easy editing and visualization. These files require that the notebook package be installed (Anaconda recommended):
```
$ pip install notebook
$ pip install ipywidgets
pip install notebook
pip install ipywidgets
```
To run each file, simply run
```
$ jupyter notebook <filename>
jupyter notebook <filename>
```
These examples include:
* `BB84_eg.ipynb`, which uses the BB84 protocol to distribute secure keys between two quantum nodes
Expand All @@ -89,7 +97,7 @@ The example directory contains an example json file `starlight.json` to specify

To view a network, simply run the script and specify the relative location of your json file:
```
$ python utils/draw_topo.py example/starlight.json
python utils/draw_topo.py example/starlight.json
```
This script also supports a flag `-m` to visualize BSM nodes created by default on quantum links between routers.

Expand Down
2 changes: 1 addition & 1 deletion docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
recommonmark
sphinx-rtd-theme
sequence
sequence
10 changes: 5 additions & 5 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ Welcome to the SeQUeNCe documentation page
:maxdepth: 1
:caption: Module References:

references/kernel/top
references/application/top
references/components/top
references/entanglement_management/top
references/resource_management/top
references/kernel/top
references/misc/top
references/network_management/top
references/application/top
references/topology/top
references/qkd/top
references/misc/top
references/resource_management/top
references/topology/top

.. toctree::
:maxdepth: 1
Expand Down
5 changes: 5 additions & 0 deletions docs/source/references/application/request_app.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Request Request
==============

.. automodule:: sequence.app.request_app
:members:
1 change: 1 addition & 0 deletions docs/source/references/application/top.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ The Application module contains code to utilize and test quantum network resourc
.. toctree::
:maxdepth: 2

request_app
random_request
5 changes: 5 additions & 0 deletions docs/source/references/misc/constants.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Constants
========

.. automodule:: sequence.constants
:members:
1 change: 1 addition & 0 deletions docs/source/references/misc/top.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Miscellaneous SeQUeNCe modules.
.. toctree::
:maxdepth: 2

constants
message
protocol
utils/top
5 changes: 5 additions & 0 deletions docs/source/references/misc/utils/config_generator.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Config Generator
========

.. automodule:: sequence.utils.config_generator
:members:
3 changes: 2 additions & 1 deletion docs/source/references/misc/utils/top.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ Utilities for SeQUeNCe.
.. toctree::
:maxdepth: 2

config_generator
encoding
log
log
2 changes: 1 addition & 1 deletion example/ANTS_demos_2023/GUI_and_code_demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@
"def test(sim_time=1.5, qc_atten=1e-5):\n",
" \"\"\"\n",
" sim_time: duration of simulation time (s)\n",
" qc_atten: quantum channel attenuation (dB/km)\n",
" qc_atten: quantum channel attenuation (dB/m)\n",
" \"\"\"\n",
" \n",
" network_config = \"star_network.json\"\n",
Expand Down
2 changes: 1 addition & 1 deletion example/ANTS_demos_2023/GUI_and_code_demo_filled.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@
"def test(sim_time=1.5, qc_atten=1e-5):\n",
" \"\"\"\n",
" sim_time: duration of simulation time (s)\n",
" qc_atten: quantum channel attenuation (dB/km)\n",
" qc_atten: quantum channel attenuation (dB/m)\n",
" \"\"\"\n",
" \n",
" network_config = \"star_network.json\"\n",
Expand Down
2 changes: 1 addition & 1 deletion example/QCE_demos_2022/GUI_and_code_demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@
"def test(sim_time=1.5, qc_atten=1e-5):\n",
" \"\"\"\n",
" sim_time: duration of simulation time (s)\n",
" qc_atten: quantum channel attenuation (dB/km)\n",
" qc_atten: quantum channel attenuation (dB/m)\n",
" \"\"\"\n",
" \n",
" network_config = \"star_network.json\"\n",
Expand Down
2 changes: 1 addition & 1 deletion example/QCE_demos_2022/Teleport_demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@
"def test(sim_time=1.5, qc_atten=1e-5):\n",
" \"\"\"\n",
" sim_time: duration of simulation time (ms)\n",
" qc_atten: quantum channel attenuation (dB/km)\n",
" qc_atten: quantum channel attenuation (dB/m)\n",
" \"\"\"\n",
" \n",
" network_config = \"star_network.json\"\n",
Expand Down
2 changes: 1 addition & 1 deletion example/QCE_demos_2022/Teleport_demo_filled.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@
"def test(sim_time=1.5, qc_atten=1e-5):\n",
" \"\"\"\n",
" sim_time: duration of simulation time (ms)\n",
" qc_atten: quantum channel attenuation (dB/km)\n",
" qc_atten: quantum channel attenuation (dB/m)\n",
" \"\"\"\n",
" \n",
" network_config = \"star_network.json\"\n",
Expand Down
2 changes: 1 addition & 1 deletion example/QCE_demos_2023/GUI_and_code_demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@
"def test(sim_time=1.5, qc_atten=1e-5):\n",
" \"\"\"\n",
" sim_time: duration of simulation time (s)\n",
" qc_atten: quantum channel attenuation (dB/km)\n",
" qc_atten: quantum channel attenuation (dB/m)\n",
" \"\"\"\n",
" \n",
" network_config = \"star_network.json\"\n",
Expand Down
2 changes: 1 addition & 1 deletion example/QCE_demos_2023/GUI_and_code_demo_filled.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@
"def test(sim_time=1.5, qc_atten=1e-5):\n",
" \"\"\"\n",
" sim_time: duration of simulation time (s)\n",
" qc_atten: quantum channel attenuation (dB/km)\n",
" qc_atten: quantum channel attenuation (dB/m)\n",
" \"\"\"\n",
" \n",
" network_config = \"star_network.json\"\n",
Expand Down
2 changes: 1 addition & 1 deletion example/qkd.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
" cc0.set_ends(n1, n2.name)\n",
" cc1.set_ends(n2, n1.name)\n",
" # construct a quantum communication channel\n",
" # (with arguments for the channel name, timeline, attenuation (in dB/km), and distance (in m))\n",
" # (with arguments for the channel name, timeline, attenuation (in db/m), and distance (in m))\n",
" qc0 = QuantumChannel(\"qc_n1_n2\", tl, attenuation=1e-5, distance=1e3,\n",
" polarization_fidelity=0.97)\n",
" qc1 = QuantumChannel(\"qc_n2_n1\", tl, attenuation=1e-5, distance=1e3,\n",
Expand Down
2 changes: 1 addition & 1 deletion example/random_request_network.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
"def test(sim_time, qc_atten):\n",
" \"\"\"\n",
" sim_time: duration of simulation time (ms)\n",
" qc_atten: quantum channel attenuation (dB/km)\n",
" qc_atten: quantum channel attenuation (dB/m)\n",
" \"\"\"\n",
" network_config = \"star_network.json\"\n",
"\n",
Expand Down
2 changes: 1 addition & 1 deletion example/random_request_network_mod.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
"def test(sim_time, qc_atten):\n",
" \"\"\"\n",
" sim_time: duration of simulation time (ms)\n",
" qc_atten: quantum channel attenuation (dB/km)\n",
" qc_atten: quantum channel attenuation (db/m)\n",
" \"\"\"\n",
" \n",
" network_config = \"star_network.json\"\n",
Expand Down
2 changes: 1 addition & 1 deletion example/three_node_eg_ep_es.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
" cc.set_ends(node1, node2.name)\n",
" \n",
" # create quantum channels linking r1 and r2 to m1\n",
" # (with arguments for the channel name, timeline, attenuation (in dB/km), and distance (in m))\n",
" # (with arguments for the channel name, timeline, attenuation (in dB/m), and distance (in m))\n",
" qc0 = QuantumChannel(\"qc_r1_m1\", tl, qc_atten, qc_dist)\n",
" qc1 = QuantumChannel(\"qc_r2_m1\", tl, qc_atten, qc_dist)\n",
" qc0.set_ends(r1, m1.name)\n",
Expand Down
2 changes: 1 addition & 1 deletion example/two_node_eg.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
" \n",
" # create linear quantum network between routers and middle node\n",
" # for this, we create quantum channels\n",
" # (with arguments for the channel name, timeline, attenuation (in dB/km), and distance (in m))\n",
" # (with arguments for the channel name, timeline, attenuation (in dB/m), and distance (in m))\n",
" qc1 = QuantumChannel(\"qc_r1_m1\", tl, qc_atten, qc_dist)\n",
" qc1.set_ends(r1, m1.name)\n",
" qc2 = QuantumChannel(\"qc_r2_m1\", tl, qc_atten, qc_dist)\n",
Expand Down
1 change: 0 additions & 1 deletion sequence/app/request_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ def get_other_reservation(self, reservation: "Reservation") -> None:

def schedule_reservation(self, reservation: "Reservation") -> None:
if reservation.initiator == self.node.name:
# NOTE: self.path will be an issue when there are multiple reservation.path at the same time
self.path = reservation.path

reservation_protocol = self.node.network_manager.protocol_stack[1]
Expand Down
2 changes: 1 addition & 1 deletion sequence/components/memory.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class Memory(Entity):
fidelity (float): (current) fidelity of memory.
frequency (float): maximum frequency at which memory can be excited.
efficiency (float): probability of emitting a photon when excited.
coherence_time (float): average usable lifetime of memory (in seconds).
coherence_time (float): average usable lifetime of memory (in seconds). Negative value means infinite coherence time.
wavelength (float): wavelength (in nm) of emitted photons.
qstate_key (int): key for associated quantum state in timeline's quantum manager.
memory_array (MemoryArray): memory array aggregating current memory.
Expand Down
40 changes: 27 additions & 13 deletions sequence/network_management/reservation.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class ResourceReservationMessage(Message):
receiver (str): name of destination protocol instance.
reservation (Reservation): reservation object relayed between nodes.
qcaps (List[QCaps]): cumulative quantum capacity object list (if `msg_type == REQUEST`)
path (List[str]): cumulative node list for entanglement path (if `msg_type == APPROVE`)
path (List[str]): cumulative node list for entanglement path (if `msg_type == APPROVE` or `msg_type == REJECT`)
"""

def __init__(self, msg_type: any, receiver: str, reservation: "Reservation", **kwargs):
Expand All @@ -54,7 +54,7 @@ def __init__(self, msg_type: any, receiver: str, reservation: "Reservation", **k
if self.msg_type is RSVPMsgType.REQUEST:
self.qcaps = []
elif self.msg_type is RSVPMsgType.REJECT:
pass
self.path = kwargs["path"]
elif self.msg_type is RSVPMsgType.APPROVE:
self.path = kwargs["path"]
else:
Expand Down Expand Up @@ -365,7 +365,6 @@ def push(self, responder: str, start_time: int, end_time: int, memory_size: int,

def pop(self, src: str, msg: "ResourceReservationMessage"):
"""Method to receive messages from lower protocols.
NOTE (caitao, 3/19/2024): argument "src" not used
Messages may be of 3 types, causing different network manager behavior:
1. REQUEST: requests are evaluated, and forwarded along the path if accepted.
Expand All @@ -387,39 +386,54 @@ def pop(self, src: str, msg: "ResourceReservationMessage"):

if msg.msg_type == RSVPMsgType.REQUEST:
assert self.owner.timeline.now() < msg.reservation.start_time
if self.schedule(msg.reservation):
qcap = QCap(self.owner.name)
msg.qcaps.append(qcap)
qcap = QCap(self.owner.name)
msg.qcaps.append(qcap)
path = [qcap.node for qcap in msg.qcaps]
if self.schedule(msg.reservation): # schedule success
if self.owner.name == msg.reservation.responder:
path = [qcap.node for qcap in msg.qcaps]
rules = self.create_rules(path, reservation=msg.reservation)
self.load_rules(rules, msg.reservation)
msg.reservation.set_path(path)
new_msg = ResourceReservationMessage(RSVPMsgType.APPROVE, self.name, msg.reservation, path=path)
self._pop(msg=msg)
self._push(dst=msg.reservation.initiator, msg=new_msg)
self._push(dst=None, msg=new_msg, next_hop=src)
else:
self._push(dst=msg.reservation.responder, msg=msg)
else:
new_msg = ResourceReservationMessage(RSVPMsgType.REJECT, self.name, msg.reservation)
self._push(dst=msg.reservation.initiator, msg=new_msg)
else: # schedule failed
new_msg = ResourceReservationMessage(RSVPMsgType.REJECT, self.name, msg.reservation, path=path)
self._push(dst=None, msg=new_msg, next_hop=src)
elif msg.msg_type == RSVPMsgType.REJECT:
for card in self.timecards:
card.remove(msg.reservation)
if msg.reservation.initiator == self.owner.name:
self._pop(msg=msg)
else:
self._push(dst=msg.reservation.initiator, msg=msg)
next_hop = self.next_hop_when_tracing_back(msg.path)
self._push(dst=None, msg=msg, next_hop=next_hop)
elif msg.msg_type == RSVPMsgType.APPROVE:
rules = self.create_rules(msg.path, msg.reservation)
self.load_rules(rules, msg.reservation)
if msg.reservation.initiator == self.owner.name:
self._pop(msg=msg)
else:
self._push(dst=msg.reservation.initiator, msg=msg)
next_hop = self.next_hop_when_tracing_back(msg.path)
self._push(dst=None, msg=msg, next_hop=next_hop)
else:
raise Exception("Unknown type of message", msg.msg_type)

def next_hop_when_tracing_back(self, path: List[str]) -> str:
'''the next hop when going back from the responder to the initiator
Args:
path (List[str]): a list of router names that goes from initiator to responder
Return:
str: the name of the next hop
'''
cur_index = path.index(self.owner.name)
assert cur_index >= 1, f'{cur_index} must be larger equal than 1'
next_hop = path[cur_index - 1]
return next_hop

def schedule(self, reservation: "Reservation") -> bool:
"""Method to attempt reservation request. If attempt succeeded, return True; otherwise, return False.
Expand Down
14 changes: 10 additions & 4 deletions sequence/network_management/routing.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,23 +69,29 @@ def update_forwarding_rule(self, dst: str, next_node: str):

self.forwarding_table[dst] = next_node

def push(self, dst: str, msg: "Message"):
def push(self, dst: str, msg: "Message", next_hop: str = None):
"""Method to receive message from upper protocols.
Routing packages the message and forwards it to the next node in the optimal path (determined by the forwarding table).
Args:
dst (str): name of destination node.
dst (str): name of destination node. If not None, resort to the forwarding table to get the next hop.
msg (Message): message to relay.
next_hop (str): name of next hop. If dst is None, next_hop shouldn't be None. next_hop directly tells the next hop.
Side Effects:
Will invoke `push` method of lower protocol or network manager.
"""

assert dst != self.owner.name
dst = self.forwarding_table[dst]
new_msg = StaticRoutingMessage(Enum, self.name, msg)
self._push(dst=dst, msg=new_msg)
if dst: # if dst is not None, use the forwarding table
next_hop = self.forwarding_table[dst]
self._push(dst=next_hop, msg=new_msg)
elif next_hop: # if next_hop is not None, use next_hop
self._push(dst=next_hop, msg=new_msg)
else:
raise Exception(f'Both dst and next_hop are None!')

def pop(self, src: str, msg: "StaticRoutingMessage"):
"""Message to receive reservation messages.
Expand Down
4 changes: 2 additions & 2 deletions sequence/qkd/BB84.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class BB84(StackProtocol):
The BB84 protocol uses photons to create a secure key between two QKD Nodes.
Attributes:
own (QKDNode): node that protocol instance is attached to.
owner (QKDNode): node that protocol instance is attached to.
name (str): label for protocol instance.
role (int): determines if instance is "alice" or "bob" node.
working (bool): shows if protocol is currently working on a key.
Expand All @@ -107,7 +107,7 @@ def __init__(self, owner: "QKDNode", name: str, lightsource: str, qsdetector: st
"""Constructor for BB84 class.
Args:
own (QKDNode): node hosting protocol instance.
owner (QKDNode): node hosting protocol instance.
name (str): name of protocol instance.
lightsource (str): name of lightsource for QKD
qsdetector (str): name of QSDetector for QKD
Expand Down
2 changes: 1 addition & 1 deletion sequence/topology/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def init(self) -> None:
def set_seed(self, seed: int) -> None:
self.generator = np.random.default_rng(seed)

def get_generator(self):
def get_generator(self) -> np.random.Generator:
return self.generator

def add_component(self, component: Entity) -> None:
Expand Down
Loading

0 comments on commit 28f72e6

Please # to comment.