Deploy dan jalankan template Qiskit Function untuk dinamika Hamiltonian AQC + Trotter
Ikhtisar
Ini adalah template Qiskit Function yang tidak spesifik terhadap eksperimen tertentu untuk dinamika Hamiltonian. Diberikan Hamiltonian Pauli tetangga terdekat 1D, keadaan awal yang telah disiapkan (opsional), dan sekumpulan observable, template ini menjalankan evolusi waktu Trotter, kompresi sirkuit approximate quantum compilation (AQC), dan eksekusi yang dimitigasi, lalu mengembalikan deret waktu setiap observable. Tukar setup (PRE) dan analisis (POST) dan inti yang sama akan menghasilkan eksperimen yang berbeda:
| PRE (setupmu) | FUNCTION (dideploy di sini) | POST (analisismu) |
|---|---|---|
| Siapkan keadaan, sebagai sirkuit atau product state, dengan kick lokal opsional | Sintesis Trotter → kompresi AQC → eksekusi pada statevector, fake, atau runtime, mengembalikan | untuk hamburan neutron, atau magnetisasi, transport, quench dynamics, dan sebagainya |
Template ini dipublikasikan di repositori template Qiskit Function, bersama template aplikasi lainnya. Notebook ini mendeploy-nya ke akun Qiskit Serverless-mu sendiri. Jalankan sekali, dan notebook mana pun kemudian bisa memanggil fungsi ini dengan serverless.load("aqc-dynamics-function").
Untuk contoh ilmiah yang dikerjakan secara lengkap, lihat Simulate neutron scattering with an AQC + Trotter dynamics Serverless workflow, yang memanggil fungsi ini untuk menghitung faktor struktur dinamis KCuF. Notebook ini membahas deployment dan kontrak input sebagai gantinya.
Persyaratan
Sebelum memulai, pastikan kamu memiliki hal-hal berikut di lingkungan kernel notebook ini:
-
Qiskit SDK v2.0 atau lebih baru (
pip install qiskit). -
Klien Qiskit IBM Catalog (
pip install qiskit-ibm-catalog), yang mendeploy dan menjalankan workload pada Qiskit Serverless.
Dependensi ilmiah milik fungsi itu sendiri (qiskit-addon-aqc-tensor, cotengrust, qiskit-aer) tidak perlu diinstal secara lokal.
Dapatkan file sumber template
Fungsi ini adalah paket Python kecil yang dijalankan Qiskit Serverless di cloud, sehingga sumbernya harus ada sebagai file lokal yang diunggah saat waktu deploy. Paket ini dipublikasikan di repositori template Qiskit Function.
Unduh source_files
Unduhan ini berupa satu file zip tunggal, dinamai sesuai jalur lengkap direktori di repositori:
qiskit-community qiskit-function-templates main physics aqc_trotter source_files.zip
-
Ekstrak (unzip) ke direktori yang menyimpan notebook ini.
-
Ganti nama folder yang diekstrak dari nama panjang tersebut menjadi
source_files.
Direktori kerjamu kemudian akan terlihat seperti ini:
your-working-directory/
├── function-template-aqc-trotter.ipynb <- this notebook
└── source_files/ <- the renamed folder
├── __init__.py
├── program.py
└── source/
├── __init__.py
├── _serverless.py
├── app_function.py
├── aqc.py
├── build.py
├── execute.py
└── hamiltonian.py
Namanya harus persis source_files, karena itulah working_dir yang diunggah oleh Langkah 3.
program.py adalah entry point yang dipanggil oleh gateway. Semua yang ada di bawah source/ adalah implementasi, dipecah berdasarkan tahap: sintesis Hamiltonian dan Trotter, kompresi AQC, dan eksekusi. Tidak ada yang perlu diedit untuk menjalankan contoh-contoh berikut. Langkah 3 mengunggah seluruh direktori, jadi ulangi langkah tersebut setiap kali kamu mengubah sebuah file.
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-catalog
1. Autentikasi
Gunakan qiskit-ibm-catalog untuk mengautentikasi ke QiskitServerless dengan API key (token) dan CRN (instance) milikmu, yang bisa kamu temukan di dashboard IBM Quantum® Platform. Dengan kredensial ini kamu bisa membuat instance klien serverless secara lokal untuk mengunggah atau menjalankan fungsi yang dipilih:
from qiskit_ibm_catalog import QiskitServerless
serverless = QiskitServerless(channel="ibm_quantum_platform", token="MY_TOKEN", instance="MY_CRN")
Kamu juga bisa secara opsional menggunakan save_account() untuk menyimpan kredensialmu di lingkungan lokalmu (lihat panduan Set up your IBM Cloud® account). Perhatikan bahwa ini menulis kredensialmu ke file yang sama dengan QiskitRuntimeService.save_account():
QiskitServerless.save_account(channel="ibm_quantum_platform", token="MY_TOKEN", instance="MY_CRN")
Jika akun sudah disimpan, tidak perlu memberikan token untuk mengautentikasi:
from qiskit_ibm_catalog import QiskitServerless
# Authenticate to the remote cluster
# In this case, loading a saved account
serverless = QiskitServerless()
# REPLACE WITH YOUR OWN CREDENTIALS or SAVED ACCOUNT
# serverless = QiskitServerless(channel="ibm_quantum_platform", token="MY_TOKEN", instance="MY_CRN")
2. Deklarasikan dependensi
Paket-paket yang dibutuhkan fungsi ini di luar image dasar serverless yang dikelola.
Gateway hanya menginstal nama yang ada di daftar izinnya (requirements-dynamic-dependencies.txt), dicocokkan berdasarkan nama paket dan dipin ke versi yang diizinkan dengan ==. Hal lainnya harus datang secara transitif (sebagai dependensi dari paket yang ada di daftar izin). Sintaks [extras] didukung: qiskit-addon-aqc-tensor[quimb-jax] adalah yang menginstal quimb dan jax. cotengrust diperlukan untuk efisiensi memori selama simulasi tensor network. qiskit-aer dicantumkan secara terpisah untuk backend fake (simulasi noisy lokal).
DEPENDENCIES = [
"qiskit-addon-aqc-tensor[quimb-jax]==0.3.1",
"qiskit-aer==0.17.2",
"cotengrust==0.2.0",
]
3. Definisikan dan unggah fungsi
from qiskit_ibm_catalog import QiskitFunction
fn = QiskitFunction(
title="aqc-dynamics-function",
entrypoint="program.py",
working_dir="source_files/",
dependencies=DEPENDENCIES,
)
serverless.upload(fn)
QiskitFunction(aqc-dynamics-function)
4. Verifikasi bahwa fungsi terdaftar
next(p for p in serverless.list() if p.title == "aqc-dynamics-function")
QiskitFunction(aqc-dynamics-function)
Referensi fungsi
Ini adalah pengantar singkat. Setiap field didokumentasikan secara lengkap di AQC Dynamics Template README: tabel input lengkap dengan aturan validasinya, field output, backend eksekusi, dan contoh-contoh lebih lanjut yang dikerjakan. Berikut ini adalah versi singkatnya, cukup untuk membaca contoh-contoh berikut.
Input
Setiap run adalah satu panggilan fn.run(...) tunggal. Hanya tiga input pertama dalam tabel yang wajib: hamiltonian, t_steps, dan aqc_segments. Semua yang ada setelahnya bersifat opsional dan kembali ke default yang ditampilkan, sehingga panggilan minimal adalah tiga argumen dan sisa tabel adalah fungsionalitas yang bisa kamu pilih untuk digunakan. num_qubits dari Hamiltonian menentukan panjang chain, sehingga tidak ada input ukuran terpisah.
| Input | Default | Deskripsi |
|---|---|---|
hamiltonian | wajib | Hamiltonian Pauli tetangga terdekat 1D sebagai SparsePauliOp. String adalah operator Pauli, sehingga tidak ada faktor setengah implisit. |
t_steps | wajib | Total langkah Trotter. Berevolusi hingga T = t_steps * dt dan melaporkan setiap observable pada setiap t_k = k * dt. |
aqc_segments | wajib | Rencana kompresi: daftar {"n_steps": k, "ansatz_steps": m}. sum(n_steps) langkah dikompresi; sisanya berjalan sebagai Trotter biasa. |
dt | 0.2 | Waktu fisik yang dimajukan oleh satu langkah Trotter. |
initial_state | |0...0> | QuantumCircuit yang disiapkan untuk dievolusikan. Sertakan kick lokal apa pun ke dalam sirkuit ini. |
observables | Z per situs | Apa pun yang diterima EstimatorV2 sebagai argumen observables-nya. Satu observable per kolom output. |
trotter_options | Suzuki orde ke-2 | {"method": ..., "synthesis_settings": {...}}. reps dan time dimiliki oleh fungsi ini. |
aqc_options | lihat deskripsi | max_bond (32), cutoff (1e-8), autodiff_backend ("jax"), fidelity_target (None), optimizer_settings (L-BFGS-B, jac=True, maxiter=300). |
estimator_options | DD, twirling, TREX | EstimatorV2.options, diteruskan apa adanya. Dictionary yang diberikan mengganti default secara keseluruhan alih-alih digabung ke dalamnya. |
transpiler_options | {"optimization_level": 3} | Argumen keyword generate_preset_pass_manager. backend dan target ditolak, karena jalur eksekusi memilikinya. |
backend | "runtime" | "statevector", "fake", atau "runtime". |
backend_name | paling tidak sibuk | Nama backend IBM® untuk runtime, atau fake backend bernama. |
batches | 1 | Pisahkan sirkuit ke N runtime job. Satu batch mengirimkan satu job tunggal dan tidak membuat session. |
parallel_sim | False | Sebarkan jalur simulator lokal ke semua core yang tersedia dengan Ray. Tidak berpengaruh pada runtime. |
return_circuits | False | Kembalikan sirkuit logis AQC + Trotter dalam hasil bersama deret observable. |
Backend eksekusi
Ketiga jalur ini berbagi kode yang sama dan pengaturan mitigasi yang sama. Perbedaannya hanya di mana sirkuit dijalankan.
backend | Apa itu | Kredensial | Catatan |
|---|---|---|---|
"statevector" | StatevectorEstimator eksak | Hanya akun Serverless | Jalur referensi eksak. Tidak ada waktu QPU. |
"fake" | Simulasi lokal noisy pada fake backend Qiskit | Hanya akun Serverless | Latihan yang setia dari jalur runtime yang dimitigasi. Membutuhkan qiskit-aer. Default ke fake_sherbrooke 127-qubit. |
"runtime" (default) | EstimatorV2 yang dimitigasi terhadap QPU nyata | Akun Serverless dan instance dengan akses QPU | backend_name opsional; jika dihilangkan akan memilih perangkat paling tidak sibuk. |
Kedua jalur simulator tetap memanggil fungsi yang telah dideploy, sehingga mereka membutuhkan akun Serverless yang tersimpan meskipun mereka tidak menggunakan waktu QPU. Dua contoh berikut menjalankan workload yang sama pada statevector terlebih dahulu, lalu pada runtime.
Output
job.result() mengembalikan dictionary biasa:
{
"times": [...], # length t_steps + 1, t_k = k * dt (t=0 is the prepared state)
"expectation_values": [[...]], # shape (n_times, n_observables)
"observable_labels": [...], # for example: ["Z_0", "ZZ_0_1"]
"metadata": {
"n", "t_steps", "dt", "tier",
"aqc_compressed_steps": 5, # total compressed steps (= sum of segment n_steps)
"aqc_segments": [ # per segment: the plan plus its own results
{"n_steps": 3, "ansatz_steps": 1, "steps": [1, 2, 3], "n_params": 133,
"fidelities": {"1": ..., "2": ..., "3": ...}},
{"n_steps": 2, "ansatz_steps": 2, "steps": [4, 5], "n_params": 245,
"fidelities": {"4": ..., "5": ...}},
],
"execution_backend",
"aqc_fidelities": {"1": ..., "2": ...}, # flat per-step fidelity, all compressed steps
"circuit_stats": { # per-step 2q depth and gate count, full Trotter vs AQC
"1": {"full_trotter": {"depth_2q": ..., "num_2q_gates": ...},
"aqc_trotter": {"depth_2q": ..., "num_2q_gates": ...}},
"2": {...},
},
"warnings": [...], # non-fatal notices; for example, a cotengrust fallback
"resource_usage": { # per stage; QPU_TIME is the charged QPU time
"RUNNING: OPTIMIZING_FOR_HARDWARE": {"CPU_TIME": ...},
"RUNNING: WAITING_FOR_QPU": {"CPU_TIME": ...},
"RUNNING: EXECUTING_QPU": {"QPU_TIME": ...},
},
},
# present only when return_circuits=True
"circuits": [QuantumCircuit, ...], # one per evolved step; circuits[i] is at times[i + 1]
}
aqc_fidelities dan circuit_stats adalah dua yang perlu dibaca terlebih dahulu: bersama-sama mereka memberi tahu apakah kompresi tetap setia dan apakah benar-benar menghemat depth. Pada runtime, resource_usage melaporkan waktu tunggu antrean secara terpisah dari waktu QPU yang dikenakan biaya padamu. Input yang ditolak akan gagal dengan cepat sebagai ServerlessError terstruktur (kode 4615).
Contoh simulator
Jalankan fungsi ini pada backend statevector eksak terlebih dahulu. Ini tidak menghabiskan waktu QPU dan memvalidasi deployment secara menyeluruh. Model di sini adalah chain Ising transverse-field delapan-qubit, dan observables dihilangkan sehingga fungsi mengukur per situs default.
Rencana kompresi adalah input yang layak untuk dipahami. Setiap segmen {"n_steps": k, "ansatz_steps": m} mengompresi k langkah Trotter berurutan menjadi sebuah ansatz yang dibangun dari target Trotter m-langkah, dan langkah apa pun di luar sum(n_steps) berjalan sebagai Trotter biasa. Langkah-langkah awal dengan entanglement rendah terkompresi dengan baik menjadi ansatz satu-lapis yang dangkal; langkah-langkah selanjutnya yang keterjeratannya lebih tinggi membutuhkan ansatz yang lebih dalam.
from qiskit.quantum_info import SparsePauliOp
fn = serverless.load("aqc-dynamics-function")
n = 8
H = SparsePauliOp.from_sparse_list(
[("ZZ", [i, i + 1], 1.0) for i in range(n - 1)]
+ [("X", [i], 0.8) for i in range(n)],
num_qubits=n,
)
job = fn.run(
t_steps=8,
aqc_segments=[
{
"n_steps": 4,
"ansatz_steps": 1,
}, # early steps -> shallow 1-layer ansatz
{
"n_steps": 2,
"ansatz_steps": 2,
}, # later steps -> deeper 2-layer ansatz
],
hamiltonian=H,
aqc_options={"max_bond": 32},
backend="statevector",
)
print("job ID:", job.job_id)
job ID: ee1f3793-e995-427d-81d1-5924549beb38
Ikuti run dan baca hasilnya
status() melaporkan siklus hidup job secara garis besar sekaligus sub-status per tahap yang dipublikasikan fungsi saat berjalan. Tahapan yang sama berlaku untuk run hardware nanti di panduan ini:
QUEUED -> INITIALIZING -> RUNNING: OPTIMIZING_FOR_HARDWARE -> RUNNING: WAITING_FOR_QPU -> RUNNING: EXECUTING_QPU -> RUNNING: POST_PROCESSING -> DONE
Nilai status() | Tahap |
|---|---|
RUNNING: OPTIMIZING_FOR_HARDWARE | persiapan state, pembuatan Trotter, kompresi AQC |
RUNNING: WAITING_FOR_QPU | mengantre di QPU (hanya backend runtime) |
RUNNING: EXECUTING_QPU | sirkuit sedang dieksekusi (simulator lokal menandai ini secara langsung) |
RUNNING: POST_PROCESSING | merakit dictionary hasil |
Status akhir adalah DONE, ERROR, dan CANCELED. Run statevector ini tidak memiliki antrean QPU, sehingga melewati RUNNING: WAITING_FOR_QPU. Gunakan job.logs() kapan saja untuk melihat log per tahap, termasuk fidelity AQC yang dicapai pada setiap langkah.
print(job.status()) # re-run until this reports DONE
DONE
import numpy as np
result = job.result()
ev = np.array(result["expectation_values"])
print("observables:", result["observable_labels"])
print("shape:", ev.shape, "-> (n_times, n_observables)")
print("first row (t = 0, the prepared state):", np.round(ev[0], 4))
print("last row (t = t_steps * dt):", np.round(ev[-1], 4))
print(
"AQC fidelities:",
{k: round(v, 4) for k, v in result["metadata"]["aqc_fidelities"].items()},
)
# What the compression bought: 2-qubit depth at the final time step.
stats = result["metadata"]["circuit_stats"][
str(result["metadata"]["t_steps"])
]
print(
"2q depth at the final step:",
stats["full_trotter"]["depth_2q"],
"(full Trotter) ->",
stats["aqc_trotter"]["depth_2q"],
"(AQC + Trotter)",
)
observables: ['Z_0', 'Z_1', 'Z_2', 'Z_3', 'Z_4', 'Z_5', 'Z_6', 'Z_7']
shape: (9, 8) -> (n_times, n_observables)
first row (t = 0, the prepared state): [1. 1. 1. 1. 1. 1. 1. 1.]
last row (t = t_steps * dt): [0.1442 0.2956 0.4686 0.4877 0.4869 0.4686 0.2963 0.1441]
AQC fidelities: {'1': 1.0, '2': 1.0, '3': 1.0, '4': 1.0, '5': 1.0, '6': 0.9999}
2q depth at the final step: 210 (full Trotter) -> 79 (AQC + Trotter)
Contoh hardware
Panggilan fungsi dengan backend="runtime" mentranspilasi dan mengeksekusi pada prosesor IBM Quantum yang nyata, dengan mitigasi error bawaan fungsi: dynamical decoupling (XY4), gate twirling, dan twirled readout error extinction (TREX). backend_name memilih perangkat; jika dihilangkan, fungsi akan mengambil yang paling tidak sibuk.
Kode ilmiahnya sendiri tidak berubah sama sekali. Yang berbeda dari contoh simulator adalah panjang chain, jumlah langkah Trotter, rencana kompresi, backend, dan pengaturan mitigasi eksplisit yang dibahas di bagian berikut.
Menentukan ukuran job untuk hardware kontrol
estimator_options adalah input yang layak diatur secara sengaja. Gate twirling membangun num_randomizations sirkuit acak terpisah untuk setiap PUB, dan seluruh job, setiap PUB dengan semua randomization-nya, harus muat dalam memori instruksi sistem kontrol klasik QPU. Fungsi ini secara default menggunakan 1000 randomization, sehingga evolusi 10-langkah mengirimkan 11 PUB dengan masing-masing 1000 sirkuit: kira-kira 11.000 instance sirkuit dalam satu job tunggal.
Jika kapasitas yang bisa ditampung sistem kontrol terlampaui, job akan gagal dengan error 6073. Job limits memberikan ambang batas dan cara menghitungnya, yang utama adalah 26,8 juta instruksi sistem kontrol per qubit, diterapkan per job bukan per PUB. Dynamical decoupling menambahkan gate yang turut dihitung ke dalamnya.
Dua input mengontrol ukurannya:
-
estimator_optionsmengatur anggaran shot. Total shot adalahnum_randomizations * shots_per_randomization, jadi kamu bisa menukar randomization dengan shot per randomization, mempertahankan statistiknya, dan tetap mengecilkan programnya. Cell berikut menggunakan 100 randomization dengan 200 shot masing-masing, yaitu 20.000 shot per observable dan sekitar sepersepuluh dari instance sirkuit yang akan dikirim oleh default. Lihat TwirlingOptions dan Estimator options untuk kumpulan field lengkap. -
batchesmemisahkan PUB ke sejumlah runtime job terpisah, yang merupakan solusi yang disarankan oleh error 6073 itu sendiri dan mengapa framing per-job itu penting. Mengaturbatches=4mengirimkan kira-kira tiga PUB per job alih-alih sebelas sekaligus, dan job-job tersebut dikirim bersama dalam satu batch sehingga grup mengantre sekali alih-alih setiap job mengantre secara terpisah.
Ingat bahwa estimator_options yang diberikan mengganti default fungsi secara keseluruhan alih-alih digabung ke dalamnya, sehingga dynamical decoupling dan TREX dinyatakan ulang di cell berikut untuk membuatnya tetap aktif.
from qiskit.quantum_info import SparsePauliOp
fn = serverless.load("aqc-dynamics-function")
n = 10
H = SparsePauliOp.from_sparse_list(
[("ZZ", [i, i + 1], 1.0) for i in range(n - 1)]
+ [("X", [i], 0.8) for i in range(n)],
num_qubits=n,
)
job = fn.run(
t_steps=10,
aqc_segments=[
{
"n_steps": 3,
"ansatz_steps": 1,
}, # early steps -> shallow 1-layer ansatz
{
"n_steps": 3,
"ansatz_steps": 2,
}, # later steps -> deeper 2-layer ansatz
],
hamiltonian=H,
aqc_options={"max_bond": 32},
backend="runtime",
backend_name="ibm_marrakesh",
# The function defaults to 1000 twirling randomizations, which was too large
# for this device. Total shots is num_randomizations *
# shots_per_randomization, so this is 20,000 shots per observable.
estimator_options={
"dynamical_decoupling": {"enable": True, "sequence_type": "XY4"},
"twirling": {
"enable_gates": True,
"num_randomizations": 100,
"shots_per_randomization": 200,
},
"resilience": {"measure_mitigation": True},
},
)
print("job ID (save this to reconnect later):", job.job_id)
job ID (save this to reconnect later): 7229a8bf-9f83-4785-8dd4-489844abc2d9
Run hardware tidak cepat, dan sebagian besar waktunya bersifat klasik alih-alih di QPU. Kompresi AQC berjalan di dalam fungsi sebelum apa pun mencapai QPU, dan antrean QPU berada di atas itu. Kamu tidak perlu menjaga notebook atau kernel ini tetap terbuka selama ia berjalan.
Salin ID job yang dicetak oleh cell sebelumnya dan simpan. Tiga cell berikutnya memungkinkanmu untuk melanjutkan run tersebut nanti:
-
Sambung kembali, hanya dibutuhkan di sesi kernel baru: jalankan ulang cell Authentication untuk membuat ulang
serverless, lalu bangun ulang handlejobdari ID yang kamu simpan. Lewati cell ini jika kamu masih berada di sesi tempat kamu mengirimkan job, karena handle-nya sudah aktif. -
Periksa status: jalankan ulang hingga melaporkan
DONE. -
Ambil hasilnya: jalankan hanya setelah status-nya
DONE.
Ganti placeholder pada cell sambung kembali berikut dengan ID yang kamu simpan.
# Reconnect to a previously submitted job by its ID. Only needed in a NEW kernel
# session; if you are still in the session where you submitted, the `job` handle
# from the preceding cell is already live, so skip this cell. Replace the ID that follows with your own.
job = serverless.get_job_by_id("<your job ID>")
# Re-run this until it reports DONE, then fetch the result in the following cell.
print(job.status())
DONE
import numpy as np
# Run this only once the preceding status cell reports DONE. result() blocks until
# the job finishes, so calling it earlier just waits.
result = job.result()
ev = np.array(result["expectation_values"])
print("backend:", result["metadata"]["execution_backend"])
print("shape:", ev.shape, "-> (n_times, n_observables)")
print("last row (t = t_steps * dt):", np.round(ev[-1], 4))
print(
"AQC fidelities:",
{k: round(v, 4) for k, v in result["metadata"]["aqc_fidelities"].items()},
)
# What the compression bought: 2-qubit depth at the final time step.
stats = result["metadata"]["circuit_stats"][
str(result["metadata"]["t_steps"])
]
print(
"2q depth at the final step:",
stats["full_trotter"]["depth_2q"],
"(full Trotter) ->",
stats["aqc_trotter"]["depth_2q"],
"(AQC + Trotter)",
)
backend: runtime
shape: (11, 10) -> (n_times, n_observables)
last row (t = t_steps * dt): [0.1504 0.1361 0.218 0.2144 0.2275 0.1783 0.1749 0.1599 0.0915 0.0922]
AQC fidelities: {'1': 1.0, '2': 1.0, '3': 1.0, '4': 1.0, '5': 0.9999, '6': 0.9999}
2q depth at the final step: 342 (full Trotter) -> 171 (AQC + Trotter)
Langkah selanjutnya
-
Kerjakan Simulate neutron scattering with an AQC + Trotter dynamics Serverless workflow, contoh pendamping yang memanggil fungsi yang telah dideploy ini untuk menghitung faktor struktur dinamis KCuF.
-
Baca AQC Dynamics Template on GitHub untuk kontrak input dan output yang lengkap, contoh lebih lanjut, dan detail sitasi.
-
Jelajahi repositori template Qiskit Function untuk template aplikasi lainnya yang dibangun dengan cara yang sama.
-
Baca panduan Qiskit Serverless untuk mengelola fungsi yang telah dideploy.
-
Pelajari lebih dalam tentang tahap kompresi AQC dengan dokumentasi Qiskit addon: AQC-Tensor.