QuantumFerry 用户使用手册

Qiskit 使用示范

用你熟悉的 QuantumCircuit 编写线路,再通过 QuantumFerry 选择设备、取得报价并读取 Qiskit 结果。插件提供 BackendV2、SamplerV2 和 EstimatorV2 三种入口:测量线路直接用 backend,参数化采样用 Sampler,观测量期望值用 Estimator。

组件用它完成什么本页的入口
QuantumSourceService连接平台、查找设备、创建计算对象QuantumSourceService(...)
QuantumSourceBackend把 QuantumCircuit 准备为平台任务,返回 Qiskit Resultservice.return_backend(...)
QuantumSourceSampler为参数化线路采样,按经典寄存器读取 BitArrayservice.create_sampler(backend=backend)
QuantumSourceEstimator将 Pauli 观测量转换为测量实验,计算期望值和误差service.create_estimator(backend=backend)

选择你的学习路径

你现在想做什么阅读顺序
第一次提交测量线路本页第 1–5 步:连接 → 线路 → 报价 → 确认 → counts
查看设备门集、物理连接或 mapping 等选项Qiskit 设备能力页:目录 → capabilities / schema / Options / Target
固定物理位置编译与物理比特页:查询当前连接,再选择布局
参数扫描、批量采样、观测量估计Sampler 与 Estimator 页:PUB → 参数数组 → 完整报价 → 原生结果

本页先完成一个 Bell 实验:连接、选设备、写线路、看报价、确认、读结果。prepare 上传线路并获取报价,confirm 确认执行。后面的直接运行、批量、Sampler、Estimator 分别介绍其他使用方式,可按需要选择。确认真机实验会使用设备资源,并按报价计费。

1. 创建服务并选择设备

开始前完成安装与认证:安装 SDK 的 Qiskit 扩展,设置 QUANTUM_SOURCE_API_URL,并配置平台 SDK Key 文件或 Client ID / Client Secret。QUANTUM_SOURCE_BACKEND 填写设备列表返回的 short_code。下面各步骤在同一个 Python 会话中运行,共用 service、backend 和线路变量。

python
import os
from qiskit import QuantumCircuit
from quantum_source_qiskit import QuantumSourceService

service = QuantumSourceService(
    base_url=os.environ["QUANTUM_SOURCE_API_URL"],
    currency="OPEN",  # 使用 FULL 时在首次准备前改为 "FULL"
)
devices = service.backends(online=True)
devices

连接单元使用 OPEN,省略 currency 时也默认 OPEN。需要使用 FULL 余额时,在准备之前将这里改为 currency="FULL"。service.currency 和 service.scheduler.currency 可只读查看当前选择;由 service 创建的 Backend、Sampler、Estimator 和批次都使用这个钱包。

QuantumSourceService 负责平台连接。backends(online=True) 返回设备字典列表,在 Notebook 中显示简洁表格;short_code 是下一步选择设备时使用的标识。platform_active_tasks 显示全平台在该设备上的未结束任务总数。

python
backend = service.return_backend(os.environ["QUANTUM_SOURCE_BACKEND"])
backend.available_qubits, backend.max_shots

return_backend 返回实现 Qiskit BackendV2 接口的 QuantumSourceBackend。backend 保存所选设备的能力和默认选项,后面的 prepare、run 和 transpile 都针对这台设备。available_qubits 是可用物理编号集合,max_shots 是设备公布的采样上限。

2. 创建一个逻辑线路

新建线路默认采用逻辑线路方式:SDK 转换输入门,设备端完成后续物理编译。本源设备通过 mapping 开启云端拓扑映射,将逻辑线路适配芯片连接关系。下面使用两个逻辑比特,采样 128 次。

python
circuit = QuantumCircuit(2, 2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure([0, 1], [0, 1])
circuit.draw("text")

QuantumCircuit(2, 2) 创建两条量子线和两位经典结果。h(0) 和 cx(0, 1) 构造 Bell 线路,measure 将测量写入经典位。这里的 0、1 是逻辑线路编号;物理位置由设备映射决定。draw("text") 在本地显示线路。

3. 准备线路并查看报价

python
prepared = backend.prepare(circuit, shots=128)
prepared.quote

prepare 返回保存线路和报价的准备对象 prepared。shots=128 表示这个实验采样 128 次;插件完成线路转换和平台准备后,把任务数量、采样次数和价格放在 prepared.quote 中,供确认执行前查看。

本例参数省略时覆盖范围
circuit必填的位置参数;也可传线路列表本次准备的线路
shots=128采用 backend.options.shots,初始为 100每条线路各自的采样次数
memory采用 backend.options.memory,初始为 True请求设备提供的逐次测量数据;只读取 counts 时可设为 False
export_format按当前设备能力选择 qasm3 或 qasm2线路序列化使用的 OpenQASM 版本
报价字段怎样读取
backends本次准备所涉及的设备
task_count / total_shots实际任务数及所有任务采样次数之和
total_amount / currency精确 Decimal 金额及币种;amount 提供字符串金额
expires_at_utc这份报价的到期时间
python
prepared.quote.to_dict()

to_dict() 将报价转换为适合展示或保存的字典。

金额和币种在 prepare 时确定,OPEN 与 FULL 分别记账。需要改用 FULL 时,用 FULL service 创建 backend,再为尚未执行的实验准备新报价。已有 prepared 保留它原来的金额和币种。

4. 核对后单独确认

接受上述报价后,运行下一单元确认执行。SDK 使用 prepared 保存的完整报价提交实验;真机任务按报价计费。

python
job = prepared.confirm()

confirm 使用 prepared 保存的线路和报价确认提交,返回 job。job 用于查询实验进度,并在计算完成后读取结果。

5. 等待并读取测量计数

python
result = job.result(timeout=300)
result.get_counts()

result(timeout=300) 等待实验结果,为本次调用设置 300 秒等待预算,完成后返回 Qiskit Result。get_counts() 读取测量计数字典:键是比特串,值是对应次数,各计数之和与结果中的 shots 一致。

Qiskit 的结果位序按经典寄存器解释:本例左侧字符对应 c[1],右侧对应 c[0]。即使将线路固定在物理 1、11 上,结果仍使用这两位经典寄存器。

get_counts() 读取平台的整数计数通道;设备提供逐次测量数据时还可使用 get_memory()。job.status() 查询当前进度,job.platform_job_ids 列出已经取得的任务号。排队阶段可使用句柄的 submission_ids 跟踪提交;job_id() 在任务号分配前返回 None。

替代方式:直接运行

run 将准备和确认合并为一步,适合程序已经决定执行的实验。它默认自动批准服务端报价并提交;需要逐次查看报价时,使用前面的 prepare → quote → confirm 流程。

python
job = backend.run(circuit, shots=128)
result = job.result(timeout=300)
result.get_counts()
希望怎样使用选哪个入口
先显示完整价格,再由程序或用户决定backend.prepare(...) → prepared.quote → prepared.confirm()
已接受当前计费规则,直接执行backend.run(...),默认自动确认
保留 run 调用形式,但要求显式审价run(..., auto_approve_quote=False),处理 QuoteApprovalRequired.prepared

可在 service.return_backend(..., config={"auto_approve_quote": False}) 设置后续默认不自动确认;也可在单次 run 中传 auto_approve_quote=False。此时抛出 QuoteApprovalRequired,其 prepared 属性保留准备好的报价。Sampler 和 Estimator 继承后端的这一设置。

可选:等待时间、查询间隔与进度

Backend 的 prepare/run 可以设置 verbose 和 job_timeout_seconds,分别控制进度显示和默认等待时间。下面为第 3 步的准备调用增加这两个选项。已有任务的等待时间可以直接通过 job.result(timeout=...) 调整。

python
prepared = backend.prepare(
    circuit,
    shots=128,
    verbose=True,
    job_timeout_seconds=300,
)
prepared.quote

verbose=True 显示简短英文阶段或状态变化,job_timeout_seconds=300 为后续结果等待设置默认预算。prepare 准备报价,confirm 确认执行;backend.run(...) 合并这两步并返回任务句柄,随后用 job.result() 等待计算结果。

先按第 4 步查看报价并确认取得 job,再选择下面一种结果读取写法。

python
# 已经取得同一实验的 job:采用提交时设置的默认等待预算。
result = job.result(wait=2)
result.get_counts()
python
# 或显式设置本次等待时间,继续读取同一个 job。
result = job.result(timeout=600, wait=2)
result.get_counts()
参数设置位置含义
verbosebackend.prepare/run默认 False;True 显示准备、提交及后续等待的简短进度。
job_timeout_secondsbackend.prepare/run作为后续 result() 的默认等待秒数;从 result() 调用时开始计算。
timeoutjob.result(timeout=...)本次调用使用的等待秒数。
waitjob.result(wait=2)状态查询间隔,覆盖平台排队和设备任务等待。

省略 wait 时,平台排队阶段使用 scheduler 的查询间隔,设备任务阶段使用 2 秒。一次 result 调用中的排队和全部线路共享同一份等待预算;恢复 prepared 得到的任务句柄沿用这些设置。单次 HTTP 请求的超时由连接层控制。

等待超时后,任务仍会继续处理。再次调用原 job.result(...) 即可继续等待和读取结果。本节介绍 Backend 的等待设置;Sampler、Estimator 的用法见原语教程,PennyLane 的用法见对应插件教程。

设备选项与固定物理位置

选择设备后,查看 backend.configuration_schema 中的参数说明和 backend.options 中的当前默认值。

python
backend.configuration_schema, backend.options

configuration_schema 的 properties 给出设备选项的类型、允许值和默认值,例如本源设备的 amend、mapping、optimization。有默认值的选项进入 backend.options,可用 set_options 设置后续默认;单次 prepare/run 可通过直接关键字或扁平 configuration_data 设置。

固定位置时,选择 physical_qubits 或 initial_layout 中的一个入口,按逻辑线顺序填写物理编号。先从当前设备的可用编号及直接连接中选位;也可先 transpile 生成布局,再直接提交带布局的线路。完整步骤见编译与物理比特。

多线路与完整报价

以下是独立的多线路实验示例,使用前面定义的 circuit 和 backend。shots=128 对每条线路取同一值,也可传与线路数相同的正整数列表。先看整个批次的实际任务数、shots 和金额,再决定是否确认。

python
batch = backend.prepare([circuit, circuit.copy()], shots=[128, 128])
batch.quote

这里输入两条线路,分别采样 128 次。返回的批次准备对象通过 quote 展示两条线路的总报价。确认该批次后,按原线路顺序读取结果。

python
batch_job = batch.confirm()
python
batch_result = batch_job.result(timeout=300)
batch_result.get_counts(0), batch_result.get_counts(1)

每条实际任务分别占用组织名额。如果批量确认中途停止,已接受的任务继续处理;保留 batch,使用 recover() 查看已尝试提交的进度。

Sampler:参数绑定与采样结果

这是独立的 Sampler 实验,沿用本页连接阶段的 service 和 backend。准备阶段会绑定参数并取得所有实际任务的报价;确认和结果分开运行。

python
from qiskit.circuit import Parameter

theta = Parameter("theta")
sample_circuit = QuantumCircuit(1, 1)
sample_circuit.ry(theta, 0)
sample_circuit.measure(0, 0)
sampler = service.create_sampler(backend=backend)
sample_pubs = [(sample_circuit, [[0.0], [0.5]], 128)]
sample_prepared = sampler.prepare(sample_pubs)
sample_prepared.quote

sample_pubs 是一组 PUB 输入;本例的一个 PUB 由线路、参数值数组、shots 组成。[[0.0], [0.5]] 为 theta 提供两个参数点,每点采样 128 次,共 256 shots。

python
sample_job = sample_prepared.confirm()
python
sample_result = sample_job.result(timeout=300)
sample_result[0].data.c.get_counts(0)

sample_result[0] 选择第一个 PUB,data.c 选择名为 c 的经典寄存器,get_counts(0) 读取第一个参数点,get_counts(1) 读取第二点。

PUB 中的 shots 优先于通用默认值;工厂参数 options={"default_shots": 128} 可设置默认采样次数。经典寄存器保留在同名 data 字段中,BitArray 按平台返回的 counts 展开。sampler.run(sample_pubs) 可直接准备、自动确认并执行实验。

Estimator:期望值与测量任务

这是另一个独立实验,沿用本页连接阶段的 service 和 backend。下例使用单个已绑定线路和 Z 观测量,precision=0.1 对每个实际测量线路采用 100 shots;若设备有更严格限制,请先调整精度。

python
from qiskit.quantum_info import SparsePauliOp

state_circuit = QuantumCircuit(1)
state_circuit.ry(0.5, 0)
observable = SparsePauliOp.from_list([("Z", 1.0)])
estimator = service.create_estimator(backend=backend)
estimate_prepared = estimator.prepare([(state_circuit, observable)], precision=0.1)
estimate_prepared.quote

Estimator 输入不需要事先添加最终测量。这里的 PUB 是 (线路, 观测量):SparsePauliOp 中 Z 表示测量 Z 的期望值,系数为 1.0。prepare 会安排所需测量线路,报价反映展开后的实际数量。

python
estimate_job = estimate_prepared.confirm()
python
estimate_result = estimate_job.result(timeout=300)
estimate_result[0].data.evs, estimate_result[0].data.stds

evs 是观测量期望值,stds 是对应估计标准误。可以将实际估计与 Ry(0.5) 后测 Z 的理论值 cos(0.5) 比较。

Estimator 在客户端完成参数绑定、Pauli 测量分组和结果归约。每个实际测量线路的 shots 为 ceil(1 / precision**2),因此一个参数点可能展开为多个任务。以准备后的完整报价为准。Sampler、Estimator 的 prepare/run 均接受 physical_qubits 或 initial_layout,以及当前设备声明的选项。

Primitive 确认后在本机后台整理结果。primitive_job.result(timeout=300) 为本次等待设置 300 秒时限,超时后可用原句柄继续等待。读取结果期间保持内核和 service 可用;跨会话读取平台任务结果的方式见专页的等待与恢复。

状态查询、取消与组织名额

python
job.status(), getattr(job, "submission_ids", ()), job.platform_job_ids

依次查看状态、句柄可提供的原提交 ID、已取得的真实任务 ID。排队句柄提供 submission_ids;直接返回真实任务时,中间项为空元组。

平台排队中的任务可继续用 result(timeout=...) 等待。取消尚未被平台领取的 queued 项时调用 job.cancel()。全部取消成功返回 True;单任务失败抛对应异常,多任务部分失败抛 BatchCancellationError,已成功取消的部分保持生效。

同一组织的成员、Key、项目与设备共享 10 个未结束任务名额。平台接受确认后占用名额,确认 Completed、Failed 或 Canceled 后释放。达到上限时,JobLimitReachedError 提示查看已有任务,待名额可用后再提交新的实验。

简短报错与原任务恢复

提交或查询报错时,阅读异常消息并保留 prepared 或 job,随后查询同一个实验。已经取得 job 时调用它的 status() 或 result(timeout=...);提交结果待核实时调用 prepared.recover()。recover() 使用原提交信息,返回可等待任务句柄后即可继续调用 result(timeout=...)。仍返回回执时,稍后再次 recover()。等待超时后,任务继续保留,重新调用原 job.result(...) 即可继续等待。

SDK 通过简短的异常类型和消息显示可用的提交原因。平台确认任务最终 Failed 后,按原币种退还该任务费用。

配置入口速查

设备选项统一写入扁平的 configuration_data,或使用当前设备声明的单次关键字。钱包在 QuantumSourceService / SchedulerClient 构造时通过 currency="OPEN" 或 "FULL" 选择。prepared.quote.currency 可查看已准备实验的币种;换用新客户端后,已有 prepared 保留原报价。

SDK 默认使用 OPEN,在 service 构造时可选择 FULL。APIError(HTTP 402)表示所选钱包余额不足,本次确认项停留在提交前;批次此前接受的任务继续处理。当前通道为 public / stand,执行方案 auto 对应 public,队列 auto 或 standard 对应 stand。完成结果读取后关闭 service,任务记录仍保存在平台。

python
service.close()

下一步

下载本页 Jupyter Notebook

收录本页 Python 示例与说明,便于在 Jupyter Notebook 中学习和运行;安装命令保留为说明。

下载《Qiskit 入门与示例》Notebook(.ipynb)

输入关键词;所有搜索都在本机完成。