Package: netQuil
NetQuil: A quantum playground for distributed quantum computing simulationsNetQuil is an open-source Python framework designed specifically for simulating quantum networks and distributed quantum protocol. Built on the already extensive quantum computing frameworkpyQuil, byRigetti Computing, netQuil is perfect for extending your current quantum computing experiments and testing ideas in quantum network topology and distributed quantum protocol. NetQuil offers an extensible device simulator, quantum and classical noise modules, and a performant multi-threaded simulation manager. It also allows you to run multiple trials across your network, syncronize agents based on local and master clocks, and review traffic in real time with a network monitor. NetQuil is also optimized for distributed quantum protocol with its implementation of the primitive cat-entangler and cat-disentangler introduced byYimsiriwattana Lomonaco. This primitive protocols can be used to implement non-local CNOTs, non-local controlled gates, and teleportation, and should be the backbone of any distributed quantum protocol you create.NetQuil is a project by AT&T Foundry. NetQuil is a work in progress and contributions are encouraged.DocumentationExplore netQuil'sdocumentation centerlearn more about the framework and its use cases. If you are interested in learning about the state of distributed quantum computing (DQC) and netQuil's role as a framework in the field read thewhitepaper, "netQuil: A quantum playground for distributed quantum computing simulations".InstallationYou can install netQuil directly usingpip:pip install netquilnetQuil DesignDemosCheckout netQuil in action in thedemosfolder and at thedocumentation center:Quantum TeleportationAs a simple demonstration of netQuil, let's imagine a scenario where Alice wants to send Bob the quantum state of an arbitrary qubit she possesses.
Since Alice does not know the state of the qubit, and she cannot measure it, because measuring it would cause the state to collapse, Alice decides to usequantum
teleportation.Charlie creates a bell state pair and sends one qubit to Alice and the other to Bob.Alice receives Charlie's qubit. Alice projects her arbitrary quantum state onto qubit A using a CNOT and Hadamard gate.Alice measures her qubits and classically sends the results to Bob. As a result of the measurements Bob's state collapses to one of the four Bell States.Bob recreate's Alice's arbitrary state based on Alice's measurements, namely applying a Pauli-X (X) gate if Alice's bell state pair is 1 and applying a Pauli-Z (Z) gate if the arbitrary state is measured to be 1.We can implement quantum teleportation using netQuil in the following manner:from pyquil import Program
from pyquil.api import WavefunctionSimulator, QVMConnection
from pyquil.gates import *

def printWF(p):
    '''
    Prints the wavefunction from simulating a program p
    '''
    wf_sim = WavefunctionSimulator()
    waveFunction = wf_sim.wavefunction(p)
    print(waveFunction)


class Charlie(Agent):
    '''
    Charlie sends Bell pairs to Alice and Bob
    '''
    def run(self):

        # Create Bell State Pair
        p = self.program
        p += H(0)
        p += CNOT(0,1)

        self.qsend(alice.name, [0])
        self.qsend(bob.name, [1])

class Alice(Agent): 
    '''
    Alice projects her state on her Bell State Pair from Charlie
    '''
    def run(self): 
        p = self.program

        # Define Alice's Qubits
        phi = self.qubits[0]
        qubitsCharlie = self.qrecv(charlie.name)
        a = qubitsCharlie[0]

        # Entangle Ancilla and Phi
        p += CNOT(phi, a)
        p += H(phi)

        # Measure Ancilla and Phi
        p += MEASURE(a, ro[0])
        p += MEASURE(phi, ro[1])


class Bob(Agent): 
    '''
    Bob recreates Alice's state based on her measurements
    '''
    def run(self):
        p = self.program

        # Define Bob's qubits
        qubitsCharlie = self.qrecv(charlie.name)
        b = qubitsCharlie[0]

        # Prepare State Based on Measurements
        p.if_then(ro[0], X(b))
        p.if_then(ro[1], Z(b))


p = Program()

# Prepare psi
p += H(2)
p += Z(2)
p += RZ(1.2, 2)
print("Initial Alice State: ")
printWF(p)

# Create Classical Memory
ro = p.declare('ro', 'BIT', 3)

# Create Alice, Bob, and Charlie. Give Alice qubit 2 (phi). Give Charlie qubits [0,1] (Bell State Pairs). 
alice = Alice(p, qubits=[2], name='alice')
bob = Bob(p, name='bob')
charlie = Charlie(p, qubits=[0,1], name='charlie')

# Connect agents to distribute qubits and report results
QConnect(alice, charlie, bob)
CConnect(alice, bob)

# Run simulation
Simulation(alice, bob, charlie).run(trials=1, agent_classes=[Alice, Bob, Charlie])
qvm = QVMConnection()
qvm.run(p)
print("Final Bob's State: ")
printWF(p)