@clawhub-agony5757-e378a35de7
Use when the user asks about UnifiedQuantum, uniqc, OriginIR, OpenQASM, circuit building, local simulation, cloud submission, dummy mode, VQE, QAOA, UCCSD, q...
---
name: quantum-computing
description: "Use when the user asks about UnifiedQuantum, uniqc, OriginIR, OpenQASM, circuit building, local simulation, cloud submission, dummy mode, VQE, QAOA, UCCSD, quantum ML, or PyTorch integration with UnifiedQuantum. Focus on the current public workflow: build circuits, export IR/QASM, run with uniqc CLI or task_manager, and add extras only when needed."
version: 1.0.0
---
# UnifiedQuantum Skill
当用户在使用当前 UnifiedQuantum 的公开 API、CLI 或示例时,使用这个 skill。
## 默认处理思路
优先采用当前的高层工作流:
1. 用 `uniqc.circuit_builder.Circuit` 构建线路
2. 导出 `circuit.originir` 或 `circuit.qasm`
3. 用 `uniqc` CLI 或 `uniqc.task_manager` 执行
4. 只为确实需要的功能安装额外 extras
当用户给的是一段 QASM 线路时,更稳妥的处理路径通常是:
1. 先用 `uniqc circuit` 转成 OriginIR
2. 再对这份归一化后的 OriginIR 做模拟或提交
这样可以减少不同输入路径带来的行为差异。
## 环境与安装处理
- 不要默认用户已经先决定好如何安装 `unified-quantum`,也不要默认用户已经选好了 CLI 入口。
- 先检查用户环境里已经有什么:解释器、已安装包、模块路径、CLI 是否可用,以及相关 extras 是否存在。
- 需要安装时,不要直接替用户决定安装路径。先给出简短可选项,让用户选择,再执行。
- 决定安装方式前,先识别用户当前是在 `venv`、Conda、Pixi 还是系统 Python 中工作。
- 默认把安装选项整理成 2 到 3 个最相关方案,并说明各自取舍;推荐项放第一,但不要静默直接执行。
- 常见可选项:
- `uv tool install`:适合偏 CLI 的隔离安装,命令可跨目录直接使用。
- `uv venv` 或普通 `venv`:适合项目内或 Python API 场景,依赖与仓库隔离。
- 当前已激活环境里的 `pip install`:适合用户明确希望复用现有 `venv`、Conda 或 Pixi 环境。
- 如果用户已经在 Pixi 生态里工作,`pixi global` 也是可接受的选项,但通常只在用户明确偏好 Pixi 时再列出。
- 如果当前环境是已激活的 Conda 环境,默认不要直接改它。把“装进当前 Conda 环境”作为一个可选项交给用户决定。
- 如果唯一可写目标是系统 Python,安装前必须明确征求用户同意。
- 如果用户没有明确偏好,再给出推荐:
- 偏 CLI:优先推荐 `uv tool install`
- 偏 Python API / 示例:优先推荐 `uv venv`
- 已在现有虚拟环境里工作:可推荐装进当前环境
- 如果 `uv` 不可用或不合适,再提供 `pip` / `venv` 方案作为替代。
- 只有在用户已经明确要求某种安装路径,或者当前会话上下文已经表达了稳定偏好时,才可以不再重复询问。
## 几个容易混淆但要记清的点
- 包名:`unified-quantum`
- CLI 名:`uniqc`
- 主 Python 包名:`uniqc`
- 配置文件:`~/.uniqc/uniqc.yml`
- 本地任务缓存:`~/.uniqc/cache/tasks.sqlite`
- 如果主题 reference 仍然解释不了问题,再回到 [references/troubleshooting.md](references/troubleshooting.md) 做通用诊断。
## 依赖边界
不要默认基础安装就包含所有功能。
- 核心包:`pip install unified-quantum`
- 本地模拟 / dummy 模式常见需要:`pip install "unified-quantum[simulation]"`
- OriginQ 适配器:`pip install "unified-quantum[originq]"`
- Quafu 适配器:`pip install "unified-quantum[quafu]"`
- IBM 适配器:`pip install "unified-quantum[qiskit]"`
- PyTorch 辅助工具:`pip install "unified-quantum[pytorch]"`
- TorchQuantum 集成:`pip install "unified-quantum[torchquantum]"`
如果用户提到 `qutip`、`torch`、`qiskit`、`quafu` 或 `pyqpanda3` 相关导入失败,先把它当成缺少可选依赖,而不是先判断核心包坏了。
## CLI 指引
当前 CLI 主要分组有:
- `uniqc circuit`
- `uniqc simulate`
- `uniqc submit`
- `uniqc result`
- `uniqc task`
- `uniqc config`
当用户要在 shell 里做格式转换、本地执行或云任务管理时,优先用 `uniqc`,不要先写临时辅助脚本。
当前有几个细节要特别注意:
- `uniqc submit` 使用 `--platform`,并可选搭配 `--backend`
- 对 OriginQ,当前 CLI 选项是 `--backend`,不是旧的 `--chip-id`
- 对 Quafu,`chip_id` 在 Python API 中仍然相关,但当前 CLI 没有单独暴露 `--chip-id`
- `simulate` 最稳妥的输入仍是 OriginIR;如果手里是 QASM,先做归一化
## Python API 指引
如果是编程式的任务工作流,优先使用:
```python
from uniqc import submit_task, submit_batch, query_task, wait_for_result
```
构造 ansatz 时,优先使用当前公开导出:
```python
from uniqc.algorithmics.ansatz import hea, qaoa_ansatz, uccsd_ansatz
```
不要再使用像 `uccsd` 这样的旧名字。
PyTorch 集成优先使用:
```python
from uniqc.pytorch import (
QuantumLayer,
batch_execute,
batch_execute_with_params,
parameter_shift_gradient,
compute_all_gradients,
)
```
## 接下来读什么
- 线路构建与导出:[references/circuit-building.md](references/circuit-building.md)
- CLI 用法:[references/cli-guide.md](references/cli-guide.md)
- 本地模拟与 dummy 模式:[references/simulators.md](references/simulators.md)
- 配置、云端后端与任务缓存:[references/cloud-platforms.md](references/cloud-platforms.md)
- ansatz 与变分工作流:[references/variational-algorithms.md](references/variational-algorithms.md)
- PyTorch 辅助接口:[references/pytorch-integration.md](references/pytorch-integration.md)
- H2 风格的 VQE 任务:[references/h2-molecular-simulation.md](references/h2-molecular-simulation.md)
- 主题检查之后仍然不清楚的通用排障:[references/troubleshooting.md](references/troubleshooting.md)
## 回答启发式
- 如果用户想要一个快速起步,先从 `Circuit -> originir -> uniqc` 开始。
- 如果用户卡在云端执行,先检查配置和后端特有 kwargs;如果仍然不清楚,再回到 [references/troubleshooting.md](references/troubleshooting.md)。
- 如果用户问的是本地模拟失败,先检查 `simulation` 相关依赖;必要时再回到 [references/troubleshooting.md](references/troubleshooting.md)。
- 如果用户提到缺命令、缺导入、缺 extra、缺配置路径,或者文档与本地行为不一致,先拍安装快照,再判断是不是版本漂移导致,然后查同类 issue,最后再进入 [references/troubleshooting.md](references/troubleshooting.md) 的完整通用排障流程。
- 如果需要安装,先用简短选项问清用户想装到哪里,再执行;不要直接替用户选安装路径。
- 如果用户想看现代的变分示例,优先从 `hea`、`qaoa_ansatz` 或 `uccsd_ansatz` 开始,不要从旧 helper 名称起步。
- 如果用户想走 shell 工作流,优先给 `uniqc` CLI 方案,而不是自定义 wrapper。
FILE:examples/basic_circuit.py
#!/usr/bin/env python3
"""Basic UnifiedQuantum circuit example.
Builds a Bell circuit, prints both export formats, and tries a local
probability simulation when simulation dependencies are available.
"""
from __future__ import annotations
from pprint import pprint
from uniqc.circuit_builder import Circuit
def build_bell_circuit() -> Circuit:
circuit = Circuit(2)
circuit.h(0)
circuit.cnot(0, 1)
circuit.measure(0, 1)
return circuit
def try_local_simulation(circuit: Circuit) -> None:
try:
from uniqc.task.optional_deps import check_simulation
except ImportError:
check_simulation = lambda: False
if not check_simulation():
print("Local simulation skipped: install unified-quantum[simulation] first.")
return
from uniqc.simulator import OriginIR_Simulator
simulator = OriginIR_Simulator(backend_type="statevector")
probabilities = simulator.simulate_pmeasure(circuit.originir)
print("\nState probabilities:")
pprint(
{
format(index, f"0{simulator.qubit_num}b"): float(probability)
for index, probability in enumerate(probabilities)
if float(probability) > 1e-10
}
)
def main() -> None:
circuit = build_bell_circuit()
print("OriginIR")
print("-" * 60)
print(circuit.originir)
print("\nOpenQASM 2.0")
print("-" * 60)
print(circuit.qasm)
try_local_simulation(circuit)
if __name__ == "__main__":
main()
FILE:examples/cli_demo.sh
#!/usr/bin/env bash
# Demo of the current uniqc CLI workflow.
set -euo pipefail
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT
run_uniqc() {
if command -v uniqc >/dev/null 2>&1; then
uniqc "$@"
else
python3 -m uniqc "$@"
fi
}
cat >"$TMP_DIR/build_bell.py" <<'PY'
from uniqc.circuit_builder import Circuit
c = Circuit(2)
c.h(0)
c.cnot(0, 1)
c.measure(0, 1)
with open("bell.ir", "w", encoding="utf-8") as f:
f.write(c.originir)
PY
echo "[1/4] Build a Bell circuit as OriginIR"
(cd "$TMP_DIR" && python3 build_bell.py)
echo
echo "[2/4] Show circuit info"
run_uniqc circuit "$TMP_DIR/bell.ir" --info
echo
echo "[3/4] Convert to OpenQASM 2.0"
run_uniqc circuit "$TMP_DIR/bell.ir" --format qasm -o "$TMP_DIR/bell.qasm"
sed -n '1,40p' "$TMP_DIR/bell.qasm"
echo
echo "[4/4] Try local simulation and dummy submission"
echo "These steps usually require unified-quantum[simulation]."
if run_uniqc simulate "$TMP_DIR/bell.ir" --shots 1024 --format json; then
echo
run_uniqc submit "$TMP_DIR/bell.ir" --platform dummy --wait --format json
else
echo "Simulation failed. Install unified-quantum[simulation] and retry."
fi
FILE:examples/cloud_submission.py
#!/usr/bin/env python3
"""Programmatic cloud-task examples for UnifiedQuantum.
By default this script runs a dummy submission so it is safe for local
testing. Real backend examples are included as callable functions but are
not executed automatically.
"""
from __future__ import annotations
import argparse
from pprint import pprint
from uniqc import Circuit, query_task, submit_task, wait_for_result
def build_bell_circuit() -> Circuit:
circuit = Circuit(2)
circuit.h(0)
circuit.cnot(0, 1)
circuit.measure(0, 1)
return circuit
def print_result(result: dict | None) -> None:
if not result:
print("No result returned.")
return
print("Normalized result payload:")
pprint(result)
if "counts" in result:
print("\nCounts:")
pprint(result["counts"])
if "probabilities" in result:
print("\nProbabilities:")
pprint(result["probabilities"])
def run_dummy_demo(shots: int) -> None:
try:
from uniqc.task.optional_deps import check_simulation
except ImportError:
check_simulation = lambda: False
if not check_simulation():
raise RuntimeError(
"Dummy mode uses the local simulator. Install unified-quantum[simulation] first."
)
circuit = build_bell_circuit()
task_id = submit_task(
circuit,
backend="originq",
shots=shots,
dummy=True,
metadata={"example": "cloud_submission.py"},
)
print(f"Dummy task submitted: {task_id}")
task_info = query_task(task_id)
print(f"Cached task status: {task_info.status}")
print(f"Cached backend tag: {task_info.backend}")
result = wait_for_result(task_id, timeout=60)
print_result(result)
def real_originq_example(shots: int) -> str:
"""Skeleton for a real OriginQ submission.
Requires:
1. pip install "unified-quantum[originq]"
2. uniqc config set originq.token YOUR_TOKEN
"""
circuit = build_bell_circuit()
return submit_task(
circuit,
backend="originq",
shots=shots,
backend_name="origin:wuyuan:d5",
metadata={"example": "real-originq"},
)
def real_quafu_example(shots: int) -> str:
"""Skeleton for a real Quafu submission.
Requires:
1. pip install "unified-quantum[quafu]"
2. uniqc config set quafu.token YOUR_TOKEN
"""
circuit = build_bell_circuit()
return submit_task(
circuit,
backend="quafu",
shots=shots,
chip_id="ScQ-P10",
metadata={"example": "real-quafu"},
)
def real_ibm_example(shots: int) -> str:
"""Skeleton for a real IBM submission.
Requires:
1. pip install "unified-quantum[qiskit]"
2. uniqc config set ibm.token YOUR_TOKEN
"""
circuit = build_bell_circuit()
return submit_task(
circuit,
backend="ibm",
shots=shots,
metadata={"example": "real-ibm"},
)
def main() -> None:
parser = argparse.ArgumentParser(description="UnifiedQuantum cloud submission demo")
parser.add_argument("--shots", type=int, default=1000)
args = parser.parse_args()
run_dummy_demo(args.shots)
print("\nReal backend entry points are available as helper functions:")
print(" - real_originq_example(shots)")
print(" - real_quafu_example(shots)")
print(" - real_ibm_example(shots)")
if __name__ == "__main__":
main()
FILE:examples/h2_hea_vqe.py
#!/usr/bin/env python3
"""Minimal H2-style VQE workflow with HEA.
This example uses a reduced two-qubit Hamiltonian to demonstrate the
current UnifiedQuantum variational workflow:
1. build an ansatz with ``hea()``
2. simulate probabilities locally
3. evaluate expectation values with ``calculate_expectation()``
4. optimize with SciPy
It is intentionally lightweight and should be read as a workflow template,
not as a complete quantum-chemistry stack.
"""
from __future__ import annotations
import argparse
from typing import Iterable
import numpy as np
from scipy.optimize import minimize
from uniqc.algorithmics.ansatz import hea
from uniqc.analyzer import calculate_expectation
REDUCED_H2_TERMS: list[tuple[float, str]] = [
(-1.052373245772859, "II"),
(0.39793742484318045, "ZI"),
(-0.39793742484318045, "IZ"),
(-0.01128010425623538, "ZZ"),
]
def probability_dict(probabilities: Iterable[float], n_qubits: int) -> dict[str, float]:
return {
format(index, f"0{n_qubits}b"): float(value)
for index, value in enumerate(probabilities)
if float(value) > 1e-12
}
def build_energy_function(depth: int):
try:
from uniqc.task.optional_deps import check_simulation
except ImportError:
check_simulation = lambda: False
if not check_simulation():
raise RuntimeError(
"This example needs local simulation. Install unified-quantum[simulation] first."
)
from uniqc.simulator import OriginIR_Simulator
simulator = OriginIR_Simulator(backend_type="statevector")
n_qubits = 2
def energy(params: np.ndarray) -> float:
circuit = hea(n_qubits=n_qubits, depth=depth, params=params)
probabilities = simulator.simulate_pmeasure(circuit.originir)
probs = probability_dict(probabilities, n_qubits)
total = 0.0
for coefficient, pauli in REDUCED_H2_TERMS:
if pauli == "II":
total += coefficient
else:
total += coefficient * calculate_expectation(probs, pauli)
return float(total)
return energy
def main() -> None:
parser = argparse.ArgumentParser(description="Reduced H2-style HEA VQE demo")
parser.add_argument("--depth", type=int, default=1)
parser.add_argument("--maxiter", type=int, default=100)
parser.add_argument("--seed", type=int, default=7)
args = parser.parse_args()
np.random.seed(args.seed)
energy = build_energy_function(args.depth)
n_params = 2 * 2 * args.depth
x0 = np.random.uniform(0.0, 2 * np.pi, size=n_params)
result = minimize(
energy,
x0=x0,
method="COBYLA",
options={"maxiter": args.maxiter},
)
print("Reduced H2-style VQE")
print("-" * 60)
print(f"Depth: {args.depth}")
print(f"Initial energy: {energy(x0):.8f}")
print(f"Optimized energy: {result.fun:.8f}")
print(f"Iterations: {result.nfev}")
print(f"Best parameters: {result.x}")
if __name__ == "__main__":
main()
FILE:examples/mnist_classifier.py
#!/usr/bin/env python3
"""Lightweight digit-classification demo using UnifiedQuantum.
This file keeps the historical ``mnist_classifier.py`` name, but the
current example is intentionally smaller and easier to run:
- loads the scikit-learn digits dataset
- keeps only digits 0 and 1
- angle-encodes 4 PCA features into a 4-qubit circuit
- extracts simple quantum features in parallel with ``batch_execute``
- trains a classical logistic regression head
Requirements:
pip install "unified-quantum[simulation]" scikit-learn
"""
from __future__ import annotations
import argparse
import numpy as np
from sklearn.datasets import load_digits
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from uniqc.analyzer import calculate_expectation
from uniqc.circuit_builder import Circuit
from uniqc.pytorch import batch_execute
def require_simulation() -> None:
try:
from uniqc.task.optional_deps import check_simulation
except ImportError:
check_simulation = lambda: False
if not check_simulation():
raise RuntimeError(
"This example needs local simulation. Install unified-quantum[simulation] first."
)
def load_binary_digits(max_samples: int) -> tuple[np.ndarray, np.ndarray]:
dataset = load_digits()
mask = np.isin(dataset.target, [0, 1])
data = dataset.data[mask]
target = dataset.target[mask]
if max_samples > 0:
data = data[:max_samples]
target = target[:max_samples]
scaler = StandardScaler()
data = scaler.fit_transform(data)
pca = PCA(n_components=4)
reduced = pca.fit_transform(data)
min_value = reduced.min()
max_value = reduced.max()
encoded = (reduced - min_value) / (max_value - min_value + 1e-12) * np.pi
return encoded, target
def build_encoding_circuit(sample: np.ndarray) -> Circuit:
circuit = Circuit(4)
for qubit, angle in enumerate(sample[:4]):
circuit.ry(qubit, float(angle))
circuit.cx(0, 1)
circuit.cx(1, 2)
circuit.cx(2, 3)
circuit.measure(0, 1, 2, 3)
return circuit
def extract_quantum_features(samples: np.ndarray) -> np.ndarray:
from uniqc.simulator import OriginIR_Simulator
simulator = OriginIR_Simulator(backend_type="statevector")
circuits = [build_encoding_circuit(sample) for sample in samples]
def executor(circuit: Circuit) -> np.ndarray:
probabilities = simulator.simulate_pmeasure(circuit.originir)
probs = {
format(index, "04b"): float(value)
for index, value in enumerate(probabilities)
if float(value) > 1e-12
}
return np.array(
[
calculate_expectation(probs, "ZIII"),
calculate_expectation(probs, "IZII"),
calculate_expectation(probs, "IIZI"),
calculate_expectation(probs, "IIIZ"),
]
)
features = batch_execute(circuits, executor, n_workers=4)
return np.vstack(features)
def main() -> None:
parser = argparse.ArgumentParser(description="Binary digit classification with quantum features")
parser.add_argument("--max-samples", type=int, default=200)
parser.add_argument("--test-size", type=float, default=0.25)
args = parser.parse_args()
require_simulation()
x, y = load_binary_digits(args.max_samples)
x_train, x_test, y_train, y_test = train_test_split(
x, y, test_size=args.test_size, random_state=42, stratify=y
)
train_features = extract_quantum_features(x_train)
test_features = extract_quantum_features(x_test)
model = LogisticRegression(max_iter=500)
model.fit(train_features, y_train)
predictions = model.predict(test_features)
print("Quantum feature extraction completed.")
print(f"Train samples: {len(x_train)}")
print(f"Test samples: {len(x_test)}")
print("\nClassification report:")
print(classification_report(y_test, predictions))
if __name__ == "__main__":
main()
FILE:examples/qaoa_maxcut.py
#!/usr/bin/env python3
"""QAOA MaxCut demo aligned with the current qaoa_ansatz API."""
from __future__ import annotations
import argparse
import numpy as np
from scipy.optimize import minimize
from uniqc.algorithmics.ansatz import qaoa_ansatz
PRESET_GRAPHS = {
"triangle": [(0, 1), (1, 2), (0, 2)],
"square": [(0, 1), (1, 2), (2, 3), (3, 0)],
"line3": [(0, 1), (1, 2)],
}
def require_simulation() -> None:
try:
from uniqc.task.optional_deps import check_simulation
except ImportError:
check_simulation = lambda: False
if not check_simulation():
raise RuntimeError(
"This example needs local simulation. Install unified-quantum[simulation] first."
)
def build_cost_hamiltonian(edges: list[tuple[int, int]]) -> list[tuple[str, float]]:
return [(f"Z{i}Z{j}", -0.5) for i, j in edges]
def bitstring_cut_value(bitstring: str, edges: list[tuple[int, int]]) -> int:
return sum(1 for i, j in edges if bitstring[i] != bitstring[j])
def expected_cut(probabilities: dict[str, float], edges: list[tuple[int, int]]) -> float:
return sum(probability * bitstring_cut_value(bitstring, edges) for bitstring, probability in probabilities.items())
def main() -> None:
parser = argparse.ArgumentParser(description="QAOA MaxCut demo")
parser.add_argument("--graph", choices=sorted(PRESET_GRAPHS), default="triangle")
parser.add_argument("--p", type=int, default=1)
parser.add_argument("--maxiter", type=int, default=80)
parser.add_argument("--seed", type=int, default=7)
args = parser.parse_args()
require_simulation()
from uniqc.simulator import OriginIR_Simulator
np.random.seed(args.seed)
edges = PRESET_GRAPHS[args.graph]
n_qubits = max(max(edge) for edge in edges) + 1
cost_hamiltonian = build_cost_hamiltonian(edges)
simulator = OriginIR_Simulator(backend_type="statevector")
def objective(parameters: np.ndarray) -> float:
betas = parameters[: args.p]
gammas = parameters[args.p :]
circuit = qaoa_ansatz(cost_hamiltonian, p=args.p, betas=betas, gammas=gammas)
circuit.measure(*range(n_qubits))
raw_probabilities = simulator.simulate_pmeasure(circuit.originir)
probabilities = {
format(index, f"0{n_qubits}b"): float(value)
for index, value in enumerate(raw_probabilities)
if float(value) > 1e-12
}
return -expected_cut(probabilities, edges)
initial = np.random.uniform(0.0, np.pi, size=2 * args.p)
result = minimize(
objective,
x0=initial,
method="COBYLA",
options={"maxiter": args.maxiter},
)
best_betas = result.x[: args.p]
best_gammas = result.x[args.p :]
final_circuit = qaoa_ansatz(cost_hamiltonian, p=args.p, betas=best_betas, gammas=best_gammas)
final_circuit.measure(*range(n_qubits))
final_raw_probabilities = simulator.simulate_pmeasure(final_circuit.originir)
final_probabilities = {
format(index, f"0{n_qubits}b"): float(value)
for index, value in enumerate(final_raw_probabilities)
if float(value) > 1e-12
}
print("QAOA MaxCut")
print("-" * 60)
print(f"Graph: {args.graph}")
print(f"Edges: {edges}")
print(f"Layers p: {args.p}")
print(f"Best expected cut: {-result.fun:.6f}")
print(f"Best betas: {best_betas}")
print(f"Best gammas: {best_gammas}")
print("\nTop bitstrings:")
for bitstring, probability in sorted(final_probabilities.items(), key=lambda item: item[1], reverse=True)[:5]:
print(
f" {bitstring} prob={probability:.4f} cut={bitstring_cut_value(bitstring, edges)}"
)
if __name__ == "__main__":
main()
FILE:README.md
# quantum-computing
[](https://github.com/IAI-USTC-Quantum)
面向 [UnifiedQuantum](https://github.com/IAI-USTC-Quantum/UnifiedQuantum) 的本地 skill 仓库。
安装后,支持 skills 的 Agent 可以更稳地处理 UnifiedQuantum 相关任务,例如线路构建、OriginIR / QASM 转换、本地模拟、云平台提交、变分算法示例、PyTorch 集成和通用排障。
## 这个 skill 能帮你什么
适合让 Agent 帮你处理这类事情:
- 写或修改 `Circuit` 线路代码
- 把线路导出成 OriginIR 或 OpenQASM
- 用 `uniqc` CLI 做转换、模拟、提交和查结果
- 检查本地模拟、dummy 模式或云平台配置问题
- 搭一个最小的 VQE / QAOA / UCCSD 示例
- 看 `QuantumLayer`、parameter-shift 和批处理接口怎么接进 PyTorch
## 你可以直接让 Agent 做什么
安装后,可以直接对 Agent 说这类请求:
- “帮我写一个 Bell state 的 UnifiedQuantum 示例,并导出 OriginIR。”
- “帮我把这段 QASM 转成更适合 `uniqc simulate` 的流程。”
- “帮我查一下为什么 `uniqc` 命令存在,但 `import uniqc` 失败。”
- “帮我写一个最小 QAOA MaxCut 例子。”
- “帮我看一下 dummy 模式为什么跑不通。”
- “帮我把这个 PyTorch 训练循环接上 `QuantumLayer`。”
## 安装此 skill
先把仓库放到本地,再把它链接或复制到你的 skill 目录。
```bash
git clone https://github.com/IAI-USTC-Quantum/quantum-computing.skill.git
mkdir -p ~/.Agents/skills
ln -s /path/to/quantum-computing.skill ~/.Agents/skills/quantum-computing
```
如果你已经有自己的共享 skills 目录,就安装到那个目录里。
安装完成后,Agent 就可以从 `SKILL.md` 和 `references/` 里读取更具体的操作规则、主题说明和排障步骤。
## 仓库内容
- `SKILL.md`:主入口,包含触发条件、操作规则和导航
- `references/`:按主题整理的使用说明与排障参考
- `examples/`:可复用的示例代码
- `scripts/`:环境检查和辅助脚本
## 许可证
Apache 2.0 许可证
FILE:references/circuit-building.md
# 线路构建参考
当前 UnifiedQuantum 的核心对象仍然是 `uniqc.circuit_builder.Circuit`。
最常见的工作流是:
1. 构建 `Circuit`
2. 导出 `originir` 或 `qasm`
3. 交给 `uniqc` CLI、模拟器或 `task_manager`
## 快速开始
```python
from uniqc.circuit_builder import Circuit
c = Circuit()
c.h(0)
c.cnot(0, 1)
c.measure(0, 1)
print(c.originir)
print(c.qasm)
```
## 初始化方式
```python
from uniqc.circuit_builder import Circuit
c = Circuit() # 自动按使用到的 qubit 推断
c = Circuit(4) # 固定 qubit 数
c = Circuit(qregs={"data": 4, "ancilla": 2}) # 命名寄存器
```
## 常用属性
| 属性 | 含义 |
|------|------|
| `originir` | OriginIR 文本 |
| `qasm` | OpenQASM 2.0 文本 |
| `circuit` | 一般可视为 `originir` 别名 |
| `qubit_num` | 当前线路的 qubit 数 |
| `cbit_num` | 当前线路的 classical bit 数 |
| `depth` | 线路深度 |
| `used_qubit_list` | 实际用到的 qubit |
| `measure_list` | 已加入测量的 qubit |
| `opcode_list` | 内部 opcode 列表 |
## 常用门
### 单比特门
```python
c.h(0)
c.x(0)
c.y(0)
c.z(0)
c.s(0)
c.t(0)
c.sx(0)
c.sxdg(0)
c.identity(0)
```
### 旋转门
```python
c.rx(0, theta)
c.ry(0, theta)
c.rz(0, theta)
c.rphi(0, theta, phi)
c.u1(0, lam)
c.u2(0, phi, lam)
c.u3(0, theta, phi, lam)
```
### 双比特 / 三比特门
```python
c.cnot(0, 1)
c.cx(0, 1)
c.cz(0, 1)
c.swap(0, 1)
c.iswap(0, 1)
c.xx(0, 1, theta)
c.yy(0, 1, theta)
c.zz(0, 1, theta)
c.phase2q(0, 1, t1, t2, tzz)
c.uu15(0, 1, params)
c.toffoli(0, 1, 2)
c.cswap(0, 1, 2)
```
## 测量
```python
c.measure(0)
c.measure(0, 1, 2)
```
测量会按调用顺序分配 classical bit。
## 控制与 dagger 上下文
```python
with c.control(0):
c.x(1)
c.z(2)
with c.dagger():
c.h(0)
c.rx(1, 0.5)
```
## 命名寄存器
```python
c = Circuit(qregs={"data": 4, "anc": 2})
data = c.get_qreg("data")
c.h(data[0])
c.cnot(data[0], data[1])
```
常用类型:
```python
from uniqc.circuit_builder import Qubit, QReg, QRegSlice
```
## 参数与可复用电路
可复用子线路一般通过 `circuit_def` / `NamedCircuit` 表达:
```python
from uniqc.circuit_builder import Circuit, circuit_def
@circuit_def(name="bell_pair", qregs={"q": 2})
def bell_pair(circ, q):
circ.h(q[0])
circ.cnot(q[0], q[1])
return circ
c = Circuit(2)
bell_pair(c, qreg_mapping={"q": [0, 1]})
```
如果用户需要参数化子线路,优先沿这条路径组织,而不是手工约定一套外部模板格式。
## 复制、拼接、重映射
```python
c2 = c.copy()
c2.add_circuit(other)
mapped = c.remapping({0: 3, 1: 5})
```
`remapping()` 返回新线路,不会原地改动。
## 屏障
```python
c.barrier(0, 1, 2)
```
## 输出建议
最稳妥的导出方式通常是:
- 需要 CLI、云提交、dummy 模式时:优先 `originir`
- 需要和第三方工具交换时:使用 `qasm`
如果后续步骤涉及 `uniqc simulate`,建议先把输入统一到 OriginIR,再继续执行。
FILE:references/cli-guide.md
# CLI 使用参考
UnifiedQuantum 当前的 CLI 入口是:
```bash
uniqc
```
等价 Python 入口:
```bash
python3 -m uniqc
```
## 命令总览
- `uniqc circuit`
- `uniqc simulate`
- `uniqc submit`
- `uniqc result`
- `uniqc task`
- `uniqc config`
## 一条稳妥的 Shell 工作流
如果输入来自 QASM,推荐先归一化:
```bash
uniqc circuit input.qasm --format originir -o normalized.ir
uniqc simulate normalized.ir
uniqc submit normalized.ir --platform dummy --wait
```
这样比直接把多种格式混进不同命令里更稳。
## `uniqc circuit`
格式转换和统计信息:
```bash
uniqc circuit INPUT_FILE [--format originir|qasm] [--output PATH] [--info]
```
示例:
```bash
uniqc circuit bell.ir --format qasm -o bell.qasm
uniqc circuit bell.qasm --format originir -o bell.ir
uniqc circuit bell.ir --info
```
## `uniqc simulate`
本地模拟:
```bash
uniqc simulate INPUT_FILE [--backend statevector] [--shots 1024] [--format table|json]
```
示例:
```bash
uniqc simulate bell.ir
uniqc simulate bell.ir --shots 4096 --format json
```
注意:
- 当前最安全的输入是 OriginIR
- 本地模拟通常需要安装 `unified-quantum[simulation]`
- 当前 CLI 的 `simulate` 路径最适合 `statevector`
- 密度矩阵工作流更建议走 Python API,并显式使用 `OriginIR_Simulator(backend_type="densitymatrix")`
## `uniqc submit`
提交云任务或 dummy 任务:
```bash
uniqc submit INPUT_FILES... --platform originq|quafu|ibm|dummy
```
当前可见选项:
```bash
--platform / -p
--backend / -b
--shots / -s
--name
--wait / -w
--timeout
--format / -f
```
示例:
```bash
uniqc submit bell.ir --platform originq --shots 1000
uniqc submit bell.ir --platform originq --backend origin:wuyuan:d5
uniqc submit bell.ir --platform dummy --wait
uniqc submit a.ir b.ir --platform quafu --shots 2000
```
关键区别:
- 当前 CLI 用的是 `--backend`,不是一些旧示例里常见的 `--chip-id`
- 对 OriginQ,`--backend` 常用于指定硬件名,例如 `origin:wuyuan:d5`
- 对 Quafu,底层 Python API 仍可传 `chip_id`,但当前 CLI 没有单独的 `--chip-id`
## `uniqc result`
查询任务结果:
```bash
uniqc result TASK_ID [--platform PLATFORM] [--wait] [--timeout 300] [--format table|json]
```
示例:
```bash
uniqc result abc123 --platform originq
uniqc result abc123 --wait --timeout 600
```
如果任务已经在本地 cache 里,通常可以少传一点参数;如果不在 cache 里,再补 `--platform`。
## `uniqc task`
本地任务缓存管理:
```bash
uniqc task list
uniqc task show TASK_ID
uniqc task clear
```
可用选项包括:
- `task list --status ... --platform ... --limit ... --format ...`
- `task clear --status ... --force`
## `uniqc config`
配置 `~/.uniqc/uniqc.yml`:
```bash
uniqc config init
uniqc config set originq.token YOUR_TOKEN
uniqc config get originq
uniqc config list
uniqc config validate
uniqc config profile list
uniqc config profile create dev
uniqc config profile use dev
```
## 配置 profile 与环境变量
- 默认 profile:`default`
- 当前激活 profile 可写进配置文件
- 临时覆盖可用:
```bash
export UNIQC_PROFILE=dev
```
## 常见误区
- 不要再把 CLI 讲成旧版的 `chip-id` 优先接口
- 不要假设裸环境一定能直接 `simulate`
- 不要默认系统里有 `python`;脚本示例优先写 `python3` 或 `uv run`
FILE:references/cloud-platforms.md
# 云平台参考
当前 UnifiedQuantum 的云执行路径分两层:
1. CLI:`uniqc submit` / `uniqc result` / `uniqc task`
2. Python API:`submit_task` / `submit_batch` / `query_task` / `wait_for_result`
## 配置文件
默认配置路径:
```text
~/.uniqc/uniqc.yml
```
典型结构:
```yaml
default:
originq:
token: ""
available_qubits: []
available_topology: []
task_group_size: 200
quafu:
token: ""
ibm:
token: ""
proxy:
http: ""
https: ""
```
初始化:
```bash
uniqc config init
```
设置 token:
```bash
uniqc config set originq.token YOUR_ORIGINQ_TOKEN
uniqc config set quafu.token YOUR_QUAFU_TOKEN
uniqc config set ibm.token YOUR_IBM_TOKEN
```
## 配置 profile
可通过多 profile 管理不同环境:
```bash
uniqc config profile create dev
uniqc config profile use dev
uniqc config profile list
```
也可以临时覆盖:
```bash
export UNIQC_PROFILE=dev
```
## Python 任务 API
最常用的公共入口:
```python
from uniqc import (
submit_task,
submit_batch,
query_task,
wait_for_result,
list_tasks,
clear_completed_tasks,
)
```
### `submit_task`
```python
task_id = submit_task(
circuit,
backend="originq",
shots=1000,
metadata={"name": "demo"},
)
```
后端相关的常见 kwargs:
- OriginQ:
- `backend_name="origin:wuyuan:d5"`
- `circuit_optimize=...`
- `measurement_amend=...`
- Quafu:
- `chip_id="ScQ-P10"`
- `auto_mapping=True`
- 通用 dummy 覆盖:
- `dummy=True`
### `submit_batch`
```python
task_ids = submit_batch(
[circuit_a, circuit_b],
backend="quafu",
shots=2000,
)
```
### `query_task`
```python
task_info = query_task(task_id)
print(task_info.status)
```
如果任务不在本地 cache 中,通常需要补 `backend=...`。
### `wait_for_result`
```python
result = wait_for_result(task_id, backend="originq", timeout=300)
```
返回值通常是一个归一化后的结果字典;dummy 路径下最常见的结构类似:
```python
{
"counts": {"00": 500, "11": 500},
"probabilities": {"00": 0.5, "11": 0.5},
"shots": 1000,
"platform": "dummy",
"task_id": "...",
}
```
不同平台的原始数据会被归一化,但如果用户只关心最稳妥的兼容字段,优先读:
- `counts`
- `probabilities`
## dummy 模式
dummy 模式用于本地模拟,不消耗真实云平台额度。
启用方式有两类:
### 1. 单次任务
```python
task_id = submit_task(circuit, backend="originq", dummy=True)
```
### 2. 全局环境变量
```bash
export UNIQC_DUMMY=true
```
然后:
```python
task_id = submit_task(circuit, backend="originq")
```
注意:
- dummy 模式通常仍需要本地模拟依赖
- 它更适合开发 / 测试 / 文档示例,不等于“完全无依赖”
## 本地任务缓存
当前任务缓存使用 SQLite:
```text
~/.uniqc/cache/tasks.sqlite
```
相关接口:
```python
from uniqc import list_tasks, clear_completed_tasks, clear_cache
```
CLI 里对应:
```bash
uniqc task list
uniqc task show TASK_ID
uniqc task clear
```
## `TaskInfo`
缓存和查询结果常见字段:
- `task_id`
- `backend`
- `status`
- `result`
- `shots`
- `submit_time`
- `update_time`
- `metadata`
## 平台建议
### OriginQ
- 先确认 token 已配置
- Python API 更适合传 `backend_name`
- CLI 用 `--backend`
### Quafu
- 先确认 token 已配置
- Python API 可传 `chip_id`
- 当前 CLI 对 Quafu 的专有参数表达较少,必要时优先 Python
### IBM
- 先确认 token 已配置
- 代理设置写在 `ibm.proxy.http` / `ibm.proxy.https`
## 使用这些接口时不要默认
- 不要默认 dummy 模式“无条件可用”
- 不要默认 CLI 已经完整暴露了所有平台专有参数
- 不要默认任务结果永远只有一种字段布局;更稳妥的是优先读取常用字段
FILE:references/h2-molecular-simulation.md
# H2 分子模拟参考
这个主题最容易受版本和依赖影响。用户提到 “H2 模拟” 时,先不要默认当前环境已经具备完整、固定的量子化学求解栈,更稳妥的做法是先确认他到底想解决哪一层问题。
## 推荐的定位
当用户说“H2 模拟”时,先分清楚他要的是哪一层:
1. 想看一个最小 VQE 例子
2. 想看 `hea` / `uccsd_ansatz` 如何接进变分循环
3. 想接入真实量子化学积分与 Hamiltonian 生成
当前 UnifiedQuantum 更适合稳定覆盖前两层。
## 推荐的理解方式
优先把 H2 任务理解成:
- 选一个小规模哈密顿量
- 选一个 ansatz(HEA 或 UCCSD)
- 用本地模拟器估计目标值
- 用经典优化器最小化能量
不要默认当前环境已经“内置了完整分子积分、Jordan-Wigner、basis set 流水线”。
## 最常用两个入口
### HEA
```python
from uniqc.algorithmics.ansatz import hea
```
适合:
- 教学演示
- 先跑通 VQE 外框架
### UCCSD
```python
from uniqc.algorithmics.ansatz import uccsd_ansatz
```
适合:
- 更接近量子化学 ansatz 的表达
- 已知 qubit 数和电子数时的最小示例
## 结果估计
当前更推荐两种估计路线:
1. 从 `simulate_pmeasure()` 得到概率分布,再用 `calculate_expectation()` 算 Z 型项
2. 从 `simulate_statevector()` 得到态矢,在示例里手工实现所需的观测量计算
如果只做教学示例,第一种通常更简单。
## 应该明确说出的限制
- H2 示例通常依赖本地模拟能力,因此往往需要 `unified-quantum[simulation]`
- 这里的 H2 示例更偏“工作流模板”,不是完整量化化学软件替代品
- 如果用户真的需要从分子几何一路生成哈密顿量,通常还要引入额外化学工具链
FILE:references/pytorch-integration.md
# PyTorch 集成参考
UnifiedQuantum 当前的 PyTorch 集成是辅助工具风格,而不是“一整套端到端训练框架”。
基础安装:
```bash
pip install "unified-quantum[pytorch]"
```
如果需要 TorchQuantum:
```bash
pip install "unified-quantum[torchquantum]"
```
## 当前公开接口
```python
from uniqc.pytorch import (
QuantumLayer,
batch_execute,
batch_execute_with_params,
parameter_shift_gradient,
compute_all_gradients,
)
```
可选情况下还可能有:
```python
from uniqc.pytorch import TorchQuantumLayer
```
## `QuantumLayer`
`QuantumLayer` 是一个基于 parameter-shift 的 `nn.Module` 包装器。
它需要两个核心输入:
1. 一个带参数映射的电路模板
2. 一个从绑定后线路计算期望值的函数
这里要特别保守一点说明:
- `QuantumLayer` 不是“给任意 `Circuit` 一包就能直接训练”
- 调用方需要准备好一个适配它的参数化线路模板
- 如果用户只是想先验证思路,通常先用 `parameter_shift_gradient` 或 `batch_execute_with_params` 更稳
因此更稳妥的理解是:把 `QuantumLayer` 当成“已有参数化线路模板后的包装器”,不要把它当成零配置的端到端训练入口。
## Parameter-shift 辅助函数
### 单参数梯度
```python
from uniqc.pytorch import parameter_shift_gradient
grad = parameter_shift_gradient(circuit, "theta", expectation_fn)
```
### 全部参数梯度
```python
from uniqc.pytorch import compute_all_gradients
grads = compute_all_gradients(circuit, expectation_fn)
```
## 批处理辅助函数
### 批量执行多个线路
```python
from uniqc.pytorch import batch_execute
results = batch_execute(circuits, executor, n_workers=4)
```
### 对一个模板绑定多组参数
```python
from uniqc.pytorch import batch_execute_with_params
results = batch_execute_with_params(
circuit_template,
[{"theta": 0.1}, {"theta": 0.2}],
executor,
)
```
## `TorchQuantumLayer`
如果用户安装了 `torchquantum`,还可能使用 `TorchQuantumLayer`,它走的是 TorchQuantum 的原生自动求导路径,而不是 parameter-shift。
适合场景:
- 已经在用 TorchQuantum
- 想要更“端到端”的可微分体验
## 使用这些接口时记住
- 把这些工具理解为“辅助工具”
- 用户仍要自己定义 expectation / loss / optimizer
- 不要默认 UnifiedQuantum 自带完整数据集管道
- 如果示例需要 `torchvision`、`scikit-learn` 等第三方库,要单独确认这些依赖
FILE:references/simulators.md
# 模拟器参考
UnifiedQuantum 提供本地模拟能力,但当前应该把它理解为“常用能力 + 明确依赖边界”,而不是默认裸环境必备。
## 依赖边界
本地模拟、dummy 模式、部分算法示例通常需要:
```bash
pip install "unified-quantum[simulation]"
```
如果用户看到这类报错,优先怀疑缺可选依赖:
- `No module named 'qutip'`
- `MissingDependencyError(... simulation ...)`
- `uniqc is not installed with UniqcCpp`
## 主要类
### `OriginIR_Simulator`
```python
from uniqc.simulator import OriginIR_Simulator
sim = OriginIR_Simulator(backend_type="statevector")
```
常见方法:
```python
probs = sim.simulate_pmeasure(circuit.originir)
statevector = sim.simulate_statevector(circuit.originir)
rho = sim.simulate_density_matrix(circuit.originir)
counts = sim.simulate_shots(circuit.originir, shots=1000)
```
### `OriginIR_NoisySimulator`
```python
from uniqc.simulator import OriginIR_NoisySimulator
```
适合在有噪声模型时做本地实验。
## 后端类型
最稳妥的后端类型选择:
- `statevector`
- `densitymatrix`
示例:
```python
sim = OriginIR_Simulator(backend_type="statevector")
sim = OriginIR_Simulator(backend_type="densitymatrix")
```
当前 CLI 的 `simulate` 子命令更适合走 `statevector` 路径;如果用户明确要密度矩阵模拟,优先给 Python API 方案。
## 输入格式建议
`OriginIR_Simulator` 最适合直接吃 OriginIR:
```python
result = sim.simulate_pmeasure(circuit.originir)
```
如果用户手里只有 QASM,先统一格式更稳:
1. `Circuit.qasm -> uniqc circuit --format originir`
2. 再用模拟器或 `uniqc simulate`
## 拓扑与可用 qubit 约束
模拟器支持传入约束:
```python
sim = OriginIR_Simulator(
backend_type="statevector",
available_qubits=[0, 1, 2, 3],
available_topology=[[0, 1], [1, 2], [2, 3]],
)
```
这适合:
- 提前检查线路是否符合目标芯片拓扑
- 在 dummy 场景里模拟“可用 qubit / coupling map”限制
## `least_qubit_remapping`
基础模拟器支持 `least_qubit_remapping` 参数。默认会做更紧凑的 qubit 映射;如果用户非常在意保留原始编号,可显式关闭。
```python
sim = OriginIR_Simulator(
backend_type="statevector",
least_qubit_remapping=False,
)
```
## 与 dummy 模式的关系
dummy 适配器底层会走本地模拟,因此:
- dummy 不是“绕过模拟依赖”
- dummy 更像“沿用统一的 task API,但把执行后端换成本地模拟器”
## 什么时候不该强推模拟器
以下情况不要默认推荐先本地模拟:
- 用户只想做格式转换
- 用户只想提交到云平台
- 用户环境明显缺少模拟依赖,而且问题与模拟无关
这时优先走:
- `Circuit -> originir -> uniqc submit`
- 或纯文档解释,不强制运行本地模拟
FILE:references/troubleshooting.md
# 通用排错参考
这份说明用于**功能主题自己的排错步骤仍不够时**的通用兜底排查。
优先顺序应当是:
1. 先看当前问题对应的功能 reference
2. 如果功能内排查仍解释不了,再回到这里做通用诊断
遇到这些情况时,优先查这里:
- 功能文档里的排错已经做过,但问题仍解释不通
- 文档里的命令、导入路径、配置文件位置和本地安装对不上
- 某个功能在说明里提到,但用户环境里“没有这个命令 / 没有这个模块 / 没有这个 extra”
- 同一份示例在不同机器上,一个能跑、一个提示参数名、模块名或行为不一致
## 先确认问题是不是功能专属
这份文档不替代功能主题内的局部排错。常见入口:
- CLI / 命令参数 / shell 工作流:`references/cli-guide.md`
- 本地模拟 / dummy / simulation 依赖:`references/simulators.md`
- 云平台 / token / task cache / dummy 提交:`references/cloud-platforms.md`
- HEA / QAOA / UCCSD / VQE:`references/variational-algorithms.md`
- PyTorch 辅助工具:`references/pytorch-integration.md`
如果这些局部文档已经看过,仍然解释不了问题,再继续下面的通用步骤。
## 推荐顺序
不要一开始就读一大堆前提。通用排障更适合按下面的顺序推进:
1. 先拍一张当前安装快照:解释器、包版本、模块路径、CLI 路径
2. 立刻判断版本变化是不是主要原因,先看对应版本摘要
3. 再查 issue / discussion 里有没有同类报错、参数改名或行为变更
4. 再回到对应功能文档和上游文档核实当前用法
5. 还解释不通时,最后再读源码
这个顺序的目标不是一次性证明所有前提,而是先快速判断“问题大概率落在哪一层”。
## 第一步:先拍安装快照
排错前不要假设用户装的是 PyPI 发布版,也不要假设 shell 里的 `uniqc` 和当前 Python 是同一套环境。至少先回答四个问题:
- 当前用的是哪个解释器
- `unified-quantum` 显示的版本号是什么
- `uniqc` 模块实际从哪里导入
- shell 里执行到的 `uniqc` 在哪里
最小检查命令:
```bash
python3 - <<'PY'
from importlib.metadata import version
from shutil import which
import sys
print("exe=", sys.executable)
print("cli=", which("uniqc"))
try:
import uniqc
except ModuleNotFoundError:
print("module= <uniqc not importable>")
else:
print("module=", uniqc.__file__)
try:
print("version=", version("unified-quantum"))
except Exception as exc:
print("version_probe_failed=", repr(exc))
PY
```
如果用户使用的是项目虚拟环境、`uv tool`、Conda 或其他解释器,要改用对应解释器执行这条命令。
结果通常可以分成三类:
- **PyPI / wheel 安装**:模块路径位于 `site-packages`
- **源码 editable 安装但对齐某个 release/tag**:模块路径指向源码目录,版本号通常仍是正式版本
- **源码 editable 安装且跟随主线**:模块路径指向源码目录,版本号可能带 `dev`,或者与已发布行为不一致
这里最重要的是:**以当前解释器真正导入到的包为准**,不要只看用户在哪个源码目录里开了终端,也不要只看仓库 README。
如果需要快速做一次环境体检,可以运行:
```bash
bash scripts/setup_uniqc.sh
```
它更适合快速回答这些通用问题:
- `uniqc` 能不能启动
- `import uniqc` 是否成功
- 基础依赖是否缺失
- simulation / PyTorch / scikit-learn 等常见可选能力是否可用
## 第二步:先看版本摘要,不要先钻细节
拿到安装快照后,先判断“版本变化是不是主要原因”。
适合优先看版本摘要的信号包括:
- 用户看的文档、示例或笔记明显比当前安装新或旧
- 报错集中在“参数名不存在”“命令组选项变了”“导出路径改了”“模块路径变了”
- 同一段代码在两台机器上表现不同,而版本号或模块路径不同
这一层先看**对应版本附近的 release notes、changelog、tag 摘要**就够了,目的是快速判断是不是版本差异导致的,不必一上来就翻完整源码。
UnifiedQuantum 当前可直接从这里看版本摘要:
- Release Notes: `https://iai-ustc-quantum.github.io/UnifiedQuantum/source/releases/index.html`
如果用户拿的是文档站里的说明但本地行为对不上,先把本地版本号和这个页面里的相邻版本条目对一遍,再决定要不要继续查 issue 或源码。
如果已经确认用户直接在 `UnifiedQuantum` 源码 checkout 里工作,且需要判断“当前代码大致落在哪个 tag 附近”,才额外使用:
```bash
git describe --tags --always
```
它只是辅助判断源码树和最近 tag 的相对位置,不能替代“当前解释器里实际导入了哪个版本”的检查。
## 第三步:查 issue / discussion 有没有同类问题
如果版本摘要提示“这里确实变过”,或者报错看起来像回归、兼容性问题、文档滞后问题,就优先查 issue / discussion。
搜索时优先组合这些信息:
- 版本号或 tag
- 精确报错文本
- 具体命令、参数名、模块名或函数名
- 所属平台或可选依赖,例如 `simulation`、`originq`、`qiskit`、`torch`
这一层最有价值的问题通常是:
- 某个参数或命令最近是否改名
- 某个 extra 是否刚被拆分、上移或不再默认安装
- 某个功能是否只在主线修复、尚未发版
- 某个示例或文档是否已知落后于当前实现
## 第四步:再回到功能文档和上游文档
确认大致方向后,再去读具体文档,效率会高很多。优先顺序通常是:
1. 当前问题对应的主题 reference
2. 与当前安装来源匹配的上游文档
3. 与当前版本相邻的示例或官方说明
很多“看起来像程序问题”的情况,其实只是解释器、CLI 入口或可选依赖没对齐。这里重点再核对:
- 当前 shell 里的 `uniqc` 和你用来 `import uniqc` 的解释器是不是同一套环境
- 需要模拟、dummy、PyTorch、云平台适配器时,有没有装对应 extra
- 用户是不是把主线源码 README、历史笔记或旧示例,当成了当前安装版本的真实能力
## 第五步:最后再读源码
只有前面几步还解释不通时,才进入源码层。
源码排查的推荐顺序:
1. 如果模块已经能导入,先读当前环境里真正加载到的源码或已安装文件
2. 如果需要对照上游实现,再在用户允许的前提下 clone `UnifiedQuantum`
3. 如果用户已经有本地 checkout,优先让用户提供大致路径,再直接在那份仓库里读
如果要 clone 或进入用户本地仓库做进一步检查,先和用户确认再动手。不要默认把排障升级成仓库操作。
## 常见排错思路
- 缺命令、缺导入、缺 extra 时,先确认是不是装错了解释器或少装了可选依赖
- `uniqc` 能运行但 `import uniqc` 失败,或反过来时,优先怀疑不是同一个环境
- 文档和本地行为不一致时,先看安装快照,再判断是不是版本差异
- 如果模块路径指向源码目录,不要立刻把 README 上写的能力当成“当前环境一定具备”
- 如果模块路径指向 `site-packages`,但用户拿的是主线源码说明,优先怀疑“文档比安装版本新”
- 不要先入为主地判定“包坏了”或“这份说明过时了”;很多问题只是安装来源和参考文档不一致
## 使用这份参考时记住
- 功能专属问题优先回到对应主题 reference,不要在这里一次性展开所有细节
- 这里主要解决通用排错顺序、环境快照、版本识别、issue 检索和源码升级路径
- 需要解释功能差异时,优先看与当前安装来源匹配的官方版本摘要、issue 和文档
- 如果你看到手工维护的版本断点表,不要把它当成主判断依据;只有当某个识别步骤本身会影响排障时,它才值得参考
FILE:references/variational-algorithms.md
# 变分算法参考
当前 UnifiedQuantum 对变分算法更适合从“ansatz 构造器 + 自己的目标函数 / 优化器”来理解,而不是依赖一套过度封装的旧接口。
## 当前公开 ansatz
```python
from uniqc.algorithmics.ansatz import hea, qaoa_ansatz, uccsd_ansatz
```
注意:
- `uccsd_ansatz` 才是当前公开名字
- 如果用户拿的是旧示例,注意当前公开名字不是旧的 `uccsd`
## HEA
```python
from uniqc.algorithmics.ansatz import hea
circuit = hea(
n_qubits=4,
depth=2,
params=params, # 长度应为 2 * n_qubits * depth
)
```
特点:
- 结构轻
- NISQ 友好
- 常用于最小 VQE / VQC 示例
## QAOA ansatz
```python
from uniqc.algorithmics.ansatz import qaoa_ansatz
cost_hamiltonian = [
("Z0Z1", 1.0),
("Z1Z2", 1.0),
]
circuit = qaoa_ansatz(
cost_hamiltonian,
p=2,
betas=betas,
gammas=gammas,
)
```
要点:
- `cost_hamiltonian` 形如 `[(pauli_string, coefficient), ...]`
- `betas`、`gammas` 长度都应等于 `p`
- 如果不给,构造器会随机初始化
## UCCSD ansatz
```python
from uniqc.algorithmics.ansatz import uccsd_ansatz
circuit = uccsd_ansatz(
n_qubits=4,
n_electrons=2,
params=params,
)
```
要点:
- 适合量子化学风格任务
- 默认先准备 Hartree-Fock 初态
- 参数长度取决于单激发 / 双激发计数
## 一个典型 VQE 结构
UnifiedQuantum 当前更推荐这样组织 VQE:
1. 选 ansatz
2. 写一个目标函数
3. 在目标函数里调用模拟器得到概率或态矢
4. 用 `scipy.optimize.minimize` 或你自己的优化器迭代
示意:
```python
import numpy as np
from scipy.optimize import minimize
from uniqc.algorithmics.ansatz import hea
from uniqc.simulator import OriginIR_Simulator
from uniqc.analyzer import calculate_expectation
sim = OriginIR_Simulator(backend_type="statevector")
def objective(params):
circuit = hea(n_qubits=2, depth=1, params=params)
probs = sim.simulate_pmeasure(circuit.originir)
return calculate_expectation(probs, "ZZ")
result = minimize(objective, x0=np.zeros(4), method="COBYLA")
```
## 一个典型 QAOA 结构
1. 从图构造 cost Hamiltonian
2. 用 `qaoa_ansatz()` 生成电路
3. 用概率分布评估 cut value
4. 优化 `betas` / `gammas`
## 使用这些 ansatz 时记住
- 把 ansatz 当作“线路生成器”来解释
- 把优化器和目标函数当作用户可替换部分
- 不要把示例当成“唯一正确范式”
- 如果示例依赖本地模拟,明确标出 `simulation` extra
FILE:scripts/setup_uniqc.sh
#!/usr/bin/env bash
# Installation verification script for UnifiedQuantum examples and common workflows.
set -u
PASSED=0
FAILED=0
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m'
check_pass() {
echo -e "GREEN✓NC $1"
PASSED=$((PASSED + 1))
}
check_fail() {
echo -e "RED✗NC $1"
FAILED=$((FAILED + 1))
}
check_warn() {
echo -e "YELLOW!NC $1"
}
run_py() {
python3 "$@"
}
echo "============================================================"
echo "UnifiedQuantum Environment Check"
echo "============================================================"
echo
echo "1. Python"
echo "------------------------------------------------------------"
if command -v python3 >/dev/null 2>&1; then
echo " Python: $(python3 --version)"
if python3 -c "import sys; raise SystemExit(0 if (3, 10) <= sys.version_info[:2] < (3, 14) else 1)"; then
check_pass "Python version is within UnifiedQuantum's supported range"
else
check_fail "UnifiedQuantum expects Python >= 3.10 and < 3.14"
fi
else
check_fail "python3 not found"
fi
echo
echo "2. Core Package"
echo "------------------------------------------------------------"
if run_py - <<'PY'
import uniqc
print(getattr(uniqc, "__version__", "unknown"))
PY
then
check_pass "uniqc imports successfully"
else
check_fail "uniqc import failed. Install with: pip install unified-quantum"
fi
echo
echo "3. Core Runtime Dependencies"
echo "------------------------------------------------------------"
for pkg in numpy scipy requests yaml sympy; do
if run_py - <<PY
import pkg
print(getattr(pkg, "__version__", "ok"))
PY
then
check_pass "pkg is importable"
else
check_fail "pkg is missing"
fi
done
echo
echo "4. CLI"
echo "------------------------------------------------------------"
if command -v uniqc >/dev/null 2>&1; then
if uniqc --help >/dev/null 2>&1; then
check_pass "uniqc CLI command works"
else
check_fail "uniqc command exists but --help failed"
fi
elif run_py -m uniqc --help >/dev/null 2>&1; then
check_pass "python3 -m uniqc works"
else
check_fail "No working CLI entrypoint found"
fi
echo
echo "5. Circuit Builder Smoke Test"
echo "------------------------------------------------------------"
if run_py - <<'PY'
from uniqc.circuit_builder import Circuit
c = Circuit(2)
c.h(0)
c.cnot(0, 1)
c.measure(0, 1)
assert "QINIT" in c.originir
assert "OPENQASM" in c.qasm
print(c.originir)
PY
then
check_pass "Circuit export to OriginIR and QASM works"
else
check_fail "Circuit builder smoke test failed"
fi
echo
echo "6. Optional Features"
echo "------------------------------------------------------------"
if run_py - <<'PY'
import qutip
print(qutip.__version__)
PY
then
check_pass "qutip is available (simulation extra looks installed)"
else
check_warn "qutip is missing; local simulation and dummy mode examples may fail"
fi
if run_py - <<'PY'
import torch
print(torch.__version__)
PY
then
check_pass "torch is available"
else
check_warn "torch is missing; PyTorch helper examples will be skipped"
fi
if run_py - <<'PY'
import sklearn
print(sklearn.__version__)
PY
then
check_pass "scikit-learn is available"
else
check_warn "scikit-learn is missing; digit-classification example will be skipped"
fi
echo
echo "7. Local Simulation Smoke Test"
echo "------------------------------------------------------------"
if run_py - <<'PY'
from uniqc.task.optional_deps import check_simulation
if not check_simulation():
raise SystemExit(2)
from uniqc.circuit_builder import Circuit
from uniqc.simulator import OriginIR_Simulator
c = Circuit(2)
c.h(0)
c.cnot(0, 1)
c.measure(0, 1)
sim = OriginIR_Simulator(backend_type="statevector")
probs = sim.simulate_pmeasure(c.originir)
assert len(probs) > 0
print("nonzero entries:", sum(1 for value in probs if float(value) > 1e-12))
PY
then
check_pass "Local simulation works"
else
status=$?
if [ "$status" -eq 2 ]; then
check_warn "Simulation extra not installed; local simulation smoke test skipped"
else
check_fail "Local simulation smoke test failed"
fi
fi
echo
echo "============================================================"
echo "Summary"
echo "============================================================"
echo -e "Passed: GREENPASSEDNC"
echo -e "Failed: REDFAILEDNC"
if [ "$FAILED" -eq 0 ]; then
echo
echo -e "GREENEnvironment looks good for the current UnifiedQuantum workflow.NC"
else
echo
echo -e "YELLOWSome checks failed. Suggested installs:NC"
echo " pip install unified-quantum"
echo " pip install \"unified-quantum[simulation]\""
echo " pip install \"unified-quantum[pytorch]\""
exit 1
fi