From 299711d077dac15dcba68ccc13620204af108354 Mon Sep 17 00:00:00 2001 From: Ben Rosand Date: Wed, 16 Sep 2020 11:51:13 -0400 Subject: [PATCH 01/14] slight changes to make QOC work --- qiskit/pulse/instruction_schedule_map.py | 7 +++++-- qiskit/scheduler/lowering.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/qiskit/pulse/instruction_schedule_map.py b/qiskit/pulse/instruction_schedule_map.py index 239928761278..4596c2c5953d 100644 --- a/qiskit/pulse/instruction_schedule_map.py +++ b/qiskit/pulse/instruction_schedule_map.py @@ -33,6 +33,7 @@ from .schedule import Schedule, ParameterizedSchedule from .exceptions import PulseError +from qiskit.circuit.gate import Gate class InstructionScheduleMap(): @@ -138,7 +139,7 @@ def assert_has(self, instruction: str, qubits: Union[int, Iterable[int]]) -> Non "system.".format(inst=instruction)) def get(self, - instruction: str, + instruction: Union[str, Gate], qubits: Union[int, Iterable[int]], *params: Union[int, float, complex], **kwparams: Union[int, float, complex]) -> Schedule: @@ -154,6 +155,8 @@ def get(self, Returns: The Schedule defined for the input. """ + if isinstance(instruction, Gate): + instruction = instruction.name self.assert_has(instruction, qubits) schedule_generator = self._map[instruction].get(_to_tuple(qubits)) @@ -163,7 +166,7 @@ def get(self, return schedule_generator def add(self, - instruction: str, + instruction: Union[str, Gate], qubits: Union[int, Iterable[int]], schedule: Union[Schedule, Callable[..., Schedule]]) -> None: """Add a new known instruction for the given qubits and its mapping to a pulse schedule. diff --git a/qiskit/scheduler/lowering.py b/qiskit/scheduler/lowering.py index c95dc312bdd1..779314b8c70f 100644 --- a/qiskit/scheduler/lowering.py +++ b/qiskit/scheduler/lowering.py @@ -122,7 +122,7 @@ def get_measure_schedule(qubit_mem_slots: Dict[int, int]) -> CircuitPulseDef: try: circ_pulse_defs.append( - CircuitPulseDef(schedule=inst_map.get(inst.name, inst_qubits, *inst.params), + CircuitPulseDef(schedule=inst_map.get(inst, inst_qubits, *inst.params), qubits=inst_qubits)) except PulseError: raise QiskitError("Operation '{}' on qubit(s) {} not supported by the backend " From fe807c45022ea3a5979a6045acf162f1eec8d120 Mon Sep 17 00:00:00 2001 From: Ben Rosand Date: Wed, 16 Sep 2020 12:11:13 -0400 Subject: [PATCH 02/14] added change to docstring for PR --- qiskit/pulse/instruction_schedule_map.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/pulse/instruction_schedule_map.py b/qiskit/pulse/instruction_schedule_map.py index 73daa318c742..dd0feae57aad 100644 --- a/qiskit/pulse/instruction_schedule_map.py +++ b/qiskit/pulse/instruction_schedule_map.py @@ -147,7 +147,7 @@ def get(self, the given qubits. Args: - instruction: Name of the instruction. + instruction: Name of the instruction or the instruction (gate) itself. qubits: The qubits for the instruction. *params: Command parameters for generating the output schedule. **kwparams: Keyworded command parameters for generating the schedule. From e6deb35848f19cdd1d0bb9092d05d864677ad371 Mon Sep 17 00:00:00 2001 From: brosand Date: Tue, 20 Oct 2020 12:14:11 -0400 Subject: [PATCH 03/14] added get gate input testing to test_instruction_schedule_map --- .../pulse/test_instruction_schedule_map.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/test/python/pulse/test_instruction_schedule_map.py b/test/python/pulse/test_instruction_schedule_map.py index 816a8ba2bef8..f490f1f4d7c0 100644 --- a/test/python/pulse/test_instruction_schedule_map.py +++ b/test/python/pulse/test_instruction_schedule_map.py @@ -16,6 +16,7 @@ import numpy as np import qiskit.pulse.library as library +from qiskit.circuit.library.standard_gates import XGate from qiskit.circuit.parameter import Parameter from qiskit.circuit.parameterexpression import ParameterExpression from qiskit.pulse import (InstructionScheduleMap, Play, PulseError, Schedule, @@ -121,10 +122,22 @@ def test_get(self): sched = Schedule() sched.append(Play(Waveform(np.ones(5)), DriveChannel(0))) inst_map = InstructionScheduleMap() + inst_map.add('x', 0, sched) - inst_map.add('u1', 0, sched) + self.assertEqual(sched, inst_map.get('x', (0,))) + + def test_get_from_gate(self): + """Test `get` with a full gate instruction obj inpput (as opposed to a string)""" + sched = Schedule() + sched.append(Play(Waveform(np.ones(5)), DriveChannel(0))) + inst_map = InstructionScheduleMap() + + gate = XGate() + gate_name = gate.name + inst_map.add(gate_name, 0, sched) - self.assertEqual(sched, inst_map.get('u1', (0,))) + self.assertEqual(sched, inst_map.get(gate, (0,))) + def test_remove(self): """Test removing a defined operation and removing an undefined operation.""" @@ -233,3 +246,4 @@ def test_func(dur: ParameterExpression, t_val: int): self.assertEqual(inst_map.get('f', (0,), dur=2*t_param, t_val=5), expected_sched) self.assertEqual(inst_map.get_parameters('f', (0,)), ('dur', 't_val',)) + From eb114444b111f31d7b58409638cfc61f13eb503f Mon Sep 17 00:00:00 2001 From: brosand Date: Tue, 20 Oct 2020 12:43:10 -0400 Subject: [PATCH 04/14] shortened line length a bit was slightly over lint length --- test/python/pulse/test_instruction_schedule_map.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/python/pulse/test_instruction_schedule_map.py b/test/python/pulse/test_instruction_schedule_map.py index f490f1f4d7c0..b2f9f5191f40 100644 --- a/test/python/pulse/test_instruction_schedule_map.py +++ b/test/python/pulse/test_instruction_schedule_map.py @@ -127,7 +127,7 @@ def test_get(self): self.assertEqual(sched, inst_map.get('x', (0,))) def test_get_from_gate(self): - """Test `get` with a full gate instruction obj inpput (as opposed to a string)""" + """Test `get` with a full gate obj inpput (as opposed to a string)""" sched = Schedule() sched.append(Play(Waveform(np.ones(5)), DriveChannel(0))) inst_map = InstructionScheduleMap() From f6e908e274259341012e9076bc3ccac61ac8fa8a Mon Sep 17 00:00:00 2001 From: brosand Date: Tue, 20 Oct 2020 12:45:37 -0400 Subject: [PATCH 05/14] more style changes --- test/python/pulse/test_instruction_schedule_map.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/python/pulse/test_instruction_schedule_map.py b/test/python/pulse/test_instruction_schedule_map.py index b2f9f5191f40..b72481ed1c21 100644 --- a/test/python/pulse/test_instruction_schedule_map.py +++ b/test/python/pulse/test_instruction_schedule_map.py @@ -125,7 +125,7 @@ def test_get(self): inst_map.add('x', 0, sched) self.assertEqual(sched, inst_map.get('x', (0,))) - + def test_get_from_gate(self): """Test `get` with a full gate obj inpput (as opposed to a string)""" sched = Schedule() @@ -137,7 +137,6 @@ def test_get_from_gate(self): inst_map.add(gate_name, 0, sched) self.assertEqual(sched, inst_map.get(gate, (0,))) - def test_remove(self): """Test removing a defined operation and removing an undefined operation.""" @@ -245,5 +244,4 @@ def test_func(dur: ParameterExpression, t_val: int): inst_map.add('f', (0,), test_func) self.assertEqual(inst_map.get('f', (0,), dur=2*t_param, t_val=5), expected_sched) - self.assertEqual(inst_map.get_parameters('f', (0,)), ('dur', 't_val',)) - + self.assertEqual(inst_map.get_parameters('f', (0,)), ('dur', 't_val',)) \ No newline at end of file From 35d895cd650001599e9716d3df7d7b4a014b8804 Mon Sep 17 00:00:00 2001 From: brosand Date: Tue, 20 Oct 2020 13:05:40 -0400 Subject: [PATCH 06/14] lint wanted a newline at end of file --- test/python/pulse/test_instruction_schedule_map.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/python/pulse/test_instruction_schedule_map.py b/test/python/pulse/test_instruction_schedule_map.py index b72481ed1c21..af22306cf351 100644 --- a/test/python/pulse/test_instruction_schedule_map.py +++ b/test/python/pulse/test_instruction_schedule_map.py @@ -244,4 +244,4 @@ def test_func(dur: ParameterExpression, t_val: int): inst_map.add('f', (0,), test_func) self.assertEqual(inst_map.get('f', (0,), dur=2*t_param, t_val=5), expected_sched) - self.assertEqual(inst_map.get_parameters('f', (0,)), ('dur', 't_val',)) \ No newline at end of file + self.assertEqual(inst_map.get_parameters('f', (0,)), ('dur', 't_val',)) From 70bb57721712402a55e9db7d02b6f9589a9a32f4 Mon Sep 17 00:00:00 2001 From: brosand Date: Thu, 29 Oct 2020 13:50:19 -0400 Subject: [PATCH 07/14] updated other InstructionScheduleMap methods and TestInstructionScheduleMap tests(added a corresponding test for each previous test) for gate input --- qiskit/pulse/instruction_schedule_map.py | 39 +++-- .../pulse/test_instruction_schedule_map.py | 134 ++++++++++++++++-- 2 files changed, 152 insertions(+), 21 deletions(-) diff --git a/qiskit/pulse/instruction_schedule_map.py b/qiskit/pulse/instruction_schedule_map.py index dd0feae57aad..ceafdc974380 100644 --- a/qiskit/pulse/instruction_schedule_map.py +++ b/qiskit/pulse/instruction_schedule_map.py @@ -34,6 +34,8 @@ from qiskit.pulse.exceptions import PulseError from qiskit.pulse.schedule import ParameterizedSchedule, Schedule from qiskit.circuit.gate import Gate +from qiskit.circuit import Instruction + class InstructionScheduleMap(): @@ -69,7 +71,8 @@ def instructions(self) -> List[str]: """ return list(self._map.keys()) - def qubits_with_instruction(self, instruction: str) -> List[Union[int, Tuple[int]]]: + def qubits_with_instruction(self, + instruction: Union[str, Gate]) -> List[Union[int, Tuple[int]]]: """Return a list of the qubits for which the given instruction is defined. Single qubit instructions return a flat list, and multiqubit instructions return a list of ordered tuples. @@ -84,6 +87,7 @@ def qubits_with_instruction(self, instruction: str) -> List[Union[int, Tuple[int Raises: PulseError: If the instruction is not found. """ + instruction = _get_instruction_string(instruction) if instruction not in self._map: return [] return [qubits[0] if len(qubits) == 1 else qubits @@ -106,7 +110,7 @@ def qubit_instructions(self, qubits: Union[int, Iterable[int]]) -> List[str]: return list(self._qubit_instructions[_to_tuple(qubits)]) return [] - def has(self, instruction: str, qubits: Union[int, Iterable[int]]) -> bool: + def has(self, instruction: Union[str, Gate], qubits: Union[int, Iterable[int]]) -> bool: """Is the instruction defined for the given qubits? Args: @@ -116,10 +120,11 @@ def has(self, instruction: str, qubits: Union[int, Iterable[int]]) -> bool: Returns: True iff the instruction is defined. """ + instruction = _get_instruction_string(instruction) return instruction in self._map and \ _to_tuple(qubits) in self._map[instruction] - def assert_has(self, instruction: str, qubits: Union[int, Iterable[int]]) -> None: + def assert_has(self, instruction: Union[str, Gate], qubits: Union[int, Iterable[int]]) -> None: """Error if the given instruction is not defined. Args: @@ -129,6 +134,7 @@ def assert_has(self, instruction: str, qubits: Union[int, Iterable[int]]) -> Non Raises: PulseError: If the instruction is not defined on the qubits. """ + instruction = _get_instruction_string(instruction) if not self.has(instruction, _to_tuple(qubits)): if instruction in self._map: raise PulseError("Operation '{inst}' exists, but is only defined for qubits " @@ -155,8 +161,7 @@ def get(self, Returns: The Schedule defined for the input. """ - if isinstance(instruction, Gate): - instruction = instruction.name + instruction = _get_instruction_string(instruction) self.assert_has(instruction, qubits) schedule_generator = self._map[instruction].get(_to_tuple(qubits)) @@ -179,6 +184,8 @@ def add(self, Raises: PulseError: If the qubits are provided as an empty iterable. """ + instruction = _get_instruction_string(instruction) + qubits = _to_tuple(qubits) if qubits == (): raise PulseError("Cannot add definition {} with no target qubits.".format(instruction)) @@ -188,13 +195,14 @@ def add(self, self._map[instruction][qubits] = schedule self._qubit_instructions[qubits].add(instruction) - def remove(self, instruction: str, qubits: Union[int, Iterable[int]]) -> None: + def remove(self, instruction: Union[str, Gate], qubits: Union[int, Iterable[int]]) -> None: """Remove the given instruction from the listing of instructions defined in self. Args: instruction: The name of the instruction to add. qubits: The qubits which the instruction applies to. """ + instruction = _get_instruction_string(instruction) qubits = _to_tuple(qubits) self.assert_has(instruction, qubits) self._map[instruction].pop(qubits) @@ -205,7 +213,7 @@ def remove(self, instruction: str, qubits: Union[int, Iterable[int]]) -> None: self._qubit_instructions.pop(qubits) def pop(self, - instruction: str, + instruction: Union[str, Gate], qubits: Union[int, Iterable[int]], *params: Union[int, float, complex, ParameterExpression], **kwparams: Union[int, float, complex, ParameterExpression]) -> Schedule: @@ -221,11 +229,14 @@ def pop(self, Returns: The Schedule defined for the input. """ + instruction = _get_instruction_string(instruction) schedule = self.get(instruction, qubits, *params, **kwparams) self.remove(instruction, qubits) return schedule - def get_parameters(self, instruction: str, qubits: Union[int, Iterable[int]]) -> Tuple[str]: + def get_parameters(self, + instruction: Union[str, Gate], + qubits: Union[int, Iterable[int]]) -> Tuple[str]: """Return the list of parameters taken by the given instruction on the given qubits. Args: @@ -235,6 +246,8 @@ def get_parameters(self, instruction: str, qubits: Union[int, Iterable[int]]) -> Returns: The names of the parameters required by the instruction. """ + instruction = _get_instruction_string(instruction) + self.assert_has(instruction, qubits) schedule_generator = self._map[instruction][_to_tuple(qubits)] if isinstance(schedule_generator, ParameterizedSchedule): @@ -270,3 +283,13 @@ def _to_tuple(values: Union[int, Iterable[int]]) -> Tuple[int, ...]: return tuple(values) except TypeError: return (values,) + +def _get_instruction_string(inst: Union[str, Gate, Instruction]): + if isinstance(inst, str): + return inst + elif isinstance(inst, Gate): + assert(inst.name), "Gate has no name" + return inst.name + else: + assert(inst.name), "Instruction has no name" + return inst.name diff --git a/test/python/pulse/test_instruction_schedule_map.py b/test/python/pulse/test_instruction_schedule_map.py index af22306cf351..a7a5c1ac229a 100644 --- a/test/python/pulse/test_instruction_schedule_map.py +++ b/test/python/pulse/test_instruction_schedule_map.py @@ -16,7 +16,7 @@ import numpy as np import qiskit.pulse.library as library -from qiskit.circuit.library.standard_gates import XGate +from qiskit.circuit.library.standard_gates import U1Gate, U3Gate, CXGate, XGate from qiskit.circuit.parameter import Parameter from qiskit.circuit.parameterexpression import ParameterExpression from qiskit.pulse import (InstructionScheduleMap, Play, PulseError, Schedule, @@ -126,18 +126,6 @@ def test_get(self): self.assertEqual(sched, inst_map.get('x', (0,))) - def test_get_from_gate(self): - """Test `get` with a full gate obj inpput (as opposed to a string)""" - sched = Schedule() - sched.append(Play(Waveform(np.ones(5)), DriveChannel(0))) - inst_map = InstructionScheduleMap() - - gate = XGate() - gate_name = gate.name - inst_map.add(gate_name, 0, sched) - - self.assertEqual(sched, inst_map.get(gate, (0,))) - def test_remove(self): """Test removing a defined operation and removing an undefined operation.""" sched = Schedule() @@ -164,6 +152,126 @@ def test_pop(self): with self.assertRaises(PulseError): inst_map.pop('not_there', (0,)) + def test_add_gate(self): + """Test add, and that errors are raised when expected.""" + sched = Schedule() + sched.append(Play(Waveform(np.ones(5)), DriveChannel(0))) + inst_map = InstructionScheduleMap() + + inst_map.add(U1Gate(0), 1, sched) + inst_map.add(U1Gate(0), 0, sched) + + self.assertIn('u1', inst_map.instructions) + self.assertEqual(inst_map.qubits_with_instruction(U1Gate(0)), [0, 1]) + self.assertTrue('u1' in inst_map.qubit_instructions(0)) + + with self.assertRaises(PulseError): + inst_map.add(U1Gate(0), (), sched) + with self.assertRaises(PulseError): + inst_map.add(U1Gate(0), 1, "not a schedule") + + def test_instructions_gate(self): + """Test `instructions`.""" + sched = Schedule() + inst_map = InstructionScheduleMap() + + inst_map.add(U1Gate(0), 1, sched) + inst_map.add(U3Gate(0, 0, 0), 0, sched) + + instructions = inst_map.instructions + for inst in ['u1', 'u3']: + self.assertTrue(inst in instructions) + + def test_has_gate(self): + """Test `has` and `assert_has`.""" + sched = Schedule() + inst_map = InstructionScheduleMap() + + inst_map.add(U1Gate(0), (0,), sched) + inst_map.add(CXGate(), [0, 1], sched) + + self.assertTrue(inst_map.has(U1Gate(0), [0])) + self.assertTrue(inst_map.has(CXGate(), (0, 1))) + with self.assertRaises(PulseError): + inst_map.assert_has('dne', [0]) + with self.assertRaises(PulseError): + inst_map.assert_has(CXGate(), 100) + + def test_has_from_mock_gate(self): + """Test `has` and `assert_has` from mock data.""" + inst_map = FakeOpenPulse2Q().defaults().instruction_schedule_map + self.assertTrue(inst_map.has(U1Gate(0), [0])) + self.assertTrue(inst_map.has(CXGate(), (0, 1))) + self.assertTrue(inst_map.has(U3Gate(0, 0, 0), 0)) + self.assertTrue(inst_map.has('measure', [0, 1])) + self.assertFalse(inst_map.has(U1Gate(0), [0, 1])) + with self.assertRaises(PulseError): + inst_map.assert_has('dne', [0]) + with self.assertRaises(PulseError): + inst_map.assert_has(CXGate(), 100) + + def test_qubits_with_instruction_gate(self): + """Test `qubits_with_instruction`.""" + sched = Schedule() + inst_map = InstructionScheduleMap() + + inst_map.add(U1Gate(0), (0,), sched) + inst_map.add(U1Gate(0), (1,), sched) + inst_map.add(CXGate(), [0, 1], sched) + + self.assertEqual(inst_map.qubits_with_instruction(U1Gate(0)), [0, 1]) + self.assertEqual(inst_map.qubits_with_instruction(CXGate()), [(0, 1)]) + self.assertEqual(inst_map.qubits_with_instruction('none'), []) + + def test_qubit_instructions_gate(self): + """Test `qubit_instructions`.""" + sched = Schedule() + inst_map = InstructionScheduleMap() + + inst_map.add(U1Gate(0), (0,), sched) + inst_map.add(U1Gate(0), (1,), sched) + inst_map.add(CXGate(), [0, 1], sched) + + self.assertEqual(inst_map.qubit_instructions(0), ['u1']) + self.assertEqual(inst_map.qubit_instructions(1), ['u1']) + self.assertEqual(inst_map.qubit_instructions((0, 1)), ['cx']) + self.assertEqual(inst_map.qubit_instructions(10), []) + + def test_get_gate(self): + """Test `get`.""" + sched = Schedule() + sched.append(Play(Waveform(np.ones(5)), DriveChannel(0))) + inst_map = InstructionScheduleMap() + inst_map.add(XGate(), 0, sched) + + self.assertEqual(sched, inst_map.get(XGate(), (0,))) + + def test_remove_gate(self): + """Test removing a defined operation and removing an undefined operation.""" + sched = Schedule() + inst_map = InstructionScheduleMap() + + inst_map.add('tmp', 0, sched) + inst_map.remove('tmp', 0) + self.assertFalse(inst_map.has('tmp', 0)) + with self.assertRaises(PulseError): + inst_map.remove('not_there', (0,)) + self.assertFalse('tmp' in inst_map.qubit_instructions(0)) + + def test_pop_gate(self): + """Test pop with default.""" + sched = Schedule() + inst_map = InstructionScheduleMap() + + inst_map.add(XGate(), 100, sched) + self.assertEqual(inst_map.pop(XGate(), 100), sched) + self.assertFalse(inst_map.has(XGate(), 100)) + + self.assertEqual(inst_map.qubit_instructions(100), []) + self.assertEqual(inst_map.qubits_with_instruction(XGate()), []) + with self.assertRaises(PulseError): + inst_map.pop('not_there', (0,)) + def test_sequenced_parameterized_schedule(self): """Test parametrized schedule consists of multiple instruction. """ From f88384b2044ce89961d413b3ed7bae943434f773 Mon Sep 17 00:00:00 2001 From: brosand Date: Thu, 29 Oct 2020 13:53:39 -0400 Subject: [PATCH 08/14] removed reference to in struction --- qiskit/pulse/instruction_schedule_map.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/qiskit/pulse/instruction_schedule_map.py b/qiskit/pulse/instruction_schedule_map.py index ceafdc974380..631f30a8439a 100644 --- a/qiskit/pulse/instruction_schedule_map.py +++ b/qiskit/pulse/instruction_schedule_map.py @@ -284,12 +284,11 @@ def _to_tuple(values: Union[int, Iterable[int]]) -> Tuple[int, ...]: except TypeError: return (values,) -def _get_instruction_string(inst: Union[str, Gate, Instruction]): + +def _get_instruction_string(inst: Union[str, Gate]): if isinstance(inst, str): return inst - elif isinstance(inst, Gate): - assert(inst.name), "Gate has no name" - return inst.name else: - assert(inst.name), "Instruction has no name" + assert(isinstance(inst, Gate)), "Instruction must be Gate obj or str" + assert(inst.name), "Gate has no name" return inst.name From da3fad1a3e34d43755ce0618571c25ae0a34e595 Mon Sep 17 00:00:00 2001 From: brosand Date: Thu, 29 Oct 2020 14:13:35 -0400 Subject: [PATCH 09/14] style fixes --- qiskit/pulse/instruction_schedule_map.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/qiskit/pulse/instruction_schedule_map.py b/qiskit/pulse/instruction_schedule_map.py index 631f30a8439a..5fb4c16fa9ae 100644 --- a/qiskit/pulse/instruction_schedule_map.py +++ b/qiskit/pulse/instruction_schedule_map.py @@ -34,9 +34,6 @@ from qiskit.pulse.exceptions import PulseError from qiskit.pulse.schedule import ParameterizedSchedule, Schedule from qiskit.circuit.gate import Gate -from qiskit.circuit import Instruction - - class InstructionScheduleMap(): """Mapping from :py:class:`~qiskit.circuit.QuantumCircuit` From e1f2f9a63659867ddd1dfdce92ac55d76a363cc7 Mon Sep 17 00:00:00 2001 From: brosand Date: Thu, 29 Oct 2020 14:59:43 -0400 Subject: [PATCH 10/14] more style changes --- qiskit/pulse/instruction_schedule_map.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/qiskit/pulse/instruction_schedule_map.py b/qiskit/pulse/instruction_schedule_map.py index 5fb4c16fa9ae..6cdf99ed48a7 100644 --- a/qiskit/pulse/instruction_schedule_map.py +++ b/qiskit/pulse/instruction_schedule_map.py @@ -35,6 +35,7 @@ from qiskit.pulse.schedule import ParameterizedSchedule, Schedule from qiskit.circuit.gate import Gate + class InstructionScheduleMap(): """Mapping from :py:class:`~qiskit.circuit.QuantumCircuit` :py:class:`qiskit.circuit.Instruction` names and qubits to @@ -68,7 +69,7 @@ def instructions(self) -> List[str]: """ return list(self._map.keys()) - def qubits_with_instruction(self, + def qubits_with_instruction(self, instruction: Union[str, Gate]) -> List[Union[int, Tuple[int]]]: """Return a list of the qubits for which the given instruction is defined. Single qubit instructions return a flat list, and multiqubit instructions return a list of ordered @@ -232,7 +233,7 @@ def pop(self, return schedule def get_parameters(self, - instruction: Union[str, Gate], + instruction: Union[str, Gate], qubits: Union[int, Iterable[int]]) -> Tuple[str]: """Return the list of parameters taken by the given instruction on the given qubits. From e055ec19339dcc324c5686d70cd7d2516c314d34 Mon Sep 17 00:00:00 2001 From: brosand Date: Fri, 30 Oct 2020 12:10:00 -0400 Subject: [PATCH 11/14] Update qiskit/pulse/instruction_schedule_map.py Co-authored-by: Thomas Alexander --- qiskit/pulse/instruction_schedule_map.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qiskit/pulse/instruction_schedule_map.py b/qiskit/pulse/instruction_schedule_map.py index 6cdf99ed48a7..8d030ae98f8a 100644 --- a/qiskit/pulse/instruction_schedule_map.py +++ b/qiskit/pulse/instruction_schedule_map.py @@ -287,6 +287,7 @@ def _get_instruction_string(inst: Union[str, Gate]): if isinstance(inst, str): return inst else: - assert(isinstance(inst, Gate)), "Instruction must be Gate obj or str" - assert(inst.name), "Gate has no name" - return inst.name + try: + return inst.name + except AttributeError: + raise PulseError('Input "inst" has no attribute "name". This should be a circuit "Instruction".') From 84ea19080cbc52a053b2b6996f11d2bc7f92b6f6 Mon Sep 17 00:00:00 2001 From: brosand Date: Fri, 30 Oct 2020 14:04:29 -0400 Subject: [PATCH 12/14] switched gates to instructions --- qiskit/pulse/instruction_schedule_map.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/qiskit/pulse/instruction_schedule_map.py b/qiskit/pulse/instruction_schedule_map.py index 8d030ae98f8a..d476c7ecfed6 100644 --- a/qiskit/pulse/instruction_schedule_map.py +++ b/qiskit/pulse/instruction_schedule_map.py @@ -33,7 +33,7 @@ from qiskit.circuit.parameterexpression import ParameterExpression from qiskit.pulse.exceptions import PulseError from qiskit.pulse.schedule import ParameterizedSchedule, Schedule -from qiskit.circuit.gate import Gate +from qiskit.circuit.instruction import Instruction class InstructionScheduleMap(): @@ -70,7 +70,7 @@ def instructions(self) -> List[str]: return list(self._map.keys()) def qubits_with_instruction(self, - instruction: Union[str, Gate]) -> List[Union[int, Tuple[int]]]: + instruction: Union[str, Instruction]) -> List[Union[int, Tuple[int]]]: """Return a list of the qubits for which the given instruction is defined. Single qubit instructions return a flat list, and multiqubit instructions return a list of ordered tuples. @@ -108,7 +108,7 @@ def qubit_instructions(self, qubits: Union[int, Iterable[int]]) -> List[str]: return list(self._qubit_instructions[_to_tuple(qubits)]) return [] - def has(self, instruction: Union[str, Gate], qubits: Union[int, Iterable[int]]) -> bool: + def has(self, instruction: Union[str, Instruction], qubits: Union[int, Iterable[int]]) -> bool: """Is the instruction defined for the given qubits? Args: @@ -122,7 +122,7 @@ def has(self, instruction: Union[str, Gate], qubits: Union[int, Iterable[int]]) return instruction in self._map and \ _to_tuple(qubits) in self._map[instruction] - def assert_has(self, instruction: Union[str, Gate], qubits: Union[int, Iterable[int]]) -> None: + def assert_has(self, instruction: Union[str, Instruction], qubits: Union[int, Iterable[int]]) -> None: """Error if the given instruction is not defined. Args: @@ -143,7 +143,7 @@ def assert_has(self, instruction: Union[str, Gate], qubits: Union[int, Iterable[ "system.".format(inst=instruction)) def get(self, - instruction: Union[str, Gate], + instruction: Union[str, Instruction], qubits: Union[int, Iterable[int]], *params: Union[int, float, complex, ParameterExpression], **kwparams: Union[int, float, complex, ParameterExpression]) -> Schedule: @@ -151,7 +151,7 @@ def get(self, the given qubits. Args: - instruction: Name of the instruction or the instruction (gate) itself. + instruction: Name of the instruction or the instruction itself. qubits: The qubits for the instruction. *params: Command parameters for generating the output schedule. **kwparams: Keyworded command parameters for generating the schedule. @@ -169,7 +169,7 @@ def get(self, return schedule_generator def add(self, - instruction: Union[str, Gate], + instruction: Union[str, Instruction], qubits: Union[int, Iterable[int]], schedule: Union[Schedule, Callable[..., Schedule]]) -> None: """Add a new known instruction for the given qubits and its mapping to a pulse schedule. @@ -193,7 +193,7 @@ def add(self, self._map[instruction][qubits] = schedule self._qubit_instructions[qubits].add(instruction) - def remove(self, instruction: Union[str, Gate], qubits: Union[int, Iterable[int]]) -> None: + def remove(self, instruction: Union[str, Instruction], qubits: Union[int, Iterable[int]]) -> None: """Remove the given instruction from the listing of instructions defined in self. Args: @@ -211,7 +211,7 @@ def remove(self, instruction: Union[str, Gate], qubits: Union[int, Iterable[int] self._qubit_instructions.pop(qubits) def pop(self, - instruction: Union[str, Gate], + instruction: Union[str, Instruction], qubits: Union[int, Iterable[int]], *params: Union[int, float, complex, ParameterExpression], **kwparams: Union[int, float, complex, ParameterExpression]) -> Schedule: @@ -233,7 +233,7 @@ def pop(self, return schedule def get_parameters(self, - instruction: Union[str, Gate], + instruction: Union[str, Instruction], qubits: Union[int, Iterable[int]]) -> Tuple[str]: """Return the list of parameters taken by the given instruction on the given qubits. @@ -283,7 +283,7 @@ def _to_tuple(values: Union[int, Iterable[int]]) -> Tuple[int, ...]: return (values,) -def _get_instruction_string(inst: Union[str, Gate]): +def _get_instruction_string(inst: Union[str, Instruction]): if isinstance(inst, str): return inst else: From 43721e2e1059643a6338bd845c673522c3f2e321 Mon Sep 17 00:00:00 2001 From: brosand Date: Fri, 30 Oct 2020 16:11:31 -0400 Subject: [PATCH 13/14] fixing for linting --- qiskit/pulse/instruction_schedule_map.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/qiskit/pulse/instruction_schedule_map.py b/qiskit/pulse/instruction_schedule_map.py index d476c7ecfed6..2abf7b593bb6 100644 --- a/qiskit/pulse/instruction_schedule_map.py +++ b/qiskit/pulse/instruction_schedule_map.py @@ -70,7 +70,8 @@ def instructions(self) -> List[str]: return list(self._map.keys()) def qubits_with_instruction(self, - instruction: Union[str, Instruction]) -> List[Union[int, Tuple[int]]]: + instruction: Union[str, Instruction]) -> List[Union[int, + Tuple[int]]]: """Return a list of the qubits for which the given instruction is defined. Single qubit instructions return a flat list, and multiqubit instructions return a list of ordered tuples. @@ -122,7 +123,9 @@ def has(self, instruction: Union[str, Instruction], qubits: Union[int, Iterable[ return instruction in self._map and \ _to_tuple(qubits) in self._map[instruction] - def assert_has(self, instruction: Union[str, Instruction], qubits: Union[int, Iterable[int]]) -> None: + def assert_has(self, + instruction: Union[str, Instruction], + qubits: Union[int, Iterable[int]]) -> None: """Error if the given instruction is not defined. Args: @@ -193,7 +196,9 @@ def add(self, self._map[instruction][qubits] = schedule self._qubit_instructions[qubits].add(instruction) - def remove(self, instruction: Union[str, Instruction], qubits: Union[int, Iterable[int]]) -> None: + def remove(self, + instruction: Union[str, Instruction], + qubits: Union[int, Iterable[int]]) -> None: """Remove the given instruction from the listing of instructions defined in self. Args: @@ -290,4 +295,5 @@ def _get_instruction_string(inst: Union[str, Instruction]): try: return inst.name except AttributeError: - raise PulseError('Input "inst" has no attribute "name". This should be a circuit "Instruction".') + raise PulseError('Input "inst" has no attribute "name".' + 'This should be a circuit "Instruction".') From 2c3807bc2e3e46765658760f5c1df392d28f3624 Mon Sep 17 00:00:00 2001 From: brosand Date: Fri, 30 Oct 2020 16:37:18 -0400 Subject: [PATCH 14/14] slight lint change --- qiskit/pulse/instruction_schedule_map.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qiskit/pulse/instruction_schedule_map.py b/qiskit/pulse/instruction_schedule_map.py index 2abf7b593bb6..b9a8f10ff32f 100644 --- a/qiskit/pulse/instruction_schedule_map.py +++ b/qiskit/pulse/instruction_schedule_map.py @@ -71,7 +71,7 @@ def instructions(self) -> List[str]: def qubits_with_instruction(self, instruction: Union[str, Instruction]) -> List[Union[int, - Tuple[int]]]: + Tuple[int]]]: """Return a list of the qubits for which the given instruction is defined. Single qubit instructions return a flat list, and multiqubit instructions return a list of ordered tuples.