Úvod do primitiv
Verze balíčků
Kód na této stránce byl vyvinut pomocí následujících požadavků. Doporučujeme používat tyto nebo novější verze.
qiskit[all]~=2.3.0
qiskit-ibm-runtime~=0.43.1
Je nyní dostupná beta verze nového modelu spouštění. Řízený model spouštění nabízí větší flexibilitu při přizpůsobování pracovního postupu pro zmírnění chyb. Více informací najdeš v průvodci Řízený model spouštění.
Proč Qiskit zavedl primitiva?
Podobně jako v počátcích klasických počítačů, kdy vývojáři museli přímo manipulovat s registry CPU, rané rozhraní pro QPU jednoduše vracelo surová data z řídicí elektroniky.
To nebyl velký problém, dokud QPU žily v laboratořích a přímý přístup byl umožněn pouze výzkumníkům.
Vzhledem k tomu, že většina vývojářů by neměla a nemusela být obeznámena s převodem těchto surových dat na 0 a 1, Qiskit zavedl backend.run jako první abstrakci pro přístup k QPU v cloudu. To umožnilo vývojářům pracovat s důvěrně známým datovým formátem a soustředit se na celkový obraz.
Jak se přístup k QPU stával rozšířenějším a s tím, jak bylo vyvíjeno stále více kvantových algoritmů,
opět se objevila potřeba abstrakce na vyšší úrovni. V reakci na to Qiskit zavedl
rozhraní primitiv, které je optimalizováno pro dva klíčové úkoly při vývoji kvantových algoritmů:
odhad střední hodnoty (Estimator) a vzorkování Circuit (Sampler). Cílem je opět
pomoci vývojářům více se soustředit na inovaci a méně na převod dat. Rozhraní primitiv nahrazuje rozhraní backend.run, protože Sampler poskytuje stejný přímý přístup k hardwaru, jaký nabízel backend.run.
Co je to primitivum?
Výpočetní systémy jsou postaveny na více vrstvách abstrakce. Abstrakce ti umožňují soustředit se na konkrétní úroveň detailu relevantní pro daný úkol. Čím blíže jsi k hardwaru, tím nižší úroveň abstrakce potřebuješ (například možná budeš muset přesouvat nebo manipulovat s daty na úrovni instrukcí CPU). Čím složitější úkol chceš provést, tím vyšší úroveň abstrakce bude potřeba (například bys mohl používat programovací knihovnu k provádění algebraických výpočtů).
V tomto kontextu je primitivum nejmenší zpracovatelská instrukce, nejjednodušší stavební kámen, ze kterého lze vytvořit něco užitečného pro danou úroveň abstrakce.
Nedávný pokrok v kvantových výpočtech zvýšil potřebu pracovat na vyšších úrovních abstrakce. Jak se oblast posouvá směrem k větším kvantovým zpracovatelským jednotkám (QPU) a složitějším pracovním postupům, přesouvá se zaměření od interakce s jednotlivými signály Qubit k pohledu na kvantová zařízení jako na systémy, které provádějí potřebné úkoly.
Dva nejčastější úkoly pro kvantové počítače jsou vzorkování kvantových stavů a výpočet středních hodnot. Tyto úkoly motivovaly návrh Qiskit primitiv: Estimator a Sampler.
- Estimator vypočítává střední hodnoty pozorovatelných veličin vzhledem ke stavům připraveným kvantovými Circuit.
- Sampler vzorkuje výstupní registr z provedení kvantového Circuit.
Stručně řečeno, výpočetní model zavedený Qiskit primitivy posouvá kvantové programování o krok blíže k tomu, kde se dnes nachází klasické programování, kde je zaměření méně na detaily hardwaru a více na výsledky, kterých se snažíš dosáhnout.
Definice a implementace primitiv
Existují dva typy Qiskit primitiv: základní třídy a jejich implementace. Qiskit primitiva jsou definována open-source základními třídami primitiv, které žijí v Qiskit SDK (v modulu qiskit.primitives). Poskytovatelé (jako je Qiskit Runtime) mohou tyto základní třídy použít k odvození vlastních implementací Sampler a Estimator. Většina uživatelů bude pracovat s implementacemi poskytovatelů, nikoli se základními primitivy.
Základní třídy
BaseEstimatorV2 a BaseSamplerV2 – Abstraktní základní třídy, které definují společné rozhraní pro implementaci primitiv. Všechny ostatní třídy v modulu qiskit.primitives dědí z těchto základních tříd. Vývojáři by je měli použít, pokud mají zájem o vytvoření vlastního modelu spouštění založeného na primitivech pro konkrétního poskytovatele. Tyto třídy mohou být také užitečné pro ty, kteří chtějí provádět vysoce přizpůsobené zpracování a zjistí, že stávající implementace primitiv jsou pro jejich potřeby příliš jednoduché. Běžní uživatelé základní třídy přímo používat nebudou.
Implementace
Toto jsou implementace základních tříd primitiv:
-
Primitiva Qiskit Runtime (
EstimatorV2aSamplerV2) poskytují sofistikovanější implementaci (například zahrnují zmírnění chyb) jako cloudovou službu. Tato implementace základních primitiv se používá pro přístup k hardwaru IBM Quantum®. Jsou dostupná prostřednictvím IBM Qiskit Runtime. -
StatevectorEstimatoraStatevectorSampler– Referenční implementace primitiv, které používají simulátor zabudovaný do Qiskitu. Jsou postaveny s modulem Qiskitquantum_infoa produkují výsledky na základě ideálních simulací stavového vektoru. Jsou dostupné prostřednictvím Qiskitu. -
BackendEstimatorV2aBackendSamplerV2– Tyto třídy lze použít k "zabalení" libovolného kvantového výpočetního zdroje do primitivu. To ti umožňuje psát kód ve stylu primitiv pro poskytovatele, kteří ještě nemají rozhraní založené na primitivech. Tyto třídy lze používat stejně jako běžný Sampler a Estimator, jen by měly být inicializovány s dodatečným argumentembackendpro výběr, na kterém kvantovém počítači spustit výpočet. Jsou dostupné prostřednictvím Qiskitu.
Výhody Qiskit primitiv
S primitivy mohou uživatelé Qiskitu psát kvantový kód pro konkrétní QPU, aniž by museli explicitně
spravovat každý detail. Také díky dodatečné vrstvě abstrakce by ti mohlo být snadnější
přistupovat k pokročilým hardwarovým schopnostem daného poskytovatele. Například s primitivy Qiskit Runtime
můžeš využít nejnovější pokroky v zmírňování a potlačování chyb přepínáním možností jako je resilience_level primitivu, namísto budování vlastní implementace těchto technik.
Pro poskytovatele hardwaru znamená nativní implementace primitiv, že svým uživatelům můžeš poskytnout přístup k funkcím hardwaru "hned po vybalení", jako jsou pokročilé techniky post-processingu. Pro tvé uživatele je tak snazší využívat nejlepší schopnosti tvého hardwaru.
Podrobnosti o primitivech
Jak bylo popsáno dříve, všechna primitiva jsou vytvořena ze základních tříd; proto mají stejnou obecnou strukturu a použití. Například formát vstupu pro všechna primitiva Estimator je stejný. Existují však rozdíly v implementacích, které je odlišují.
Protože většina uživatelů přistupuje k primitivům Qiskit Runtime, příklady ve zbytku této sekce jsou založeny na primitivech Qiskit Runtime.
Estimator
Primitivum Estimator vypočítává střední hodnoty jedné nebo více pozorovatelných veličin vzhledem ke stavům připraveným kvantovými Circuit. Circuit mohou být parametrizované, pokud jsou hodnoty parametrů také poskytnuty jako vstup primitivu.
Vstupem je pole PUB. Každý PUB má formát:
(<jeden circuit>, <jedna nebo více pozorovatelných veličin>, <volitelné hodnoty parametrů>, <volitelná přesnost>),
kde volitelné hodnoty parametrů mohou být seznam nebo jeden parametr. Různé implementace Estimator podporují různé možnosti konfigurace. Pokud vstup obsahuje měření, jsou ignorována.
Výstupem je PubResult, který obsahuje vypočítané střední hodnoty pro každý pár a jejich standardní chyby ve formě PubResult. Každý PubResult obsahuje data i metadata.
Estimator kombinuje prvky pozorovatelných veličin a hodnot parametrů podle pravidel broadcastingu NumPy, jak je popsáno v tématu Vstupy a výstupy primitiv.
Příklad:
# Added by doQumentation — required packages for this notebook
!pip install -q numpy qiskit qiskit-ibm-runtime
# This cell is hidden from users, it creates the circuits and observables to run
from qiskit_ibm_runtime import EstimatorV2, SamplerV2, QiskitRuntimeService
from qiskit.circuit.random import random_circuit
from qiskit.circuit import Parameter
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
import numpy as np
service = QiskitRuntimeService()
backend = service.least_busy()
phi = Parameter("phi")
circuit1 = random_circuit(10, 5, seed=12345)
circuit1.rzz(phi, 1, 2)
observable1 = SparsePauliOp.from_sparse_list(
[("ZXYZ", [1, 2, 3, 4], 1)], num_qubits=10
)
param_values1 = np.random.uniform(size=5).T
circuit2 = random_circuit(10, 5, seed=12345)
circuit2.rzz(phi, 1, 2)
observable2 = SparsePauliOp.from_sparse_list(
[("XZYX", [1, 2, 3, 4], 1)], num_qubits=10
)
param_values2 = np.random.uniform(size=5).T
shots1 = 164
shots2 = 1024
pm = generate_preset_pass_manager(optimization_level=1, backend=backend)
circuit1 = pm.run(circuit1)
circuit2 = pm.run(circuit2)
observable1 = observable1.apply_layout(circuit1.layout)
observable2 = observable2.apply_layout(circuit2.layout)
estimator = EstimatorV2(mode=backend)
estimator_job = estimator.run(
[
(circuit1, observable1, param_values1),
(circuit2, observable2, param_values2),
]
)
Sampler
Hlavním úkolem Sampleru je vzorkování výstupního registru z provedení jednoho nebo více kvantových Circuit. Vstupní Circuit mohou být parametrizované, pokud jsou hodnoty parametrů také poskytnuty jako vstup primitivu.
Vstupem je jeden nebo více PUB, ve formátu:
(<jeden circuit>, <jedna nebo více volitelných hodnot parametrů>, <volitelný počet měření>),
kde může být více položek hodnot parametrů a každá položka může být buď pole nebo jeden parametr, v závislosti na zvoleném Circuit. Vstup navíc musí obsahovat měření.
Výstupem jsou počty nebo měření pro každé provedení jako objekty PubResult, bez vah. Třída výsledků však má metody pro vrácení vážených vzorků, jako jsou počty. Úplné podrobnosti najdeš v části Vstupy a výstupy primitiv.
Příklad:
# This cell is hidden from users, add measurement instructions to circuits
circuit1.measure_active()
circuit2.measure_active()
sampler = SamplerV2(mode=backend)
sampler_job = sampler.run(
[
(circuit1, param_values1, shots1),
(circuit2, param_values2, shots2),
]
)
Další kroky
- Přečti si Začínáme s primitivy pro implementaci primitiv ve své práci.
- Prostuduj si podrobné příklady primitiv.
- Procvič si primitiva prací s lekcí o funkci nákladů v IBM Quantum Learning.
- Viz referenci API EstimatorV2 a referenci API SamplerV2.
- Přečti si Migrace na primitiva V2.