Getting Started¶
Requirements¶
Pyquil 2.0, Python 3.6 or higher, and NumPy are requirements for netQuil. You will also need to download the Rigetti’s QVM and Compiler as described on their Getting Started page.
Installation¶
To install using the Python package manager, pip:
pip install netquil
To install without pip:
easy_install netquil
To instead install netQuil from the source, clone the repository.
git clone https://github.com/att-innovate/netquil.git
Tutorial - Bell State Distribution¶
Lets start by building our first netQuil program that creates and distributes a bell state pair
between Alice and Bob. In this tutorial you will be introduced to Agents
(the nodes in your network),
QConnections
and CConnections
(the channels connecting nodes), and Devices
(the customizable noise modules and error simulators).
Checkout our other demos to see more advanced examples of netQuil in action, and, for bold of you, review our whitepaper to learn about the state of
distributed quantum protocols and netQuil.
This tutorial assumes you have a basic understanding of quantum information theory and the pyquil framework built on Quil. For a quick refresher, review this resource.
Import Dependencies¶
Let’s start by importing all of our dependencies.
1 2 3 | from netquil import *
from pyquil import Program
from pyquil.gates import *
|
Define Agents¶
Agents are nodes in our quantum network. Each Agent should extend the agent class and define
a run
function, allowing that agent to run on its own thread. Agents can send and receive quantum and classical information,
as well as define source and target devices that ingress and egress information must pass through, respectively. They also maintain local clocks
that increment based on traffic and the delay that devices return, a network monitor recording their traffic, and a list of qubits and classical bits that
they manage.
All agents should share the same PyQuil program that they can modify to simulate network traffic. The program can be explicitly attached to each agent if presimulation computations must be done, or be omitted to default to a blank program.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | from netquil import *
from pyquil import Program
from pyquil.gates import *
class Alice(Agent):
def run(self):
a, b = self.qubits
p = self.program
class Bob(Agent):
def run(self):
pass
alice = Alice(qubits=[0,1])
bob = Bob()
|
Create the Run Function¶
An agent’s run function should encapsulate all of the work that agent is responsible for. self.qubits
returns the list of qubits that
an agent owns and may modify. self.program
returns the global program shared between agents, and qsend(name, qubits)
and qrecv(name)
will send and receive qubits from one agent to another, respectively.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | class Alice(Agent):
def run(self):
a, b = self.qubits
p = self.program
# Create Bell State
p += H(a)
p += CNOT(a,b)
# Send half of bell state to Bob
self.qsend('bob', b)
class Bob(Agent):
def run(self):
p = self.program
# Receive half of bell state from Alice
b = self.qrecv('alice')
# Measure qubits and run program
p += Measure(b)
|
Connect the Agents¶
QConnect()
will create a quantum channel between the given agents.
Without establishing this connection, agents have no way of communicating between each other.
Similarly CConnect()
will create a classical channel between the given agents. Both
QConnect()
and CConnect()
will create channels between all agents passed to them. On
QConnect()
you may also specify transit_devices
which all qubits will travel through when passed
between agents.
alice = Alice(qubits=[0,1])
bob = Bob()
# Connect alice and bob to quantum network
QConnect(alice, bob)
Simulate the Network¶
Simulation(agents...)
will start each agent on its own thread and call agents’ run
function.
Simulation().run
will return a list of Quil programs, one for each trial (defaults to one trial),
that can be executed on a qvm.
alice = Alice(qubits=[0,1])
bob = Bob()
# Create Quantum Channel between Alice and Bob
QConnect(alice, bob)
programs = Simulation(alice, bob).run()
results = qvm.run(programs[0])
print(results)
Next Steps¶
All together, your program should look something like this!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | from netquil import *
from pyquil import Program
from pyquil.gates import *
class Alice(Agent):
def run(self):
a, b = self.qubits
p = self.program
# Create Bell State
p += H(a)
p += CNOT(a,b)
# Send half of bell state to Bob
self.qsend('bob', b)
class Bob(Agent):
def run(self):
p = self.program
# Receive half of bell state from Alice
b = self.qrecv('alice')
# Measure qubits and run program
p += Measure(b)
alice = Alice(qubits=[0,1])
bob = Bob()
# Connect alice and bob to quantum network
QConnect(alice, bob)
programs = Simulation(alice, bob).run()
results = qvm.run(programs[0])
print(results)
|
Congratulations! You now have a working netQuil program that creates and distributes a bell state pair between Alice and Bob.
Explore our advanced usage demo to learn about netQuil’s error module for quantum noise and transit, source and target devices, as well as how to run multiple trials and syncronize agents.
Read the distributed protocol demo to see how the cat-entangler and cat-disentangler can be used to implement non-local CNOTs, non-local controlled gates, and teleportation.
Or, just for fun, checkout the middle-man attack, teleportation, or superdense coding demos to learn about common quantum networking protocols.