def generate_network(): """ Generate the network. For BB84, we need a quantum and classical channel. """ network = Network("BB92etwork") alice = Node("alice", qmemory=create_processor()) bob = Node("bob", qmemory=create_processor()) network.add_nodes([alice, bob]) p_ab, p_ba = network.add_connection(alice, bob, label="q_chan", channel_to=QuantumChannel('AqB', delay=10), channel_from=QuantumChannel('BqA', delay=10), port_name_node1="qubitIO", port_name_node2="qubitIO") # Map the qubit input port from the above channel to the memory index 0 on Bob"s # side alice.ports[p_ab].forward_input(alice.qmemory.ports["qin0"]) bob.ports[p_ba].forward_input(bob.qmemory.ports["qin0"]) network.add_connection(alice, bob, label="c_chan", channel_to=ClassicalChannel('AcB', delay=10), channel_from=ClassicalChannel('BcA', delay=10), port_name_node1="classicIO", port_name_node2="classicIO") return network
def main(): # Initialise the simulation. ns.sim_reset() distance = 2.74 / 1000 # default unit of length in channels is km delay_model = PingPongDelayModel() # Set-up the network. node_ping = Node("Ping", port_names=["port_to_channel"]) node_pong = Node("Pong", port_names=["port_to_channel"]) connection = DirectConnection( "Connection", QuantumChannel(name="qchannel[ping to pong]", length=distance, models={"delay_model": delay_model}), QuantumChannel(name="qchannel[pong to ping]", length=distance, models={"delay_model": delay_model})) node_ping.connect_to(remote_node=node_pong, connection=connection, local_port_name="qubitIO", remote_port_name="qubitIO") # Assign protocols to the nodes. qubits = ns.qubits.create_qubits(1) ping_protocol = PingPongProtocol(node_ping, observable=ns.Z, qubit=qubits[0]) pong_protocol = PingPongProtocol(node_pong, observable=ns.X) # Start the protocols and the simulation. print("Start the PingPong simulation:\n") ping_protocol.start() pong_protocol.start() stats = ns.sim_run(91) print(stats)
def generate_network(): """ Generate the network. For BB84, we need a quantum and classical channel. """ network = Network("Quantum Cheque Network") customer = Node("customer", qmemory=create_processor()) banker = Node("banker", qmemory=create_processor()) network.add_nodes([customer, banker]) p_ab, p_ba = network.add_connection(banker, customer, label="q_chan", channel_to=QuantumChannel('AqB', delay=10), channel_from=QuantumChannel('BqA', delay=10), port_name_node1="qubitIO", port_name_node2="qubitIO") customer.ports[p_ba].forward_input(customer.qmemory.ports["qin0"]) banker.ports[p_ab].forward_input(banker.qmemory.ports["qin0"]) network.add_connection(banker, customer, label="c_chan", channel_to=ClassicalChannel('AcB', delay=10), channel_from=ClassicalChannel('BcA', delay=10), port_name_node1="classicIO", port_name_node2="classicIO") return network
def build(self, network): delay_model = get_delay_model(self.delay_type, **self.delay_config) loss_model = get_loss_model(self.loss_type, **self.loss_config) if self.TYPE == "quantum": channel_1 = QuantumChannel(name="AtoB", length=self.distance, models={ "delay_model": delay_model, 'quantum_loss_model': loss_model }) channel_2 = QuantumChannel(name="BtoA", length=self.distance, models={ "delay_model": delay_model, 'quantum_loss_model': loss_model }) self.conn = connection = DirectConnection(name=self.NAME, channel_AtoB=channel_1, channel_BtoA=channel_2) to_node = network.NODES[self.CONNECTION["to"]["id"]] to_port = self.CONNECTION["to"]["port"] from_node = network.NODES[self.CONNECTION["from"]["id"]] from_port = self.CONNECTION["from"]["port"] to_node.node.ports[to_port].connect(self.conn.ports["A"]) from_node.node.ports[from_port].connect(self.conn.ports["B"]) pass
def _generate_network(name, with_ent=False): network = Network(name) alice = Node( "alice", qmemory=TwoPartyNetwork._create_noiseless_processor(with_ent)) bob = Node("bob", qmemory=TwoPartyNetwork._create_noiseless_processor()) network.add_nodes([alice, bob]) p_ab, p_ba = network.add_connection( alice, bob, label="q_chan", channel_to=QuantumChannel('AqB', delay=10), channel_from=QuantumChannel('BqA', delay=10), port_name_node1="qubitIO", port_name_node2="qubitIO") alice.ports[p_ab].forward_input(alice.qmemory.ports["qin0"]) bob.ports[p_ba].forward_input(bob.qmemory.ports["qin0"]) network.add_connection(alice, bob, label="c_chan", channel_to=ClassicalChannel('AcB', delay=10), channel_from=ClassicalChannel('BcA', delay=10), port_name_node1="classicIO", port_name_node2="classicIO") return network
def board_network(board_size): network = Network("Board") #Create nodes tm_node, p0_node, p1_node = network.add_nodes(["TaskMasterNode", "PlayerZeroNode", "PlayerOneNode"]) logging.debug('nw: nodes created') #Add Memories tm_node.add_subcomponent(QuantumProcessor("TaskMasterMemory", num_positions=board_size)) p0_node.add_subcomponent(QuantumProcessor("PlayerZeroMemory", num_postiions=1)) p1_node.add_subcomponent(QuantumProcessor("PlayerOneMemory", num_positions=1)) logging.debug('nw: added memories') #Quantum channels qchannel_tm0 = QuantumChannel("QChannelTMtoP0") qchannel_0tm = QuantumChannel("QChannelP0toTM") qchannel_tm1 = QuantumChannel("QChannelTMtoP1") qchannel_1tm = QuantumChannel("QChannelP1toTM") logging.debug('nw: created channels') #Quantum connections tm_port0, p0_port0 = network.add_connection(tm_node, p0_node, channel_to=qchannel_tm0, channel_from=qchannel_0tm, label="QTMP0") tm_port1, p1_port0 = network.add_connection(tm_node, p1_node, channel_to=qchannel_tm1, channel_from=qchannel_1tm, label="QTMP1") logging.debug('nw: created connections') #Port forwarding p0_node.qmemory.ports["qout"].forward_output(p0_node.ports[p0_port0]) p0_node.ports[p0_port0].forward_input(p0_node.qmemory.ports["qin0"]) p1_node.qmemory.ports["qout"].forward_output(p1_node.ports[p1_port0]) p1_node.ports[p1_port0].forward_input(p1_node.qmemory.ports["qin0"]) #Classical channels channel_0tm = Channel("ChannelP0toTM") channel_1tm = Channel("ChannelP1toTM") channel_tm0 = Channel("ChannelTMtoP0") channel_tm1 = Channel("ChannelTMtoP1") #Classical connections p0_port1, tm_port3 = network.add_connection(p0_node, tm_node, channel_to=channel_0tm, channel_from=channel_tm0, label="TMP0") p1_port1, tm_port4 = network.add_connection(p1_node, tm_node, channel_to=channel_1tm, channel_from=channel_tm1, label="TMP1") logging.debug('nw: port forwarding done. Network init complete.') return network
def __init__(self, length, dephase_rate, loss=(0, 0), name='QubitConn'): super().__init__(name=name) error_models = { 'quantum_noise_model': DephaseNoiseModel(dephase_rate=dephase_rate, time_independent=False), 'delay_model': FibreDelayModel(length=length), 'quantum_loss_model': FibreLossModel(p_loss_init=loss[0], p_loss_length=loss[1]) } q_channel = QuantumChannel(name='q_channel', length=length, models=error_models) self.add_subcomponent(q_channel, forward_output=[('B', 'recv')], forward_input=[('A', 'send')])
def generate_network(): """ Generate the network. There are two nodes in the network connected with a quantum and classical channel, both unidirectional from A -> B. """ q_chan = QuantumChannel(name='AqB') c_chan = ClassicalChannel(name='AcB') network = Network('Teleport Network') alice = Node('alice', qmemory=create_processor(1e7, 0.2)) bob = Node('bob', qmemory=create_processor(1e7, 0.2)) network.add_nodes([alice, bob]) _, p_ba = network.add_connection(alice, bob, label='q_chan', connection=DirectConnection( name="q_conn[A|B]", channel_AtoB=q_chan), port_name_node1='portQA_1', port_name_node2='portQB_1') # Map the qubit input port from the above channel to the memory index 0 on Bob's # side bob.ports[p_ba].forward_input(bob.qmemory.ports['qin0']) network.add_connection(alice, bob, label='c_chan', connection=DirectConnection(name="c_conn[A|B]", channel_AtoB=c_chan), port_name_node1='portCA_1', port_name_node2='portCB_1') return network
def setup_network(source_attempts, memory_depth, **kwargs): # retrieve setup parameters from sim_params, substituting defaults when required source_frequency = kwargs.get('source_frequency', 100e6) channel_A_length = kwargs.get('channel_A_length', 1) channel_A_static_loss = kwargs.get('channel_A_static_loss', 0) channel_A_loss = kwargs.get('channel_A_loss', 0) channel_A_speed = kwargs.get('channel_A_speed', 3e5) channel_B_length = kwargs.get('channel_B_length', 1) channel_B_static_loss = kwargs.get('channel_B_static_loss', 0) channel_B_loss = kwargs.get('channel_B_loss', 0) channel_B_speed = kwargs.get('channel_B_speed', 3e5) memory_T1 = kwargs.get('memory_T1', 1.0e8) memory_T2 = kwargs.get('memory_T2', 1.0e4) physical_instructions = kwargs.get('physical_instructions', None) # find each channel's propagation time [ns]: propagation_time_A = (channel_A_length / channel_A_speed) * 1e9 propagation_time_B = (channel_B_length / channel_B_speed) * 1e9 if propagation_time_A < propagation_time_B: clock_A_delay = propagation_time_B - propagation_time_A clock_B_delay = 0 clock_R_delay = propagation_time_B elif propagation_time_A > propagation_time_B: clock_A_delay = 0 clock_B_delay = propagation_time_A - propagation_time_B clock_R_delay = propagation_time_A else: clock_A_delay = 0 clock_B_delay = 0 clock_R_delay = propagation_time_A # arbitrary choice since matched time source_period = 1e9 / source_frequency # source period [ns] clock_model = { 'timing_model': GaussianDelayModel(delay_mean=source_period, delay_std=0.00) } channel_A_model = { 'quantum_loss_model': FibreLossModel(loss_init=channel_A_static_loss, p_loss_length=channel_A_loss), 'delay_model': FibreDelayModel(c=channel_A_speed) } # define channel_A_model according to passed sim_params channel_B_model = { 'quantum_loss_model': FibreLossModel(loss_init=channel_B_static_loss, p_loss_length=channel_B_loss), 'delay_model': FibreDelayModel(c=channel_B_speed) } # define channel_B_model according to passed sim_params memory_model = T1T2NoiseModel(memory_T1, memory_T2) network = Network('Entanglement_swap') node_a, node_b, node_r = network.add_nodes(['node_A', 'node_B', 'node_R']) state_sampler = StateSampler( qs_reprs=[ks.s11], probabilities=[1.0], formalism=QFormalism.DM ) # define desired states to be generated by source # Setup end node A: source_a = QSource( name='QSource_node_A', state_sampler=state_sampler, num_ports=2, status=SourceStatus.EXTERNAL, output_meta={ 'qm_replace': True, 'qm_positions': [0] } ) # allow incoming qubits to replace anything in slot 0, recall we use the default slots only to sort into slots with QProgram clock_a = Clock( name='Clock_node_A', models=clock_model, start_delay=clock_A_delay, max_ticks=source_attempts ) # "max_ticks" will timeout the program after desired number of connection attempts node_a.add_subcomponent(source_a) node_a.add_subcomponent(clock_a) # Setup end node B: source_b = QSource( name='QSource_node_B', state_sampler=state_sampler, num_ports=2, status=SourceStatus.EXTERNAL, output_meta={ 'qm_replace': True, 'qm_positions': [1] } ) # allow incoming qubits to replace anything in slot 1, recall we use the default slots only to sort into slots with QProgram clock_b = Clock( name='Clock_node_B', models=clock_model, start_delay=clock_B_delay, max_ticks=source_attempts ) # "max_ticks" will timeout the program after desired number of connection attempts node_b.add_subcomponent(source_b) node_b.add_subcomponent(clock_b) # Setup midpoint repeater node R: if memory_depth == 0: # special case, initialize non-physical processor to handle measurement on simultaneous input total_positions = 2 qprocessor_r = QuantumProcessor(name='QProcessor_R', num_positions=total_positions, fallback_to_nonphysical=True, phys_instructions=None, memory_noise_models=None) else: total_positions = memory_depth * 2 + 2 qprocessor_r = QuantumProcessor( name='QProcessor_R', num_positions=total_positions, fallback_to_nonphysical=True, phys_instructions=physical_instructions, memory_noise_models=memory_model) if memory_depth != 0: # initialization of memories for position in qprocessor_r.mem_positions[2:memory_depth + 2]: memory_default, = ns.qubits.create_qubits(1, no_state=True) ns.qubits.assign_qstate([memory_default], ns.h0, formalism=QFormalism.DM) position.add_property( 'origin', value=node_a.name ) # first half of qmemory is allocated for qubits from node_A position.set_qubit(memory_default) # initialize to default state position.in_use = False position.add_property(name='status', value="IDLE") for position in qprocessor_r.mem_positions[memory_depth + 2:]: memory_default, = ns.qubits.create_qubits(1, no_state=True) ns.qubits.assign_qstate([memory_default], ns.h0, formalism=QFormalism.DM) position.add_property( 'origin', value=node_b.name ) # second half of qmemory is allocated for qubits from node_B position.set_qubit(memory_default) # initialize to default state position.in_use = False position.add_property(name='status', value="IDLE") qprocessor_r.set_position_used( True, position=0 ) # flag as used, never accessed for storage, used as holding location to sort into memory qprocessor_r.set_position_used( True, position=1) # flag as used, never accessed for storage node_r.add_subcomponent(qprocessor_r) clock_r = Clock(name='Clock_node_R', models=clock_model, start_delay=clock_R_delay, max_ticks=source_attempts) node_r.add_subcomponent(clock_r) # Setup quantum channels: qchannel_ar = QuantumChannel(name='QChannel_A->R', length=channel_A_length, models=channel_A_model) port_name_a, port_name_ra = network.add_connection( node_a, node_r, channel_to=qchannel_ar, label='quantum', port_name_node1='conn|A->R|', port_name_node2='conn|R<-A|') qchannel_br = QuantumChannel(name='QChannel_B->R', length=channel_B_length, models=channel_B_model) port_name_b, port_name_rb = network.add_connection( node_b, node_r, channel_to=qchannel_br, label='quantum', port_name_node1='conn|B->R|', port_name_node2='conn|R<-B|') # Setup Alice ports: node_a.subcomponents['QSource_node_A'].ports['qout0'].forward_output( node_a.ports[port_name_a]) # Setup Bob ports: node_b.subcomponents['QSource_node_B'].ports['qout0'].forward_output( node_b.ports[port_name_b]) # Set up Repeater ports: node_r.ports[port_name_ra].forward_input( node_r.subcomponents['QProcessor_R'].ports['qin0'] ) # incoming qubits on QChannel_A->R go to slot 0 node_r.ports[port_name_rb].forward_input( node_r.subcomponents['QProcessor_R'].ports['qin1'] ) # incoming qubits on QChannel_B->R go to slot 1' return network
std = self.properties["std"] # The 'rng' property contains a random number generator # We can use that to generate a random speed speed = self.properties["rng"].normal(avg_speed, avg_speed * std) delay = 1e9 * kwargs['length'] / speed # in nanoseconds return delay from netsquid.components import QuantumChannel atl_2_nyc = 1200 #distance from ATL to NYC in km distance = atl_2_nyc / 1000 # default unit of length in channels is km delay_model = PingPongDelayModel() channel_1 = QuantumChannel(name="qchannel[A to B]", length=distance, models={"delay_model": delay_model}) channel_2 = QuantumChannel(name="qchannel[B to A]", length=distance, models={"delay_model": delay_model}) from netsquid.nodes import DirectConnection connection = DirectConnection(name="conn[A|B]", channel_AtoB=channel_1, channel_BtoA=channel_2) node_A.connect_to(remote_node=node_B, connection=connection, local_port_name="qubitIO", remote_port_name="qubitIO")
self.properties["std"] = standard_deviation self.required_properties = ['length'] # in km def generate_delay(self, **kwargs): avg_speed = self.properties["speed"] std = self.properties["std"] speed = self.properties["rng"].normal(avg_speed, avg_speed * std) delay = 1e9 * kwargs['length'] / speed # in nanoseconds return delay distance = 2.74 / 1000 delay_model = PingPongDelayModel() channel_1 = QuantumChannel(name="qchannel[alice to bob]", length=distance, models={"delay_model": delay_model}) channel_2 = QuantumChannel(name="qchannel[bob to alice]", length=distance, models={"delay_model": delay_model}) connection = DirectConnection(name="conn[alice|bob]", channel_AtoB=channel_1, channel_BtoA=channel_2) alice.connect_to(remote_node=bob, connection=connection, local_port_name="qubitIO", remote_port_name="qubitIO")