142 lines
7.4 KiB
Plaintext
142 lines
7.4 KiB
Plaintext
---
|
||
title: call
|
||
description: API reference for qiskit.pulse.builder.call
|
||
in_page_toc_min_heading_level: 1
|
||
python_api_type: function
|
||
python_api_name: qiskit.pulse.builder.call
|
||
---
|
||
|
||
# qiskit.pulse.builder.call
|
||
|
||
<Function id="qiskit.pulse.builder.call" isDedicatedPage={true} github="https://github.com/qiskit/qiskit/tree/stable/0.22/qiskit/pulse/builder.py" signature="call(target, name=None, value_dict=None, **kw_params)">
|
||
Call the subroutine within the currently active builder context with arbitrary parameters which will be assigned to the target program.
|
||
|
||
<Admonition title="Note" type="note">
|
||
If the `target` program is a [`ScheduleBlock`](qiskit.pulse.ScheduleBlock "qiskit.pulse.ScheduleBlock"), then a [`Reference`](qiskit.pulse.instructions.Reference "qiskit.pulse.instructions.Reference") instruction will be created and appended to the current context. The `target` program will be immediately assigned to the current scope as a subroutine. If the `target` program is [`Schedule`](qiskit.pulse.Schedule "qiskit.pulse.Schedule"), it will be wrapped by the [`Call`](qiskit.pulse.instructions.Call "qiskit.pulse.instructions.Call") instruction and appended to the current context to avoid a mixed representation of [`ScheduleBlock`](qiskit.pulse.ScheduleBlock "qiskit.pulse.ScheduleBlock") and [`Schedule`](qiskit.pulse.Schedule "qiskit.pulse.Schedule"). If the `target` program is a [`QuantumCircuit`](qiskit.circuit.QuantumCircuit "qiskit.circuit.QuantumCircuit") it will be scheduled and the new [`Schedule`](qiskit.pulse.Schedule "qiskit.pulse.Schedule") will be added as a [`Call`](qiskit.pulse.instructions.Call "qiskit.pulse.instructions.Call") instruction.
|
||
</Admonition>
|
||
|
||
**Examples**
|
||
|
||
1. Calling a schedule block (recommended)
|
||
|
||
```python
|
||
from qiskit import circuit, pulse
|
||
from qiskit.providers.fake_provider import FakeBogotaV2
|
||
|
||
backend = FakeBogotaV2()
|
||
|
||
with pulse.build() as x_sched:
|
||
pulse.play(pulse.Gaussian(160, 0.1, 40), pulse.DriveChannel(0))
|
||
|
||
with pulse.build() as pulse_prog:
|
||
pulse.call(x_sched)
|
||
|
||
print(pulse_prog)
|
||
```
|
||
|
||
```python
|
||
ScheduleBlock(ScheduleBlock(Play(Gaussian(duration=160, amp=(0.1+0j), sigma=40), DriveChannel(0)), name="block0", transform=AlignLeft()), name="block1", transform=AlignLeft())
|
||
```
|
||
|
||
The actual program is stored in the reference table attached to the schedule.
|
||
|
||
```python
|
||
print(pulse_prog.references)
|
||
```
|
||
|
||
```python
|
||
ReferenceManager:
|
||
- ('block0', '582c571bb77a4bc4ae4573e68a72f32e'): ScheduleBlock(Play(Gaussian(duration=160, amp=(0.1...
|
||
```
|
||
|
||
In addition, you can call a parameterized target program with parameter assignment.
|
||
|
||
```python
|
||
amp = circuit.Parameter("amp")
|
||
|
||
with pulse.build() as subroutine:
|
||
pulse.play(pulse.Gaussian(160, amp, 40), pulse.DriveChannel(0))
|
||
|
||
with pulse.build() as pulse_prog:
|
||
pulse.call(subroutine, amp=0.1)
|
||
pulse.call(subroutine, amp=0.3)
|
||
|
||
print(pulse_prog)
|
||
```
|
||
|
||
```python
|
||
ScheduleBlock(ScheduleBlock(Play(Gaussian(duration=160, amp=(0.1+0j), sigma=40), DriveChannel(0)), name="block2", transform=AlignLeft()), ScheduleBlock(Play(Gaussian(duration=160, amp=(0.3+0j), sigma=40), DriveChannel(0)), name="block2", transform=AlignLeft()), name="block3", transform=AlignLeft())
|
||
```
|
||
|
||
If there is a name collision between parameters, you can distinguish them by specifying each parameter object in a python dictionary. For example,
|
||
|
||
```python
|
||
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 pulse_prog:
|
||
pulse.call(subroutine, value_dict={amp1: 0.1, amp2: 0.3})
|
||
|
||
print(pulse_prog)
|
||
```
|
||
|
||
```python
|
||
ScheduleBlock(ScheduleBlock(Play(Gaussian(duration=160, amp=(0.1+0j), sigma=40), DriveChannel(0)), Play(Gaussian(duration=160, amp=(0.3+0j), sigma=40), DriveChannel(1)), name="block4", transform=AlignLeft()), name="block5", transform=AlignLeft())
|
||
```
|
||
|
||
2. Calling a schedule
|
||
|
||
```python
|
||
x_sched = backend.instruction_schedule_map.get("x", (0,))
|
||
|
||
with pulse.build(backend) as pulse_prog:
|
||
pulse.call(x_sched)
|
||
|
||
print(pulse_prog)
|
||
```
|
||
|
||
```python
|
||
ScheduleBlock(Call(Schedule((0, Play(Drag(duration=160, amp=(0.18989731546729305+0j), sigma=40, beta=-1.201258305015517, name='drag_86a8'), DriveChannel(0), name='drag_86a8')), name="x"), name='x'), name="block6", transform=AlignLeft())
|
||
```
|
||
|
||
Currently, the backend calibrated gates are provided in the form of [`Schedule`](qiskit.pulse.Schedule "qiskit.pulse.Schedule"). The parameter assignment mechanism is available also for schedules. However, the called schedule is not treated as a reference.
|
||
|
||
3. Calling a quantum circuit
|
||
|
||
```python
|
||
backend = FakeBogotaV2()
|
||
|
||
qc = circuit.QuantumCircuit(1)
|
||
qc.x(0)
|
||
|
||
with pulse.build(backend) as pulse_prog:
|
||
pulse.call(qc)
|
||
|
||
print(pulse_prog)
|
||
```
|
||
|
||
```python
|
||
ScheduleBlock(Call(Schedule((0, Play(Drag(duration=160, amp=(0.18989731546729305+0j), sigma=40, beta=-1.201258305015517, name='drag_86a8'), DriveChannel(0), name='drag_86a8')), name="circuit-87"), name='circuit-87'), name="block7", transform=AlignLeft())
|
||
```
|
||
|
||
<Admonition title="Warning" type="caution">
|
||
Calling a circuit from a schedule is not encouraged. Currently, the Qiskit execution model is migrating toward the pulse gate model, where schedules are attached to circuits through the [`QuantumCircuit.add_calibration()`](qiskit.circuit.QuantumCircuit#add_calibration "qiskit.circuit.QuantumCircuit.add_calibration") method.
|
||
</Admonition>
|
||
|
||
**Parameters**
|
||
|
||
* **target** (`Union`\[[`QuantumCircuit`](qiskit.circuit.QuantumCircuit "qiskit.circuit.quantumcircuit.QuantumCircuit"), [`Schedule`](qiskit.pulse.Schedule "qiskit.pulse.schedule.Schedule"), [`ScheduleBlock`](qiskit.pulse.ScheduleBlock "qiskit.pulse.schedule.ScheduleBlock"), `None`]) – Target circuit or pulse schedule to call.
|
||
* **name** (`Optional`\[`str`]) – Optional. A unique name of subroutine if defined. When the name is explicitly provided, one cannot call different schedule blocks with the same name.
|
||
* **value\_dict** (`Optional`\[`Dict`\[`Union`\[[`ParameterExpression`](qiskit.circuit.ParameterExpression "qiskit.circuit.parameterexpression.ParameterExpression"), `float`], `Union`\[[`ParameterExpression`](qiskit.circuit.ParameterExpression "qiskit.circuit.parameterexpression.ParameterExpression"), `float`]]]) – Optional. Parameters assigned to the `target` program. If this dictionary is provided, the `target` program is copied and then stored in the main built schedule and its parameters are assigned to the given values. This dictionary is keyed on [`Parameter`](qiskit.circuit.Parameter "qiskit.circuit.Parameter") objects, allowing parameter name collision to be avoided.
|
||
* **kw\_params** (`Union`\[[`ParameterExpression`](qiskit.circuit.ParameterExpression "qiskit.circuit.parameterexpression.ParameterExpression"), `float`]) – Alternative way to provide parameters. Since this is keyed on the string parameter name, the parameters having the same name are all updated together. If you want to avoid name collision, use `value_dict` with [`Parameter`](qiskit.circuit.Parameter "qiskit.circuit.Parameter") objects instead.
|
||
|
||
**Raises**
|
||
|
||
[**exceptions.PulseError**](pulse#qiskit.pulse.PulseError "qiskit.pulse.exceptions.PulseError") – If the input `target` type is not supported.
|
||
</Function>
|
||
|