From 52bb9ea61c9bc579b10640524536a7eee8d1b191 Mon Sep 17 00:00:00 2001 From: Alex-Kolar Date: Tue, 5 Jul 2022 11:29:33 -0500 Subject: [PATCH 1/4] Update units for jupyter notebook examples --- example/random_request_network.ipynb | 31 +++++--- example/random_request_network_mod.ipynb | 28 ++++--- example/three_node_eg_ep_es.ipynb | 29 +++++--- example/two_node_eg.ipynb | 93 ++++++++++++++++++------ 4 files changed, 130 insertions(+), 51 deletions(-) diff --git a/example/random_request_network.ipynb b/example/random_request_network.ipynb index c7d83cbc..24d3565b 100644 --- a/example/random_request_network.ipynb +++ b/example/random_request_network.ipynb @@ -77,7 +77,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -86,6 +86,7 @@ " sim_time: duration of simulation time (ms)\n", " qc_atten: quantum channel attenuation (dB/km)\n", " \"\"\"\n", + " \n", " network_config = \"star_network.json\"\n", "\n", " # here, we make a new topology using the configuration JSON file.\n", @@ -163,13 +164,20 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ - "def set_parameters(topology, simulation_time, attenuation):\n", + "def set_parameters(topology, sim_time, qc_atten):\n", + " \"\"\"\n", + " sim_time: duration of simulation time (ms)\n", + " qc_atten: attenuation on quantum channels (db/m)\n", + " \"\"\"\n", + " \n", + " PS_PER_MS = 1e9\n", + " \n", " # set timeline stop time\n", - " topology.get_timeline().stop_time = (simulation_time * 1e12)\n", + " topology.get_timeline().stop_time = (sim_time * PS_PER_MS)\n", " \n", " # set memory parameters\n", " MEMO_FREQ = 2e3\n", @@ -199,7 +207,7 @@ " node.network_manager.protocol_stack[1].set_swapping_degradation(SWAP_DEGRADATION)\n", " \n", " # set quantum channel parameters\n", - " ATTENUATION = attenuation\n", + " ATTENUATION = qc_atten\n", " QC_FREQ = 1e11\n", " for qc in topology.qchannels:\n", " qc.attenuation = ATTENUATION\n", @@ -212,12 +220,17 @@ "source": [ "### Running the Simulation\n", "\n", - "All that is left is to run the simulation with user input. Note that different hardware parameters or network topologies may cause the simulation to run for a very long time." + "All that is left is to run the simulation with user input. We'll specify:\n", + "\n", + " sim_time: duration of simulation time (ms)\n", + " qc_atten: attenuation on quantum channels (db/m)\n", + "\n", + "Note that different hardware parameters or network topologies may cause the simulation to run for a very long time." ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 7, "metadata": { "scrolled": false }, @@ -225,7 +238,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "6b8e00c4681e4657865cdb0ae9687707", + "model_id": "dd506771a175451fa4b6bb1c50b8232b", "version_major": 2, "version_minor": 0 }, @@ -242,7 +255,7 @@ "" ] }, - "execution_count": 25, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } diff --git a/example/random_request_network_mod.ipynb b/example/random_request_network_mod.ipynb index cbb2859d..f29475f3 100644 --- a/example/random_request_network_mod.ipynb +++ b/example/random_request_network_mod.ipynb @@ -28,7 +28,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -39,7 +39,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -80,7 +80,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -89,6 +89,7 @@ " sim_time: duration of simulation time (ms)\n", " qc_atten: quantum channel attenuation (dB/km)\n", " \"\"\"\n", + " \n", " network_config = \"star_network.json\"\n", " \n", " # here, we make a new topology using the configuration JSON file.\n", @@ -167,13 +168,20 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ - "def set_parameters(topology, simulation_time, attenuation):\n", + "def set_parameters(topology, sim_time, qc_atten):\n", + " \"\"\"\n", + " sim_time: duration of simulation time (ms)\n", + " qc_atten: attenuation on quantum channels (db/m)\n", + " \"\"\"\n", + " \n", + " PS_PER_MS = 1e9\n", + " \n", " # set timeline stop time\n", - " topology.get_timeline().stop_time = (simulation_time * 1e12)\n", + " topology.get_timeline().stop_time = (sim_time * PS_PER_MS)\n", " \n", " # set memory parameters\n", " MEMO_FREQ = 2e3\n", @@ -203,7 +211,7 @@ " node.network_manager.protocol_stack[1].set_swapping_degradation(SWAP_DEGRADATION)\n", " \n", " # set quantum channel parameters\n", - " ATTENUATION = attenuation\n", + " ATTENUATION = qc_atten\n", " QC_FREQ = 1e11\n", " for qc in topology.qchannels:\n", " qc.attenuation = ATTENUATION\n", @@ -221,7 +229,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 5, "metadata": { "scrolled": false }, @@ -229,7 +237,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "7fe65a6237ca41fcaebab1ae42a3cb08", + "model_id": "7779e45afd3b4de9a73594ae711ee7e7", "version_major": 2, "version_minor": 0 }, @@ -246,7 +254,7 @@ "" ] }, - "execution_count": 15, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } diff --git a/example/three_node_eg_ep_es.ipynb b/example/three_node_eg_ep_es.ipynb index 92bf5e08..a47f0251 100644 --- a/example/three_node_eg_ep_es.ipynb +++ b/example/three_node_eg_ep_es.ipynb @@ -88,16 +88,21 @@ "def test(sim_time, cc_delay, qc_atten, qc_dist):\n", " \"\"\"\n", " sim_time: duration of simulation time (ms)\n", - " cc_delay: delay on classical channels (ns)\n", + " cc_delay: delay on classical channels (ms)\n", " qc_atten: attenuation on quantum channels (db/m)\n", " qc_dist: distance of quantum channels (km)\n", " \"\"\"\n", - " cc_delay *= 1e6\n", - " qc_dist *= 1e3\n", + " PS_PER_MS = 1e9\n", + " M_PER_KM = 1e3\n", + " \n", + " # convert units for cc delay (to ps) and qc distance (to m)\n", + " cc_delay *= PS_PER_MS\n", + " qc_dist *= M_PER_KM\n", + " \n", " raw_fidelity = 0.85\n", + " \n", " # construct the simulation timeline; the constructor argument is the simulation time (in ps)\n", - " tl = Timeline(sim_time * 1e9)\n", - " tl.seed(0)\n", + " tl = Timeline(sim_time * PS_PER_MS)\n", " \n", " ## create our quantum network and update parameters as needed\n", " \n", @@ -111,6 +116,12 @@ " m1 = BSMNode(\"m1\", tl, [\"r1\", \"r2\"])\n", " m2 = BSMNode(\"m2\", tl, [\"r2\", \"r3\"])\n", " \n", + " r1.set_seed(0)\n", + " r2.set_seed(1)\n", + " r3.set_seed(2)\n", + " m1.set_seed(3)\n", + " m2.set_seed(4)\n", + " \n", " r1.add_bsm_node(m1.name, r2.name)\n", " r2.add_bsm_node(m1.name, r1.name)\n", " r2.add_bsm_node(m2.name, r3.name)\n", @@ -262,7 +273,7 @@ "Parameters:\n", "\n", " sim_time: duration of simulation time (ms)\n", - " cc_delay: delay on classical channels (ns)\n", + " cc_delay: delay on classical channels (ms)\n", " qc_atten: attenuation on quantum channels (db/m)\n", " qc_dist: distance of quantum channels (km)\n", " \n", @@ -279,12 +290,12 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "71c13bbf69664b55a2fffeffcd21f59a", + "model_id": "2a827b474ef6441aa31a56e6340ed219", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "interactive(children=(IntSlider(value=3000, description='sim_time', max=4000, min=2000, step=500), IntSlider(v…" + "interactive(children=(IntSlider(value=3000, description='sim_time', max=4000, min=2000, step=500), FloatSlider…" ] }, "metadata": {}, @@ -302,7 +313,7 @@ } ], "source": [ - "interactive_plot = interact(test, sim_time=(2000, 4000, 500), cc_delay=(100, 1000, 100), qc_atten=[1e-5, 2e-5, 3e-5], qc_dist=(1, 10, 1))\n", + "interactive_plot = interact(test, sim_time=(2000, 4000, 500), cc_delay=(0.1, 1, 0.1), qc_atten=[1e-5, 2e-5, 3e-5], qc_dist=(1, 10, 1))\n", "interactive_plot" ] }, diff --git a/example/two_node_eg.ipynb b/example/two_node_eg.ipynb index 5d7d2bc1..85a094dd 100644 --- a/example/two_node_eg.ipynb +++ b/example/two_node_eg.ipynb @@ -2,7 +2,11 @@ "cells": [ { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, "source": [ "# Two Node Entanglement Distribution\n", "\n", @@ -13,7 +17,11 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, "source": [ "## Example\n", "\n", @@ -31,7 +39,11 @@ { "cell_type": "code", "execution_count": 1, - "metadata": {}, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, "outputs": [], "source": [ "from ipywidgets import interact\n", @@ -42,7 +54,11 @@ { "cell_type": "code", "execution_count": 2, - "metadata": {}, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, "outputs": [], "source": [ "from sequence.kernel.timeline import Timeline\n", @@ -54,7 +70,11 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, "source": [ "### Defining Custom Behavior with Rules\n", "\n", @@ -67,8 +87,12 @@ }, { "cell_type": "code", - "execution_count": 18, - "metadata": {}, + "execution_count": 3, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, "outputs": [], "source": [ "# our rule condition requires RAW (unentangled) memories\n", @@ -106,7 +130,11 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, "source": [ "### Building the Simulation\n", "\n", @@ -125,22 +153,30 @@ }, { "cell_type": "code", - "execution_count": 16, - "metadata": {}, + "execution_count": 15, + "metadata": { + "pycharm": { + "name": "#%%\n" + } + }, "outputs": [], "source": [ "def test(sim_time, cc_delay, qc_atten, qc_dist):\n", " \"\"\"\n", " sim_time: duration of simulation time (ms)\n", - " cc_delay: delay on classical channels (ns)\n", + " cc_delay: delay on classical channels (ms)\n", " qc_atten: attenuation on quantum channels (db/m)\n", " qc_dist: distance of quantum channels (km)\n", " \"\"\"\n", - " cc_delay *= 1e6\n", - " qc_dist *= 1e3\n", + " PS_PER_MS = 1e9\n", + " M_PER_KM = 1e3\n", + " \n", + " # convert units for cc delay (to ps) and qc distance (to m)\n", + " cc_delay *= PS_PER_MS\n", + " qc_dist *= M_PER_KM\n", + " \n", " # construct the simulation timeline; the constructor argument is the simulation time (in ps)\n", - " tl = Timeline(sim_time * 1e9)\n", - " tl.seed(0)\n", + " tl = Timeline(sim_time * PS_PER_MS)\n", " \n", " # first, construct the quantum routers\n", " # (with arguments for the node name, timeline, and number of quantum memories)\n", @@ -149,6 +185,10 @@ " # next, construct the BSM nodes\n", " # (with arguments for the node name, timeline, and the names of connected routers)\n", " m1 = BSMNode(\"m1\", tl, [\"r1\", \"r2\"])\n", + " r1.set_seed(0)\n", + " r2.set_seed(1)\n", + " m1.set_seed(2)\n", + " \n", " for node in [r1, r2]:\n", " # update coherence time parameter for node memories (measured in seconds)\n", " node.memory_array.update_memory_params(\"coherence_time\", 0.3)\n", @@ -197,7 +237,11 @@ }, { "cell_type": "markdown", - "metadata": {}, + "metadata": { + "pycharm": { + "name": "#%% md\n" + } + }, "source": [ "### Running the Simulation\n", "\n", @@ -206,7 +250,7 @@ "Parameters:\n", "\n", " sim_time: duration of simulation time (ms)\n", - " cc_delay: delay on classical channels (ns)\n", + " cc_delay: delay on classical channels (ms)\n", " qc_atten: attenuation on quantum channels (db/m)\n", " qc_dist: distance of quantum channels (km)\n", " \n", @@ -215,20 +259,23 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 16, "metadata": { + "pycharm": { + "name": "#%%\n" + }, "scrolled": false }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "291ae74f670e4624ba0266667d57aff3", + "model_id": "9f0d3be855cb4596a8f804ff4f1beb61", "version_major": 2, "version_minor": 0 }, "text/plain": [ - "interactive(children=(IntSlider(value=500, description='sim_time', max=1000, min=100, step=100), IntSlider(val…" + "interactive(children=(IntSlider(value=500, description='sim_time', max=1000, min=100, step=100), FloatSlider(v…" ] }, "metadata": {}, @@ -240,13 +287,13 @@ "" ] }, - "execution_count": 19, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "interactive_plot = interact(test, sim_time=(100, 1000, 100), cc_delay=(100, 10000, 100), qc_atten=[1e-4, 2e-4, 3e-4], qc_dist=(1, 10, 1))\n", + "interactive_plot = interact(test, sim_time=(100, 1000, 100), cc_delay=(0.1, 10, 0.1), qc_atten=[1e-4, 2e-4, 3e-4], qc_dist=(1, 10, 1))\n", "interactive_plot" ] }, @@ -285,4 +332,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} +} \ No newline at end of file From 8962b9a76f182854708e10886181134080365557 Mon Sep 17 00:00:00 2001 From: Alex-Kolar Date: Tue, 5 Jul 2022 11:48:40 -0500 Subject: [PATCH 2/4] Update tutorial chapter 2 --- docs/source/tutorial/chapter2/example1.py | 9 ++++++++- docs/source/tutorial/chapter2/hardware.md | 21 +++++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/docs/source/tutorial/chapter2/example1.py b/docs/source/tutorial/chapter2/example1.py index 42525582..e271db61 100644 --- a/docs/source/tutorial/chapter2/example1.py +++ b/docs/source/tutorial/chapter2/example1.py @@ -6,12 +6,16 @@ from sequence.components.memory import Memory from sequence.components.optical_channel import QuantumChannel from sequence.components.detector import Detector +from sequence.components.circuit import Circuit from sequence.topology.node import Node NUM_TRIALS = 1000 FREQUENCY = 1e3 +_meas_circuit = Circuit(1) +_meas_circuit.measure(0) + class Counter(): def __init__(self): @@ -36,7 +40,10 @@ def __init__(self, name, timeline): self.detector.owner = self def receive_qubit(self, src, qubit): - if not qubit.is_null: + qm = self.timeline.quantum_manager + key = qubit.qstate_key + meas_res = qm.run_circuit(_meas_circuit, [key], self.get_generator().random())[key] + if meas_res: self.detector.get() diff --git a/docs/source/tutorial/chapter2/hardware.md b/docs/source/tutorial/chapter2/hardware.md index 70e3da12..0ffbc5ba 100644 --- a/docs/source/tutorial/chapter2/hardware.md +++ b/docs/source/tutorial/chapter2/hardware.md @@ -39,6 +39,10 @@ from sequence.kernel.timeline import Timeline from sequence.topology.node import Node from sequence.components.memory import Memory from sequence.components.detector import Detector +from sequence.components.circuit import Circuit + +_meas_circuit = Circuit(1) +_meas_circuit.measure(0) class SenderNode(Node): def __init__(self, name: str, timeline: Timeline): @@ -55,11 +59,24 @@ class ReceiverNode(Node): self.detector.owner = self def receive_qubit(self, src: str, qubit) -> None: - if not qubit.is_null: + qm = self.timeline.quantum_manager + key = qubit.qstate_key + meas_res = qm.run_circuit(_meas_circuit, [key], self.get_generator().random())[key] + if meas_res: self.detector.get() ``` -Notice that we also needed to change the `receive_qubit` method of the base `Node` class. This method is invoked by the quantum channel when transmitting photons, and by default is set to do nothing. For this method, the `src` input specifies the name of the node sending the qubit. In our case, we don’t care about the source node, so we can ignore it. The `qubit` input is the transmitted photon. For single atom memories, this photon may be in a null state, signified with a true value for the `is_null` attribute. A photon may be marked as null if it is somehow lost or should not have been emitted by the memory originally (if the memory is in the up state or has low fidelity). In this case, we must ignore the photon and not record it. Otherwise, it is sent to the detector for measurement. The detector uses the `get` method to receive photons, and this interface is shared by many other optical hardware elements. +Notice that we also needed to change the `receive_qubit` method of the base `Node` class. +This method is invoked by the quantum channel when transmitting photons, and by default is set to do nothing. +For this method, the `src` input specifies the name of the node sending the qubit. +In our case, we don’t care about the source node, so we can ignore it. +The `qubit` input is the transmitted photon. +For single atom memories, the memory state heralded by the denotes the presence or absence of a photon. +This corresponds to the up or down state of the memory. +We will thus measure the memory state and record the photon accordingly (this will be done automatically in future updates). +If we measure 0, we must ignore the photon and not record it. +Otherwise, it is sent to the detector for recording. +The detector uses the `get` method to receive photons, and this interface is shared by many other optical hardware elements. ### Step 2: Custom Protocol From 01ad038188ed62f22bec5f810c9768d6db2bae1d Mon Sep 17 00:00:00 2001 From: Alex-Kolar Date: Tue, 5 Jul 2022 11:54:21 -0500 Subject: [PATCH 3/4] Update optical channel units --- src/components/optical_channel.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/components/optical_channel.py b/src/components/optical_channel.py index 9edeec48..2ac18faf 100644 --- a/src/components/optical_channel.py +++ b/src/components/optical_channel.py @@ -28,19 +28,20 @@ class OpticalChannel(Entity): timeline (Timeline): timeline for simulation. sender (Node): node at sending end of optical channel. receiver (Node): node at receiving end of optical channel. - atteunuation (float): attenuation of the fiber (in dB/km). + atteunuation (float): attenuation of the fiber (in dB/m). distance (int): length of the fiber (in m). polarization_fidelity (float): probability of no polarization error for a transmitted qubit. light_speed (float): speed of light within the fiber (in m/ps). """ - def __init__(self, name: str, timeline: "Timeline", attenuation: float, distance: int, polarization_fidelity: float, light_speed: float): + def __init__(self, name: str, timeline: "Timeline", attenuation: float, distance: int, + polarization_fidelity: float, light_speed: float): """Constructor for abstract Optical Channel class. Args: name (str): name of the beamsplitter instance. timeline (Timeline): simulation timeline. - attenuation (float): loss rate of optical fiber (in dB/km). + attenuation (float): loss rate of optical fiber (in dB/m). distance (int): length of fiber (in m). polarization_fidelity (float): probability of no polarization error for a transmitted qubit. light_speed (float): speed of light within the fiber (in m/ps). @@ -71,7 +72,7 @@ class QuantumChannel(OpticalChannel): timeline (Timeline): timeline for simulation. sender (Node): node at sending end of optical channel. receiver (Node): node at receiving end of optical channel. - atteunuation (float): attenuation of the fiber (in dB/km). + atteunuation (float): attenuation of the fiber (in dB/m). distance (int): length of the fiber (in m). polarization_fidelity (float): probability of no polarization error for a transmitted qubit. light_speed (float): speed of light within the fiber (in m/ps). @@ -88,7 +89,7 @@ def __init__(self, name: str, timeline: "Timeline", attenuation: float, Args: name (str): name of the quantum channel instance. timeline (Timeline): simulation timeline. - attenuation (float): loss rate of optical fiber (in dB/km). + attenuation (float): loss rate of optical fiber (in dB/m). distance (int): length of fiber (in m). polarization_fidelity (float): probability of no polarization error for a transmitted qubit (default 1). light_speed (float): speed of light within the fiber (in m/ps) (default 2e-4). @@ -223,7 +224,7 @@ class ClassicalChannel(OpticalChannel): receiver (Node): node at receiving end of optical channel. distance (float): length of the fiber (in m). light_speed (float): speed of light within the fiber (in m/ps). - delay (float): delay in message transmission (default distance / light_speed). + delay (float): delay (in ps) of message transmission (default distance / light_speed). """ def __init__(self, name: str, timeline: "Timeline", distance: int, delay=-1): From 7840d2211c24054ad0233c0bc14c793749d6aed6 Mon Sep 17 00:00:00 2001 From: Alex-Kolar Date: Wed, 6 Jul 2022 10:32:48 -0500 Subject: [PATCH 4/4] Update version to 0.3.2 --- CHANGELOG.md | 6 ++++++ docs/source/conf.py | 2 +- setup.py | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5561bc2..03a03f01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,3 +77,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Mirror` class for simple reflection of photons - Sends photon to another node with quantum channel connection to the local node - Quantum++ package acknowledgement to README + +## [0.3.2] +### Changed +- Corrected units in jupyter notebook example files +- Corrected units for the optical channel class +- Bug fixes for tutorial scripts diff --git a/docs/source/conf.py b/docs/source/conf.py index c9c43d1e..1e4597ba 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -22,7 +22,7 @@ author = 'Xiaoliang Wu, Joaquin Chung, Alexander Kolar, Eugene Wang, Tian Zhong, Rajkumar Kettimuthu, Martin Suchara' # The full version, including alpha/beta/rc tags -release = '0.3.1' +release = '0.3.2' # -- General configuration --------------------------------------------------- diff --git a/setup.py b/setup.py index c330b1fa..dc741ea6 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="sequence", - version="0.3.1", + version="0.3.2", author="Xiaoliang Wu, Joaquin Chung, Alexander Kolar, Eugene Wang, Tian Zhong, Rajkumar Kettimuthu, Martin Suchara", author_email="xwu64@hawk.iit.edu, chungmiranda@anl.gov, akolar@anl.gov, eugenewang@yahoo.com, tzh@uchicago.edu, kettimut@mcs.anl.gov, msuchara@anl.gov", description="Simulator of Quantum Network Communication: SEQUENCE-Python is a prototype version of the official SEQUENCE release.",