你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

如何使用 Cirq 将线路提交到 Azure Quantum

了解如何使用 azure-quantumPython 包提交 Cirq 量子线路。 可以使用具有内置 azure-quantumPython 包的 Azure Quantum 笔记本或本地计算机将 Cirq 线路提交到 Azure Quantum。

有关详细信息,请参阅量子线路

先决条件

有关安装详细信息,请参阅 在 VS Code 上安装 QDK。

  • Azure 订阅中的 Azure Quantum 工作区。 若要创建工作区,请参阅创建 Azure Quantum 工作区

  • Python安装了 Python Pip 的环境。

  • 安装了 Azure Quantum 开发工具包PythonJupyter 扩展的 VS Code。

  • 带有 [cirq] 标记和包的 qsharp ipykernel Azure Quantum azure-quantum 包。

    python -m pip install --upgrade azure-quantum[cirq] qsharp ipykernel 
    

    注意

    如果未检测到 Jupyter Python 内核 ipykernel ,VS Code 将提示你安装它。

创建新的 Jupyter Notebook

  1. 在 VS Code 中,选择“视图 > 命令面板”,然后选择“创建:新 Jupyter Notebook”。
  2. 在右上角,VS Code 将检测并显示为笔记本选择的版本 Python 和虚拟 Python 环境。 如果有多个 Python 环境,可能需要使用右上角的内核选取器选择内核。 如果未检测到任何环境,请参阅 VS Code 中的 Jupyter Notebook 以获取设置信息。

加载所需的导入项

在笔记本的第一个单元中,运行以下代码以加载所需的导入:

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

连接到 Azure Quantum 服务

若要连接到 Azure Quantum 服务,程序将需要资源 ID 和 Azure Quantum 工作区的位置。

  1. 登录到 Azure 帐户, https://portal.azure.com

  2. 选择 Azure Quantum 工作区,然后导航到 “概述”。

  3. 复制字段中的参数。

    Visual Studio Code 的屏幕截图,其中显示了如何展开 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.simulator", avg. queue time=3 s, Available>,
<Target name="ionq.qpu.aria-1", avg. queue time=1136774 s, Available>]

创建简单线路

接下来,创建要运行的简单 Cirq 线路。 此线路使用 IonQ 硬件系统固有的 X 门平方根。

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 上运行作业之前,应估算运行的成本。

有关最新定价详细信息,请参阅 IonQ 定价,或通过以下网页找到你的工作区并查看该工作区的“提供商”选项卡中的定价选项:aka.ms/aq/myworkspaces

在 IonQ QPU 上运行

上一个作业在默认模拟器 "ionq.simulator" 上运行。 但是,你也可以在 IonQ 的硬件处理器(Quantum 处理器单位 (QPU))上运行它。 若要在 IonQ QPU 上运行,请提供 "ionq.qpu.aria-1" 作为 target 参数:

result = service.run(
    program=circuit,
    repetitions=100,
    target="ionq.qpu.aria-1",
    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 服务

接下来,使用workspace上一单元格中的对象创建一个AzureQuantumService对象,以连接到 Azure Quantum 工作区。 使用以下代码添加新单元格:

provider = AzureQuantumService(workspace)

定义简单线路

接下来,创建要运行的简单 Cirq 线路。 此线路使用 IonQ 硬件系统固有的 X 门平方根。

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.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)上运行作业之前,应估算运行成本。

有关最新定价详细信息,请参阅 IonQ 定价,或查看工作区的“提供商”边栏选项卡中的定价选项。 若要查看当前额度状态和用量,请选择“额度和配额”

在 IonQ QPU 上运行

上一个作业在默认模拟器 ionq.simulator 上运行。 但是,也可以在 IonQ 的硬件处理器或量子处理单元 (QPU) 上运行该作业。 若要在 IonQ QPU 上运行,请提供 ionq.qpu.aria-1 作为 target 参数:

result = service.run(
    program=circuit,
    repetitions=100,
    target="ionq.qpu.aria-1",
    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())