Lewati ke konten utama
Proyek ini masih dalam tahap beta. Menemukan bug? Buat isu GitHub. Punya pertanyaan atau ide? Tanya di Discussions — kami sangat menghargai masukan kamu!
Bagaimana kualitas terjemahan di halaman ini?

Jalankan circuit pertamamu di perangkat keras

Versi paket

Kode di halaman ini dikembangkan menggunakan persyaratan berikut. Kami sarankan menggunakan versi ini atau yang lebih baru.

qiskit[all]~=2.5.2
qiskit-ibm-runtime~=0.47.0

Contoh ini terdiri dari dua bagian. Pertama, kamu akan membuat program kuantum "Hello world" sederhana dan menjalankannya di unit pemrosesan kuantum (QPU). Karena penelitian kuantum nyata membutuhkan program yang jauh lebih tangguh, di bagian kedua (Skalakan ke jumlah qubit yang besar), kamu akan menskalakan program sederhana tersebut ke tingkat utilitas.

# Added by doQumentation — installs the packages this notebook needs if they are missing
import importlib.util

_needed = {"matplotlib": "matplotlib", "qiskit": "qiskit", "qiskit_ibm_runtime": "qiskit-ibm-runtime"}
_missing = [pip for module, pip in _needed.items()
if importlib.util.find_spec(module) is None]
# One at a time, so a package that fails to install does not block the others
for _pip in _missing:
%pip install -q {_pip}
if not _missing:
print("\u2713 All required packages are installed")

Instal dan autentikasi​

  1. Jika Anda belum menginstal Qiskit, temukan petunjuknya di panduan Quickstart.

    • Instal klien IBM Quantum Compute untuk menjalankan pekerjaan pada perangkat keras kuantum:

      pip install qiskit-ibm-runtime
    • Siapkan lingkungan untuk menjalankan notebook Jupyter secara lokal:

      pip install jupyter
  2. Atur autentikasi untuk akses ke perangkat keras kuantum melalui Open Plan yang gratis.

    (Jika Anda mendapat undangan melalui email untuk bergabung ke akun, ikuti langkah untuk pengguna yang diundang sebagai gantinya.)

    • Buka IBM Quantum Platform untuk login atau membuat akun.

      Penting

      Jika Anda terhubung melalui server proxy, Anda harus menggunakan qiskit-ibm-runtime v0.44.0 atau lebih baru.

    • Buat API key-mu (juga disebut API token) di dashboard, lalu salin ke lokasi yang aman.

    • Buka halaman Instances dan temukan instance yang ingin Anda gunakan. Arahkan kursor ke CRN-nya dan klik untuk menyalinnya.

    • Simpan kredensialmu secara lokal dengan kode ini:

      from qiskit_ibm_runtime import QiskitRuntimeService

      QiskitRuntimeService.save_account(
      # For `token`, use the 44-character API_KEY you created
      # and saved from the IBM Quantum Platform Home dashboard
      token="<your-api-key>",
      instance="<CRN>", # Optional
      )
  3. Sekarang Anda bisa menggunakan kode Python ini setiap kali ingin autentikasi ke IBM Quantum Compute Service:

    from qiskit_ibm_runtime import QiskitRuntimeService

    # Run every time you need the service
    service = QiskitRuntimeService()
Tidak menggunakan lingkungan Python yang terpercaya?

Jika Anda menggunakan komputer umum atau lingkungan yang tidak aman, ikuti petunjuk autentikasi manual sebagai gantinya untuk menjaga keamanan kredensial autentikasimu.

Buat dan jalankan program kuantum sederhana​

Empat langkah dalam menulis program kuantum menggunakan pola Qiskit adalah:

  1. Petakan masalah ke format native kuantum.

  2. Optimalkan Circuit dan operator.

  3. Eksekusi menggunakan fungsi primitif kuantum.

  4. Analisis hasilnya.

Langkah 1. Petakan masalah ke format native kuantum​

Dalam program kuantum, Circuit kuantum adalah format native untuk merepresentasikan instruksi kuantum, dan operator merepresentasikan observabel yang akan diukur. Saat membuat Circuit, biasanya Anda akan membuat objek QuantumCircuit baru, lalu menambahkan instruksi secara berurutan. Sel kode berikut membuat Circuit yang menghasilkan Bell state, yaitu keadaan di mana dua qubit saling terjalin sepenuhnya.

Catatan: urutan bit

Qiskit SDK menggunakan penomoran bit LSb 0 di mana digit ke-nn memiliki nilai 1≪n1 \ll n atau 2n2^n. Untuk detail lebih lanjut, lihat topik Bit-ordering in the Qiskit SDK.

# This cell is hidden from users. It hides several unnecessary warnings.

import warnings
import logging

warnings.filterwarnings("ignore", message=".*Instance was not set*")
warnings.filterwarnings("ignore", message=".*loading instance*")
warnings.filterwarnings("ignore", message=".*using instance*")

# This cell is hidden from users. It hides several unnecessary warnings.

class IgnoreSpecificMessages(logging.Filter):
def filter(self, record):
for text in [
"Instance was not set",
"Loading default saved account",
"Loading instance",
"Instance was not set",
"using instance",
]:
if text in record.getMessage():
return False
return True

logger = logging.getLogger("qiskit_ibm_runtime")
logger.addFilter(IgnoreSpecificMessages())

for handler in logger.handlers:
handler.addFilter(IgnoreSpecificMessages())
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import QiskitRuntimeService
from matplotlib import pyplot as plt

# Legacy server-side primitive before qiskit-ibm-runtime 0.50.0
# from qiskit_ibm_runtime import EstimatorOptions
# from qiskit_ibm_runtime import Estimator

# Client-side primitive introduced in qiskit-ibm-runtime 0.50.0
from qiskit_ibm_runtime.options_models import EstimatorOptions
from qiskit_ibm_runtime.executor_estimator import Estimator

# Uncomment the next line if you want to use a simulator:
# from qiskit_ibm_runtime.fake_provider import FakeBelemV2

# Create a new circuit with two qubits
qc = QuantumCircuit(2)

# Add a Hadamard gate to qubit 0
qc.h(0)

# Perform a controlled-X gate on qubit 1, controlled by qubit 0
qc.cx(0, 1)

# Return a drawing of the circuit using MatPlotLib ("mpl").
# These guides are written by using Jupyter notebooks, which
# display the output of the last line of each cell.
# If you're running this in a script, use `print(qc.draw())` to
# print a text drawing.
qc.draw("mpl")

Output of the previous code cell

Lihat QuantumCircuit di dokumentasi untuk semua operasi yang tersedia. Saat membuat Circuit kuantum, kamu juga harus mempertimbangkan jenis data apa yang ingin dikembalikan setelah eksekusi. Qiskit menyediakan dua cara untuk mengembalikan data: kamu bisa mendapatkan output sampling untuk sekumpulan qubit yang kamu pilih untuk diukur, atau kamu bisa mendapatkan nilai ekspektasi dari sebuah observabel. Siapkan beban kerjamu untuk mengukur Circuit dengan salah satu dari dua cara ini dengan primitif (dijelaskan secara detail di Langkah 3).

Contoh ini mengukur nilai ekspektasi menggunakan submodul qiskit.quantum_info, yang ditentukan menggunakan operator (objek matematis yang digunakan untuk merepresentasikan tindakan atau proses yang mengubah keadaan kuantum). Sel kode berikut membuat enam operator Pauli dua-qubit: IZ, IX, ZI, XI, ZZ, dan XX.

# Set up six different observables.

observables_labels = ["IZ", "IX", "ZI", "XI", "ZZ", "XX"]
observables = [SparsePauliOp(label) for label in observables_labels]
Notasi Operator

Di sini, operator seperti ZZ adalah singkatan dari produk tensor Z⊗ZZ\otimes Z, yang berarti mengukur Z pada qubit 1 dan Z pada qubit 0 secara bersamaan, dan mendapatkan informasi tentang korelasi antara qubit 1 dan qubit 0. Nilai ekspektasi seperti ini juga biasanya ditulis sebagai ⟨Z1Z0⟩\langle Z_1 Z_0 \rangle.

Jika keadaannya terjalin, maka pengukuran ⟨Z1Z0⟩\langle Z_1 Z_0 \rangle seharusnya berbeda dari pengukuran ⟨I1⊗Z0⟩⟨Z1⊗I0⟩\langle I_1 \otimes Z_0 \rangle \langle Z_1 \otimes I_0 \rangle. Untuk keadaan terjalin spesifik yang dibuat oleh Circuit yang dijelaskan di atas, pengukuran ⟨Z1Z0⟩\langle Z_1 Z_0 \rangle seharusnya 1 dan pengukuran ⟨I1⊗Z0⟩⟨Z1⊗I0⟩\langle I_1 \otimes Z_0 \rangle \langle Z_1 \otimes I_0 \rangle seharusnya nol.

Langkah 2. Optimalkan Circuit dan operator​

Saat mengeksekusi Circuit pada perangkat, penting untuk mengoptimalkan sekumpulan instruksi yang ada dalam Circuit dan meminimalkan kedalaman keseluruhan (kurang lebih jumlah instruksi) dari Circuit. Ini memastikan Anda mendapatkan hasil terbaik dengan mengurangi efek error dan noise. Selain itu, instruksi Circuit harus sesuai dengan Instruction Set Architecture (ISA) perangkat Backend dan harus mempertimbangkan gate dasar serta konektivitas qubit perangkat.

Kode berikut menginstansiasi perangkat nyata untuk mengirimkan pekerjaan dan mengubah Circuit serta observabel agar sesuai dengan ISA Backend tersebut. Ini mengharuskan kamu sudah menyimpan kredensialmu.

service = QiskitRuntimeService()

backend = service.least_busy(simulator=False, operational=True)

# Convert to an ISA circuit and layout-mapped observables.
pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)

isa_circuit.draw("mpl", idle_wires=False)

Output of the previous code cell

Langkah 3. Eksekusi menggunakan primitif kuantum​

Komputer kuantum bisa menghasilkan hasil acak, jadi biasanya kamu mengumpulkan sampel dari output dengan menjalankan Circuit berkali-kali. Kamu bisa memperkirakan nilai observabel menggunakan kelas Estimator. Estimator adalah salah satu dari dua primitif; yang lainnya adalah Sampler, yang bisa digunakan untuk mendapatkan data dari komputer kuantum. Objek-objek ini memiliki metode run() yang mengeksekusi pilihan Circuit, observabel, dan parameter (jika berlaku), menggunakan primitive unified bloc (PUB).

# Construct the Estimator instance.

estimator = Estimator(mode=backend)
estimator.options.resilience_level = 1
estimator.options.default_shots = 5000

mapped_observables = [
observable.apply_layout(isa_circuit.layout) for observable in observables
]

# One pub, with one circuit to run against five different observables.
job = estimator.run([(isa_circuit, mapped_observables)])

# Use the job ID to retrieve your job data later
print(f">>> Job ID: {job.job_id()}")
>>> Job ID: dab7lm9l216s739p6q10

Setelah pekerjaan dikirim, Anda bisa menunggu hingga pekerjaan selesai dalam instance Python saat ini, atau menggunakan job_id untuk mengambil data di lain waktu. (Lihat bagian tentang mengambil pekerjaan untuk detailnya.)

Setelah pekerjaan selesai, periksa outputnya melalui atribut result() dari pekerjaan.

# This is the result of the entire submission. You submitted one Pub,
# so this contains one inner result (and some metadata of its own).
job_result = job.result()

# This is the result from our single pub, which had six observables,
# so contains information on all six.
pub_result = job.result()[0]
# Check there are six observables.
# If not, edit the comments in the previous cell and update this test.
assert len(pub_result.data.evs) == 6
Alternatif: jalankan contoh menggunakan simulator

Saat kamu menjalankan program kuantummu di perangkat nyata, beban kerjamu harus menunggu dalam antrean sebelum dijalankan. Untuk menghemat waktu, kamu bisa menggunakan kode berikut untuk menjalankan beban kerja kecil ini di fake_provider dengan mode pengujian lokal qiskit-ibm-runtime. Perhatikan bahwa ini hanya memungkinkan untuk Circuit kecil. Saat kamu menskalakan program di bagian berikutnya, kamu perlu menggunakan perangkat nyata.


# Use the following code instead if you want to run on a simulator:

from qiskit_ibm_runtime.fake_provider import FakeBelemV2
backend = FakeBelemV2()
estimator = Estimator(backend)

# Convert to an ISA circuit and layout-mapped observables.

pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
isa_circuit = pm.run(qc)
mapped_observables = [
observable.apply_layout(isa_circuit.layout) for observable in observables
]

job = estimator.run([(isa_circuit, mapped_observables)])
result = job.result()

# This is the result of the entire submission. You submitted one Pub,
# so this contains one inner result (and some metadata of its own).

job_result = job.result()

# This is the result from our single pub, which had five observables,
# so contains information on all five.

pub_result = job.result()[0]

Langkah 4. Analisis hasilnya​

Langkah analisis biasanya adalah tempat kamu bisa melakukan pasca-pemrosesan hasilmu menggunakan, misalnya, mitigasi error pengukuran atau zero noise extrapolation (ZNE). Kamu bisa memasukkan hasil ini ke dalam alur kerja lain untuk analisis lebih lanjut atau menyiapkan plot nilai dan data utama. Secara umum, langkah ini spesifik untuk masalahmu. Untuk contoh ini, buat plot setiap nilai ekspektasi yang diukur untuk Circuit kita.

Nilai ekspektasi dan standar deviasi untuk observabel yang Anda tentukan ke Estimator diakses melalui atribut PubResult.data.evs dan PubResult.data.stds dari hasil pekerjaan. Untuk mendapatkan hasil dari Sampler, gunakan fungsi PubResult.data.meas.get_counts(), yang akan mengembalikan dict pengukuran dalam bentuk bitstring sebagai kunci dan hitungan sebagai nilai yang sesuai. Untuk informasi lebih lanjut, lihat panduan Sampler quickstart.

# Plot the result

values = pub_result.data.evs

errors = pub_result.data.stds

# plotting graph
plt.plot(observables_labels, values, "-o")
plt.xlabel("Observables")
plt.ylabel("Values")
plt.show()

Output of the previous code cell

Perhatikan bahwa untuk qubit 0 dan 1, nilai ekspektasi independen dari X dan Z keduanya adalah 0, sedangkan korelasi (XX dan ZZ) adalah 1. Ini adalah ciri khas keterjalinan kuantum.

# Make sure the results follow the claim from the previous markdown cell.
# This can happen when the device occasionally behaves strangely. If this cell
# fails, you may just need to run the notebook again.

_results = {obs: val for obs, val in zip(observables_labels, values)}
for _label in ["IZ", "IX", "ZI", "XI"]:
assert abs(_results[_label]) < 0.2
for _label in ["XX", "ZZ"]:
assert _results[_label] > 0.8

Skalakan ke jumlah qubit yang besar​

Dalam komputasi kuantum, pekerjaan skala utilitas sangat penting untuk kemajuan di bidang ini. Pekerjaan semacam itu membutuhkan komputasi dalam skala yang jauh lebih besar; bekerja dengan Circuit yang mungkin menggunakan lebih dari 100 qubit dan lebih dari 1000 Gate. Contoh ini menunjukkan bagaimana Anda bisa menyelesaikan pekerjaan skala utilitas di IBM® QPU dengan membuat dan menganalisis keadaan GHZ 100-qubit. Ini menggunakan alur kerja pola Qiskit dan diakhiri dengan mengukur nilai ekspektasi ⟨Z0Zi⟩\langle Z_0 Z_i \rangle untuk setiap qubit.

Langkah 1. Petakan masalahnya​

Tulis fungsi yang mengembalikan QuantumCircuit yang mempersiapkan keadaan GHZ nn-qubit (pada dasarnya Bell state yang diperluas), lalu gunakan fungsi tersebut untuk mempersiapkan keadaan GHZ 100-qubit dan kumpulkan observabel yang akan diukur.

def get_qc_for_n_qubit_GHZ_state(n: int) -> QuantumCircuit:
"""This function will create a qiskit.QuantumCircuit (qc)
for an n-qubit GHZ state.

Args:
n (int): Number of qubits in the n-qubit GHZ state

Returns:
QuantumCircuit: Quantum circuit that generate the n-qubit GHZ state,
assuming all qubits start in the 0 state
"""
if isinstance(n, int) and n >= 2:
qc = QuantumCircuit(n)
qc.h(0)
for i in range(n - 1):
qc.cx(i, i + 1)
else:
raise Exception("n is not a valid input")
return qc

# Create a new circuit with 100 qubits in the GHZ state
n = 100
qc = get_qc_for_n_qubit_GHZ_state(n)

Selanjutnya, petakan ke operator yang diminati. Contoh ini menggunakan operator ZZ antara qubit untuk memeriksa perilaku saat qubit semakin jauh terpisah. Nilai ekspektasi antar-qubit yang berjauhan yang semakin tidak akurat (rusak) akan mengungkap tingkat noise yang ada.

# ZZII...II, ZIZI...II, ... , ZIII...IZ
operator_strings = [
"Z" + "I" * i + "Z" + "I" * (n - 2 - i) for i in range(n - 1)
]

operators = [SparsePauliOp(operator) for operator in operator_strings]

Langkah 2. Optimalkan masalah untuk eksekusi pada perangkat keras kuantum​

Kode berikut mengubah Circuit dan observabel agar sesuai dengan ISA Backend. Ini mengharuskan kamu sudah menyimpan kredensialmu.

service = QiskitRuntimeService()

backend = service.least_busy(
simulator=False, operational=True, min_num_qubits=100
)
pm = generate_preset_pass_manager(optimization_level=1, backend=backend)

isa_circuit = pm.run(qc)
isa_operators_list = [op.apply_layout(isa_circuit.layout) for op in operators]

Langkah 3. Eksekusi pada perangkat keras​

Kirim pekerjaan dan aktifkan penekanan error menggunakan teknik untuk mengurangi error yang disebut dynamical decoupling. Tingkat resiliensi menentukan seberapa besar ketahanan terhadap error yang dibangun. Tingkat yang lebih tinggi menghasilkan hasil yang lebih akurat, dengan mengorbankan waktu pemrosesan yang lebih lama. Untuk penjelasan lebih lanjut tentang opsi yang diatur dalam kode berikut, lihat Error mitigation and suppression techniques.

options = EstimatorOptions()
options.resilience_level = 1
options.dynamical_decoupling.enable = True
options.dynamical_decoupling.sequence_type = "XY4"

# Create an Estimator object
estimator = Estimator(backend, options=options)
# Submit the circuit to Estimator
job = estimator.run([(isa_circuit, isa_operators_list)])
job_id = job.job_id()
print(job_id)
dab84omrrl7c7386h52g

Langkah 4. Pasca-proses hasil​

Setelah pekerjaan selesai, buat plot hasilnya dan perhatikan bahwa ⟨Z0Zi⟩\langle Z_0 Z_i \rangle menurun seiring meningkatnya ii, meskipun dalam simulasi ideal semua ⟨Z0Zi⟩\langle Z_0 Z_i \rangle seharusnya 1.

# data
data = list(range(1, len(operators) + 1)) # Distance between the Z operators
result = job.result()[0]
values = result.data.evs # Expectation value at each Z operator.
values = [
v / values[0] for v in values
] # Normalize the expectation values to evaluate how they decay with distance.

# plotting graph
plt.plot(data, values, marker="o", label="100-qubit GHZ state")
plt.xlabel("Distance between qubits $i$")
plt.ylabel(r"$\langle Z_i Z_0 \rangle / \langle Z_1 Z_0 \rangle $")
plt.legend()
plt.show()

Output of the previous code cell

Plot sebelumnya menunjukkan bahwa saat jarak antara qubit meningkat, sinyal melemah karena adanya noise.

Langkah selanjutnya​

Rekomendasi