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 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 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 _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 generate_noisy_network(self): """ Generate the QKD network. """ network = Network("Noisy Network") alice = Node("alice", qmemory=self._create_processor( dephase_rate=self._dephase_rate, t_times=self._t_time, memory_size=self._memory_size, qsource={ 'freq': 1, 'probs': self._q_source_probs }, qdetect={ 'sys_delay': 0, 'dead_time': 0 }, ent_source=True)) bob = Node("bob", qmemory=self._create_processor( dephase_rate=self._dephase_rate, t_times=self._t_time, memory_size=self._memory_size, qdetect={ 'sys_delay': 0, 'dead_time': 0 })) network.add_nodes([alice, bob]) q_conn = QubitConnection(length=self._length, dephase_rate=self._dephase_rate, loss=self._loss) network.add_connection(alice, bob, label='q_chan', connection=q_conn, port_name_node1='qubitIO', port_name_node2='qubitIO') 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 generate_network(): """ Generate the network. For BB84, we need a quantum and classical channel. """ network = Network("Classical Network") alice = Node("alice") bob = Node("bob") network.add_nodes([alice, bob]) 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 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