def test_barrier_edge_cases(self): r"""Test that the barrier works in edge cases.""" def qfunc(): qml.Barrier(wires=0) qml.Hadamard(wires=0) qml.Hadamard(wires=0) qml.Barrier(wires=0) return qml.expval(qml.PauliZ(0)) dev = qml.device("default.qubit", wires=3) qnode = qml.QNode(qfunc, dev) gates = qml.specs(qnode)()["gate_sizes"][1] assert gates == 4 optimized_qfunc = qml.compile()(qfunc) optimized_qnode = qml.QNode(optimized_qfunc, dev) optimized_gates = qml.specs(optimized_qnode)()["gate_sizes"][1] assert optimized_gates == 0 def qfunc(): qml.Hadamard(wires=0) qml.Barrier(wires=0) qml.Barrier(wires=0) qml.Hadamard(wires=0) return qml.expval(qml.PauliZ(0)) dev = qml.device("default.qubit", wires=3) qnode = qml.QNode(qfunc, dev) gates = qml.specs(qnode)()["gate_sizes"][1] assert gates == 4 def qfunc(): qml.Hadamard(wires=0) qml.Barrier(only_visual=True, wires=0) qml.Barrier(wires=0) qml.Hadamard(wires=0) return qml.expval(qml.PauliZ(0)) dev = qml.device("default.qubit", wires=3) optimized_qfunc = qml.compile()(qfunc) optimized_qnode = qml.QNode(optimized_qfunc, dev) optimized_gates = qml.specs(optimized_qnode)()["gate_sizes"][1] assert optimized_gates == 2
def test_empty(self, diff_method, len_info): dev = qml.device("default.qubit", wires=1) @qml.qnode(dev, diff_method=diff_method) def circ(): return qml.expval(qml.PauliZ(0)) info_func = qml.specs(circ) info = info_func() circ() assert info == circ.specs assert len(info) == len_info assert info["gate_sizes"] == defaultdict(int) assert info["gate_types"] == defaultdict(int) assert info["num_observables"] == 1 assert info["num_operations"] == 0 assert info["num_diagonalizing_gates"] == 0 assert info["num_used_wires"] == 1 assert info["depth"] == 0 assert info["num_device_wires"] == 1 assert info["diff_method"] == diff_method if diff_method == "parameter-shift": assert info["num_parameter_shift_executions"] == 1 if diff_method != "backprop": assert info["device_name"] == "default.qubit" assert info["num_trainable_params"] == 0 else: assert info["device_name"] == "default.qubit.autograd"
def test_max_expansion(self): """Test that a user can calculation specifications for a different max expansion parameter.""" n_layers = 2 n_wires = 5 dev = qml.device("default.qubit", wires=n_wires) @qml.qnode(dev) def circuit(params): qml.templates.BasicEntanglerLayers(params, wires=range(n_wires)) return qml.expval(qml.PauliZ(0)) params_shape = qml.templates.BasicEntanglerLayers.shape(n_layers=n_layers, n_wires=n_wires) rng = np.random.default_rng(seed=10) params = rng.standard_normal(params_shape) assert circuit.max_expansion == 10 info = qml.specs(circuit, max_expansion=0)(params) assert circuit.max_expansion == 10 assert len(info) == 10 assert info["gate_sizes"] == defaultdict(int, {5: 1}) assert info["gate_types"] == defaultdict(int, {"BasicEntanglerLayers": 1}) assert info["num_operations"] == 1 assert info["num_observables"] == 1 assert info["num_used_wires"] == 5 assert info["depth"] == 1 assert info["num_device_wires"] == 5 assert info["device_name"] == "default.qubit.autograd" assert info["diff_method"] == "backprop"
def test_entangling_mask_application(self): size = 4 mp = self._create_circuit_with_entangling_gates(size) rotations = [pnp.random.choice([0, 1, 2]) for _ in range(size * size)] circuit = qml.QNode( original_variational_circuit, device(mp.mask(Axis.WIRES).size), ) circuit(mp.differentiable_parameters, rotations, mp) assert (qml.specs(circuit)(mp.differentiable_parameters, rotations, mp)["gate_types"]["CZ"] == 12) mp.perturb(axis=Axis.ENTANGLING, mode=Mode.SET, amount=6) circuit(mp.differentiable_parameters, rotations, mp) assert (qml.specs(circuit)(mp.differentiable_parameters, rotations, mp)["gate_types"]["CZ"] == 6)
def test_use_barrier(self): r"""Test that the barrier influences compilation.""" def qfunc(): qml.Hadamard(wires=0) qml.Barrier(wires=0) qml.Hadamard(wires=0) return qml.expval(qml.PauliZ(0)) dev = qml.device("default.qubit", wires=3) qnode = qml.QNode(qfunc, dev) gates = qml.specs(qnode)()["gate_sizes"][1] assert gates == 3 optimized_qfunc = qml.compile()(qfunc) optimized_qnode = qml.QNode(optimized_qfunc, dev) optimized_gates = qml.specs(optimized_qnode)()["gate_sizes"][1] assert optimized_gates == 2
def test_gradient_transform(self): """Test that a gradient transform is properly labelled""" dev = qml.device("default.qubit", wires=2) @qml.beta.qnode(dev, diff_method=qml.gradients.param_shift) def circuit(): return qml.probs(wires=0) info = qml.specs(circuit)() assert info[ "diff_method"] == "pennylane.gradients.parameter_shift.param_shift" assert info[ "gradient_fn"] == "pennylane.gradients.parameter_shift.param_shift"
def test_barrier_only_visual(self): r"""Test that the barrier doesn't influence compilation when the only_visual parameter is True.""" def qfunc(): qml.Hadamard(wires=0) qml.Barrier(only_visual=True, wires=0) qml.Hadamard(wires=0) return qml.expval(qml.PauliZ(0)) dev = qml.device("default.qubit", wires=3) optimized_qfunc = qml.compile()(qfunc) optimized_qnode = qml.QNode(optimized_qfunc, dev) optimized_gates = qml.specs(optimized_qnode)()["gate_sizes"][1] assert optimized_gates == 0
def test_specs(self, diff_method, len_info): """Test the specs transforms works in standard situations""" dev = qml.device("default.qubit", wires=4) @qml.qnode(dev, diff_method=diff_method) def circuit(x, y, add_RY=True): qml.RX(x[0], wires=0) qml.Toffoli(wires=(0, 1, 2)) qml.CRY(x[1], wires=(0, 1)) qml.Rot(x[2], x[3], y, wires=2) if add_RY: qml.RY(x[4], wires=1) return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliX(1)) x = np.array([0.05, 0.1, 0.2, 0.3, 0.5], requires_grad=True) y = np.array(0.1, requires_grad=False) info_func = qml.specs(circuit) info = info_func(x, y, add_RY=False) circuit(x, y, add_RY=False) assert info == circuit.specs assert len(info) == len_info assert info["gate_sizes"] == defaultdict(int, {1: 2, 3: 1, 2: 1}) assert info["gate_types"] == defaultdict(int, { "RX": 1, "Toffoli": 1, "CRY": 1, "Rot": 1 }) assert info["num_operations"] == 4 assert info["num_observables"] == 2 assert info["num_diagonalizing_gates"] == 1 assert info["num_used_wires"] == 3 assert info["depth"] == 3 assert info["num_device_wires"] == 4 assert info["diff_method"] == diff_method if diff_method == "parameter-shift": assert info["num_parameter_shift_executions"] == 7 if diff_method != "backprop": assert info["device_name"] == "default.qubit" assert info["num_trainable_params"] == 4 else: assert info["device_name"] == "default.qubit.autograd"
def test_custom_gradient_transform(self): """Test that a custom gradient transform is properly labelled""" dev = qml.device("default.qubit", wires=2) @qml.gradients.gradient_transform def my_transform(tape): return tape, None @qml.beta.qnode(dev, diff_method=my_transform) def circuit(): return qml.probs(wires=0) info = qml.specs(circuit)() assert info["diff_method"] == "test_specs.my_transform" assert info["gradient_fn"] == "test_specs.my_transform"
def test_specs_state(self, diff_method, len_info): """Test specs works when state returned""" dev = qml.device("default.qubit", wires=2) @qml.beta.qnode(dev, diff_method=diff_method) def circuit(): return qml.state() info_func = qml.specs(circuit) info = info_func() assert len(info) == len_info assert info["num_observables"] == 1 assert info["num_diagonalizing_gates"] == 0
def test_specs(self): """Test that the specs of a VQE circuit can be computed""" dev = qml.device("default.qubit", wires=2) H = qml.Hamiltonian([0.1, 0.2], [qml.PauliZ(0), qml.PauliZ(0) @ qml.PauliX(1)]) @qml.qnode(dev) def circuit(): qml.Hadamard(wires=0) qml.CNOT(wires=[0, 1]) return qml.expval(H) res = qml.specs(circuit)() assert res["num_observables"] == 1 assert res["num_diagonalizing_gates"] == 0 assert res["num_used_wires"] == 2