Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ScheduleBlock 2/4 - add Call instruction #5781

Merged
merged 84 commits into from
Feb 25, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
09fc52f
remove timeslot dependency from instruction
nkanazawa1989 Jan 22, 2021
09fed68
update type hint
nkanazawa1989 Jan 22, 2021
01b7e3e
update unittest
nkanazawa1989 Jan 22, 2021
609481c
update validation logic
nkanazawa1989 Jan 22, 2021
e838c7d
fix lint and test
nkanazawa1989 Jan 22, 2021
50a3fb7
Update qiskit/pulse/utils.py
nkanazawa1989 Jan 28, 2021
1c7c3fd
Update qiskit/pulse/instructions/instruction.py
nkanazawa1989 Jan 28, 2021
73ff507
Update qiskit/pulse/schedule.py
nkanazawa1989 Jan 28, 2021
85b79e8
minor updates
nkanazawa1989 Jan 28, 2021
cb8d11c
Merge branch 'issue-5679-1_schedule_block' of github.com:nkanazawa198…
nkanazawa1989 Jan 28, 2021
e888cea
add reno
nkanazawa1989 Jan 28, 2021
ceefcb4
Merge branch 'issue-5679-1_schedule_block' into issue-5679-2_schedule…
nkanazawa1989 Jan 28, 2021
42cb633
wip add call instruction
nkanazawa1989 Jan 28, 2021
20b2548
update flatten method
nkanazawa1989 Jan 28, 2021
8939e25
wip
nkanazawa1989 Jan 29, 2021
15e302f
deprecate flatten method
nkanazawa1989 Jan 29, 2021
cb53c12
cyclic import fix
nkanazawa1989 Feb 1, 2021
df858fb
fix recursion bug
nkanazawa1989 Feb 2, 2021
33d68b2
split subroutine removal function
nkanazawa1989 Feb 2, 2021
7cf36b8
update parameter table for call
nkanazawa1989 Feb 2, 2021
e7fa08c
update builder logic and relevant unittests
nkanazawa1989 Feb 3, 2021
bd17f6e
add reno
nkanazawa1989 Feb 3, 2021
5d63b7d
update docstring
nkanazawa1989 Feb 3, 2021
64ee355
Merge branch 'master' of github.com:Qiskit/qiskit-terra into issue-56…
nkanazawa1989 Feb 3, 2021
d1cdd5c
update docstring
nkanazawa1989 Feb 3, 2021
e1bfdc6
revert unittest
nkanazawa1989 Feb 3, 2021
c67fb64
update reno for deprecation
nkanazawa1989 Feb 3, 2021
d7936cd
fix empty subroutine bug
nkanazawa1989 Feb 3, 2021
7e63c0a
update docstring
nkanazawa1989 Feb 3, 2021
00d062b
update docstring
nkanazawa1989 Feb 3, 2021
35285ca
remove whitespace
nkanazawa1989 Feb 4, 2021
312a4c4
feedback from Lauren
nkanazawa1989 Feb 4, 2021
88654ff
lint
nkanazawa1989 Feb 4, 2021
da3d039
Update qiskit/pulse/builder.py
nkanazawa1989 Feb 8, 2021
a29857e
Update qiskit/pulse/builder.py
nkanazawa1989 Feb 8, 2021
2b2cded
Update releasenotes/notes/add-call-instruction-6f4fc37994090c2f.yaml
nkanazawa1989 Feb 8, 2021
fe90614
Update releasenotes/notes/add-call-instruction-6f4fc37994090c2f.yaml
nkanazawa1989 Feb 8, 2021
7817f27
Update qiskit/pulse/transforms.py
nkanazawa1989 Feb 8, 2021
3a28c91
update function name
nkanazawa1989 Feb 8, 2021
450971e
update Call instruction
nkanazawa1989 Feb 8, 2021
0c71ce2
update logic of inline function
nkanazawa1989 Feb 8, 2021
28f8f1e
update call function
nkanazawa1989 Feb 8, 2021
a6d7901
update test and fix bugs
nkanazawa1989 Feb 8, 2021
9430307
add test for call instruction
nkanazawa1989 Feb 8, 2021
3f21951
fix unittest name overlap
nkanazawa1989 Feb 8, 2021
bab92c4
update table initialization
nkanazawa1989 Feb 8, 2021
e3257d1
lint
nkanazawa1989 Feb 8, 2021
a99ebfc
update docstring
nkanazawa1989 Feb 8, 2021
6a9d86f
Merge branch 'master' into issue-5679-2_schedule_block
nkanazawa1989 Feb 9, 2021
ff11ba3
name update and type update
nkanazawa1989 Feb 9, 2021
a4c5c8a
update type hints
nkanazawa1989 Feb 9, 2021
4b035c6
Merge branch 'issue-5679-2_schedule_block' of github.com:nkanazawa198…
nkanazawa1989 Feb 9, 2021
e582a4b
Merge branch 'master' into issue-5679-2_schedule_block
nkanazawa1989 Feb 10, 2021
9897c80
feedback from Thomas
nkanazawa1989 Feb 14, 2021
4b601fd
Update qiskit/pulse/instructions/call.py
nkanazawa1989 Feb 14, 2021
fae10af
Update qiskit/pulse/instructions/call.py
nkanazawa1989 Feb 14, 2021
28d1497
Update qiskit/pulse/instructions/call.py
nkanazawa1989 Feb 14, 2021
e933698
Update qiskit/pulse/instructions/call.py
nkanazawa1989 Feb 14, 2021
d97eb2e
Update qiskit/pulse/transforms.py
nkanazawa1989 Feb 14, 2021
c7a45df
Merge branch 'issue-5679-2_schedule_block' of github.com:nkanazawa198…
nkanazawa1989 Feb 14, 2021
644dfff
Update qiskit/pulse/builder.py
nkanazawa1989 Feb 14, 2021
90df0d0
feedback from Daniel
nkanazawa1989 Feb 14, 2021
3816f25
Merge branch 'issue-5679-2_schedule_block' of github.com:nkanazawa198…
nkanazawa1989 Feb 14, 2021
d7e98af
Merge branch 'master' of github.com:Qiskit/qiskit-terra into issue-56…
nkanazawa1989 Feb 14, 2021
9954dcd
update test
nkanazawa1989 Feb 14, 2021
c582067
add value dict to call constructor
nkanazawa1989 Feb 14, 2021
abdaaa2
more test
nkanazawa1989 Feb 14, 2021
a8cae98
support calling subroutine with new parameters
nkanazawa1989 Feb 14, 2021
bfc706a
fix parameter assign bug
nkanazawa1989 Feb 14, 2021
31e2152
lint
nkanazawa1989 Feb 14, 2021
6289969
fix type hint
nkanazawa1989 Feb 14, 2021
8de880c
lint
nkanazawa1989 Feb 14, 2021
22eb83f
forward reference
nkanazawa1989 Feb 14, 2021
7886cb3
ignore lint
nkanazawa1989 Feb 14, 2021
6fe8cf5
Merge branch 'master' into issue-5679-2_schedule_block
nkanazawa1989 Feb 15, 2021
2c63fa2
expose call instruction to end user
nkanazawa1989 Feb 17, 2021
f148645
Merge branch 'issue-5679-2_schedule_block' of github.com:nkanazawa198…
nkanazawa1989 Feb 17, 2021
5d903d3
update parameter assignment logic
nkanazawa1989 Feb 18, 2021
71f66d9
Merge branch 'master' into issue-5679-2_schedule_block
nkanazawa1989 Feb 18, 2021
6f29db9
fix test
nkanazawa1989 Feb 18, 2021
894adb7
Merge branch 'issue-5679-2_schedule_block' of github.com:nkanazawa198…
nkanazawa1989 Feb 18, 2021
91315dd
test lint
nkanazawa1989 Feb 18, 2021
0ddb56d
Merge branch 'master' into issue-5679-2_schedule_block
nkanazawa1989 Feb 18, 2021
4f3b1ba
Merge branch 'master' into issue-5679-2_schedule_block
mergify[bot] Feb 25, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 55 additions & 13 deletions qiskit/pulse/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@

from qiskit import circuit
from qiskit.circuit.library import standard_gates as gates
from qiskit.circuit.parameterexpression import ParameterExpression, ParameterValueType
from qiskit.pulse import (
channels as chans,
configuration,
Expand Down Expand Up @@ -451,7 +452,8 @@ def call_schedule(self, schedule: Schedule):
def call_subroutine(self,
subroutine: Union[circuit.QuantumCircuit, Schedule],
name: Optional[str] = None,
**kw_params):
value_dict: Optional[Dict[ParameterExpression, ParameterValueType]] = None,
**kw_params: ParameterValueType):
"""Call a schedule or circuit defined outside of the current scope.

The ``subroutine`` is appended to the context schedule as a call instruction.
Expand All @@ -462,24 +464,37 @@ def call_subroutine(self,
Args:
subroutine: Target schedule or circuit to append to the current context.
name: Name of subroutine if defined.
kw_params: Parameter values to bind to the target subroutine.
value_dict: Parameter object and assigned value mapping. This is more precise way to
identify a parameter since mapping is managed with unique object id rather than
name. Especially there is any name collision in a parameter table.
kw_params: Parameter values to bind to the target subroutine
with string parameter names. If there are parameter name overlapping,
these parameters are updated with the same assigned value.

Raises:
PulseError: If specified parameter is not contained in the subroutine.
"""
if isinstance(subroutine, circuit.QuantumCircuit):
self._compile_lazy_circuit()
subroutine = self._compile_circuit(subroutine)

if len(subroutine.instructions) > 0:
value_dict = dict()
if value_dict is None:
value_dict = dict()

param_value_map = dict()
for param_name, assigned_value in kw_params.items():
param_objs = subroutine.get_parameters(param_name)
if len(param_objs) > 0:
for param_obj in param_objs:
value_dict[param_obj] = assigned_value
param_value_map[param_obj] = assigned_value
else:
warnings.warn(f'Parameter {param_name} is not defined in the '
'target subroutine. Parameter assignment is ignored.',
UserWarning)
call_def = instructions.Call(subroutine, value_dict, name)
raise exceptions.PulseError(
f'Parameter {param_name} is not defined in the target subroutine. '
f'{", ".join(map(str, subroutine.parameters))} can be specified.')

param_value_map.update(value_dict)
call_def = instructions.Call(subroutine, param_value_map, name)

self.append_instruction(call_def)

Expand Down Expand Up @@ -1689,7 +1704,10 @@ def call_circuit(circ: circuit.QuantumCircuit):
call(circ)


def call(target: Union[circuit.QuantumCircuit, Schedule], **kw_params):
def call(target: Union[circuit.QuantumCircuit, Schedule],
name: Optional[str] = None,
value_dict: Optional[Dict[ParameterValueType, ParameterValueType]] = None,
**kw_params: ParameterValueType):
"""Call the ``target`` within the currently active builder context with arbitrary
parameters which will be assigned to the target program.

Expand All @@ -1700,7 +1718,7 @@ def call(target: Union[circuit.QuantumCircuit, Schedule], **kw_params):

Examples:

.. jupyter-execute::
.. code-block:: python

from qiskit import circuit, pulse, schedule, transpile
from qiskit.test.mock import FakeOpenPulse2Q
Expand All @@ -1718,7 +1736,7 @@ def call(target: Union[circuit.QuantumCircuit, Schedule], **kw_params):

This function can optionally take parameter dictionary with the parameterized target program.

.. jupyter-execute::
.. code-block:: python

from qiskit import circuit, pulse

Expand All @@ -1731,9 +1749,33 @@ def call(target: Union[circuit.QuantumCircuit, Schedule], **kw_params):
pulse.call(subroutine, amp=0.1)
pulse.call(subroutine, amp=0.3)

If there is any parameter name collision, you can distinguish them by specifying
each parameter object as a python dictionary. Otherwise ``amp1`` and ``amp2`` will be
updated with the same value.

.. code-block:: python

from qiskit import circuit, pulse

amp1 = circuit.Parameter('amp')
amp2 = circuit.Parameter('amp')

with pulse.build() as subroutine:
pulse.play(pulse.Gaussian(160, amp1, 40), pulse.DriveChannel(0))
pulse.play(pulse.Gaussian(160, amp2, 40), pulse.DriveChannel(1))

with pulse.build() as main_prog:
pulse.call(subroutine, value_dict={amp1: 0.1, amp2: 0.2})

Args:
target: Target circuit or pulse schedule to call.
kw_params: Parameter values to bind to the target subroutine.
name: Name of subroutine if defined.
value_dict: Parameter object and assigned value mapping. This is more precise way to
identify a parameter since mapping is managed with unique object id rather than
name. Especially there is any name collision in a parameter table.
kw_params: Parameter values to bind to the target subroutine
with string parameter names. If there are parameter name overlapping,
these parameters are updated with the same assigned value.

Raises:
exceptions.PulseError: If the input ``target`` type is not supported.
Expand All @@ -1742,7 +1784,7 @@ def call(target: Union[circuit.QuantumCircuit, Schedule], **kw_params):
raise exceptions.PulseError(
'Target of type "{}" is not supported.'.format(type(target)))

_active_builder().call_subroutine(target, **kw_params)
_active_builder().call_subroutine(target, name, value_dict, **kw_params)


# Directives
Expand Down
30 changes: 25 additions & 5 deletions test/python/pulse/test_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -1109,13 +1109,10 @@ def test_call_with_not_existing_parameter(self):
with pulse.build() as subroutine:
pulse.play(pulse.Gaussian(160, amp, 40), pulse.DriveChannel(0))

with self.assertWarns(UserWarning):
with pulse.build() as sched:
with self.assertRaises(exceptions.PulseError):
with pulse.build():
pulse.call(subroutine, amp=0.1)

# just ignored
self.assertTrue(sched.is_parameterized())

def test_call_with_common_parameter(self):
"""Test call subroutine with parameter that is defined multiple times."""
amp = circuit.Parameter('amp')
Expand All @@ -1134,3 +1131,26 @@ def test_call_with_common_parameter(self):

self.assertEqual(play_0.pulse.amp, 0.1)
self.assertEqual(play_1.pulse.amp, 0.1)

def test_call_with_parameter_name_collision(self):
"""Test call subroutine with duplicated parameter names."""
amp1 = circuit.Parameter('amp')
amp2 = circuit.Parameter('amp')
sigma = circuit.Parameter('sigma')

with pulse.build() as subroutine:
pulse.play(pulse.Gaussian(160, amp1, sigma), pulse.DriveChannel(0))
pulse.play(pulse.Gaussian(160, amp2, sigma), pulse.DriveChannel(0))

with pulse.build() as main_prog:
pulse.call(subroutine, value_dict={amp1: 0.1, amp2: 0.2}, sigma=40)

assigned_sched = inline_subroutines(main_prog)

play_0 = assigned_sched.instructions[0][1]
play_1 = assigned_sched.instructions[1][1]

self.assertEqual(play_0.pulse.amp, 0.1)
self.assertEqual(play_0.pulse.sigma, 40)
self.assertEqual(play_1.pulse.amp, 0.2)
self.assertEqual(play_1.pulse.sigma, 40)