1. Ana sayfa
  2. İçerik planı
  3. Runtime yürütmesi · Qiskit
Qiskit · devre yürütme

Runtime yürütmesi — primitives, PUB ve hedef-bağımsız hesap

Qiskit Runtime; backend.run(...)'un üstüne kurulmuş, "devreyi gönder, sayım gel" boyutunu aşan yeni bir yürütme katmanıdır. Tek bir devre koşmak yerine, primitives denilen yardımcılar (Sampler, Estimator) algoritmanın istediği çıktının kendisini hedefler: ölçüm dağılımı, beklenen değer, varyans. Çağrı arayüzü PUB (Primitive Unified Bloc) hâline gelmiştir; aynı kod yerel Aer'de, FakeBackend'de, bir Session içinde veya gerçek IBM donanımında değişmeden çalışır. Bu sayfa primitives'i kavramsal olarak anlatır, PUB biçimini açar, mode parametresi üzerinden bağlam seçimini gösterir, hata azaltma ve opsiyon yüzeyine değinir; tüm çalışan örnekler yereldir (hesap/token gerektirmez).

  • Primitives: Sampler · Estimator
  • Çağrı: PUB · run([(qc, obs, params)])
  • Yerel: FakeBackend · Aer · mode=backend

Primitives nedir, ne çözer?

Primitives, Qiskit'in algoritma yazarına sunduğu üst düzey yürütme arayüzleridir. Geleneksel backend.run(...) dünyasında kullanıcı; transpile, shot, ölçüm okuma ve istatistik adımlarını elle koreografi ederdi. Primitives bunu tek soruda toplar: "bana ölçüm dağılımı ver" (Sampler) ve "bana beklenen değer ver" (Estimator). Algoritma kodu, hedefin simülatör veya gerçek donanım olduğundan habersiz yazılabilir; primitives seçilen modda işi yürütür, sonucu döndürür.

Neden ayrı bir katman?

Bir devreyi koşmanın "doğru yolu" bağlama göre değişir: yerel simülatör için shot bile gereksizken, gerçek donanımda hata azaltma ve okuma düzeltmesi kritik olabilir. Bu kararları algoritma sayfasından koparmak için primitives bir sözleşme arayüzü sunar; alt katmanın detayını saklar ve algoritmanın yalnızca çıktı talebine odaklanmasını sağlar.

Bu sayfanın sınırı

Bu sayfa primitives'in çekirdek kullanımına odaklanır; oturum disiplinleri session mantığı sayfasında, asenkron tutamağı job sistemi sayfasında derinleştirildi. Burada amaç Sampler ve Estimator'ın davranışını ve PUB biçimini netleştirmektir.

Tek cümle Primitives, "devreyi al ve çalıştır" yerine "şu algoritmik çıktıyı üret" diyen üst düzey arayüzdür; alt katman ayrıntısını saklar.

V1'den V2'ye: PUB tabanlı çağrı

Eski V1 primitives'inde her çağrı belirli pozisyonel argümanlarla yapılırdı (sampler.run(circuits, parameter_values=...)). V2 tarafında çağrılar PUB birimleri üzerinden ifade edilir: Sampler için bir PUB tipik olarak (circuit, parameter_values?, shots?); Estimator için (circuit, observables, parameter_values?) dizisidir. Tek bir çağrıda farklı yapıdaki PUB'lar bir liste hâlinde verilebilir; karşılığında her PUB için ayrı bir sonuç döner. Bu tasarım, hem batch hem tek çağrı kalıbını tek arayüzde toplar.

Aynı kod, farklı hedef

SamplerV2 ve EstimatorV2 mode parametresiyle kurulur (aşağıda detay). PUB biçimi mode'dan bağımsız aynı kalır; yani algoritmik kod yerelden buluta taşınırken yeniden yazılmaz, yalnızca ortam parametresi değişir. Bu da Qiskit Runtime'ın temel vaadidir.

Doğrudan import ipucu

Yereldeki örnekler için qiskit_ibm_runtime paketindeki sınıfları yerel FakeBackend veya Aer ile birlikte kullanmak yeterlidir; gerçek servise (QiskitRuntimeService) ihtiyaç yoktur.

Sampler ile ölçüm dağılımı

Sampler, klasik ölçüm sonucu içeren bir devreyi alır ve karşılığında bit dizgi dağılımı verir. V2 sonuç yapısı, her PUB için bir öğe içeren bir liste döndürür; her öğenin .data alanı, devredeki klasik kayıtların adıyla erişilebilen alt nesnelere sahiptir (örneğin result[0].data.c.get_counts() ya da result[0].data.meas.get_counts()). Sampler, ölçümlü devre tasarımının doğal sonuca taşıyıcısıdır.

Klasik kayıt adının önemi

qc.measure_all() klasik kayıt adını meas yapar; qc.measure([0, 1], [0, 1]) ise varsayılan c adıyla bir kayıt oluşturur. Sampler sonucundan veri çekerken bu adın doğru bilinmesi gerekir; kod boyunca tutarlı kullanmak okunabilirliği artırır.

Shot ve bütçe

sampler.run([(qc,)], shots=...) ile shot sayısı çağrı başına verilebilir. Yerelde shot ölçeği doğrudan süreye yansır; shot mantığı sayfası bu seçimin istatistik tarafını derinleştirir.

Estimator ile beklenen değer

Estimator, devre + gözlemlenebilir (observable) çiftini alır ve doğrudan ⟨ψ|O|ψ⟩ değerini hesaplar. Algoritma yazarı, bit dizgi sayımlarını elle Pauli beklentilerine çevirmekten kurtulur; gözlemlenebilir bir SparsePauliOp veya PauliList olarak ifade edilir. Bu, VQE / QAOA gibi varyasyonel algoritmaların doğal arayüzüdür.

Ölçüm yok, gözlemlenebilir var

Estimator için devre ölçümsüz verilir; ölçüm tabanını gözlemlenebilir belirler. Bu, "aynı devreyi farklı operatörler için farklı bazlarda okuyabilirim" disiplinine doğrudan eşler.

SparsePauliOp ile ifade

SparsePauliOp.from_list([("ZZ", 1.0), ("XX", -0.5)]) gibi bir ifade, 2 qubit'lik bir Hamiltoniyen'i kısa formda verir. Estimator, bu operatör için ortalama değeri tek çağrıda döndürür; iterasyonel optimizatörler bu sayıyı doğrudan kayıp/değer fonksiyonu olarak kullanır.

Mode parametresi: backend, session, batch

Primitives nesnesi kurulurken alınan mode argümanı üç farklı bağlam üretir: doğrudan bir backend verilirse çağrılar ad-hoc yapılır, bir Session verilirse aynı oturum içinde paketlenir, bir Batch verilirse art arda gönderim tek pakette gruplanır. Algoritmik kod aynı kalır; mod seçimi kuyruk ve maliyet açısından farklı sonuçlar üretir. Karar disiplinini session mantığı ve kuyruk mantığı sayfaları ile birleşik okumak gerekir.

Yerel mod: backend = FakeBackend / Aer

Yerelde primitives, doğrudan bir FakeBackend veya Aer örneğini mode olarak alır. Bu, ağa çıkmadan tüm akışı denemenizi mümkün kılar. Aer simülatörü ve fake backend sayfaları bu hedeflerin niteliklerini tartışır.

Hibrit kullanım

Bir session içinde batch işler dönmek mümkündür: optimizatör her iterasyonda bir batch paketi gönderir, sonuçlar session'a düşer. Bu hibrit kalıp, üretim akışlarının normal örüntüsüdür; algoritma sayfası bu kararı bilmek zorunda değildir.

Seçenekler ve hata azaltma çengelleri

Primitives kurulumunda options alanı, optimizasyon düzeyi, dynamical decoupling, ölçüm hata düzeltmesi, twirling ve zero-noise extrapolation gibi pek çok hata azaltma ayarına çengel sağlar. Bu seçenekler bağlamdan bağlama anlamlıdır: ideal Aer'da çoğunlukla gereksizdir; FakeBackend'in gürültü modelinde etkisini görmeye başlarsınız; gerçek donanımda raporlanan rakamları belirgin biçimde değiştirebilir.

Yerelde gözlemlenebilirlik

Yerel hedeflerde bile seçeneklerin etkisini ölçmek mantıklıdır: aynı PUB'ı seçeneksiz ve seçenekli kurup karşılaştırmak, hata azaltma adımlarının nasıl davrandığını anlamanın kolay yoludur. Hata azaltma fikri sayfası, kuramsal arka planı sağlar.

Sürüm dikkati

Seçenek isimleri ve varsayılanları sürüme göre değişebilir; üretim koduna geçerken doğrudan resmi belgeye bakmak ve doğrulanmış bir varsayılan listesi tutmak iyi bir alışkanlıktır.

Result yapısı ve çoklu PUB

V2 result yapısı, çağrıya verilen PUB listesiyle birebir hizalı bir liste döndürür. Sampler için her öğe .data ile ölçüm verisine, Estimator için .data.evs (expectation values) ve .data.stds (standart sapmalar) alanlarına erişim verir. Bu sözleşme; tek devre, çok devre, çok parametre ve çok observable senaryolarını aynı kabuk altında düşünmeyi mümkün kılar.

Çoklu PUB tek çağrı

Aynı kuyruğa yapılacak ardışık gönderimleri tek çağrıda göndermek (her biri ayrı PUB), kuyruk maliyetini büyük ölçüde düşürür. Bu yaklaşım kuyruk mantığı sayfasında ele alınan "az ve büyük gönderim" disiplinini destekler.

Endian, klasik kayıt adı

Sampler verisini okurken devredeki klasik kayıt adını ve Qiskit'in endian (sağdan-sola) okuma sözleşmesini hatırlamak gerekir; raporda farklı bir kütüphane ile karşılaştırma yapacaksanız endian'ı açıkça yazın.

backend.run'dan primitives'e geçiş

backend.run(...) hâlâ yaşıyor ve eğitim için son derece uygun; ancak üretimde primitives, hem hedef-bağımsızlık hem hata azaltma çengelleri açısından kazanç sağlar. Geçişin pratik adımları: (1) algoritmanın "ne istediğini" netleştirin — dağılım mı, beklenen değer mi? (2) çağrıyı PUB hâline getirin. (3) primitives nesnesini ortam mode'una göre kurun. (4) sonuç okuma kodunu V2'nin .data alanlarına uyarlayın.

Geriye dönük uyum

backend.run(...).result().get_counts() kalıbı kısa devre ve hızlı prototip için hâlâ değerlidir; primitives ile yarışmaz, onun altında çalışan farklı bir patikadır. Aynı projede iki yolu birlikte kullanmak iyi düşünülmüş tasarım için doğaldır.

Test stratejisi

Aynı algoritmayı önce ideal Aer'da, sonra gürültülü FakeBackend'de, sonra (varsa) gerçek donanımda koşturmak; primitives'in bağlam-değiştirme vaadinin sınanmasıdır. Bu üç adımı bir test akışı olarak otomatikleştirmek üretim disiplinine yakışır.

Pratik kural "Ne istiyorum?" sorusunu önce sorun: dağılım → Sampler, beklenen değer → Estimator. PUB biçimini disiplinli yazın, mod parametresini ortamı tanımlayan tek nokta yapın.

Kod laboratuvarı

Üç blok da tamamen yereldir: ağ yok, IBM hesabı yok. Birinci blok SamplerV2'yi FakeBackend üzerinde PUB ile gösterir; ikinci blok EstimatorV2 ile beklenen değer hesabını paylaşır; üçüncü blok tek çağrıda çoklu PUB göndererek iki farklı parametre setini batch gibi paketler.

Referans iskelet — çalıştırmayın Aşağıdaki kalıp IBM Quantum hesabı ve token gerektirir; statik sayfada çalıştırmanız önerilmez. Yalnızca akışı hatırlatmak içindir.
# from qiskit_ibm_runtime import QiskitRuntimeService, Session, SamplerV2, EstimatorV2
# service  = QiskitRuntimeService()
# backend  = service.least_busy(simulator=False, operational=True)
# with Session(backend=backend) as session:
#     sampler   = SamplerV2(mode=session)
#     estimator = EstimatorV2(mode=session)
#     dist  = sampler.run([(qc_meas,)]).result()
#     evs   = estimator.run([(qc_state, observable)]).result()
samplerv2_local.py Python
from qiskit import QuantumCircuit
from qiskit_ibm_runtime import SamplerV2 as Sampler
from qiskit_ibm_runtime.fake_provider import FakeManilaV2

qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()                        # klasik kayıt adı: 'meas'

backend = FakeManilaV2()
sampler = Sampler(mode=backend)

# PUB: (circuit,) yeterli; PUB tek elemanlıdır.
job = sampler.run([(qc,)], shots=1024)
result = job.result()

# Result yapısı: her PUB için bir öğe; .data altında klasik kayıt adı
counts = result[0].data.meas.get_counts()
print("counts:", counts)
qiskit-runtime SamplerV2 · PUB tek elemanlı · result[0].data.meas UTF-8 · LF
estimatorv2_local.py Python
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit_ibm_runtime import EstimatorV2 as Estimator
from qiskit_ibm_runtime.fake_provider import FakeManilaV2

# Estimator için devre ölçümsüz verilir
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)

H = SparsePauliOp.from_list([("ZZ", 1.0), ("XX", -0.5)])

backend = FakeManilaV2()
estimator = Estimator(mode=backend)

# PUB: (circuit, observable[, params])
job = estimator.run([(qc, H)])
result = job.result()

print("<ψ|H|ψ> =", float(result[0].data.evs))
if hasattr(result[0].data, "stds"):
    print("std       =", float(result[0].data.stds))
qiskit-runtime EstimatorV2 · SparsePauliOp ile beklenen değer UTF-8 · LF
multi_pub_parameter_sweep.py Python
import numpy as np
from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from qiskit.quantum_info import SparsePauliOp
from qiskit_ibm_runtime import EstimatorV2 as Estimator
from qiskit_ibm_runtime.fake_provider import FakeManilaV2

theta = Parameter("theta")
qc = QuantumCircuit(2)
qc.h(0)
qc.rz(theta, 0)
qc.cx(0, 1)

H = SparsePauliOp.from_list([("ZZ", 1.0)])

backend = FakeManilaV2()
estimator = Estimator(mode=backend)

# Çoklu PUB tek çağrı: her PUB ayrı parametre vektörü
pubs = [
    (qc, H, [0.0]),
    (qc, H, [np.pi / 2]),
    (qc, H, [np.pi]),
]
result = estimator.run(pubs).result()

for (_, _, params), out in zip(pubs, result):
    print(f"theta={params[0]:5.2f}  ⟨ZZ⟩={float(out.data.evs):+.3f}")
qiskit-runtime Tek çağrı · çok PUB · parametre taraması UTF-8 · LF

İleri okuma ve özet

Runtime yürütmesi, "devreyi koş ve sayım al"dan "algoritmanın istediği çıktıyı üret"e geçen üst düzey katmandır. Sampler dağılım, Estimator beklenen değer verir; çağrı PUB biçimindedir; mode parametresi yerel, session, batch arasında geçişi tek noktada tutar. Yerelde aynı kodu kurarak buluta sorunsuz taşınırsınız.

Özet Sampler ↔ dağılım, Estimator ↔ beklenen değer. PUB tek arayüz, mode tek geçiş noktası. Çoklu PUB tek çağrı = kuyruk maliyetinde tasarruf. Yerel hedeflerle aynı kodu doğrulamak, üretime risksiz taşınmanın yoludur.