Odeslání konkrétních formátovaných okruhů do Azure Quantum
Zjistěte, jak pomocí azure-quantum
Python balíčku odesílat okruhy v konkrétních formátech do služby Azure Quantum. V tomto článku se dozvíte, jak odesílat okruhy v následujících formátech:
Další informace najdete v tématu Kvantové obvody.
Poznámka
Sada Microsoft Quantum Development Kit (Classic QDK) už nebude po 30. červnu 2024 podporována. Pokud jste stávající vývojář sady QDK, doporučujeme přejít na novou sadu Azure Quantum Development Kit (Moderní QDK) a pokračovat ve vývoji kvantových řešení. Další informace najdete v tématu Migrace kódu Q# do moderní sady QDK.
Požadavky
Ke spouštění okruhů v poznámkovém bloku v Azure Portal potřebujete:
- Účet Azure s aktivním předplatným. Pokud nemáte účet Azure, zaregistrujte se zdarma a zaregistrujte si předplatné s průběžnými platbou.
- Pracovní prostor Azure Quantum. Další informace najdete v tématu Vytvoření pracovního prostoru Azure Quantum.
K vývoji a spouštění okruhů v editoru Visual Studio Code potřebujete také:
Prostředí Python s nainstalovanými Python nástroji a Pip .
VS Code s nainstalovanou sadou Azure Quantum Development Kit, Pythona rozšířeními Jupyter .
Balíčky Azure Quantum
qsharp
,azure-quantum
aipykernel
.python -m pip install --upgrade qsharp azure-quantum ipykernel
Vytvoření nového Jupyter Notebook
- Přihlaste se k Azure Portal a vyberte pracovní prostor z předchozího kroku.
- V levém okně vyberte Poznámkové bloky.
- Klikněte na Moje poznámkové bloky a pak na Přidat nový.
- V části Typ jádra vyberte IPython.
- Zadejte název souboru a klikněte na Vytvořit soubor.
Když se nový poznámkový blok otevře, automaticky vytvoří kód pro první buňku na základě informací o vašem předplatném a pracovním prostoru.
from azure.quantum import Workspace
workspace = Workspace (
resource_id = "", # Your resource_id
location = "" # Your workspace location (for example, "westus")
)
Odeslání okruhů ve formátu QIR
QIR (Quantum Intermediate Representation) je přechodná reprezentace, která slouží jako společné rozhraní mezi kvantovými programovacími jazyky a architekturami a targetplatformami pro kvantové výpočty. Další informace najdete v tématu Quantum Intermediate Representation.
Vytvořte okruh QIR. Například následující kód vytvoří jednoduchý okruh propletení.
QIR_routine = """%Result = type opaque %Qubit = type opaque define void @ENTRYPOINT__main() #0 { call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 0 to %Qubit*)) call void @__quantum__qis__cx__body(%Qubit* inttoptr (i64 0 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*)) call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*)) call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Qubit* inttoptr (i64 0 to %Qubit*)) call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 2 to %Qubit*)) call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 3 to %Qubit*)) call void @__quantum__qis__cz__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Qubit* inttoptr (i64 1 to %Qubit*)) call void @__quantum__qis__h__body(%Qubit* inttoptr (i64 3 to %Qubit*)) call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 2 to %Qubit*), %Result* inttoptr (i64 0 to %Result*)) #1 call void @__quantum__qis__mz__body(%Qubit* inttoptr (i64 3 to %Qubit*), %Result* inttoptr (i64 1 to %Result*)) #1 call void @__quantum__rt__tuple_record_output(i64 2, i8* null) call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 0 to %Result*), i8* null) call void @__quantum__rt__result_record_output(%Result* inttoptr (i64 1 to %Result*), i8* null) ret void } declare void @__quantum__qis__ccx__body(%Qubit*, %Qubit*, %Qubit*) declare void @__quantum__qis__cx__body(%Qubit*, %Qubit*) declare void @__quantum__qis__cy__body(%Qubit*, %Qubit*) declare void @__quantum__qis__cz__body(%Qubit*, %Qubit*) declare void @__quantum__qis__rx__body(double, %Qubit*) declare void @__quantum__qis__rxx__body(double, %Qubit*, %Qubit*) declare void @__quantum__qis__ry__body(double, %Qubit*) declare void @__quantum__qis__ryy__body(double, %Qubit*, %Qubit*) declare void @__quantum__qis__rz__body(double, %Qubit*) declare void @__quantum__qis__rzz__body(double, %Qubit*, %Qubit*) declare void @__quantum__qis__h__body(%Qubit*) declare void @__quantum__qis__s__body(%Qubit*) declare void @__quantum__qis__s__adj(%Qubit*) declare void @__quantum__qis__t__body(%Qubit*) declare void @__quantum__qis__t__adj(%Qubit*) declare void @__quantum__qis__x__body(%Qubit*) declare void @__quantum__qis__y__body(%Qubit*) declare void @__quantum__qis__z__body(%Qubit*) declare void @__quantum__qis__swap__body(%Qubit*, %Qubit*) declare void @__quantum__qis__mz__body(%Qubit*, %Result* writeonly) #1 declare void @__quantum__rt__result_record_output(%Result*, i8*) declare void @__quantum__rt__array_record_output(i64, i8*) declare void @__quantum__rt__tuple_record_output(i64, i8*) attributes #0 = { "entry_point" "output_labeling_schema" "qir_profiles"="base_profile" "required_num_qubits"="4" "required_num_results"="2" } attributes #1 = { "irreversible" } ; module flags !llvm.module.flags = !{!0, !1, !2, !3} !0 = !{i32 1, !"qir_major_version", i32 1} !1 = !{i32 7, !"qir_minor_version", i32 0} !2 = !{i32 1, !"dynamic_qubit_management", i1 false} !3 = !{i32 1, !"dynamic_result_management", i1 false} """
Vytvořte pomocnou
submit_qir_job
funkci pro odeslání okruhu QIR do target. Všimněte si, že formáty vstupních a výstupních dat jsou zadané jakoqir.v1
amicrosoft.quantum-results.v1
.# Submit the job with proper input and output data formats def submit_qir_job(target, input, name, count=100): job = target.submit( input_data=input, input_data_format="qir.v1", output_data_format="microsoft.quantum-results.v1", name=name, input_params = { "entryPoint": "ENTRYPOINT__main", "arguments": [], "count": count } ) print(f"Queued job: {job.id}") job.wait_until_completed() print(f"Job completed with state: {job.details.status}") #if job.details.status == "Succeeded": result = job.get_results() return result
target Vyberte a odešlete okruh QIR do Azure Quantum. Pokud chcete například odeslat okruh QIR do simulátoru targetIonQ:
target = workspace.get_targets(name="ionq.simulator") result = submit_qir_job(target, QIR_routine, "QIR routine") result
{'Histogram': ['(0, 0)', 0.5, '(1, 1)', 0.5]}
Odeslání okruhu s formátem specifickým pro poskytovatele do Azure Quantum
Kromě jazyků QIR, jako je Q# nebo Qiskit, můžete do Azure Quantum odesílat kvantové okruhy ve formátech specifických pro poskytovatele. Každý zprostředkovatel má svůj vlastní formát pro reprezentaci kvantových obvodů.
Odeslání okruhu do IonQ pomocí formátu JSON
Vytvořte kvantový okruh pomocí formátu JSON nezávislého na jazyce, který podporuje IonQ targets, jak je popsáno v dokumentaci k rozhraní IonQ API. Například následující ukázka vytvoří superpozici mezi třemi qubity:
circuit = { "qubits": 3, "circuit": [ { "gate": "h", "target": 0 }, { "gate": "cnot", "control": 0, "target": 1 }, { "gate": "cnot", "control": 0, "target": 2 }, ] }
Odešlete okruh do IonQ target. Následující příklad používá simulátor IonQ, který vrací
Job
objekt .target = workspace.get_targets(name="ionq.simulator") job = target.submit(circuit)
Počkejte na dokončení úlohy a načtěte výsledky.
results = job.get_results() print(results)
..... {'duration': 8240356, 'histogram': {'0': 0.5, '7': 0.5}}
Výsledky pak můžete vizualizovat pomocí knihovny Matplotlib.
import pylab as pl pl.rcParams["font.size"] = 16 hist = {format(n, "03b"): 0 for n in range(8)} hist.update({format(int(k), "03b"): v for k, v in results["histogram"].items()}) pl.bar(hist.keys(), hist.values()) pl.ylabel("Probabilities")
Před spuštěním úlohy na QPU můžete odhadnout, kolik bude jeho spuštění stát. K odhadu nákladů na spuštění úlohy na QPU můžete použít metodu
estimate_cost
:target = workspace.get_targets(name="ionq.qpu") cost = target.estimate_cost(circuit, shots=500) print(f"Estimated cost: {cost.estimated_total}")
Tím se zobrazí odhadované náklady v USD.
Poznámka
Nejnovější podrobnosti o cenách najdete v tématu Ceny ionQ nebo vyhledejte svůj pracovní prostor a zobrazte cenové možnosti na kartě Poskytovatel vašeho pracovního prostoru prostřednictvím : aka.ms/aq/myworkspaces.
Odeslání okruhu do PASQAL pomocí sady Pulser SDK
Pokud chcete odeslat okruh do PASQAL, můžete pomocí sady Pulser SDK vytvořit sekvence impulsů a odeslat je do PASQAL target.
Instalace sady Pulser SDK
Pulser je architektura pro vytváření, simulaci a spouštění pulzních sekvencí pro kvantová zařízení s neutrálními atomy. Nástroj PASQAL ho navrhl jako průchozí k odesílání kvantových experimentů do jejich kvantových procesorů. Další informace najdete v dokumentaci k pulseru.
Pokud chcete odeslat pulzní sekvence, nejprve nainstalujte balíčky Pulser SDK:
try:
import pulser
except ImportError:
!pip -q install pulser
!pip -q install pulser-core
Vytvoření kvantového registru
Nejprve načtěte požadované importy:
import numpy as np import pulser from pprint import pprint from pulser import Pulse, Sequence, Register
QPU pasqal se skládá z neutrálních atomů zachycených v přesně definovaných pozicích v mřížce. K definování kvantových registrů vytvoříte pole qubitů na mřížce. Například následující kód vytvoří čtvercovou mřížku qubitů 4x4:
L = 4 square = np.array([[i, j] for i in range(L) for j in range(L)], dtype=float) square -= np.mean(square, axis=0) square *= 5 qubits = dict(enumerate(square)) reg = Register(qubits) reg.draw()
Zápis sekvence impulsů
Neutrální atomy jsou řízeny laserovými impulsy. Sada Pulser SDK umožňuje vytvářet sekvence impulsů, které se použijí pro kvantový registr.
Nejprve musíte nastavit sekvenci impulsů a deklarovat kanály, které se použijí k ovládání atomů. Následující kód například deklaruje dva kanály:
ch0
ach1
.from pulser.devices import Chadoq2 seq = Sequence(reg, Chadoq2) seq.declare_channel("ch0", "raman_local") print("Available channels after declaring 'ch0':") pprint(seq.available_channels) seq.declare_channel("ch1", "rydberg_local", initial_target=4) print("\nAvailable channels after declaring 'ch1':") pprint(seq.available_channels)
Pár věcí, které byste měli zvážit:
- V
Sequence
Pulseru je řada operací, které se mají provést v kvantovém registru. - Kód nastaví sekvenci operací, které se mají provést na
AnalogDevice
zařízení.AnalogDevice
je předdefinované zařízení v Pulseru, které představuje kvantový počítač ekvivalentní Fresnel1.
- V
Vytvořte sekvenci impulsů. Uděláte to tak, že vytvoříte a přidáte do kanálů, které jste deklarovali, a přidáte do nich impulsy. Například následující kód vytvoří jednoduchý impuls a přidá ho do kanálu
ch0
a pak vytvoří komplexní puls a přidá ho do kanáluch1
.seq.target(1, "ch0") # Target qubit 1 with channel "ch0" simple_pulse = Pulse.ConstantPulse(200, 2, -10, 0) seq.add(simple_pulse, "ch0") # Add the pulse to channel "ch0" seq.delay(100, "ch1") from pulser.waveforms import RampWaveform, BlackmanWaveform duration = 1000 # Create a Blackman waveform with a duration of 1000 ns and an area of pi/2 rad amp_wf = BlackmanWaveform(duration, np.pi / 2) # Create a ramp waveform with a duration of 1000 ns and a linear sweep from -20 to 20 rad/µs detuning_wf = RampWaveform(duration, -20, 20) # Create a pulse with the amplitude waveform amp_wf, the detuning waveform detuning_wf, and a phase of 0 rad. complex_pulse = Pulse(amp_wf, detuning_wf, phase=0) complex_pulse.draw() seq.add(complex_pulse, "ch1") # Add the pulse to channel "ch1"
Na obrázku je vidět jednoduchý a složitý puls.
Převod sekvence na řetězec JSON
Pokud chcete odeslat pulzní sekvence, musíte převést objekty Pulser na řetězec JSON, který lze použít jako vstupní data.
import json
# Convert the sequence to a JSON string
def prepare_input_data(seq):
input_data = {}
input_data["sequence_builder"] = json.loads(seq.to_abstract_repr())
to_send = json.dumps(input_data)
#print(json.dumps(input_data, indent=4, sort_keys=True))
return to_send
Odeslání pulzní sekvence do PASQAL target
Nejprve je potřeba nastavit správné formáty vstupních a výstupních dat. Následující kód například nastaví formát vstupních dat na
pasqal.pulser.v1
a formát výstupních dat napasqal.pulser-results.v1
.# Submit the job with proper input and output data formats def submit_job(target, seq): job = target.submit( input_data=prepare_input_data(seq), # Take the JSON string previously defined as input data input_data_format="pasqal.pulser.v1", output_data_format="pasqal.pulser-results.v1", name="PASQAL sequence", shots=100 # Number of shots ) print(f"Queued job: {job.id}") job.wait_until_completed() print(f"Job completed with state: {job.details.status}") result = job.get_results() return result
Poznámka
Doba potřebná ke spuštění okruhu na QPU závisí na aktuální době fronty. Průměrnou dobu fronty můžete zobrazit tak, target že v pracovním prostoru vyberete okno Poskytovatelé .
Odešlete program do služby PASQAL. Můžete například odeslat program do PASQAL Emu-TN target.
target = workspace.get_targets(name="pasqal.sim.emu-tn") submit_job(target, seq)
{'0000000000000000': 59, '0000100000000000': 39, '0100000000000000': 1, '0100100000000000': 1}
Odeslání okruhu do Quantinuum pomocí OpenQASM
Vytvořte kvantový okruh v reprezentaci OpenQASM . Například následující příklad vytvoří teleportační okruh:
circuit = """OPENQASM 2.0; include "qelib1.inc"; qreg q[3]; creg c0[3]; h q[0]; cx q[0], q[1]; cx q[1], q[2]; measure q[0] -> c0[0]; measure q[1] -> c0[1]; measure q[2] -> c0[2]; """
Volitelně můžete okruh načíst ze souboru:
with open("my_teleport.qasm", "r") as f: circuit = f.read()
Odešlete okruh do Quantinuum target. Následující příklad používá validátor rozhraní API Quantinuum, který vrací
Job
objekt.target = workspace.get_targets(name="quantinuum.sim.h1-1sc") job = target.submit(circuit, shots=500)
Počkejte, až se úloha dokončí, a pak načtěte výsledky.
results = job.get_results() print(results)
........ {'c0': ['000', '000', '000', '000', '000', '000', '000', ... ]}
Výsledky pak můžete vizualizovat pomocí knihovny Matplotlib.
import pylab as pl pl.hist(results["c0"]) pl.ylabel("Counts") pl.xlabel("Bitstring")
Při pohledu na histogram si můžete všimnout, že generátor náhodných čísel pokaždé vrátil hodnotu 0, což není příliš náhodné. Je to proto, že zatímco validátor rozhraní API zajišťuje úspěšné spuštění kódu na hardwaru Quantinuum, vrátí také hodnotu 0 pro každé kvantové měření. Pro skutečný generátor náhodných čísel je nutné spustit okruh na kvantovém hardwaru.
Před spuštěním úlohy na QPU můžete odhadnout, kolik bude jeho spuštění stát. K odhadu nákladů na spuštění úlohy na QPU můžete použít metodu
estimate_cost
.target = workspace.get_targets(name="quantinuum.qpu.h1-1") cost = target.estimate_cost(circuit, shots=500) print(f"Estimated cost: {cost.estimated_total}")
Tím se vytisknou odhadované náklady v kreditech H-System Quantum Credits (HQCs).
Poznámka
Pokud chcete spustit odhad nákladů pro Quantinuum target, musíte nejprve znovu načíst balíček azure-quantumPython pomocí parametru [qiskit]. Další informace najdete v tématu Aktualizace balíčku azure-quantumPython.
Poznámka
Nejnovější podrobnosti o cenách najdete v tématu Ceny služby Azure Quantum nebo vyhledejte svůj pracovní prostor a zobrazte cenové možnosti na kartě Poskytovatel pracovního prostoru prostřednictvím : aka.ms/aq/myworkspaces.
Odeslání okruhu do Rigetti pomocí Quil
Nejjednodušším způsobem, jak odeslat úlohy Quil, je použít balíček pyquil-for-azure-quantum , který umožňuje používat nástroje a dokumentaci knihovny pyQuil . Bez tohoto balíčku lze pyQuil použít k vytváření programů Quil, ale ne k jejich odesílání do Azure Quantum.
Programy Quil můžete také vytvářet ručně a odesílat je přímo pomocí azure-quantum
balíčku.
Nejprve načtěte požadované importy.
from pyquil.gates import CNOT, MEASURE, H from pyquil.quil import Program from pyquil.quilbase import Declare from pyquil_for_azure_quantum import get_qpu, get_qvm
get_qvm
Pomocí funkce neboget_qpu
získejte připojení k QVM nebo QPU.qc = get_qvm() # For simulation # qc = get_qpu("Ankaa-2") for submitting to a QPU
Vytvořte program Quil. Je přijat jakýkoli platný program Quil, ale čtení musí mít název
ro
.program = Program( Declare("ro", "BIT", 2), H(0), CNOT(0, 1), MEASURE(0, ("ro", 0)), MEASURE(1, ("ro", 1)), ).wrap_in_numshots_loop(5) # Optionally pass to_native_gates=False to .compile() to skip the compilation stage result = qc.run(qc.compile(program)) data_per_shot = result.readout_data["ro"]
data_per_shot
Tady jenumpy
pole, takže můžete použítnumpy
metody.assert data_per_shot.shape == (5, 2) ro_data_first_shot = data_per_shot[0] assert ro_data_first_shot[0] == 1 or ro_data_first_shot[0] == 0
Vytiskněte všechna data.
print("Data from 'ro' register:") for i, shot in enumerate(data_per_shot): print(f"Shot {i}: {shot}")
Důležité
Odesílání více okruhů v jedné úloze se v současné době nepodporuje. Jako alternativní řešení můžete volat metodu backend.run
, která asynchronně odešle každý okruh a pak načte výsledky jednotlivých úloh. Příklad:
jobs = []
for circuit in circuits:
jobs.append(backend.run(circuit, shots=N))
results = []
for job in jobs:
results.append(job.result())
Další kroky
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro