def test_trim(self): """ Tests that gates that do not lead to the output gate are not displayed. """ # set the desired batch size: L = 10 # create a simple sample circuit: circuit = ic.IBMCircuit(L) # create input wires: w1 = iw.IBMInputWire("w1", circuit) w2 = iw.IBMInputWire("w2", circuit) w3 = iw.IBMInputWire("w3", circuit) # create gates that do lead to the output gate: g1 = iga.IBMAddGate("g1", w1, w2, circuit) g2 = igm.IBMMulGate("g2", g1, w3, circuit) # create a gate that does not lead to the output gate: g3 = iga.IBMAddGate("g3", w2, g2, circuit) # create the output gate: output_gate = iga.IBMAddGate("og", g1, g2, circuit) # set the circuit with the input wires and output gate: circuit.set_input_wires([w1, w2, w3]) circuit.set_output_gate(output_gate) self.assertEqual(("W=3,D=1.2,L=10\ng1:LADD(w1,w2)\ng2:LMUL(g1,w3)" "\nog:LADD(g1,g2)"), circuit.display())
def generate_circuit_by_depth(B, L, D, W, gate_maker): """ This function this generates an IBM circuit. It is called with the following inputs: L, the number of bits per batch, D, the depth of the circuit as defined by IBM, W, the number of input 'wires' (batch inputs taken) in the circuit, and gate_maker, the function used to produce each gate. """ # Create the circuit: circuit = ic.IBMCircuit(L) # Create W input wires: wires = [ iw.IBMInputWire("".join(("W", str(wire_ind))), circuit) for wire_ind in xrange(W) ] circuit.set_input_wires(wires) ultimate_level = wires # the last level created penultimate_level = [] # the second-to-last level created # Keep track of the smallest gate depth at the last level: min_depth = 0 # Maintain a list of gates at depth D: depth_D_gates = [] # Maintain a list of gates between depth D and D+1, not including D: depth_around_D_gates = [] # Initialize the global gate counter, which acts as the unique numerical id # of each gate: unique_gate_num = W while (min_depth <= D): new_level = [] for gate_index in range(W): # create W new gates new_gate = gate_maker(B, L, ultimate_level, penultimate_level, "".join(["G", str(unique_gate_num)]), circuit) # If the new gate has depth D, add it to depth_D_gates: if (new_gate.get_depth() == D): depth_D_gates.append(new_gate) # If the new gate has D < depth <= D+1, add it to # depth_around_D_gates: if ((new_gate.get_depth() > D) and (new_gate.get_depth() < D + 1)): depth_around_D_gates.append(new_gate) # Add the new gate to the new level: new_level.append(new_gate) # Increment the unique gate number: unique_gate_num += 1 # Increment the smallest gate depth at the last level as needed: min_depth = min(gate.get_depth() for gate in new_level) # Update the ultimate_level and penultimate_level pointers: penultimate_level = ultimate_level ultimate_level = new_level # If there is at least one gate of depth exactly D, select the output # gate from among such gates at random. Otherwise, select the output # gate from among gates between depth D and D+1. if (len(depth_D_gates) > 0): output_gate = sr.choice(depth_D_gates) else: output_gate = sr.choice(depth_around_D_gates) circuit.set_output_gate(output_gate) return circuit
def test_get_depth(self): """ Tests that the get_depth method returns the correct depth, as defined by IBM. """ circuit1 = ic.IBMCircuit(600) w1 = iw.IBMInputWire("w1", circuit1) g1 = igr.IBMRotateGate("g1", w1, 3, circuit1) self.assertEqual(.75, g1.get_depth()) circuit2 = ic.IBMCircuit(650) w2 = iw.IBMInputWire("w2", circuit2) g2 = igr.IBMRotateGate("g2", w2, 3, circuit2) self.assertEqual(.25, g2.get_depth()) circuit3 = ic.IBMCircuit(570) w3 = iw.IBMInputWire("w3", circuit3) g3 = igr.IBMRotateGate("g3", w3, 3, circuit3) self.assertEqual(.5, g3.get_depth())
def test_get_level(self): """ Test that getting level returns 0. """ L = 15 circuit = ic.IBMCircuit(L) w1_name = "w1" w1 = iw.IBMInputWire(w1_name, circuit) self.assertEquals(0, w1.get_level())
def test_get_depth(self): """ Tests that the get_depth method returns the correct depth, as defined by IBM. """ circuit = ic.IBMCircuit(10) w1 = iw.IBMInputWire("w1", circuit) w2 = iw.IBMInputWire("w2", circuit) const = ci.Input([ib.IBMBatch([1, 0, 1])]) g1 = igs.IBMSelectGate("g1", w1, w2, const, circuit) self.assertEqual(.6, g1.get_depth())
def test_get_batch_size(self): """ Tests to see that the get_batch_size method functions as expected. """ co1_name = "object1" D = 5 level = 2 batch_size = 10 circuit = ic.IBMCircuit(batch_size) co1 = ico.IBMCircuitObject(co1_name, D, level, circuit) self.assertEqual(batch_size, co1.get_batch_size())
def test_bad_displayname_init(self): """ Tests that initializing a circuit object with an empty string as a displayname throws an error. """ D = 5 level = 2 batch_size = 10 circuit = ic.IBMCircuit(batch_size) self.assertRaises(AssertionError, ico.IBMCircuitObject, "", D, level, circuit)
def test_get_inputs(self): """ Tests that the get_inputs method functions as expected. """ L = 20 circuit = ic.IBMCircuit(L) gate_name = "g" D = 10 input1 = iw.IBMInputWire("w1", circuit) const = "constant" g = igoiac.IBMGateOneInpAndConst(gate_name, D, input1, const, circuit) self.assertEqual([input1], g.get_inputs())
def test_get_full_display_string(self): """ Tests that the method get_full_display_string returns the correct string. """ #Initialize the circuit: circuit = ic.IBMCircuit(10) #Initialize the input wires: w1 = iw.IBMInputWire("w1", circuit) #Initialize the gate: g = igr.IBMRotateGate("g", w1, 5, circuit) self.assertEquals("g:LROTATE(w1,5)", g.get_full_display_string())
def test_get_inputs(self): """ Tests that the get_inputs method functions as expected. """ L = 20 circuit = ic.IBMCircuit(L) gate_name = "g" D = 10 input1 = iw.IBMInputWire("w1", circuit) input2 = iw.IBMInputWire("w2", circuit) g = igti.IBMGateTwoInps(gate_name, D, input1, input2, circuit) self.assertEqual([input1, input2], g.get_inputs())
def test_get_depth(self): """ Tests that the get_depth method returns the correct depth, as defined by IBM. """ circuit = ic.IBMCircuit(10) w1 = iw.IBMInputWire("w1", circuit) g1 = igac.IBMAddConstGate("g1", w1, ib.IBMBatch([True, True]), circuit) g2 = igm.IBMMulGate("g2", g1, w1, circuit) g3 = igac.IBMAddConstGate("g3", g2, ib.IBMBatch([True, True]), circuit) self.assertEqual(0, g1.get_depth()) self.assertEqual(1, g2.get_depth()) self.assertEqual(1, g3.get_depth())
def test_get_full_display_string(self): """ Tests that the method get_full_display_string returns the correct string. """ #Initialize the circuit: circuit = ic.IBMCircuit(10) #Initialize the input wires: w1 = iw.IBMInputWire("w1", circuit) w2 = iw.IBMInputWire("w2", circuit) #Initialize the gate: g = iga.IBMAddGate("g", w1, w2, circuit) self.assertEquals("g:LADD(w1,w2)", g.get_full_display_string())
def test_get_full_display_string(self): """ Tests that the method get_full_display_string returns the correct string. """ #Initialize the circuit: circuit = ic.IBMCircuit(10) #Initialize the input wire: w1 = iw.IBMInputWire("w1", circuit) #Initialize the constnat: const = ci.Input([ib.IBMBatch([True, False])]) #Initialize the gate: g = igmc.IBMMulConstGate("g", w1, const, circuit) self.assertEquals("g:LMULconst(w1,[10])", g.get_full_display_string())
def test_unimplemented_methods(self): """ Tests that calling methods which are only implemented in subclasses causes errors. """ L = 10 circuit = ic.IBMCircuit(L) w1 = iw.IBMInputWire("w1", circuit) w2 = iw.IBMInputWire("w2", circuit) D = 10 level = 9 g = ig.IBMGate("g", D, level, circuit) # AssertionError expected: self.assertRaises(AssertionError, g.get_func_name)
def test_get_full_display_string(self): """ Tests that the method get_full_display_string returns the correct string. """ #Initialize the circuit: circuit = ic.IBMCircuit(10) #Initialize the input wires: w1 = iw.IBMInputWire("w1", circuit) w2 = iw.IBMInputWire("w2", circuit) #Initialize the constant: const = ci.Input([ib.IBMBatch([1, 0])]) #Initialize the gate: g = igs.IBMSelectGate("g", w1, w2, const, circuit) self.assertEquals(g.get_full_display_string(), "g:LSELECT(w1,w2,[10])")
def test_get_depth(self): """ Tests that the get_depth method returns the correct depth, as defined by IBM. """ circuit = ic.IBMCircuit(10) w1 = iw.IBMInputWire("w1", circuit) w2 = iw.IBMInputWire("w2", circuit) w3 = iw.IBMInputWire("w3", circuit) w4 = iw.IBMInputWire("w4", circuit) g1 = iga.IBMAddGate("g1", w1, w2, circuit) g2 = iga.IBMAddGate("g2", g1, w3, circuit) g3 = iga.IBMAddGate("g3", g2, w4, circuit) self.assertEqual(.1, g1.get_depth()) self.assertEqual(.2, g2.get_depth()) self.assertEqual(.3, g3.get_depth())
def test_get_num_inputs(self): """ Tests that the get_num_inputs method functions as expected. """ # set the desired batch size: L = 10 # create a simple sample circuit: circuit = ic.IBMCircuit(L) # create input wires: w1 = iw.IBMInputWire("w1", circuit) w2 = iw.IBMInputWire("w2", circuit) w3 = iw.IBMInputWire("w3", circuit) # create gates: g1 = iga.IBMAddGate("g1", w1, w2, circuit) g2 = igm.IBMMulGate("g2", g1, w3, circuit) output_gate = iga.IBMAddGate("og", g1, g2, circuit) # set the circuit with the input wires and output gate: circuit.set_input_wires([w1, w2, w3]) circuit.set_output_gate(output_gate) self.assertEqual(3, circuit.get_num_inputs())
def test_display(self): """ Tests that the display method works as intended in a simple circuit. """ # set the desired batch size: L = 10 # create a simple sample circuit: circuit = ic.IBMCircuit(L) # create input wires: w1 = iw.IBMInputWire("w1", circuit) w2 = iw.IBMInputWire("w2", circuit) w3 = iw.IBMInputWire("w3", circuit) # create gates: g1 = iga.IBMAddGate("g1", w1, w2, circuit) g2 = igm.IBMMulGate("g2", g1, w3, circuit) output_gate = iga.IBMAddGate("og", g1, g2, circuit) # set the circuit with the input wires and output gate: circuit.set_input_wires([w1, w2, w3]) circuit.set_output_gate(output_gate) self.assertEqual(("W=3,D=1.2,L=10\ng1:LADD(w1,w2)\ng2:LMUL(g1,w3)" "\nog:LADD(g1,g2)"), circuit.display())
def test_get_num_gates(self): # set the desired batch size: L = 10 # create a simple sample circuit: circuit = ic.IBMCircuit(L) # create input wires: w1 = iw.IBMInputWire("w1", circuit) w2 = iw.IBMInputWire("w2", circuit) w3 = iw.IBMInputWire("w3", circuit) # create gates that do lead to the output gate: g1 = iga.IBMAddGate("g1", w1, w2, circuit) g2 = igm.IBMMulGate("g2", g1, w3, circuit) # create a gate that does not lead to the output gate: g3 = iga.IBMAddGate("g3", w2, g2, circuit) # create the output gate: output_gate = iga.IBMAddGate("og", g1, g2, circuit) # set the circuit with the input wires and output gate: circuit.set_input_wires([w1, w2, w3]) circuit.set_output_gate(output_gate) self.assertEqual(3, circuit.get_num_gates(gate_func_name="LADD")) self.assertEqual(1, circuit.get_num_gates(gate_func_name="LMUL"))
def generate_circuit_by_level(B, L, num_levels, W, gate_maker): """ This function this generates a random IBM circuit with num_levels instead of depth specified. It is called with the following inputs: L, the number of bits per batch, num_levels, the the number of levels in the circuit, W, the number of input 'wires' (batch inputs taken) in the circuit, and gate_maker, the function used to produce each gate. """ # Create the circuit: circuit = ic.IBMCircuit(L) # Create W input wires: wires = [ iw.IBMInputWire("".join(("W", str(wire_ind))), circuit) for wire_ind in xrange(W) ] circuit.set_input_wires(wires) ultimate_level = wires # the last level created penultimate_level = [] # the second-to-last level created # Initialize the global gate counter, which acts as the unique numerical id # of each gate: unique_gate_num = W for level in xrange(num_levels): new_level = [] for gate_index in xrange(W): # create W new gates new_gate = gate_maker(B, L, ultimate_level, penultimate_level, "".join(["G", str(unique_gate_num)]), circuit) # Add the new gate to the new level: new_level.append(new_gate) # Increment the unique gate number: unique_gate_num += 1 # Update the ultimate_level and penultimate_level pointers: penultimate_level = ultimate_level ultimate_level = new_level # Select the output gate from the last level: output_gate = sr.choice(ultimate_level) circuit.set_output_gate(output_gate) return circuit