- 科学计算
【免费下载链接】Cirq
Python framework for creating, editing, and running Noisy Intermediate-Scale Quantum (NISQ) circuits.
本文是一份面向 Cirq 贡献者的完整开发操作手册,覆盖了 docs/dev/development.md 所总结的开发者日常任务:克隆与 Fork 仓库、配置 git、用 apt 与 virtualenvwrapper 搭建开发环境、按模块做 editable 安装、重建 Protocol Buffers、运行本地测试与持续集成检查、编写规范 docstring 以及管理生产/开发依赖。读完本文,你将能够在自己的机器上从零建立一套可编辑、可测试、可提交的 Cirq 开发工作区,并理解每个 check 脚本背后依赖的源码机制。文中所有命令默认面向 Debian 环境,且除首次克隆外,均假设当前工作目录为本地 Cirq 仓库根目录。
1. 获取源码:克隆仓库与推荐的 git 配置
1.1 克隆仓库
获取一份可编辑的本地 Cirq 副本,最简单的方式是克隆仓库:
git clone https://gitcode.com/gh_mirrors/ci/Cirq.git cd Cirq克隆完成后,仓库根目录下即包含多个独立发布的模块目录:cirq-core、cirq-google、cirq-ionq、cirq-aqt、cirq-pasqal、cirq-web,以及用于开发的dev_tools/与存放全部检查脚本的check/目录。
1.2 推荐 git 配置:忽略大规模重构提交
Cirq 历史上做过多次全库范围的格式化重构,这些提交会污染git blame的溯源结果。仓库为此维护了一份.git-blame-ignore-revs文件(根目录下),其中逐行记录了"迁移到 black 格式化器""为字符串应用 flynt 格式化""按新版 black 规则重排"等大规模改动的 commit hash。执行下面的命令即可让git blame自动忽略这些提交:
git config blame.ignoreRevsFile .git-blame-ignore-revs提示:如果你使用 PyCharm,修改后可能需要执行Restart & Invalidate Caches才能让该配置生效。
1.3 Fork 工作流:为提交 PR 准备远程仓库
如果计划向 Cirq 主仓库提交代码,推荐标准的 Fork 工作流:
- 在代码托管平台上 Fork Cirq 仓库(点击仓库页面右上角的 Fork 按钮),Fork 会在你的账号下创建一个独立的仓库副本。
- 克隆你 Fork 出来的仓库到本地,并进入该目录:
git clone <你的 fork 仓库地址> cd Cirq(也可以直接使用仓库页面 "Clone or Download" 绿色按钮提供的地址。)
- 添加名为
upstream的远程,指向 Cirq 主仓库(区别于刚克隆的origin远程),用于把主仓库的最新改动合并进你的本地开发副本:git remote add upstream <Cirq 主仓库地址>用
git remote -v验证,此时应同时看到origin与upstream两个远程。 - 与
upstream同步:git fetch upstream可通过
git ls-remote --branches upstream或git branch -r查看upstream上的分支,最重要的是应能看到upstream/main。 - 把 upstream 的 main 合并进本地 main,保持最新:
git checkout main git merge upstream/main
完成以上步骤后,本地main就与 Cirq 主仓库的main保持同步,可以开始基于它切分支开发了。
2. 搭建开发环境(基于 apt 的 Linux)
环境搭建共 6 步,前 3 步完成后即可拥有一个带全部 dev tools 的隔离 Python 环境。
2.1 安装系统依赖
首先确保 Python 版本不低于 3.11(python3 --version可查)。其余系统依赖通过apt-get一次性安装。命令会拼接仓库根目录下两份清单文件的内容作为安装列表:
cat apt-system-requirements.txt dev_tools/conf/apt-list-dev-tools.txt | xargs sudo apt-get install --yes两份清单的实际内容如下:
- apt-system-requirements.txt:
latexmk、python3-tk、texlive-latex-extra——latex 相关工具用于渲染文档与 notebook 中的 LaTeX 公式; - dev_tools/conf/apt-list-dev-tools.txt:
shellcheck(Shell 脚本静态检查)、virtualenvwrapper(虚拟环境管理工具)。
注意:如果后续修改了 Protocol Buffers,还需要额外的步骤,见本文第 4 节。
2.2 配置 virtualenvwrapper
virtualenvwrapper是上面安装的系统依赖之一,它让你可以快速创建虚拟环境。如果此前未配置过,需要把以下三行追加到~/.bashrc或~/.zshrc,保存后新开终端或执行source ~/.bashrc激活:
export WORKON_HOME=$HOME/.virtualenvs export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3 source /usr/share/virtualenvwrapper/virtualenvwrapper.sh(完整用法请参阅 virtualenvwrapper 官方文档。)
2.3 创建虚拟环境并安装开发依赖
创建一个包含 Cirq 开发工具(如 Mypy)的 Python 虚拟环境:
mkvirtualenv cirq-py3 --python=/usr/bin/python3 workon cirq-py3 python -m pip install --upgrade pip python -m pip install -r dev_tools/requirements/dev.env.txt之后每次新开终端,只需workon cirq-py3即可重新激活该环境。
注:部分管理严格或定制过的设备可能与
virtualenv冲突,此时改用 anaconda 环境是更稳妥的选择。
dev_tools/requirements/dev.env.txt 是一份"完整开发环境"清单,其实际内容只有两行引用:
-r deps/cirq-all.txt -r deps/dev-tools.txt其中 deps/cirq-all.txt 汇总了全部模块(含 contrib),而 deps/dev-tools.txt 则继续引用mypy.txt、pytest.txt、format.txt、pylint.txt、protos.txt、notebook.txt、tensorflow-docs.txt、packaging.txt、ruff.txt,并额外固定了qiskit-aer~=0.17.0(用于验证 QASM 输出行为)与stimcirq(用于测试 cirq-google 的 stimcirq 兼容性)。requirements 文件之间的-r互相引用机制是去重的主要手段,这一点在第 7 节还会展开。
2.4 验证测试通过
安装完成后先跑一遍全量测试,确认环境正常:
./check/pytest .2.5(可选)把开发副本加入 Python 路径
开发 Cirq 源码时通常希望import cirq直接命中本地代码,有两种方式:
方式一:source 脚本(推荐,bash 与 zsh 均可):
source dev_tools/pypathdev_tools/pypath 的实现值得一看:它先通过dirname "${BASH_SOURCE[0]}"定位脚本自身位置从而推导仓库根目录,然后调用python dev_tools/modules.py list --mode folder列出所有模块的根文件夹,再拼接成完整的PYTHONPATH前缀(含cirq-core、cirq-google、cirq-ionq、cirq-aqt、cirq-pasqal、cirq-web等),最后在已包含该前缀时才跳过重复设置。如果当前python不是 Python 3,脚本会给出明确报错。
方式二:写入虚拟环境。先列出模块:
python dev_tools/modules.py listdev_tools/modules.py 是一个可作 CLI 亦可作库的工具,list子命令支持--mode参数:folder(模块根目录,如cirq-google)、package-path(顶层 Python 包路径,如cirq-google/cirq_google)、package(顶层包名,如cirq_google),还支持--include-parent把 metapackage 一并纳入;此外它还有print_version(校验所有模块版本一致并打印)与replace_version --old <旧版本> --new <新版本>(批量改写各模块_version.py与_version_test.py中的版本号)两个子命令。把上一步输出的模块目录粘贴给add2virtualenv:
add2virtualenv <粘贴上一步列出的模块>(add2virtualenv通常无法用xargs直接执行,所以需要分两步。)
3. Editable 安装:按模块安装而非装 metapackage
如果希望用pip install的方式以可编辑(editable)模式安装 Cirq,必须按模块逐个安装:
pip install -e ./cirq-core -e ./cirq-google -e ./cirq-ionq -e ./cirq-aqt这里有一个很容易踩的坑:pip install -e .只会安装cirq这个 metapackage 本身,你的代码改动不会被拾取。这是因为仓库采用多模块结构,每个模块(cirq-core、cirq-google等)都有独立的setup.py与requirements.txt,deps/cirq-all-no-contrib.txt 中正是用-e ./cirq-aqt、-e ./cirq-core、-e ./cirq-google、-e ./cirq-ionq、-e ./cirq-pasqal、-e ./cirq-web的方式在 pip 层面一次性 editable 安装全部子包。
4. Protocol Buffers:修改后的重建流程
Protocol Buffers(protobuf)在 Cirq 中用于把电路、门及其他对象转换成标准形式,便于其他程序读写。Cirq 的 proto 定义位于 cirq-google/cirq_google/api 下,包含v1/与v2/两代 API:v2目录中可以看到program.proto、run_context.proto、result.proto、calibration.proto、device.proto、batch.proto、metrics.proto、ndarrays.proto等定义文件,以及它们对应的生成产物(*_pb2.py与*_pb2.pyi)。
如果更新了任何 proto,其依赖产物可以通过脚本重建:
dev_tools/build-protos.shdev_tools/build-protos.sh 的实现揭示了完整生成链路:
- 进入
cirq-google目录,并定位tunits包的 proto 路径(importlib.resources.files('tunits').parent),该包为生成提供类型单位支持; - 对
cirq_google/api/v1与cirq_google/api/v2两个包分别执行python -m grpc_tools.protoc,同时输出 Python 代码(--python_out=.)与 mypy 桩(--mypy_out=.); - 由于当前 protoc 生成的导入语句是绝对导入形式,脚本最后用
sed将其统一替换为相对导入(from cirq.google.api.* import ...→from . import ...),保证生成的*_pb2.py在包内可正常导入。
生成所需的依赖来自 dev_tools/requirements/deps/protos.txt:grpcio-tools~=1.78.0(打包了 protoc 工具)、mypy-protobuf~=5.1.0(生成 mypy 桩)、typedunits。
5. 持续集成与本地测试:从快速检查到完整校验
Cirq 提供从"又快又方便"到"慢而可靠"的多个检查层级。最朴素的方式是自行调用工具:
pytest pylint . mypy .但这种方式要求你已经用source dev_tools/pypath设置好 Python 路径。更省心的方式是使用 check/ 目录下的脚本——它们会自动设置 Python 路径与配置参数,并覆盖更多场景。所有脚本都先通过git rev-parse --show-toplevel定位仓库根目录并cd过去,因此可以从任意子目录执行。
5.1 快速检查(几秒到几十秒完成)
检查/应用代码格式(仅针对变更行):
./check/format-incremental [--apply] [BASE_REVISION]check/format-incremental 内部会找出相对基线版本变更(diff-filter=MAR)的
*.py与*.ipynb(排除*_pb2.py),先用isort排序导入(__init__.py除外),再用black格式化;默认只打印 diff 并以退出码 1 表示需要修改,--apply才真正改写文件,另支持--all检查全部文件。依赖见 dev_tools/requirements/deps/format.txt(black[jupyter]==26.5.1、isort[colors]~=8.0.1)。Lint 检查:
ruff check ./check/pylint-changed-filesruff check直接调用 dev_tools/requirements/deps/ruff.txt 中固定的ruff==0.15.15;pylint-changed-files只对变更涉及的.py文件(限定cirq、dev_tools、examples前缀,排除cirq-google/cirq_google/cloud/*与*_pb2.py)运行pylint --jobs=0。运行与变更文件关联的测试:
./check/pytest-changed-files [BASE_REVISION]该脚本"并不聪明":它不解析文件间依赖,只是把变更的
x.py映射为x_test.py交给 pytest(若修改了__init__.py还会额外纳入全局 API 序列化测试 cirq-core/cirq/protocols/json_serialization_test.py)。同样,pytest-changed-files-and-incremental-coverage在此基础上再对变更文件所在目录加--cov=<目录>并调用python dev_tools/check_incremental_coverage_annotations.py分析覆盖率注释。运行 docstring 内嵌测试:
./check/doctest底层调用 dev_tools/docs/run_doctest.py:它收集
cirq**/cirq**/**/*.py下所有源码文件(排除_test.py、cirq-google/cirq_google/api/等目录),以doctest.ELLIPSIS选项执行 docstring 中的>>>示例,并预置cirq、cirq_google、np、pd、sympy等全局名字,使示例无需显式导入即可运行。增量覆盖率(只用与变更文件关联的测试):
./check/pytest-changed-files-and-incremental-coverage [BASE_REVISION]注意:该检查比实际 CI 强制执行的增量覆盖率检查更严格——真实 CI 允许"未关联文件的测试"覆盖某些行。
类型检查:
./check/typecheck [传给 mypy 的 flags]内部就是
source dev_tools/pypath && mypy "$@" .,依赖 dev_tools/requirements/deps/mypy.txt 中的mypy==2.1.0及types-protobuf、types-requests桩包。杂项检查:
./check/misc目前做两件事:一是确保
cirq.contrib之外的文件不引用cirq.contrib(避免pip install cirq而非pip install cirq-core[contrib]的用户出错);二是用git diff --check(core.whitespace=incomplete-line)检查空白错误与文件末尾换行。
5.2 慢速检查(每项数分钟)
运行全部测试:
./check/pytest [传给 pytest 的文件与 flags]check/pytest 默认以
-n=auto(pytest-xdist 并行)运行;若需单进程可传-n0(最后的-n参数生效)。pytest的依赖见 dev_tools/requirements/deps/pytest.txt:包含pytest、pytest-asyncio、pytest-benchmark、pytest-cov、pytest-randomly、pytest-xdist、coverage~=7.4等。全量 lint:
./check/pylint [传给 pylint 的 flags]即
pylint --jobs=0 "$@" .,依赖 dev_tools/requirements/deps/pylint.txt 的pylint~=4.0.2。增量覆盖率:
./check/pytest-and-incremental-coverage [BASE_REVISION]先
check/pytest --cov全量跑测试并生成*.py,cover覆盖率注解文件,再交给dev_tools/check_incremental_coverage_annotations.py <base>统计相对基线的未覆盖变更行,最后用git clean -x -- "*.py,cover"清理中间产物。运行全部 CI 检查:
./check/all [BASE_REVISION] [--changed] [--fix]--changed:让可聚焦的检查只针对变更文件(以速度换准确性);--fix:自动应用 linter 与格式化工具的安全修正。
check/all 的源码展示了真实的执行顺序:依次运行
check/misc、check/format-incremental、ruff check、pylint或pylint-changed-files、pytest-and-incremental-coverage或pytest-changed-files-and-incremental-coverage、check/typecheck,最后在非--changed模式下再跑check/doctest(注释解释:doctest 很少失败但最耗时,所以 only-changed 模式下跳过)。任何一项失败都会被收集并在结束时汇总打印。脚本还提示--apply-format-changes已废弃,应改用--fix。
5.3 BASE_REVISION 的解析逻辑
上文多个脚本的[BASE_REVISION]参数控制"与哪个提交对比"(例如用于确定哪些文件变更)。未指定时的默认优先级为:
upstream/main(若存在)origin/main(若存在)main
实际用于对比的提交是基线与当前工作目录的git merge-base(即最近公共祖先)。注意上述脚本的结果可能与 GitHub 上的 CI 工作流不完全一致——例如你本地可能跑着旧版pylint或numpy。若需要针对真实 CI 验证,请直接开一个 Pull Request(可以以 draft 模式或标记为[Testing]以免被评审)。
6. 编写 docstring 与生成文档
Cirq 使用Google style docstrings(Markdown 风格,支持 LaTeX)。关键规范:
- 含 LaTeX 的 docstring 应写成r-string(原始字符串),避免反斜杠被转义;
- 支持块级 LaTeX(
$$ ... $$)与行内 LaTeX($y = x^2$); - 支持行内代码(如
`cirq.unitary(cirq.X)`); - 标准段落包含
Args:、Returns:、Raises:。
仓库文档给出的完整示例:
def some_method(a: int, b: str) -> float: r"""One line summary of method. Additional information about the method, perhaps with some sort of LaTeX equation to make it clearer: $$ M = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix} $$ Notice that this docstring is an r-string, since the LaTeX has backslashes. We can also include example code: print(cirq_google.Sycamore) You can also do inline LaTeX like $y = x^2$ and inline code like `cirq.unitary(cirq.X)`. And of course there's the standard sections. Args: a: The first argument. b: Another argument. Returns: An important value. Raises: ValueError: The value of `a` wasn't quite right. """docstring 中的>>>示例由./check/doctest验证(机制见第 5.1 节),从而保证文档中的代码示例始终可运行。
7. 依赖管理策略
7.1 生产依赖:模块内声明、保持宽松
Cirq 采用模块化设计,每个模块在自己目录下的requirements.txt中声明依赖,例如 cirq-core/requirements.txt 与cirq-google/requirements.txt。以cirq-core为例,运行期依赖包括attrs>=21.3.0、duet>=0.2.8、matplotlib~=3.10、networkx~=3.4、numpy~=2.2、pandas>=2.3,<3.1.0.dev、scipy~=1.15、sympy、tqdm>=4.12。总体原则是:依赖越少越好;必须添加时尽量放宽版本约束而非精确 pin 死;若确知精确版本或约束,以注释形式说明。
7.2 开发依赖:一份全量清单 + 按 CI job 拆分
本地开发使用 dev_tools/requirements/dev.env.txt 一次装齐所有模块依赖与全部 dev tools;若嫌太重,可只装 dev_tools/requirements/deps/dev-tools.txt 加对应模块依赖。
持续集成则讲究按需安装:每个 job 需要的依赖不同,给每个小 job(如单独的mypy检查)都装完整 dev 环境太浪费,因此在 dev_tools/requirements 下为每个 job 建立独立的<job>.env.txt,只包含必要工具。仓库中现存的环境文件包括:
lint.env.txt:cirq-all.txt+pylint.txt+ruff.txt(让 pylint 能检查依赖函数调用的实参);mypy.env.txt:cirq-all.txt+mypy.txt;notebooks.env.txt:cirq-all.txt+pytest.txt+notebook.txt(notebook 测试的最小环境);pytest-minimal.env.txt:pytest.txt+cirq-all-no-contrib.txt+ipython.txt+pylint.txt(用于pytest-changed-files的最小环境,见 dev_tools/conf/pip-install-minimal-for-pytest-changed-files.sh);isolated-base.env.txt:pytest.txt+notebook.txt(隔离测试 notebook 与包的最小环境)。
requirements 文件之间可以互相-r包含,这套机制被大量用于去重。要展开某个文件的所有约束(扁平化输出),使用仓库自带的工具:
python dev_tools/requirements/reqs.py dev_tools/requirements/dev.env.txtdev_tools/requirements/reqs.py 的实现很直观:递归解析-r指令(相对路径按当前文件所在目录解析),按包含顺序输出每一行约束;它自带测试用例 dev_tools/requirements/reqs_test.py(配合test_data/下的a.req.txt、b.req.txt等样例),可独立验证展开逻辑。
8. 小结:一份可落地的开发流程清单
把以上内容串起来,一个典型的 Cirq 开发周期是:
- 克隆/Fork:
git clone主仓库(或先 Fork 再添加upstream远程并git fetch upstream+git merge upstream/main),并配置blame.ignoreRevsFile .git-blame-ignore-revs; - 建环境:
apt-get安装系统依赖 → 配置virtualenvwrapper→mkvirtualenv cirq-py3→pip install -r dev_tools/requirements/dev.env.txt→./check/pytest .验证; - 开发:
source dev_tools/pypath(或add2virtualenv)让本地代码生效,按模块pip install -e ./cirq-*做 editable 安装;改动 proto 时运行dev_tools/build-protos.sh; - 提交前自检:
./check/format-incremental --apply、ruff check、./check/pylint-changed-files、./check/pytest-changed-files、./check/doctest、./check/typecheck、./check/misc等快速检查; - 全面验证:合并前跑
./check/all(必要时加--changed提速或--fix自动修正),并以upstream/main为基线解读增量覆盖率结果。
这套流程既覆盖了仓库文档定义的开发者任务全集,也与 check/ 各脚本、dev_tools 工具链的真实实现一一对应,可以作为日常开发与提交评审的可靠参照。
- 科学计算
【免费下载链接】Cirq
Python framework for creating, editing, and running Noisy Intermediate-Scale Quantum (NISQ) circuits.
相关推荐
handson-ml3 环境搭建完整指南:从克隆仓库到运行 Jupyter Notebook 的 Anaconda 实战手册
handson ml3 环境搭建完整指南:从克隆仓库到运行 Jupyter Notebook 的 Anaconda 实战手册 导读 本指南围绕《Hands On
示例工程教程AI-For-Beginners 环境搭建与运行故障排查指南:从仓库克隆到 Notebook 实战的完整排障手册
AI For Beginners 环境搭建与运行故障排查指南:从仓库克隆到 Notebook 实战的完整排障手册 本指南以《AI For Beginners 故
教程人工智能机器学习深度学习Code Blocks与highlight.js:揭秘Google Docs代码高亮背后的技术原理
Code Blocks与highlight.js:揭秘Google Docs代码高亮背后的技术原理 想要在Google Docs文档中优雅地展示代码片段吗?Co
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考