Adott formázott kapcsolatcsoportok elküldése az Azure Quantumba
Ebből a azure-quantum
Python cikkből megtudhatja, hogyan küldhet el kapcsolatcsoportokat adott formátumban az Azure Quantum service-nek a csomag használatával. Ez a cikk bemutatja, hogyan küldhet be kapcsolatcsoportokat a következő formátumokban:
További információ: Kvantum-kapcsolatcsoportok.
Előfeltételek
Ha a kapcsolatcsoportokat egy Jegyzetfüzetben szeretné futtatni az Azure Portalon, a következőkre van szüksége:
- Egy Azure-fiók, aktív előfizetéssel. Ha nem rendelkezik Azure-fiókkal, regisztráljon ingyenesen, és regisztráljon használatalapú fizetéses előfizetésre.
- Egy Azure Quantum-munkaterület. További információ: Azure Quantum-munkaterület létrehozása.
A kapcsolatcsoportok Visual Studio Code-ban való fejlesztéséhez és futtatásához a következőkre is szükség van:
A Python környezet és a Python Pip telepítve.
VS Code az Azure Quantum Development Kittel és Pythona Telepített Jupyter-bővítményekkel.
Az Azure Quantum
qsharp
ésazure-quantum
ipykernel
a csomagok.python -m pip install --upgrade qsharp azure-quantum ipykernel
Új Jupyter Notebook létrehozása
Jegyzetfüzetet a VS Code-ban vagy közvetlenül az Azure Quantum Portalon hozhat létre.
- Jelentkezzen be az Azure Portalra , és válassza ki a munkaterületet az előző lépésből.
- A bal oldali panelen válassza a Jegyzetfüzetek lehetőséget.
- Kattintson a Saját jegyzetfüzetek elemre, majd az Új hozzáadása parancsra.
- Kerneltípusban válassza az IPython lehetőséget.
- Írja be a fájl nevét, és kattintson a Fájl létrehozása parancsra.
Amikor megnyílik az új jegyzetfüzet, automatikusan létrehozza az első cellához tartozó kódot az előfizetés és a munkaterület adatai alapján.
from azure.quantum import Workspace
workspace = Workspace (
resource_id = "", # Your resource_id
location = "" # Your workspace location (for example, "westus")
)
QIR-formátumú kapcsolatcsoportok küldése
A kvantum köztes reprezentáció (QIR) egy köztes reprezentáció, amely a kvantumprogramozási nyelvek/keretrendszerek és a célzott kvantumszámítási platformok közös interfésze. További információ: Kvantum köztes ábrázolás.
Hozza létre a QIR-kapcsolatcsoportot. A következő kód például létrehoz egy egyszerű összefonódási áramkört.
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} """
Hozzon létre egy
submit_qir_job
segédfüggvényt a QIR-kapcsolatcsoport elküldéséhez egy target. Vegye figyelembe, hogy a bemeneti és kimeneti adatformátumok és a kimeneti adatformátumok is meg vannak advaqir.v1
microsoft.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
Válasszon ki egy QIR-kapcsolatcsoportot target , és küldje el az Azure Quantumnak. Például a QIR-kapcsolatcsoport elküldése az IonQ-szimulátorba target:
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]}
Szolgáltatóspecifikus formátumú kapcsolatcsoport beküldése az Azure Quantumba
A QIR-nyelvek, például a Q# vagy a Qiskit mellett szolgáltatóspecifikus formátumban is küldhet kvantum áramköröket az Azure Quantumnak. Minden szolgáltató saját formátummal rendelkezik a kvantumkörök ábrázolásához.
Kapcsolatcsoport beküldése az IonQ-ba JSON formátum használatával
Hozzon létre egy kvantumköröket az IonQ targetsáltal támogatott nyelvi JSON-formátummal, az IonQ API dokumentációjában leírtak szerint. Az alábbi minta például egy szuperpozíciót hoz létre három qubit között:
circuit = { "qubits": 3, "circuit": [ { "gate": "h", "target": 0 }, { "gate": "cnot", "control": 0, "target": 1 }, { "gate": "cnot", "control": 0, "target": 2 }, ] }
Küldje el a kapcsolatcsoportot az IonQ-nak target. Az alábbi példa az IonQ-szimulátort használja, amely egy objektumot
Job
ad vissza.target = workspace.get_targets(name="ionq.simulator") job = target.submit(circuit)
Várjon, amíg a feladat befejeződik, majd kérje le az eredményeket.
results = job.get_results() print(results)
..... {'duration': 8240356, 'histogram': {'0': 0.5, '7': 0.5}}
Ezután megjelenítheti az eredményeket a Matplotlib használatával.
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")
Mielőtt futtatna egy feladatot a QPU-n, meg kell becsülnie, hogy mennyibe fog kerülni a futtatás.
Feljegyzés
A legfrissebb díjszabási részletekért tekintse meg az IonQ díjszabását, vagy keresse meg a munkaterületet, és tekintse meg a díjszabási beállításokat a munkaterület "Szolgáltató" lapján a következő aka.ms/aq/myworkspaces keresztül.
Kapcsolatcsoport elküldése a PASQAL-ba a Pulser SDK használatával
Ha a PASQAL-nak szeretne áramkört küldeni, a Pulser SDK-val impulzussorozatokat hozhat létre, és elküldheti őket a PASQAL-nak target.
A Pulser SDK telepítése
A Pulser a semleges atom kvantumeszközök impulzusütemezéseinek írására, szimulálására és végrehajtására szolgáló keretrendszer. A PASQAL úgy lett kialakítva, hogy továbbítsa a kvantumkísérleteket a kvantumprocesszoraiknak. További információt a Pulser dokumentációjában talál.
Az impulzusütemezések elküldéséhez először telepítse a Pulser SDK-csomagokat:
try:
import pulser
import pulser_pasqal
except ImportError:
!pip -q install pulser pulser-pasqal --index-url https://pypi.org/simple
Kvantumregisztrációs regiszter létrehozása
A folytatás előtt meg kell határoznia a nyilvántartást és az elrendezést is. A regiszter meghatározza az atomok elhelyezésének helyét, míg az elrendezés meghatározza az atomok rögzítéséhez és szerkezetéhez szükséges csapdák helyét a regiszterben.
Az elrendezésekkel kapcsolatos részletekért tekintse meg a Pulser dokumentációját.
Először létre kell hoznia egy "eszközök" objektumot a PASQAL kvantumszámítógép target( Fresnel) importálásához.
from pulser_pasqal import PasqalCloud devices = PasqalCloud().fetch_available_devices() QPU = devices["FRESNEL"]
Előre kalibrált elrendezések
Az eszköz előre kalibrált elrendezések listáját határozza meg. A regisztrációt ezen elrendezések egyikéből hozhatja létre.
Ez az ajánlott lehetőség, mert javítja a QPU teljesítményét.
1. lehetőség: A regisztráció definiálása előre kalibrált elrendezésekkel
Vizsgálja meg a Fresnelen elérhető elrendezéseket, és határozza meg a nyilvántartást ebből az elrendezésből. Erről további információt a pulser dokumentációjában talál.
Példa:
# let's say we are interested in the first layout available on the device layout = QPU.pre_calibrated_layouts[0] # Select traps 1, 3 and 5 of the layout to define the register traps = [1,3,5] reg = layout.define_register(*traps) # You can draw the resulting register to verify it matches your expectations reg.draw()
Tetszőleges elrendezések
Ha az előre kalibrált elrendezések nem felelnek meg a kísérlet követelményeinek, létrehozhat egy egyéni elrendezést.
Bármely tetszőleges regiszter esetében a semleges atom QPU az elrendezésnek megfelelően csapdákat helyez el, amelyeket ezután kalibrálásnak kell alávetni. Mivel minden kalibrációhoz idő szükséges, általában célszerű a meglévő kalibrált elrendezést újra felhasználni, amikor csak lehetséges
2. lehetőség: Elrendezés automatikus levezetése a megadott regiszterből
Ez a beállítás lehetővé teszi egy elrendezés automatikus létrehozását egy megadott regiszter alapján. A nagy méretű regiszterek esetében azonban ez a folyamat az elrendezés létrehozásához használt algoritmus korlátai miatt az optimálisnál rosszabb megoldásokat eredményezhet.
from pulser import Register qubits = { "q0": (0, 0), "q1": (0, 10), "q2": (8, 2), "q3": (1, 15), "q4": (-10, -3), "q5": (-8, 5), } reg = Register(qubits).with_automatic_layout(device)
3. lehetőség: A regisztráció definiálása manuálisan meghatározott elrendezés használatával
- Tetszőleges elrendezés létrehozása 20 trap véletlenszerű elhelyezésével egy 2D síkban
import numpy as np from pulser.register.register_layout import RegisterLayout # Generating random coordinates np.random.seed(301122) # Keeps results consistent between runs traps = np.random.randint(0, 30, size=(20, 2)) traps = traps - np.mean(traps, axis=0) # Creating the layout layout = RegisterLayout(traps, slug="random_20")
- A regisztráció definiálása adott trapazonosítókkal
trap_ids = [4, 8, 19, 0] reg = layout.define_register(*trap_ids, qubit_ids=["a", "b", "c", "d"]) reg.draw()
Impulzusütemezés írása
A semleges atomokat lézerimpulzusokkal irányítják. A Pulser SDK lehetővé teszi, hogy impulzussorozatokat hozzon létre a kvantumregisztrációs regiszterre való alkalmazáshoz.
Először meg kell határoznia az impulzusütemezési attribútumokat az atomok vezérléséhez használt csatornák deklarálásával. A létrehozáshoz
Sequence
meg kell adnia egy példányt, valamint aztRegister
az eszközt, amelyben a sorozat végrehajtásra kerül. A következő kód például egy csatornát deklarál:ch0
.Feljegyzés
A nagyobb rugalmasság érdekében használhatja az
QPU = devices["FRESNEL"]
eszközt, vagy importálhat egy virtuális eszközt a Pulserből. A használatVirtualDevice
lehetővé teszi a sorozat létrehozását, amely kevésbé korlátozza az eszköz specifikációi, így alkalmas a végrehajtás egy emulátor. További információt a Pulser dokumentációjában talál.from pulser import Sequence seq = Sequence(reg, QPU) # print the available channels for your sequence print(seq.available_channels) # Declare a channel. In this example we will be using `rydberg_global` seq.declare_channel("ch0", "rydberg_global")
Adjon hozzá impulzusokat a sorozathoz. Ehhez impulzusokat hozhat létre és adhat hozzá a deklarált csatornákhoz. Az alábbi kód például létrehoz egy impulzust, és hozzáadja a csatornához
ch0
.from pulser import Pulse from pulser.waveforms import RampWaveform, BlackmanWaveform import numpy as np amp_wf = BlackmanWaveform(1000, np.pi) det_wf = RampWaveform(1000, -5, 5) pulse = Pulse(amp_wf, det_wf, 0) seq.add(pulse, "ch0") seq.draw()
Az alábbi képen az impulzussorozat látható.
A sorozat átalakítása JSON-sztringgé
Az impulzusütemezések elküldéséhez a Pulser-objektumokat JSON-sztringgé kell konvertálnia, amely bemeneti adatokként használható.
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)
return to_send
Az impulzusütemezés elküldése a PASQAL-nak target
Először meg kell adnia a megfelelő bemeneti és kimeneti adatformátumokat. A következő kód például a bemeneti adatformátumot
pasqal.pulser.v1
állítja be, a kimeneti adatformátumot pedig a következőrepasqal.pulser-results.v1
.# Submit the job with proper input and output data formats def submit_job(target, seq, shots): 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=shots # Number of shots ) print(f"Queued job: {job.id}") return job
Feljegyzés
A feladat QPU-n való futtatásához szükséges idő az aktuális várakozási időtől függ. Az átlagos üzenetsor-időt target a munkaterület Szolgáltatók paneljének kiválasztásával tekintheti meg.
Küldje el a programot a PASQAL-nak. Mielőtt valódi kvantumhardverbe küldené a kódot, tesztelheti a kódot az emulátor
pasqal.sim.emu-tn
használatával target.target = workspace.get_targets(name="pasqal.sim.emu-tn") # Change to "pasqal.qpu.fresnel" to use Fresnel QPU job = submit_job(target, seq, 10) job.wait_until_completed() print(f"Job completed with state: {job.details.status}") result = job.get_results() print(result)
{ "1000000": 3, "0010000": 1, "0010101": 1 }
Kapcsolatcsoport elküldése a Quantinuumba az OpenQASM használatával
Hozzon létre egy kvantum-kapcsolatcsoportot az OpenQASM-ábrázolásban . Az alábbi példa például létrehoz egy Teleportation-kapcsolatcsoportot:
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]; """
A kapcsolatcsoportot egy fájlból is betöltheti:
with open("my_teleport.qasm", "r") as f: circuit = f.read()
Küldje el a kapcsolatcsoportot a Quantinuumnak target. Az alábbi példa a Quantinuum API-érvényesítőt használja, amely egy objektumot
Job
ad vissza.target = workspace.get_targets(name="quantinuum.sim.h1-1sc") job = target.submit(circuit, shots=500)
Várjon, amíg a feladat befejeződik, majd kérje le az eredményeket.
results = job.get_results() print(results)
........ {'c0': ['000', '000', '000', '000', '000', '000', '000', ... ]}
Ezután megjelenítheti az eredményeket a Matplotlib használatával.
import pylab as pl pl.hist(results["c0"]) pl.ylabel("Counts") pl.xlabel("Bitstring")
A hisztogramot vizsgálva észreveheti, hogy a véletlenszerű számgenerátor minden alkalommal 0-t ad vissza, ami nem túl véletlenszerű. Ennek az az oka, hogy bár az API Validator biztosítja, hogy a kód sikeresen fusson a Quantinuum hardveren, a 0 értéket is visszaadja minden kvantumméréshez. Egy valódi véletlenszám-generátorhoz kvantumhardveren kell futtatnia a kapcsolatcsoportot.
Mielőtt futtatna egy feladatot a QPU-n, meg kell becsülnie, hogy mennyibe fog kerülni a futtatás.
Feljegyzés
A legfrissebb díjszabási részletekért tekintse meg az Azure Quantum díjszabását, vagy keresse meg a munkaterületet, és tekintse meg a díjszabási lehetőségeket a munkaterület "Szolgáltató" lapján a következő aka.ms/aq/myworkspaces keresztül.
Kapcsolatcsoport elküldése Rigettinek a Quil használatával
A Quil-feladatok elküldésének legegyszerűbb módja a pyquil-for-azure-quantum csomag használata, mivel lehetővé teszi a pyQuil-kódtár eszközeinek és dokumentációjának használatát. A csomag nélkül a pyQuil használható Quil-programok létrehozására, de nem az Azure Quantumba való beküldésére.
A Quil-programokat manuálisan is létrehozhatja, és közvetlenül a azure-quantum
csomag használatával küldheti el őket.
Először töltse be a szükséges importálásokat.
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
A vagy
get_qpu
függvényget_qvm
használatával kapcsolatot létesíthet a QVM-hez vagy a QPU-hoz.qc = get_qvm() # For simulation # qc = get_qpu("Ankaa-3") for submitting to a QPU
Hozzon létre egy Quil-programot. A rendszer elfogadja az érvényes Quil-programokat, de az olvasást el kell nevezni
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
Itt egynumpy
tömb található, így használhatnumpy
módszereket.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
Nyomtassa ki az összes adatot.
print("Data from 'ro' register:") for i, shot in enumerate(data_per_shot): print(f"Shot {i}: {shot}")
Fontos
Több kapcsolatcsoport elküldése egy feladaton jelenleg nem támogatott. Áthidaló megoldásként meghívhatja a metódust az backend.run
egyes áramkörök aszinkron elküldéséhez, majd lekérheti az egyes feladatok eredményeit. Példa:
jobs = []
for circuit in circuits:
jobs.append(backend.run(circuit, shots=N))
results = []
for job in jobs:
results.append(job.result())