Skip to content
This repository was archived by the owner on Aug 21, 2023. It is now read-only.

Commit 8f7e2ae

Browse files
committed
Configuration section is done!
1 parent e06e132 commit 8f7e2ae

1 file changed

Lines changed: 346 additions & 1 deletion

File tree

qiskit/advanced/terra/programming_with_pulses/gathering_system_information.ipynb

Lines changed: 346 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,352 @@
44
"cell_type": "markdown",
55
"metadata": {},
66
"source": [
7-
"## Utilizing `backend` data for schedule building"
7+
"# Obtaining information about your `backend`\n",
8+
"\n",
9+
"#### _Note: All the attributes of the backend are described in detail in the [Qiskit Backend Specifications](https://arxiv.org/pdf/1809.03452.pdf). This page reviews a subset of the spec._\n",
10+
"\n",
11+
"Programming a quantum computer at the microwave pulse level requires more information about the device than is required at the circuit level. A quantum circuit is built for an abstract quantum computer -- it will yield the same quantum state on any quantum computer (except for varying performance levels). A pulse schedule, on the other hand, is so specific to the device, that running one program on two different backends is not expected to have the same result, even on perfectly noiseless systems.\n",
12+
"\n",
13+
"As a basic example, imagine a drive pulse `q0_X180` calibrated on qubit 0 to enact an $X180$ pulse, which flips the state of qubit 0. If we use the samples from that pulse on qubit 1 on the same device, or qubit 0 on another device, we do not know what the resulting state will be -- but we can be pretty sure it won't be an $X180$ operation. The qubits are each unique, with various drive coupling strengths. If we have specified a frequency for the drive pulse, it's very probable that pulse would have little effect on another qubit, which has its own resonant frequency.\n",
14+
"\n",
15+
"With that, we have motivated why information from the backend may be very useful at times for building Pulse schedules. The information included in a `backend` is broken into three main parts:\n",
16+
"\n",
17+
" - **Configuration**: static backend features\n",
18+
" - **Properties**: measured and reported backend characteristics\n",
19+
" - **Defaults**: default settings for the OpenPulse-enabled backend\n",
20+
" \n",
21+
"which are each covered in the following sections. While all three of these contain interesting data for Pulse users, the defaults are _only_ provided for backends enabled with OpenPulse.\n",
22+
"\n",
23+
"The first thing you'll need to do is grab a backend to inspect."
24+
]
25+
},
26+
{
27+
"cell_type": "code",
28+
"execution_count": 1,
29+
"metadata": {},
30+
"outputs": [],
31+
"source": [
32+
"from qiskit import IBMQ\n",
33+
"\n",
34+
"provider = IBMQ.load_account()\n",
35+
"# We are interested in one that has all the OpenPulse related attributes\n",
36+
"backend = provider.backends(open_pulse=True)[0]"
37+
]
38+
},
39+
{
40+
"cell_type": "markdown",
41+
"metadata": {},
42+
"source": [
43+
"## Configuration\n",
44+
"\n",
45+
"The configuration is where you'll find data about the static setup of the device, such as its name, version, the number of qubits, and the types of features it supports.\n",
46+
"\n",
47+
"Let's build a description of our backend using information from the `backend`'s config."
48+
]
49+
},
50+
{
51+
"cell_type": "code",
52+
"execution_count": 2,
53+
"metadata": {},
54+
"outputs": [
55+
{
56+
"name": "stdout",
57+
"output_type": "stream",
58+
"text": [
59+
"This backend is called ibmq_armonk, and is on version 1.1.0. It has 1 qubit. It supports OpenPulse programs. The basis gates supported on this device are ['id', 'u1', 'u2', 'u3'].\n"
60+
]
61+
}
62+
],
63+
"source": [
64+
"config = backend.configuration()\n",
65+
"\n",
66+
"# Basic Features\n",
67+
"print(f\"This backend is called {config.backend_name}, and is on version {config.backend_version}. \"\n",
68+
" f\"It has {config.n_qubits} qubit{'' if config.n_qubits == 1 else 's'}. It \"\n",
69+
" f\"{'supports' if config.open_pulse else 'does not support'} OpenPulse programs. The basis \"\n",
70+
" f\"gates supported on this device are {config.basis_gates}.\")"
71+
]
72+
},
73+
{
74+
"cell_type": "markdown",
75+
"metadata": {},
76+
"source": [
77+
"Neat! All of the above configuration is available for any backend, whether enabled with OpenPulse or not, although it is not an exhaustive list. There are additional attributes available on Pulse backends. Let's go into a bit more detail with those.\n",
78+
"\n",
79+
"The **timescale**, `dt`, is backend dependent. Think of this as the inverse sampling rate of the control rack's arbitrary waveform generators. Each sample point and duration in a Pulse `Schedule` is given in units of this timescale."
80+
]
81+
},
82+
{
83+
"cell_type": "code",
84+
"execution_count": 3,
85+
"metadata": {},
86+
"outputs": [
87+
{
88+
"name": "stderr",
89+
"output_type": "stream",
90+
"text": [
91+
"/Users/lauren@ibm.com/code/qiskit-terra/qiskit/providers/models/backendconfiguration.py:355: UserWarning: `dt` and `dtm` now have units of seconds(s) rather than nanoseconds(ns).\n",
92+
" warnings.warn('`dt` and `dtm` now have units of seconds(s) rather '\n"
93+
]
94+
},
95+
{
96+
"data": {
97+
"text/plain": [
98+
"2.2222222222222221e-10"
99+
]
100+
},
101+
"execution_count": 3,
102+
"metadata": {},
103+
"output_type": "execute_result"
104+
}
105+
],
106+
"source": [
107+
"config.dt # units of seconds"
108+
]
109+
},
110+
{
111+
"cell_type": "markdown",
112+
"metadata": {},
113+
"source": [
114+
"The configuration also provides information that is useful for building measurements. Pulse supports three measurement levels: `0: RAW`, `1: KERNELED`, and `2: DISCRIMINATED`. The `meas_levels` attribute tells us which of those are supported by this backend. To learn how to execute programs with these different levels, see this page -- COMING SOON."
115+
]
116+
},
117+
{
118+
"cell_type": "code",
119+
"execution_count": 4,
120+
"metadata": {},
121+
"outputs": [
122+
{
123+
"data": {
124+
"text/plain": [
125+
"[1, 2]"
126+
]
127+
},
128+
"execution_count": 4,
129+
"metadata": {},
130+
"output_type": "execute_result"
131+
}
132+
],
133+
"source": [
134+
"config.meas_levels"
135+
]
136+
},
137+
{
138+
"cell_type": "markdown",
139+
"metadata": {},
140+
"source": [
141+
"For backends which support measurement level 0, the sampling rate of the control rack's analog-to-digital converters (ADCs) also becomes relevant. The configuration also has this info, where `dtm` is the time per sample returned:"
142+
]
143+
},
144+
{
145+
"cell_type": "code",
146+
"execution_count": 5,
147+
"metadata": {},
148+
"outputs": [
149+
{
150+
"data": {
151+
"text/plain": [
152+
"2.2222222222222221e-10"
153+
]
154+
},
155+
"execution_count": 5,
156+
"metadata": {},
157+
"output_type": "execute_result"
158+
}
159+
],
160+
"source": [
161+
"config.dtm"
162+
]
163+
},
164+
{
165+
"cell_type": "markdown",
166+
"metadata": {},
167+
"source": [
168+
"The measurement map, explained in detail on [this page (IN REVIEW)](adding_measurements.ipynb), is also found here."
169+
]
170+
},
171+
{
172+
"cell_type": "code",
173+
"execution_count": 6,
174+
"metadata": {},
175+
"outputs": [
176+
{
177+
"data": {
178+
"text/plain": [
179+
"[[0]]"
180+
]
181+
},
182+
"execution_count": 6,
183+
"metadata": {},
184+
"output_type": "execute_result"
185+
}
186+
],
187+
"source": [
188+
"config.meas_map"
189+
]
190+
},
191+
{
192+
"cell_type": "markdown",
193+
"metadata": {},
194+
"source": [
195+
"The configuration also supplies convenient methods for getting channels for your schedule programs. For instance:"
196+
]
197+
},
198+
{
199+
"cell_type": "code",
200+
"execution_count": 7,
201+
"metadata": {},
202+
"outputs": [
203+
{
204+
"data": {
205+
"text/plain": [
206+
"DriveChannel(0)"
207+
]
208+
},
209+
"execution_count": 7,
210+
"metadata": {},
211+
"output_type": "execute_result"
212+
}
213+
],
214+
"source": [
215+
"config.drive(0)"
216+
]
217+
},
218+
{
219+
"cell_type": "code",
220+
"execution_count": 8,
221+
"metadata": {},
222+
"outputs": [
223+
{
224+
"data": {
225+
"text/plain": [
226+
"MeasureChannel(0)"
227+
]
228+
},
229+
"execution_count": 8,
230+
"metadata": {},
231+
"output_type": "execute_result"
232+
}
233+
],
234+
"source": [
235+
"config.measure(0)"
236+
]
237+
},
238+
{
239+
"cell_type": "code",
240+
"execution_count": 9,
241+
"metadata": {},
242+
"outputs": [
243+
{
244+
"data": {
245+
"text/plain": [
246+
"AcquireChannel(0)"
247+
]
248+
},
249+
"execution_count": 9,
250+
"metadata": {},
251+
"output_type": "execute_result"
252+
}
253+
],
254+
"source": [
255+
"config.acquire(0)"
256+
]
257+
},
258+
{
259+
"cell_type": "markdown",
260+
"metadata": {},
261+
"source": [
262+
"It is a matter of style and personal preference whether you use `config.drive(0)` or `DriveChannel(0)`."
263+
]
264+
},
265+
{
266+
"cell_type": "markdown",
267+
"metadata": {},
268+
"source": [
269+
"## Properties"
270+
]
271+
},
272+
{
273+
"cell_type": "code",
274+
"execution_count": 10,
275+
"metadata": {},
276+
"outputs": [],
277+
"source": [
278+
"# Conversions from standard SI\n",
279+
"us = 1e6\n",
280+
"GHz = 1e-9\n",
281+
"props = backend.properties()\n",
282+
"# Qubit 0 T1 time in microsec\n",
283+
"q0_t1_us = props.t1(0) * us\n",
284+
"# Qubit 0 T2 time in microsec\n",
285+
"q0_t2_us = props.t2(0) * us\n",
286+
"# # Gate error for CNOT on qubits 0, 1\n",
287+
"# cx_error = props.gate_error('cx', (0, 1))\n",
288+
"# Resonant frequency of qubit 0\n",
289+
"q2_freq_ghz = props.frequency(0) * GHz\n",
290+
"# Duration of the X gate on qubit 0\n",
291+
"q1_x_duration_us = props.gate_length('u2', 0) * us"
292+
]
293+
},
294+
{
295+
"cell_type": "markdown",
296+
"metadata": {},
297+
"source": [
298+
"## Defaults"
299+
]
300+
},
301+
{
302+
"cell_type": "code",
303+
"execution_count": 11,
304+
"metadata": {},
305+
"outputs": [
306+
{
307+
"name": "stderr",
308+
"output_type": "stream",
309+
"text": [
310+
"/Users/lauren@ibm.com/code/qiskit-terra/qiskit/providers/models/pulsedefaults.py:155: UserWarning: `qubit_freq_est` and `meas_freq_est` now have units of Hertz(Hz) rather than gigahertz(GHz).\n",
311+
" warnings.warn('`qubit_freq_est` and `meas_freq_est` now have units of '\n"
312+
]
313+
}
314+
],
315+
"source": [
316+
"defaults = backend.defaults()\n",
317+
"\n",
318+
"q0_freq = defaults.qubit_freq_est[0] \n",
319+
"q0_meas_freq = defaults.meas_freq_est[0]\n",
320+
"\n",
321+
"inst_map = defaults.instruction_schedule_map"
322+
]
323+
},
324+
{
325+
"cell_type": "markdown",
326+
"metadata": {},
327+
"source": [
328+
"### Pulse Schedule definitions for QuantumCircuit instructions"
329+
]
330+
},
331+
{
332+
"cell_type": "code",
333+
"execution_count": 13,
334+
"metadata": {},
335+
"outputs": [
336+
{
337+
"data": {
338+
"text/plain": [
339+
"False"
340+
]
341+
},
342+
"execution_count": 13,
343+
"metadata": {},
344+
"output_type": "execute_result"
345+
}
346+
],
347+
"source": [
348+
"inst_map.get('measure', (q for q in range(config.n_qubits)))\n",
349+
"\n",
350+
"inst_map.get('u1', 0, P0=3.1415)\n",
351+
"\n",
352+
"inst_map.has('x', 3) # Does qubit 3 have an x gate defined on it?"
8353
]
9354
},
10355
{

0 commit comments

Comments
 (0)