Отправка канала с Cirq в Azure Quantum

Узнайте, как отправить квантовую цепь Cirq с помощью azure-quantumPython пакета . Вы можете отправлять каналы Cirq в azure-quantumPython Azure Quantum с помощью записной книжки Azure Quantum, которая имеет встроенный пакет, или с локального компьютера.

Дополнительные сведения см. в разделе Квантовые цепи.

Примечание

Microsoft Quantum Development Kit (классический QDK) больше не будет поддерживаться после 30 июня 2024 г. Если вы уже являетесь разработчиком QDK, мы рекомендуем перейти на новый пакет средств разработки Azure Quantum (Современный QDK), чтобы продолжить разработку квантовых решений. Дополнительные сведения см. в статье Перенос кода Q# в современный QDK.

Предварительные требования

Сведения об установке см. в статье Установка современного QDK в VS Code.

Создание нового Jupyter Notebook

  1. В VS Code выберите Просмотреть > палитру команд и выберите Создать: создать Jupyter Notebook.
  2. В правом верхнем углу VS Code обнаружит и отобразит версию Python и виртуальную Python среду, выбранную для записной книжки. Если у вас несколько Python сред, может потребоваться выбрать ядро с помощью средства выбора ядра в правом верхнем углу. Если среда не обнаружена, см. сведения о настройке записных книжек Jupyter Notebook в VS Code .

Загрузка необходимых объектов импорта

В первой ячейке записной книжки выполните следующий код, чтобы загрузить необходимые импорты:

import azure.quantum
from azure.quantum.cirq import AzureQuantumService

Подключение к службе Azure Quantum

Для подключения к службе Azure Quantum программе потребуются идентификатор ресурса и расположение рабочей области Azure Quantum. Войдите в учетную запись Azure, https://portal.azure.com, перейдите в рабочую область Azure Quantum и скопируйте значения из заголовка.

Получение идентификатора ресурса и расположения из рабочей области Azure Quantum

Добавьте новую ячейку и используйте сведения об учетной записи для создания Workspace объектов и AzureQuantumService для подключения к рабочей области Azure Quantum.

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

service = AzureQuantumService(workspace)

Перечисление всех targets

Используйте метод , targets()чтобы получить список всех targets в рабочей области, которые могут запускать канал, включая текущее время очереди и доступность.

Примечание

Все в targets рабочей области могут быть не указаны. Здесь будут перечислены только targets те, которые могут принимать канал Cirq или OpenQASM.

print(service.targets())
[<Target name="quantinuum.qpu.h1-1", avg. queue time=0 s, Degraded>,
<Target name="quantinuum.sim.h1-1sc", avg. queue time=1 s, Available>,
<Target name="quantinuum.sim.h1-1e", avg. queue time=40 s, Available>,
<Target name="ionq.qpu", avg. queue time=229 s, Available>,
<Target name="ionq.simulator", avg. queue time=3 s, Available>,
<Target name="ionq.qpu.aria-1", avg. queue time=1136774 s, Available>]

Создание простого канала

Затем создайте простую цепь Cirq для выполнения. Эта цепь использует квадратный корень из гейта X, встроенного в аппаратную систему IonQ.

import cirq

q0, q1 = cirq.LineQubit.range(2)
circuit = cirq.Circuit(
    cirq.X(q0)**0.5,             # Square root of X
    cirq.CX(q0, q1),              # CNOT
    cirq.measure(q0, q1, key='b') # Measure both qubits
)
print(circuit)
0: ───X^0.5───@───M────────
              │   │
1: ───────────X───M────────

Выберите для target запуска программы

Запуск в симуляторе IonQ

Теперь можно запустить программу через службу Azure Quantum и получить результат. Следующая ячейка отправляет задание (на симулятор IonQ по умолчанию), которое запускает цепь со 100 снимками, ждет завершения задания и возвращает результаты.

result = service.run(program=circuit, repetitions=100, target="ionq.simulator")

Возвращается объект cirq.Result.

print(result)
    b=1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010, 1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010

Оценка стоимости задания

Перед выполнением задания на QPU вы можете оценить, сколько будет стоить его выполнение. Чтобы оценить затраты на выполнение задания в QPU, можно использовать метод estimate_cost:

cost = service.estimate_cost(
    program=circuit,
    repetitions=100,
    target="ionq.qpu"
)

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

Это действие выводит оценочные затраты в долларах США (USD).

Актуальные сведения о ценах см. в статье Цены на IonQ, или найдите рабочую область и просмотрите параметры ценообразования на вкладке "Поставщик" с помощью команды: aka.ms/aq/myworkspaces.

Выполнение на QPU IonQ

Предыдущее задание выполнялось в симуляторе по умолчанию "ionq.simulator". Однако его также можно запустить на аппаратном процессоре IonQ (единице квантового процессора (QPU)). Для выполнения на QPU IonQ укажите "ionq.qpu" в качестве аргумента target:

result = service.run(
    program=circuit,
    repetitions=100,
    target="ionq.qpu",
    timeout_seconds=500 # Set timeout to accommodate queue time on QPU
)

Снова возвращается объект cirq.Result.

print(result)
b=0101011011011111100001011101101011011110100010000000011110111000100100110110101100110001001111101111, 0101011011011111100001011101101011011110100010000000011110111000100100110110101100110001001111101111

Асинхронная модель, использующая задания

Длительные цепи можно выполнять асинхронно. Метод service.create_job возвращает объект Job, который можно использовать для получения результатов после успешного выполнения задания.

job = service.create_job(
    program=circuit,
    repetitions=100,
    target="ionq.simulator"
)

Чтобы проверить состояние задания, используйте job.status():

print(job.status())
'completed'

Чтобы дождаться завершения задания, а затем получить результаты, используйте блокирующий вызов job.results():

result = job.results()
print(result)
00: 0.5
11: 0.5

Обратите внимание, что объект cirq.Result при этом не возвращается. Вместо этого возвращается результирующий объект, относящийся к симулятору IonQ; при этом вместо данных снимков используются вероятности состояния.

type(result)
cirq_ionq.results.SimulatorResult

Чтобы преобразовать его в объект cirq.Result, используйте result.to_cirq_result():

print(result.to_cirq_result())
b=1110101111111110111000011101011111001100010000001011011101001111001111001101100111010000001100011100, 1110101111111110111000011101011111001100010000001011011101001111001111001101100111010000001100011100

Предварительные требования

Создание записной книжки в рабочей области

  1. Войдите на портал Azure и выберите рабочую область, которую вы назначили на предыдущем шаге.
  2. В колонке слева выберите элемент Записные книжки.
  3. Щелкните Мои записные книжки, а затем — Добавить новую.
  4. Введите имя файла, например Cirq.ipynb, и щелкните Создать файл.

Когда откроется новая записная книжка, она автоматически создает код для первой ячейки на основе сведений о подписке и рабочей области.

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

Примечание

Если не указано иное, следует выполнять ячейки в порядке их создания, чтобы избежать проблем компиляции.

Щелкните треугольный значок воспроизведения слева от ячейки, чтобы выполнить размещенный в ней код.

Загрузка необходимых объектов импорта

Сначала необходимо импортировать дополнительный модуль.

Щелкните + Код, чтобы добавить новую ячейку, а затем добавьте и выполните следующий код:

from azure.quantum.cirq import AzureQuantumService

Подключение к службе Azure Quantum

Затем создайте AzureQuantumService объект, используя workspace объект из предыдущей ячейки для подключения к рабочей области Azure Quantum. Добавьте новую ячейку со следующим кодом:

provider = AzureQuantumService(workspace)

Настройка простой цепи

Затем создайте простую цепь Cirq для выполнения. Эта цепь использует квадратный корень из гейта X, встроенного в аппаратную систему IonQ.

import cirq

q0, q1 = cirq.LineQubit.range(2)
circuit = cirq.Circuit(
    cirq.X(q0)**0.5,             # Square root of X
    cirq.CX(q0, q1),              # CNOT
    cirq.measure(q0, q1, key='b') # Measure both qubits
)
print(circuit)
0: ───X^0.5───@───M────────
              │   │
1: ───────────X───M────────

Перечисление всех targets

Используйте метод , targets()чтобы получить список всех targets в рабочей области, которые могут запускать канал, включая текущее время очереди и доступность.

Примечание

Все в targets рабочей области могут быть не указаны. Здесь будут перечислены только targets те, которые могут принимать канал Cirq или OpenQASM.

print("This workspace's targets:")
for target in service.targets():
     print(target)
This workspace's targets:
<Target name="quantinuum.qpu.h1-1", avg. queue time=0 s, Degraded>
<Target name="quantinuum.sim.h1-1sc", avg. queue time=1 s, Available>
<Target name="quantinuum.sim.h1-1e", avg. queue time=40 s, Available>
<Target name="ionq.qpu", avg. queue time=229 s, Available>
<Target name="ionq.simulator", avg. queue time=3 s, Available>
<Target name="ionq.qpu.aria-1", avg. queue time=1136774 s, Available>

Примечание

Полный список может отличаться для вашей target рабочей области.

Выберите для target запуска программы

Запуск в симуляторе IonQ

Для проверки цепи перед запуском на реальном квантовом оборудовании можно применить симулятор IonQ ionq.simulator.

Следующая ячейка отправляет задание, которое запускает цепь со 100 снимками, ждет завершения задания и возвращает результаты.

result = service.run(
    program=circuit,
    repetitions=100,
    target="ionq.simulator"
)

Возвращается объект cirq.Result.

print(result)
    b=1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010, 1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010

Результаты можно представить в виде гистограммы:

import pylab as pl

pl.hist(result.data)
pl.ylabel("Counts")
pl.xlabel("Result")

Оценка стоимости задания

Перед выполнением задания на реальном квантовом оборудовании или в модуле квантовой обработки (QPU), вы можете оценить, стоимость его выполнения. Чтобы оценить затраты на выполнение задания в QPU, можно использовать метод estimate_cost:

cost = service.estimate_cost(
    program=circuit,
    repetitions=100,
    target="ionq.qpu"
)

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

Это действие выводит оценочные затраты в долларах США (USD).

Актуальные сведения о ценах можно узнать на странице цен IonQ или в колонке Поставщики для рабочей области. Чтобы просмотреть текущее состояние и потребление кредитов, перейдите в раздел Кредиты и квоты.

Выполнение на QPU IonQ

Предыдущее задание выполнялось в симуляторе по умолчанию ionq.simulator. Однако его также можно запустить на аппаратном процессоре IonQ (единице квантового процессора (QPU)). Для выполнения на QPU IonQ укажите ionq.qpu в качестве аргумента target:

result = service.run(
    program=circuit,
    repetitions=100,
    target="ionq.qpu",
    timeout_seconds=500 # Set timeout to accommodate queue time on QPU
)

Примечание

Требуемое время для выполнения цепи на QPU может оказаться разным в зависимости от текущего времени в очереди. Вы можете просмотреть среднее время очереди для, target выбрав колонку Поставщики в рабочей области.

Снова возвращается объект cirq.Result.

print(result)
    b=1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010, 1001100101100001000011011101000011010100010111100011001000100100010000001110010010101110110000011010

Асинхронная модель, использующая задания

Длительные цепи можно выполнять асинхронно. Метод service.create_job возвращает объект Job, который можно использовать для получения результатов после успешного выполнения задания.

job = service.create_job(
    program=circuit,
    repetitions=100,
    target="ionq.simulator"
)

Чтобы проверить состояние задания, используйте job.status():

print(job.status())
'completed'

Чтобы дождаться завершения задания, а затем получить результаты, используйте блокирующий вызов job.results():

result = job.results()
print(result)
00: 0.5
11: 0.5

Примечание

Функция job.results() не возвращает объект cirq.Result. Вместо этого возвращается результирующий объект, относящийся к симулятору IonQ; при этом вместо данных снимков используются вероятности состояния.

type(result)
cirq_ionq.results.SimulatorResult

Чтобы преобразовать его в объект cirq.Result, используйте result.to_cirq_result():

print(result.to_cirq_result())
b=1110101111111110111000011101011111001100010000001011011101001111001111001101100111010000001100011100, 1110101111111110111000011101011111001100010000001011011101001111001111001101100111010000001100011100

Важно!

Отправка нескольких цепей в одном задании в настоящее время не поддерживается. В качестве обходного решения можно вызвать метод backend.run для асинхронной отправки каждой цепи, а затем получить результаты каждого задания. Пример:

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

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

Дальнейшие действия