Skip to content

Commit

Permalink
fix: DefGate's no longer appear in the instructions list (#1688)
Browse files Browse the repository at this point in the history
  • Loading branch information
MarquessV authored Nov 9, 2023
1 parent 53f6d13 commit 5249142
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 109 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,15 @@ jobs:
path: .venv
key: poetry-${{ hashFiles('poetry.lock') }}
- name: Test e2e QVM (Python ${{ matrix.python-version }})
id: runTests
run: |
sudo apt update
. scripts/ci_install_deps
docker run --rm -itd -p 5555:5555 rigetti/quilc -R
docker run --rm -itd -p 5000:5000 rigetti/qvm -S
poetry run make e2e TEST_QUANTUM_PROCESSOR=2q-qvm
docker ps -q | xargs -L 1 docker logs
- name: Dump docker logs
if: always() && steps.runTests.outcome == 'failure'
run: |
docker ps -q | xargs -L 1 docker logs
97 changes: 56 additions & 41 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ rpcq = "^3.10.0"
pydantic = "^1.10.7"
networkx = ">=2.5"
importlib-metadata = { version = ">=3.7.3,<5", python = "<3.8" }
qcs-sdk-python = "0.13.1"
qcs-sdk-python = "0.13.4"
tenacity = "^8.2.2"
types-python-dateutil = "^2.8.19"
types-retry = "^0.9.9"
Expand Down
2 changes: 0 additions & 2 deletions pyquil/api/_compiler_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,6 @@ class CompilerClient:
Client for making requests to a Quil compiler.
"""

_client_configuration: QCSClient

def __init__(
self,
*,
Expand Down
38 changes: 4 additions & 34 deletions pyquil/quil.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@
DefWaveform,
_convert_to_rs_instruction,
_convert_to_rs_instructions,
_convert_to_py_instruction,
_convert_to_py_instructions,
_convert_to_py_qubits,
)
Expand Down Expand Up @@ -197,6 +196,7 @@ def copy_everything_except_instructions(self) -> "Program":
list(self.frames.values()),
list(self.waveforms.values()),
self.calibrations,
self.defined_gates,
self.measure_calibrations,
)
if self.native_quil_metadata is not None:
Expand All @@ -220,7 +220,7 @@ def defined_gates(self) -> List[DefGate]:
"""
A list of defined gates on the program.
"""
return [DefGate._from_rs_gate_definition(gate) for gate in self._program.defined_gates]
return [DefGate._from_rs_gate_definition(gate) for gate in self._program.gate_definitions.values()]

@property
def instructions(self) -> List[AbstractInstruction]:
Expand Down Expand Up @@ -377,33 +377,7 @@ def _add_instruction(self, instruction: quil_rs.Instruction) -> None:
For backwards compatibility, it also prevents duplicate calibration, measurement, and gate definitions from
being added. Users of ``Program`` should use ``inst`` or ``Program`` addition instead.
"""
if instruction.is_gate_definition():
defgate = instruction.to_gate_definition()
# If the gate definition differs from the current one, print a warning and replace it.
idx, existing_defgate = next(
(
(i, gate)
for i, gate in enumerate(
map(lambda inst: inst.as_gate_definition(), self._program.body_instructions)
)
if gate and gate.name == defgate.name
),
(0, None),
)

if existing_defgate is None:
self._program.add_instruction(instruction)
elif (
existing_defgate.specification != defgate.specification
or existing_defgate.specification.inner() != existing_defgate.specification.inner()
):
warnings.warn("Redefining gate {}".format(defgate.name))
new_instructions = (
self._program.body_instructions[:idx] + [instruction] + self._program.body_instructions[idx + 1 :]
)
self._program = self._program.clone_without_body_instructions()
self._program.add_instructions(new_instructions)
elif instruction.is_calibration_definition():
if instruction.is_calibration_definition():
defcal = instruction.to_calibration_definition()
idx, existing_calibration = next(
(
Expand Down Expand Up @@ -936,11 +910,7 @@ def __getitem__(self, index: Union[slice, int]) -> Union[AbstractInstruction, "P
:param index: The action at the specified index.
:return:
"""
return (
Program(self._program.to_instructions()[index])
if isinstance(index, slice)
else _convert_to_py_instruction(self._program.to_instructions()[index])
)
return Program(self.instructions[index]) if isinstance(index, slice) else self.instructions[index]

def __iter__(self) -> Iterator[AbstractInstruction]:
"""
Expand Down
21 changes: 5 additions & 16 deletions test/unit/__snapshots__/test_quil.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -313,42 +313,31 @@
# ---
# name: test_prog_merge
'''
X 0
DEFGATE test AS MATRIX:
1, 0
0, 1

X 0
test 0
Y 0
DEFGATE test AS MATRIX:
1, 0
0, 1

test 0

'''
# ---
# name: test_prog_merge.1
'''
X 0
DEFGATE test AS MATRIX:
1, 0
0, 1

test 0
DEFGATE PERM AS PERMUTATION:
0, 1, 3, 2

PERM 0 1
Y 0
DEFGATE test AS MATRIX:
1, 0
0, 1

X 0
test 0
PERM 0 1
Y 0
test 0
DEFGATE PERM AS PERMUTATION:
0, 1, 3, 2

PERM 1 0

'''
Expand Down
3 changes: 3 additions & 0 deletions test/unit/test_reference_wavefunction.py
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,7 @@ def test_if_then():
branch_b = Program()
prog.if_then(creg, branch_a, branch_b)
prog += MEASURE(0, creg)
prog.resolve_placeholders()
qam = PyQVM(n_qubits=1, quantum_simulator_type=ReferenceWavefunctionSimulator)
qam.execute(prog)
assert qam.ram["creg"][0] == 0
Expand All @@ -634,6 +635,7 @@ def test_if_then_2():
branch_b = Program()
prog.if_then(creg, branch_a, branch_b)
prog += MEASURE(0, creg)
prog.resolve_placeholders()
qam = PyQVM(n_qubits=1, quantum_simulator_type=ReferenceWavefunctionSimulator)
qam.execute(prog)
assert qam.ram["creg"][0] == 1
Expand All @@ -649,6 +651,7 @@ def test_while():
# Put it all together in a loop program:
loop_prog = init_register.while_do(classical_flag_register, loop_body)

loop_prog.resolve_placeholders()
qam = PyQVM(n_qubits=1, quantum_simulator_type=ReferenceWavefunctionSimulator)
qam.execute(loop_prog)
assert qam.ram[classical_flag_register.name][0] == 0
Expand Down
20 changes: 5 additions & 15 deletions test/unit/test_rewrite_arithmetic.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,20 +117,10 @@ def test_rewrite_arithmetic_frequency():
ParameterAref(index=1, name="__P1"): "theta[0]/20.0",
}

# Ordering of attributes on frame definitions aren't guaranteed when
# exported to quil, so we break the assertions and use the more reliable
# method of checking equality via the instruction types.
response_program = Program(response.quil)
assert response_program[0].out() == "DECLARE __P1 REAL[2]"
assert response_program[1].out() == "DECLARE theta REAL[1]"
assert (response_program[2] == fdefn0 and response_program[3] == fdefn1) or (
response_program[2] == fdefn1 and response_program[3] == fdefn0
)
assert [inst.out() for inst in response_program[4:]] == [
'SET-FREQUENCY 0 "rf" __P1[0]',
'SHIFT-FREQUENCY 0 "rf" __P1[0]',
'SET-FREQUENCY 1 "rf" __P1[1]',
]
assert {response_program[0].out(), response_program[1].out()} == {"DECLARE __P1 REAL[2]", "DECLARE theta REAL[1]"}
assert response_program.frames[fdefn0.frame] == fdefn0
assert response_program.frames[fdefn1.frame] == fdefn1


def test_rewrite_arithmetic_mixed_mutations():
Expand All @@ -157,8 +147,8 @@ def test_rewrite_arithmetic_mixed_mutations():

response_program = Program(response.quil)
assert set(response_program[0:2].out().split("\n")) == {"DECLARE __P1 REAL[3]", "DECLARE theta REAL[1]", ""}
assert response_program[2] == fdefn
assert [inst.out() for inst in response_program[3:]] == [
assert response_program.frames[fdefn.frame] == fdefn
assert [inst.out() for inst in response_program[2:]] == [
'SET-FREQUENCY 0 "rf" __P1[0]',
'SET-PHASE 0 "rf" __P1[1]',
'SET-SCALE 0 "rf" __P1[2]',
Expand Down

0 comments on commit 5249142

Please sign in to comment.