Jak przesłać obwód za pomocą zestawu Qiskit do usługi Azure Quantum

Dowiedz się, jak przesłać obwód kwantowy Qiskit przy użyciu azure-quantumPython pakietu. Obwody qiskit można przesyłać do usługi Azure Quantum przy użyciu notesu Usługi Azure Quantum, który ma wbudowany azure-quantumPython pakiet lub z komputera lokalnego.

Aby uzyskać więcej informacji, zobacz Quantum circuits (Obwody kwantowe).

Uwaga

Zestaw Microsoft Quantum Development Kit (klasyczny zestaw QDK) nie będzie już obsługiwany po 30 czerwca 2024 r. Jeśli jesteś istniejącym deweloperem zestawu QDK, zalecamy przejście do nowego zestawu Azure Quantum Development Kit (nowoczesnego zestawu QDK), aby kontynuować opracowywanie rozwiązań kwantowych. Aby uzyskać więcej informacji, zobacz Migrowanie kodu języka Q# do nowoczesnego zestawu QDK.

Wymagania wstępne

Aby uzyskać szczegółowe informacje na temat instalacji, zobacz Instalowanie nowoczesnego zestawu QDK w programie VS Code.

Tworzenie nowego Jupyter Notebook

  1. W programie VS Code wybierz pozycję Wyświetl > paletę poleceń i wybierz pozycję Utwórz: Nowy Jupyter Notebook.
  2. W prawym górnym rogu program VS Code wykryje i wyświetli wersję środowiska wirtualnego PythonPython wybranego dla notesu. Jeśli masz wiele Python środowisk, może być konieczne wybranie jądra przy użyciu selektora jądra w prawym górnym rogu. Jeśli nie wykryto żadnego środowiska, zobacz Notesy Jupyter Notebook w programie VS Code , aby uzyskać informacje o instalacji.

Ładowanie wymaganych importów

W pierwszej komórce notesu uruchom następujący kod, aby załadować wymagane importy:

import azure.quantum
from qiskit import QuantumCircuit
from qiskit.visualization import plot_histogram
from azure.quantum.qiskit import AzureQuantumProvider

Nawiązywanie połączenia z usługą Azure Quantum

Aby nawiązać połączenie z usługą Azure Quantum, potrzebujesz identyfikatora zasobu i lokalizacji obszaru roboczego usługi Azure Quantum. Zaloguj się do konta platformy Azure, https://portal.azure.comprzejdź do obszaru roboczego usługi Azure Quantum i skopiuj wartości z nagłówka.

Jak pobrać identyfikator zasobu i lokalizację z obszaru roboczego usługi Azure Quantum

Dodaj nową komórkę i użyj informacji o koncie, aby utworzyć Workspace obiekty i AzureQuantumProvider nawiązać połączenie z obszarem roboczym usługi Azure Quantum.

workspace = Workspace(  
    resource_id = "", # Add the resourceID of your workspace
    location = "" # Add the location of your workspace (for example "westus")
    )

provider = AzureQuantumProvider(workspace)

Wyświetlanie listy wszystkich zapleczy

Teraz możesz wydrukować wszystkie zaplecza obliczeń kwantowych, które są dostępne w obszarze roboczym:

print("This workspace's targets:")
for backend in provider.backends():
    print("- " + backend.name())
This workspace's targets:
- ionq.qpu
- ionq.qpu.aria-1
- ionq.simulator
- microsoft.estimator
- quantinuum.hqs-lt-s1
- quantinuum.hqs-lt-s1-apival
- quantinuum.hqs-lt-s2
- quantinuum.hqs-lt-s2-apival
- quantinuum.hqs-lt-s1-sim
- quantinuum.hqs-lt-s2-sim
- quantinuum.qpu.h1-1
- quantinuum.sim.h1-1sc
- quantinuum.sim.h1-1e
- rigetti.sim.qvm
- rigetti.qpu.ankaa-2

Uruchamianie prostego obwodu

Najpierw utwórz prosty obwód Qiskit do uruchomienia.

# Create a Quantum Circuit acting on the q register
circuit = QuantumCircuit(3, 3)
circuit.name = "Qiskit Sample - 3-qubit GHZ circuit"
circuit.h(0)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.measure([0,1,2], [0, 1, 2])

# Print out the circuit
circuit.draw()
     ┌───┐          ┌─┐      
q_0: ┤ H ├──■───────┤M├──────
     └───┘┌─┴─┐     └╥┘┌─┐   
q_1: ─────┤ X ├──■───╫─┤M├───
          └───┘┌─┴─┐ ║ └╥┘┌─┐
q_2: ──────────┤ X ├─╫──╫─┤M├
               └───┘ ║  ║ └╥┘
c: 3/════════════════╩══╩══╩═
                     0  1  2 

Wybierz element target do uruchomienia programu

Uruchamianie na symulatorze IonQ

Przed uruchomieniem rzeczywistego sprzętu przetestujmy obwód w symulatorze. Użyj get_backend polecenia , aby utworzyć obiekt w celu nawiązania połączenia z zapleczem Backend symulatora IonQ:

simulator_backend = provider.get_backend("ionq.simulator")

Zaplecze IonQ obsługuje bramy ze zdefiniowanego zestawu bram, które są kompilowane w celu optymalnego uruchamiania na sprzęcie. Jeśli obwód zawiera bramy, które nie znajdują się na tej liście, należy przeprowadzić transpilowanie do obsługiwanej gateset funkcji udostępnionej transpile przez zestaw Qiskit:

from qiskit import transpile
circuit = transpile(circuit, simulator_backend)

Funkcja transpilu zwraca nowy obiekt obwodu, w którym bramy są rozłożone na bramy obsługiwane w określonym zapleczu.

Teraz możesz uruchomić program za pośrednictwem usługi Azure Quantum i uzyskać wynik. Poniższa komórka przesyła zadanie uruchamiające obwód z 100 strzałami:

job = simulator_backend.run(circuit, shots=100)
job_id = job.id()
print("Job id", job_id)
Job id 00000000-0000-0000-0000-000000000000

Aby poczekać na zakończenie zadania i zwrócić wyniki, uruchom polecenie :

result = job.result()
print(result)
Result(backend_name='ionq.simulator', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='00000000-0000-0000-0000-000000000000', success=True, results=[ExperimentResult(shots=100, success=True, meas_level=2, data=ExperimentResultData(counts={'000': 50, '111': 50}, probabilities={'000': 0.5, '111': 0.5}), header=QobjExperimentHeader(meas_map='[0, 1, 2]', name='Qiskit Sample - 3-qubit GHZ circuit', num_qubits='3', qiskit='True'))])

Ponieważ wynik jest obiektem natywnym dla pakietu Qiskit, można użyć zestawu result.get_counts Qiskit i plot_histogram zwizualizować wyniki. Aby upewnić się, że wszystkie możliwe etykiety bitów są reprezentowane, dodaj je do countselementu .

counts = {format(n, "03b"): 0 for n in range(8)}
counts.update(result.get_counts(circuit))
print(counts)
plot_histogram(counts)
{'000': 50, '001': 0, '010': 0, '011': 0, '100': 0, '101': 0, '110': 0, '111': 50}

Wynik obwodu qiskit w symulatorze IonQ

Szacowanie kosztu zadania

Przed uruchomieniem zadania w QPU można oszacować, ile kosztuje uruchomienie. Aby oszacować koszt uruchamiania zadania w QPU, możesz użyć estimate_cost metody :

backend = provider.get_backend("ionq.qpu")
cost = backend.estimate_cost(circuit, shots=1024)

print(f"Estimated cost: {cost.estimated_total}")

Spowoduje to wydrukowanie szacowanych kosztów w USD.

Aby uzyskać najbardziej aktualne szczegóły cennika, zobacz Cennik IonQ lub znajdź obszar roboczy i wyświetl opcje cenowe na karcie "Dostawca" obszaru roboczego za pośrednictwem: aka.ms/aq/myworkspaces.

Uruchamianie w trybie QPU IonQ

Aby nawiązać połączenie z rzeczywistym sprzętem (jednostka procesora kwantowego (QPU)), po prostu podaj nazwę target"ionq.qpu"get_backend metody:

qpu_backend = provider.get_backend("ionq.qpu")

Prześlij obwód do uruchomienia w usłudze Azure Quantum, pobierz wyniki i uruchom polecenie plot_histogram , aby wykreślić wyniki.

Uwaga

Czas wymagany do uruchomienia obwodu na QPU może się różnić w zależności od bieżących czasów kolejki.

# Submit the circuit to run on Azure Quantum
job = qpu_backend.run(circuit, shots=1024)
job_id = job.id()
print("Job id", job_id)

# Get the job results (this method waits for the Job to complete):
result = job.result()
print(result)
counts = {format(n, "03b"): 0 for n in range(8)}
counts.update(result.get_counts(circuit))
print(counts)
plot_histogram(counts)
Job id 00000000-0000-0000-0000-000000000000
Job Status: job has successfully run
Result(backend_name='ionq.simulator', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='00000000-0000-0000-0000-000000000000', success=True, results=[ExperimentResult(shots=1024, success=True, meas_level=2, data=ExperimentResultData(counts={'0': 505, '1': 6, '2': 1, '3': 1, '4': 1, '5': 10, '6': 11, '7': 488}, probabilities={'0': 0.4932, '1': 0.0059, '2': 0.001, '3': 0.001, '4': 0.001, '5': 0.0098, '6': 0.0117, '7': 0.4766}), header=QobjExperimentHeader(name='Qiskit Sample - 3-qubit GHZ circuit', num_qubits='3', qiskit='True'))])
{'000': 505, '001': 6, '010': 1, '011': 1, '100': 1, '101': 10, '110': 11, '111': 488}

Wynik obwodu qiskit na IonQ QPU

Ważne

Przesyłanie wielu obwodów w jednym zadaniu nie jest obecnie obsługiwane. Aby obejść ten problem, możesz wywołać metodę backend.run , aby przesłać każdy obwód asynchronicznie, a następnie pobrać wyniki każdego zadania. Na przykład:

jobs = []
for circuit in circuits:
    jobs.append(backend.run(circuit, shots=N))

results = []
for job in jobs:
    results.append(job.result())

Wymagania wstępne

Tworzenie nowego notesu w obszarze roboczym

  1. Zaloguj się do Azure Portal i wybierz obszar roboczy utworzony w poprzednim kroku.
  2. W bloku po lewej stronie wybierz pozycję Notesy.
  3. Kliknij pozycję Moje notesy i kliknij pozycję Dodaj nowy.
  4. Wpisz nazwę pliku, na przykład Qiskit.ipynb, a następnie kliknij przycisk Utwórz plik.

Po otwarciu nowego notesu automatycznie tworzy kod dla pierwszej komórki na podstawie informacji o subskrypcji i obszarze roboczym.

from azure.quantum import Workspace
workspace = Workspace ( 
    resource_id = "", # Add your resource_id 
    location = ""  # Add your workspace location (for example, "westus") 
)

Uwaga

O ile nie określono inaczej, należy uruchomić każdą komórkę w kolejności tworzenia, aby uniknąć problemów z kompilacją.

Kliknij trójkątną ikonę "odtwórz" po lewej stronie komórki, aby uruchomić kod.

Ładowanie wymaganych importów

Najpierw należy zaimportować kilka dodatkowych modułów.

Kliknij pozycję + Kod , aby dodać nową komórkę, a następnie dodaj i uruchom następujący kod:

from qiskit import QuantumCircuit
from qiskit.visualization import plot_histogram
from azure.quantum.qiskit import AzureQuantumProvider

Nawiązywanie połączenia z usługą Azure Quantum

Następnie utwórz AzureQuantumProvider obiekt przy użyciu Workspace obiektu z poprzedniej komórki, aby nawiązać połączenie z obszarem roboczym usługi Azure Quantum. Dodaj nową komórkę z następującym kodem:

provider = AzureQuantumProvider(workspace)

Definiowanie prostego obwodu

W nowej komórce utwórz circuit obiekt. Ten przykład to prosty kwantowy generator bitów losowych. Dodaj następujący kod, aby zdefiniować i wyświetlić obwód:

# Create a Quantum Circuit acting on the q register
circuit = QuantumCircuit(3, 3)
circuit.name = "Qiskit Sample - 3-qubit GHZ circuit"
circuit.h(0)
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.measure([0, 1, 2], [0, 1, 2])

# Print out the circuit
circuit.draw()
     ┌───┐          ┌─┐      
q_0: ┤ H ├──■───────┤M├──────
     └───┘┌─┴─┐     └╥┘┌─┐   
q_1: ─────┤ X ├──■───╫─┤M├───
          └───┘┌─┴─┐ ║ └╥┘┌─┐
q_2: ──────────┤ X ├─╫──╫─┤M├
               └───┘ ║  ║ └╥┘
c: 3/════════════════╩══╩══╩═
                     0  1  2 

Wyświetl listę wszystkich targets

Teraz możesz wyświetlić wszystkie obliczenia kwantowe targetslub zaplecza, które są dostępne w obszarze roboczym. Dodaj nową komórkę i uruchom następujący wiersz:

print("This workspace's targets:")
for backend in provider.backends():
    print("- " + backend.name())
This workspace's targets:
- ionq.qpu
- ionq.simulator
- ionq.qpu.aria-1
- microsoft.estimator
- quantinuum.qpu.h1-1
- quantinuum.sim.h1-1sc
- quantinuum.sim.h1-1e
- rigetti.sim.qvm
- rigetti.qpu.ankaa-2

Wybierz element target , aby uruchomić program

Aby sprawdzić kod przed uruchomieniem go na rzeczywistym sprzęcie kwantowym, możesz użyć symulatora kwantowego IonQ, ionq.simulator.

Dodaj nową komórkę i utwórz obiekt reprezentujący symulator targetkwantowy IonQ :

# Get IonQ quantum simulator target:
simulator_backend = provider.get_backend("ionq.simulator")

Uruchamianie w symulatorze IonQ

Aby uruchomić obwód w symulatorze, dodaj następujący kod. W tym przykładzie użyto run metody target , aby przesłać zadanie, a następnie monitoruje stan zadania.

# Submit the circuit to run on Azure Quantum
job = simulator_backend.run(circuit, shots=100)
job_id = job.id()
print("Job id", job_id)

Po pomyślnym uruchomieniu zadania pobierz wyniki zadania i wyświetl je:

# Get the job results:
result = job.result()
print(result)
Result(backend_name='ionq.simulator', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='7d909574-98d4-11ec-b382-00155d957f5d', success=True, results=[ExperimentResult(shots=100, success=True, meas_level=2, data=ExperimentResultData(counts=defaultdict(<class 'int'>, {'000': 50, '111': 50}), probabilities=defaultdict(<class 'int'>, {'000': 0.5, '111': 0.5})), header=QobjExperimentHeader(meas_map='[0, 1, 2]', name='Qiskit Sample - 3-qubit GHZ circuit', num_qubits='3', qiskit='True'))])

Ponieważ ten result typ jest obiektem natywnym dla pakietu Qiskit, można użyć zestawu Qiskit result.get_counts i plot_histogram do wizualizacji wyników. Aby upewnić się, że wszystkie możliwe etykiety ciągów bitowych są reprezentowane, dodaj je do elementu counts.

counts = {format(n, "03b"): 0 for n in range(8)}
counts.update(result.get_counts(circuit))
print(counts)
plot_histogram(counts)
{'000': 50, '001': 0, '010': 0, '011': 0, '100': 0, '101': 0, '110': 0, '111': 50}

Wynik obwodu Qiskit w symulatorze IonQ

Szacowanie kosztu zadania

Przed uruchomieniem zadania na rzeczywistym sprzęcie kwantowym lub w kwantowej jednostce przetwarzania ( QPU) możesz oszacować, ile kosztuje jego uruchomienie.

Najpierw ponownie pobierz listę dostępnych dostawców:

print("This workspace's targets:")
for backend in provider.backends():
    print("- " + backend.name())
This workspace's targets:
- ionq.qpu
- ionq.simulator
- ionq.qpu.aria-1
- microsoft.estimator
- quantinuum.qpu.h1-1
- quantinuum.sim.h1-1sc
- quantinuum.sim.h1-1e
- rigetti.sim.qvm
- rigetti.qpu.ankaa-2

Następnie utwórz obiekt reprezentujący komputer kwantowy IonQ:

qpu_backend = provider.get_backend("ionq.qpu")

Aby oszacować koszt uruchamiania zadania w QPU, dodaj i uruchom nową komórkę przy użyciu estimate_cost metody target:

cost = qpu_backend.estimate_cost(circuit, shots=100)

print(f"Estimated cost: {cost.estimated_total}")

Spowoduje to wyświetlenie szacowanych kosztów w USD.

Aby uzyskać najbardziej aktualne szczegóły cennika, zobacz Cennik usługi IonQ lub znajdź obszar roboczy i wyświetl opcje cennika w bloku Dostawcy obszaru roboczego.

Uruchamianie na QPU IonQ

Po pomyślnym uruchomieniu zadania w symulatorze IonQ i oszacowaniu kosztu QPU nadszedł czas na uruchomienie obwodu na sprzęcie.

Uwaga

Czas wymagany do uruchomienia obwodu w QPU różni się w zależności od bieżących czasów kolejki. Możesz wyświetlić średni czas kolejki dla obiektu target , wybierając blok Dostawcy obszaru roboczego.

Użyj tej samej run metody i operacji, które były wcześniej używane z modułem sprawdzania poprawności interfejsu API, aby przesłać i monitorować zadanie:

# Submit the circuit to run on Azure Quantum
job = qpu_backend.run(circuit, shots=1024)
job_id = job.id()
print("Job id", job_id)

Po zakończeniu zadania pobierz wyniki zadania tak jak wcześniej i wyświetl je na wykresie:

result = job.result()
print(result)
counts = {format(n, "03b"): 0 for n in range(8)}
counts.update(result.get_counts(circuit))
print(counts)
plot_histogram(counts)
Job id 910b5ac8-98cd-11ec-b3ba-00155d5528cf
Job Status: job has successfully run
Result(backend_name='ionq.simulator', backend_version='1', qobj_id='Qiskit Sample - 3-qubit GHZ circuit', job_id='Job id 54e8c740-98d9-11ec-b382-00155d957f5d', success=True, results=[ExperimentResult(shots=1024, success=True, meas_level=2, data=ExperimentResultData(counts={'0': 505, '1': 6, '2': 1, '3': 1, '4': 1, '5': 10, '6': 11, '7': 488}, probabilities={'0': 0.4932, '1': 0.0059, '2': 0.001, '3': 0.001, '4': 0.001, '5': 0.0098, '6': 0.0117, '7': 0.4766}), header=QobjExperimentHeader(name='Qiskit Sample - 3-qubit GHZ circuit', num_qubits='3', qiskit='True'))])
{'000': 505, '001': 6, '010': 1, '011': 1, '100': 1, '101': 10, '110': 11, '111': 488}

Wynik obwodu Qiskit na urządzeniu QPU IonQ

Ważne

Przesyłanie wielu obwodów w jednym zadaniu nie jest obecnie obsługiwane. Aby obejść ten problem, możesz wywołać metodę backend.run , aby przesłać każdy obwód asynchronicznie, a następnie pobrać wyniki każdego zadania. Na przykład:

jobs = []
for circuit in circuits:
    jobs.append(backend.run(circuit, shots=N))

results = []
for job in jobs:
    results.append(job.result())

Następne kroki