qalgora-Q Docs Hub量子文档 ✦ Ask AI✦ 问问文档

When to Use sample vs. run

Both execute a kernel many times, but they return different things. Pick by what you need back.

The difference

samplerun
ReturnsHistogram of measured bitsList of typed kernel return values
Kernel return typeNone (uses mz)Required (bool, int, tuple…)
Best forDistributions, tomography (data-collection step)Conditional logic, custom outputs
Current status参考实现可用 — runnable core API规范接口·暂未实现 — not in the reference build yet
规范接口·暂未包含 — run is a specification API
qalgora.sample is part of the runnable reference core, but qalgora.run is a specification interface the open reference build does not ship yet. The migration snippet below shows the intended run usage; to run code today, stay with sample.

Migrating sample → run

# sample style: read raw bitstrings
@qalgora.kernel
def k_sample():
    q = qalgora.qvector(2)
    h(q[0]); x.ctrl(q[0], q[1])
    mz(q)

# run style: return exactly what you care about
@qalgora.kernel
def k_run() -> tuple[bool, bool]:
    q = qalgora.qvector(2)
    h(q[0]); x.ctrl(q[0], q[1])
    return mz(q[0]), mz(q[1])

results = qalgora.run(k_run, shots_count=100)   # list[tuple[bool,bool]]
Specification API — not in the open reference build yet
This example shows a qalgora-Q specification API (or a third-party library) that the open reference build does not bundle today. It documents the intended interface; to run code now, use the reference build’s supported core API.

Custom return types

The simplest custom return is a typed tuple: list the values you care about and run hands back one typed record per shot.

@qalgora.kernel
def measure_pair() -> tuple[int, bool]:
    data = qalgora.qvector(3)
    h(data[0]); x.ctrl(data[0], data[1]); x.ctrl(data[1], data[2])
    return mz(data[0]) + 2 * mz(data[1]), mz(data[2])   # (syndrome, logical)

records = qalgora.run(measure_pair, shots_count=500)   # list[tuple[int, bool]]
Specification API — not in the open reference build yet
This example shows a qalgora-Q specification API (or a third-party library) that the open reference build does not bundle today. It documents the intended interface; to run code now, use the reference build’s supported core API.

More elaborate dataclass / structured records are a higher-level specification interface — the same kernel can instead return a user-defined record, so each shot is a named structure rather than a bare tuple, handy when a kernel measures several registers with distinct meanings.

from dataclasses import dataclass

@dataclass
class Readout:
    syndrome: int
    logical: bool

@qalgora.kernel
def measure_block() -> Readout:
    data = qalgora.qvector(3)
    h(data[0]); x.ctrl(data[0], data[1]); x.ctrl(data[1], data[2])
    return Readout(syndrome=mz(data[0]) + 2 * mz(data[1]), logical=mz(data[2]))

records = qalgora.run(measure_block, shots_count=500)   # list[Readout]
Specification API — not in the open reference build yet
This example shows a qalgora-Q specification API (or a third-party library) that the open reference build does not bundle today. It documents the intended interface; to run code now, use the reference build’s supported core API.

Postselection

Because run hands you per-shot results, you can keep only the shots that pass a condition — the basis of heralded state preparation and many error-detection schemes.

(continues the spec-only run example above; run is not in the open reference build yet)

kept = [r for r in records if r.syndrome == 0]   # discard shots that flagged an error
print(f"kept {len(kept)}/{len(records)} shots")
Cost of postselection
Throwing away shots lowers your effective shot count. If acceptance is rare, raise shots_count so enough survive — or fold the condition into the circuit instead.

何时使用 samplerun

两者都会多次执行内核,但返回的内容不同。根据所需结果来选择。

区别

samplerun
返回值测量比特的直方图内核返回值的列表(有类型)
内核返回类型无(使用 mz必须指定(boolint、tuple 等)
适用场景概率分布、量子态层析的数据采集环节条件逻辑、自定义输出
当前状态参考实现可用(核心 API)规范接口·暂未实现
规范接口·暂未包含 — run 属于规范接口
qalgora.sample 属于可运行的参考核心,而 qalgora.run 是开放参考实现尚未内置的规范接口。下面的迁移片段展示的是 run 的预期用法;如需现在就运行,请继续使用 sample

从 sample 迁移到 run

# sample style: read raw bitstrings
@qalgora.kernel
def k_sample():
    q = qalgora.qvector(2)
    h(q[0]); x.ctrl(q[0], q[1])
    mz(q)

# run style: return exactly what you care about
@qalgora.kernel
def k_run() -> tuple[bool, bool]:
    q = qalgora.qvector(2)
    h(q[0]); x.ctrl(q[0], q[1])
    return mz(q[0]), mz(q[1])

results = qalgora.run(k_run, shots_count=100)   # list[tuple[bool,bool]]
规范接口 · 参考实现暂未包含
此示例展示的是 qalgora-Q 规范中的接口(或第三方库),开放参考实现目前尚未内置,仅用于说明预期用法;如需立即运行,请使用参考实现已支持的核心 API。

自定义返回类型

最简单的自定义返回是带类型的 tuple:把你关心的值逐个列出,run 每次 shot 回传一条带类型的记录。

@qalgora.kernel
def measure_pair() -> tuple[int, bool]:
    data = qalgora.qvector(3)
    h(data[0]); x.ctrl(data[0], data[1]); x.ctrl(data[1], data[2])
    return mz(data[0]) + 2 * mz(data[1]), mz(data[2])   # (syndrome, logical)

records = qalgora.run(measure_pair, shots_count=500)   # list[tuple[int, bool]]
规范接口 · 参考实现暂未包含
此示例展示的是 qalgora-Q 规范中的接口(或第三方库),开放参考实现目前尚未内置,仅用于说明预期用法;如需立即运行,请使用参考实现已支持的核心 API。

更复杂的 dataclass/结构化记录属更高层规范接口——同一个内核也可以改为返回用户自定义记录,让每次 shot 拿到的是带名字的结构而不是裸元组,在一个内核要测量多个含义不同的寄存器时尤其方便。

from dataclasses import dataclass

@dataclass
class Readout:
    syndrome: int
    logical: bool

@qalgora.kernel
def measure_block() -> Readout:
    data = qalgora.qvector(3)
    h(data[0]); x.ctrl(data[0], data[1]); x.ctrl(data[1], data[2])
    return Readout(syndrome=mz(data[0]) + 2 * mz(data[1]), logical=mz(data[2]))

records = qalgora.run(measure_block, shots_count=500)   # list[Readout]
规范接口 · 参考实现暂未包含
此示例展示的是 qalgora-Q 规范中的接口(或第三方库),开放参考实现目前尚未内置,仅用于说明预期用法;如需立即运行,请使用参考实现已支持的核心 API。

后选择

由于 run 把逐 shot 的结果直接交给你,你可以只保留满足条件的那些 shot。这正是预示式态制备和许多错误检测方案的基础。

(接续上面的 run 规范接口示例;run 暂未在开放参考实现中内置)

kept = [r for r in records if r.syndrome == 0]   # 丢弃标记了错误的 shot
print(f"kept {len(kept)}/{len(records)} shots")
后选择的代价
丢弃 shot 会降低有效 shot 数。如果接受率很低,就把 shots_count 调大,让足够多的 shot 存活下来;或者干脆把该条件编进线路里。