diff --git a/referenceqvm/qam.py b/referenceqvm/qam.py index 7a7ed16..0e06ea2 100644 --- a/referenceqvm/qam.py +++ b/referenceqvm/qam.py @@ -23,7 +23,7 @@ from referenceqvm.unitary_generator import value_get from pyquil.quil import Program -from pyquil.quilbase import (Instr, +from pyquil.quilbase import (Gate, Measurement, UnaryClassicalInstruction, BinaryClassicalInstruction) @@ -72,9 +72,6 @@ def load_program(self, pyquil_program): raise NotImplementedError("QAM needs to be subclassed in order to " "load program") - # synthesize program into instruction list - synthesized_prog = pyquil_program.synthesize() - # create defgate dictionary defined_gates = {} for dg in pyquil_program.defined_gates: @@ -83,10 +80,9 @@ def load_program(self, pyquil_program): # if QVM_Unitary, check if all instructions are valid. invalid = False - for index, action in enumerate(synthesized_prog): - if isinstance(action, Instr): - if (action.operator_name not in self.gate_set.keys() - and action.operator_name not in self.defgate_set.keys()): + for instr in pyquil_program: + if isinstance(instr, Gate): + if not (instr.name in self.gate_set.keys() or instr.name in self.defgate_set.keys()): invalid = True break else: @@ -98,7 +94,7 @@ def load_program(self, pyquil_program): "supported") # set internal program and counter to their appropriate values - self.program = synthesized_prog + self.program = pyquil_program self.program_counter = 0 # setup quantum and classical memory @@ -121,10 +117,10 @@ def identify_bits(self): for index, inst in enumerate(self.program): if isinstance(inst, Measurement): # instruction is measurement, acts on qbits and cbits - if value_get(inst.arguments[0]) > q_max: - q_max = value_get(inst.arguments[0]) - elif value_get(inst.arguments[1]) > c_max: - c_max = value_get(inst.arguments[1]) + if value_get(inst.qubit) > q_max: + q_max = value_get(inst.qubit) + elif value_get(inst.classical_reg) > c_max: + c_max = value_get(inst.classical_reg) elif isinstance(inst, UnaryClassicalInstruction): # instruction acts on cbits if value_get(inst.target) > c_max: @@ -135,10 +131,9 @@ def identify_bits(self): c_max = value_get(inst.left) elif value_get(inst.right) > c_max: c_max = value_get(inst.right) - elif isinstance(inst, Instr): - # instruction is Gate or DefGate, acts on qbits - if max(map(lambda x: value_get(x), inst.arguments)) > q_max: - q_max = max(map(lambda x: value_get(x), inst.arguments)) + elif isinstance(inst, Gate): + if max(map(lambda x: value_get(x), inst.qubits)) > q_max: + q_max = max(map(lambda x: value_get(x), inst.qubits)) q_max += 1 # 0-indexed c_max += 1 # 0-indexed q_limit = 51 diff --git a/referenceqvm/qvm_unitary.py b/referenceqvm/qvm_unitary.py index 56646a2..1114c47 100644 --- a/referenceqvm/qvm_unitary.py +++ b/referenceqvm/qvm_unitary.py @@ -59,10 +59,9 @@ def transition(self, instruction): """ Implements a transition on the unitary-qvm. - :param instruction: QuilAction gate to be implemented + :param Gate instruction: QuilAction gate to be implemented """ - if instruction.operator_name in self.gate_set or \ - instruction.operator_name in self.defgate_set: + if instruction.name in self.gate_set or instruction.name in self.defgate_set: # get the unitary and evolve the state unitary = tensor_gates(self.gate_set, self.defgate_set, instruction, self.num_qubits) @@ -70,7 +69,7 @@ def transition(self, instruction): self.program_counter += 1 else: raise TypeError("Gate {} is not in the " - "gate set".format(instruction.operator_name)) + "gate set".format(instruction.name)) def unitary(self, pyquil_program): """ diff --git a/referenceqvm/qvm_wavefunction.py b/referenceqvm/qvm_wavefunction.py index 1ba9b7f..b205927 100644 --- a/referenceqvm/qvm_wavefunction.py +++ b/referenceqvm/qvm_wavefunction.py @@ -42,8 +42,7 @@ import scipy.sparse as sps from pyquil.quil import Program -from pyquil.quilbase import (Instr, - Measurement, +from pyquil.quilbase import (Measurement, UnaryClassicalInstruction, BinaryClassicalInstruction, ClassicalTrue, @@ -59,7 +58,7 @@ JumpConditional, JumpWhen, JumpUnless, - Halt) + Halt, Gate) from pyquil.wavefunction import Wavefunction from referenceqvm.unitary_generator import lifted_gate, tensor_gates, value_get from referenceqvm.gates import utility_gates @@ -167,8 +166,8 @@ def _transition(self, instruction): """ if isinstance(instruction, Measurement): # perform measurement and modify wf in-place - t_qbit = value_get(instruction.arguments[0]) - t_cbit = value_get(instruction.arguments[1]) + t_qbit = value_get(instruction.qubit) + t_cbit = value_get(instruction.classical_reg) measured_val, unitary = self.measurement(t_qbit, psi=None) self.wf = unitary.dot(self.wf) @@ -176,7 +175,7 @@ def _transition(self, instruction): self.classical_memory[t_cbit] = measured_val self.program_counter += 1 - elif isinstance(instruction, Instr): + elif isinstance(instruction, Gate): # apply Gate or DefGate unitary = tensor_gates(self.gate_set, self.defgate_set, instruction, self.num_qubits) self.wf = unitary.dot(self.wf) diff --git a/referenceqvm/tests/test_unitary_generator.py b/referenceqvm/tests/test_unitary_generator.py index 24df494..f7ac924 100644 --- a/referenceqvm/tests/test_unitary_generator.py +++ b/referenceqvm/tests/test_unitary_generator.py @@ -176,39 +176,39 @@ def test_single_qubit_gates(): def test_tensor_gates_single_qubit(): prog = Program().inst([Hgate(0)]) - test_unitary = tensor_gates(gate_matrix, {}, prog.actions[0][1], 1).toarray() + test_unitary = tensor_gates(gate_matrix, {}, prog.instructions[0], 1).toarray() true_unitary = gate_matrix['H'] assert np.allclose(test_unitary, true_unitary) prog = Program().inst([Hgate(0)]) - test_unitary = tensor_gates(gate_matrix, {}, prog.actions[0][1], 5).toarray() + test_unitary = tensor_gates(gate_matrix, {}, prog.instructions[0], 5).toarray() true_unitary = np.kron(np.eye(2**4), gate_matrix['H']) assert np.allclose(test_unitary, true_unitary) prog = Program().inst([RXgate(0.2)(3)]) - test_unitary = tensor_gates(gate_matrix, {}, prog.actions[0][1], 5).toarray() + test_unitary = tensor_gates(gate_matrix, {}, prog.instructions[0], 5).toarray() true_unitary = np.kron(np.eye(2**1), np.kron(gate_matrix['RX'](0.2), np.eye(2**3))) assert np.allclose(test_unitary, true_unitary) prog = Program().inst([RXgate(0.5)(4)]) - test_unitary = tensor_gates(gate_matrix, {}, prog.actions[0][1], 5).toarray() + test_unitary = tensor_gates(gate_matrix, {}, prog.instructions[0], 5).toarray() true_unitary = np.kron(np.eye(2**0), np.kron(gate_matrix['RX'](0.5), np.eye(2**4))) assert np.allclose(test_unitary, true_unitary) def test_tensor_gates_two_qubit(): prog = Program().inst([CNOTgate(0, 1)]) - test_unitary = tensor_gates(gate_matrix, {}, prog.actions[0][1], 4).toarray() + test_unitary = tensor_gates(gate_matrix, {}, prog.instructions[0], 4).toarray() true_unitary = apply_gate(gate_matrix['CNOT'], [0, 1], 4).toarray() assert np.allclose(test_unitary, true_unitary) prog = Program().inst([CNOTgate(1, 0)]) - test_unitary = tensor_gates(gate_matrix, {}, prog.actions[0][1], 4).toarray() + test_unitary = tensor_gates(gate_matrix, {}, prog.instructions[0], 4).toarray() true_unitary = apply_gate(gate_matrix['CNOT'], [1, 0], 4).toarray() assert np.allclose(test_unitary, true_unitary) prog = Program().inst([CNOTgate(1, 3)]) - test_unitary = tensor_gates(gate_matrix, {}, prog.actions[0][1], 4).toarray() + test_unitary = tensor_gates(gate_matrix, {}, prog.instructions[0], 4).toarray() true_unitary = apply_gate(gate_matrix['CNOT'], [1, 3], 4).toarray() assert np.allclose(test_unitary, true_unitary) diff --git a/referenceqvm/unitary_generator.py b/referenceqvm/unitary_generator.py index 1344fc8..d037c9b 100644 --- a/referenceqvm/unitary_generator.py +++ b/referenceqvm/unitary_generator.py @@ -23,7 +23,6 @@ """ from collections import Sequence from numbers import Integral -import warnings import scipy.sparse as sps from pyquil.quilbase import * @@ -327,16 +326,16 @@ def tensor_gates(gate_set, defgate_set, pyquil_gate, num_qubits): :param dict gate_set: gate dictionary (name, matrix) pairs :param dict defgate_set: defined gate dictionary (name, matrix) pairs - :param Instr pyquil_gate: Instruction object for pyQuil gate + :param Gate pyquil_gate: Instruction object for pyQuil gate :param int num_qubits: number of qubits in Hilbert space :return: input gate lifted to full Hilbert space and applied :rtype: np.array """ - if pyquil_gate.operator_name in gate_set: + if pyquil_gate.name in gate_set: # Input gate set. Assumed to be standard gate set. dict_check = gate_set - elif pyquil_gate.operator_name in defgate_set: + elif pyquil_gate.name in defgate_set: # defined_gates dict_check = defgate_set else: @@ -344,16 +343,16 @@ def tensor_gates(gate_set, defgate_set, pyquil_gate, num_qubits): "found in standard gate set or defined " "gate set of program!") - args = tuple(value_get(x) for x in pyquil_gate.arguments) \ - if dict_check == gate_matrix else tuple(pyquil_gate.arguments) + args = tuple(value_get(x) for x in pyquil_gate.qubits) \ + if dict_check == gate_matrix else tuple(pyquil_gate.qubits) - if pyquil_gate.parameters: - gate = apply_gate(dict_check[pyquil_gate.operator_name] - (*[value_get(p) for p in pyquil_gate.parameters]), + if pyquil_gate.params: + gate = apply_gate(dict_check[pyquil_gate.name] + (*[value_get(p) for p in pyquil_gate.params]), args, num_qubits) else: - gate = apply_gate(dict_check[pyquil_gate.operator_name], + gate = apply_gate(dict_check[pyquil_gate.name], args, num_qubits) @@ -412,8 +411,8 @@ def value_get(param_obj): """ if isinstance(param_obj, (float, int)): return param_obj - elif isinstance(param_obj, AbstractQubit): - return param_obj.index() + elif isinstance(param_obj, Qubit): + return param_obj.index elif isinstance(param_obj, Addr): return param_obj.address elif isinstance(param_obj, Slot): diff --git a/requirements.txt b/requirements.txt index cc9cec0..68f8632 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ numpy>=1.11.1 scipy>=0.18.1 -pyquil==1.3.0 +pyquil==1.4.2 funcsigs # For testing diff --git a/setup.py b/setup.py index d8ebddf..ca2c88a 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ install_requires=[ "numpy >= 1.11.1", "scipy >= 0.18.1", - "pyquil >= 1.1.1", + "pyquil >= 1.4.2", "funcsigs" ], setup_requires=['pytest-runner'],