
Warp 贡献指南从代码提交、编码规范到测试与基准测试的完整工作流【免费下载链接】warpA Python framework for GPU-accelerated simulation, robotics, and machine learning.项目地址: https://gitcode.com/GitHub_Trending/warp/warpWarp 是一个面向 GPU 加速仿真、机器人与机器学习的 Python 框架其核心能力由 Python 前端与 C/CUDA 原生层共同构成。本指南面向希望向 Warp 仓库提交贡献的开发者完整讲解从规划贡献、签署 DCO、编写代码到通过 lint 检查、构建文档、编写多设备测试、运行基准测试并最终合入main分支的端到端流程。读完本文你将掌握 Warp 仓库的编码规范、add_function_test()多设备测试机制、ASV 基准测试用法等核心实操细节能够以符合项目质量门槛的方式提交 Pull Request。贡献方式概览Warp 欢迎社区贡献的 Pull RequestPR。除了直接修改代码社区开发者还可以通过以下方式参与项目在仓库的Issues中报告 Bug、请求新特性在Discussions中提问、分享工作成果或参与讨论向 Warp 仓库新增示例例如 warp/examples 下的 core、tile、fem、optim 等子目录改进文档Sphinx 源码位于 docs提交Bug 修复或新功能将相关研究成果加入 PUBLICATIONS.md 出版物列表。规划贡献先检索再动手在打开 Pull Request 之前请先在仓库的 Issues 与 Discussions 中搜索是否已有相关报告与上下文避免重复劳动Bug 请先开 Issue先描述问题并给出可复现的最小示例再考虑是否附上修复较大改动请先讨论对于涉及面广的改动先通过 Issue 或 Discussion 说明改动要解决什么问题、为什么重要。如果改动会影响正在使用 Warp 的应用、库、研究项目或生产系统请描述其影响范围Issue 不是任务清单一个处于打开状态、未被指派给任何人的 Issue并不意味着维护者正在寻找人来实现它。是否实现、由谁实现由项目维护者决定。代码贡献流程不签 CLA用 Developer Certificate of OriginWarp 不要求签署正式的 Contributor License AgreementCLA而是采用Developer Certificate of OriginDCO开发者原创性证书机制来确认贡献者有权向项目提交其贡献。DCO 1.1 全文如下.github/.dco.yml 中配置了 DCO 机器人允许个人提交者的修复性提交Version 1.1 Copyright (C) 2004, 2006 The Linux Foundation and its contributors. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Developers Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.每个 commit 都必须包含 sign-off即用git commit --signoff或-s提交且 sign-off 中的邮箱必须与 commit 作者邮箱一致以此表示你同意该次贡献的 DCO 条款。贡献工作流fork → 分支 → 提交 → PRFork Warp 仓库将你的 fork 克隆到本地例如git clone gitgithub.com:username/warp.git创建username/short-description格式的分支进行代码修改同时注意熟悉本文的 编码规范确保改动通过 lint 与格式化检查编写测试用例验证正确性见 测试 Warp为新功能补充文档见 构建文档当改动影响用户行为时在 changelog 目录添加 changelog fragment该目录同时配有 README 说明 fragment 的命名与格式仓库中已存在大量类似1870.fixed.md、1797.added.md、1729.documentation.md的命名实例整理提交prepare commitscommit message 使用祈使语气如 Fix array bounds check而非 Fixed array bounds check主题行控制在约 50 个字符以内正文解释为什么要改而不是改了什么diff 本身展示了改了什么在 commit message 中引用相关 Issue如(GH-1234)每个 commit 都用git commit --signoff签署在 PR 被合并前清理提交历史合并提交、review 修正、WIP 存档会污染git log削弱main分支上git bisect与git cherry-pick的效果。请把分支整理成少量逻辑自洽的 commit通常一个即可每个 commit 应能独立通过测试且有清晰的 message多 commit 分支也可以接受只要它们讲述一个有意义的演进故事如先 Add new API 再 Add tests for new API但不必保留 fixup 或 merge commit。最简清理方式是把分支全部 squash 成一个 commit# Squash all commits on your branch into one git fetch https://github.com/NVIDIA/warp.git main git reset --soft FETCH_HEAD git commit -s将分支推送到 fork如git push origin username/feature-name在 GitHub 上向main分支提交 Pull Request并与 reviewers 协作直至 PR 达到可合并状态。质量期望Review 时间有限维护者无法审阅每一个 PR。一个在使用 Warp 的项目中解决实际问题、且契合项目发展方向的贡献更容易获得审阅改动聚焦、验证充分的 PR 也更易评审。请确保贡献满足以下质量期望包含测试Bug 修复应包含无修复时能复现失败、有修复时通过的测试新功能需要覆盖核心功能与重要边界条件的测试。修改核心库代码但测试覆盖不足的 PR 不会被合并。当然每个测试都会增加测试套件运行时长所以应聚焦能验证真实行为的有意义测试而非穷举琐碎变体遵循 Pull Request 模板填写所有相关章节包括说明如何验证改动的 test plan帮助 reviewer 复现并确认结果保持改动聚焦一个 PR 只解决一个 Bug 修复、功能或改进不要捆绑无关改动请拆分到独立 PR最小化 review 成本测试完善、描述清晰、commit 历史干净的贡献会更快被审阅需要 reviewer 花费大量精力验证正确性的贡献可能被降级或拒绝。编码规范通用规范所有新创建的文件都必须包含 NVIDIA SPDX 版权头并将年份更新为文件创建当年的年份使用两行形式# SPDX-FileCopyrightText: Copyright (c) YEAR NVIDIA CORPORATION AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0C/C/CUDA 文件使用//而非#。变量与函数命名力求一致性命名新函数时优先沿用既有术语例如使用points而不是新造vertex_buffer代码库中已有缩写时不要另造新缩写局部变量命名同样注意一致性与清晰度避免get_data()这类过于通用的函数名优先匹配被修改文件现有的风格与约定避免引入新依赖新的必需依赖一律不接受可选依赖如示例或 interop 场景可以按个案评估但即使可选依赖也需对包及其全部传递依赖做内部许可审查以确保与 Warp 的许可证兼容。添加前请在 Issue 或 PR 中先行讨论。Python 规范以PEP 8作为编码风格基线所有函数名使用snake_case使用Google 风格 docstring在预期用于可微编程应用的函数中wp.launch()应同时使用inputs和outputs参数以辅助可视化和调试工具。C 规范遵循 .clang-format 中定义的 clang-format 风格WebKit 风格120 字符行宽限制WebKit 大括号风格函数大括号换行控制语句大括号同行指针与引用左对齐Type* var而非Type *var命名空间内不缩进include 自动排序warp.h始终排在最前符号命名所有导出的 C/C 符号函数、全局变量必须以wp_为前缀防止命名空间污染。这是由 GitLab CI 中一个检查编译后库的 job 强制执行的正确示例wp_init()、wp_cuda_launch_kernel()、wp_graph_coloring()错误示例init()、cuda_launch_kernel()、graph_coloring()注意头文件中wp命名空间内的符号无需此前缀但从实现文件导出的 C 符号和extern C函数必须使用wp_前缀。Linting 与格式化Warp 仓库的 Python 代码使用Ruff作为 linter 与格式化器。PR 内容会被自动检查是否符合格式化与 lint 标准因此强烈建议在打开 PR 前先在本地分支上运行 linter 与 formatter。在项目根目录执行uvx pre-commit run --all-files该命令会尝试自动修复 lint 违规并格式化代码。某些 lint 违规无法自动修复Ruff 的 fix-safety 机制会阻止不安全的自动修复需要手动处理。若希望在git commit时自动执行 lint 与格式化检查安装 pre-commit 钩子uvx pre-commit install从仓库根目录的 .pre-commit-config.yaml 可以看到实际生效的钩子集合除了 Ruffruffruff-format版本 v0.16.5与 clang-formatv23.1.0之外还包含若干 Warp 自研钩子钩子 ID作用warp-check-generated-files调用 tools/pre-commit-hooks/check_generated_files.py 重新生成并检查生成文件warp-check-version-consistency调用 tools/pre-commit-hooks/check_version_consistency.py 校验版本一致性并重新生成version.hwarp-check-skill-sync调用 tools/pre-commit-hooks/sync_skills.py 同步项目 skillsruffPython linter--fix自动修复ruff-formatPython 格式化器uv-lock更新 uv lockfile对应仓库根目录的 uv.locktypos拼写检查clang-format对warp/下的 C/C/CUDA 文件格式化C 代码格式化C 代码必须符合 .clang-format 定义的风格CI/CD 流水线会对所有 PR 自动检查 C 格式合规性。使用 clang-format同一套 pre-commit 配置同时处理 PythonRuff与 Cclang-format# Run all formatters and linters (Python and C) uvx pre-commit run --all-files # Run only clang-format on C files uvx pre-commit run clang-format --all-files可选本地安装 clang-formatpre-commit 会自动下载并使用正确的 clang-format 版本因此无需手动安装。但如果你想在本地安装以便 IDE 集成例如 VS Code 的 format-on-save请安装 .pre-commit-config.yaml 中指定的版本当前为 v23.1.0例如 Ubuntu/Debian# See https://apt.llvm.org/ for repository setup instructions # Check .pre-commit-config.yaml for the current version sudo apt-get install clang-format-23直接运行 clang-format若本地已安装 clang-format也可以直接从命令行运行# Format all C files in warp/ (from repository root) # Note: nanovdb files are automatically skipped due to DisableFormat in nanovdb/.clang-format clang-format -i warp/**/*.{h,cpp,cu} # Format a specific file clang-format -i warp/native/mesh.h针对特定代码块禁用 clang-format在极少数情况下自动格式化会破坏关键格式如依赖顺序敏感的 include、精心对齐的矩阵可以对特定段落禁用格式化// clang-format off #include vec.h #include mat.h #include quat.h // clang-format on请节制使用。若原因不明显请添加注释说明。warp/native/builtin.h 中有使用示例。注意NanoVDBwarp/native/nanovdb与 cuBQLwarp/native/cuBQL目录是第三方代码通过它们各自的.clang-format配置自动排除在格式化之外。构建文档Warp 的文档由 Sphinx 构建源码在 docs 目录。构建文档前应先本地构建 Warp 库运行build_lib.py然后在项目根目录执行uv run --extra docs build_docs.py默认行为会跳过 doctest 测试运行约需 2 分钟。如果你的改动修改了核心库功能建议带--doctest标志运行build_docs.py确保文档中的代码片段仍然有效。--no-html标志可跳过 HTML 文档构建例如# Run only the doctest tests uv run --extra docs build_docs.py --no-html --doctest # Build the HTML documentation AND run the doctest tests uv run --extra docs build_docs.py --doctest默认情况下warnings 不会被视为错误因此即使外部 intersphinx 清单在无网络环境下无法访问本地构建仍会成功并产生输出。CI 构建使用--warnings-as-errors标志强制严格检查因此建议本地也传该标志以复现 CI 构建、在打开 PR 前捕获 warningsuv run --extra docs build_docs.py --warnings-as-errors如果离线构建希望完全跳过外部交叉引用解析避免网络请求及其 warnings可设置环境变量WARP_DOCS_OFFLINE1。运行build_docs.py还会重新生成 stub 文件warp/init.pyi与参考页面的 reStructuredText 文件docs/api_reference 下的warp*.rst。构建文档后建议运行git status检查这些文件是否被改动若有改动请一并提交到分支。Pull Requests使用仓库提供的PR 模板填写所有适用章节并删除不适用的部分确保 PR 标题描述性足够强清楚表达改动目的在描述中包含改动摘要Summary of changes受影响的区域Areas affected要解决的问题The problem being solved改动的局限性或未处理的部分Any limitations or non-handled areas所解决的既有 GitHub Issue使用 closes #1234 语法。设计文档对于复杂特性新用户可见 API、架构级改动、存在非显然设计权衡的特性建议在仓库根目录的 design 目录添加设计文档规范与模板见 design/README.md 与 design/TEMPLATE.md。评审过程中reviewers 也可能主动要求为某些改动补充设计文档仓库中已有api-capture-and-cpu-graphs.md、deterministic-execution.md、pluggable-allocators.md等实例可供参考。测试 Warp运行测试套件Warp 的测试套件基于 Python 标准库的unittest框架并使用unittest-parallel并行运行测试。绝大多数测试位于 warp/tests 目录此外warp/examples各子目录下的大部分示例也会通过 warp/tests/test_examples.py 纳入测试。先构建 Warp 库在项目根目录执行uv run build_lib.py然后运行测试套件uv run --extra dev -m warp.tests测试大约需要 10–20 分钟。默认只运行 warp/tests/unittest_suites.py 中default_suite()定义的测试模块若想使用 unittest 测试发现机制可加-s autodetectuv run --extra dev -m warp.tests -s autodetect后者会发现在匹配warp/tests/test*.py路径的模块中的测试。运行器默认最多使用 8 个测试进程还会受检测到的 CPU 数量与所选测试类数量限制。在 CPU 与 GPU 资源充足的系统上可用--maxjobs N提高上限。性能收益取决于工作负载与硬件进程数过高时收益通常会递减额外的 CUDA 测试 worker 也会提高 GPU 显存峰值占用。warp/bin中的原生库不会自动重建。合并或 rebase 到main后或拉取了warp/native/的改动后请用uv run build_lib.py重新构建当已安装的 CUDA 驱动版本不早于 CUDA Toolkit 时也可用uv run build_lib.py --quick。使用过期的二进制运行可能导致 JIT 编译的 kernel 以令人困惑的方式崩溃或损坏例如合并改动了原生结构体布局的情况。运行测试子集-p PATTERN与-k TESTNAMEPATTERNS两个选项必须配合-s autodetect使用。用-p PATTERN匹配测试文件名例如只运行文件名中含mesh的测试uv run --extra dev -m warp.tests -s autodetect -p *mesh*.py用-k TESTNAMEPATTERNS匹配测试名unittest 的通配符测试名模式该选项可重复使用多次。例如只运行名称中含mgpu或cuda的测试uv run --extra dev -m warp.tests -s autodetect -k mgpu -k cuda新增测试add_function_test()与多设备注册对于需要在多个设备如cpu、cuda:0、cuda:1上运行的测试推荐先在模块作用域定义一个测试函数再通过add_function_test()为测试类注册多个测试方法每个设备一个方法。add_function_test()定义于 warp/tests/unittest_utils.py其核心行为是devicesNone时注册一次devices为空列表时把测试方法替换为skip_test_func即标记为跳过否则为每个设备生成name_device形式的测试方法。新增测试模块务必加入 warp/tests/unittest_suites.py 的default_suite()这样才会被纳入默认测试运行。重要永远不要在测试文件中调用wp.clear_kernel_cache()或wp.clear_lto_cache()——无论是__main__块、测试方法内部还是模块作用域都不行。缓存清理不是多进程安全的并发清理会导致 LLVM 崩溃。测试套件运行器与build_lib.py已经负责缓存管理。下面是一个完整的多设备测试模块示例# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 import unittest import warp as wp from warp.tests.unittest_utils import * def test_amazing_code_test_one(test, device): pass devices get_test_devices() class TestAmazingCode(unittest.TestCase): pass add_function_test(TestAmazingCode, test_amazing_code_test_one, test_amazing_code_test_one, devicesdevices) if __name__ __main__: unittest.main(verbosity2)直接运行该模块时输出如下uv run test_amazing_code.py Warp 1.11.1 initialized: CUDA Toolkit 12.9, Driver 13.1 Devices: cpu : x86_64 cuda:0 : NVIDIA RTX 6000 Ada Generation (48 GiB, sm_89, mempool enabled) cuda:1 : NVIDIA RTX 6000 Ada Generation (48 GiB, sm_89, mempool enabled) CUDA peer access: Supported fully (all-directional) Kernel cache: /home/nvidia/.cache/warp/1.11.1 test_amazing_code_test_one_cpu (__main__.TestAmazingCode) ... ok test_amazing_code_test_one_cuda_0 (__main__.TestAmazingCode) ... ok test_amazing_code_test_one_cuda_1 (__main__.TestAmazingCode) ... ok ---------------------------------------------------------------------- Ran 3 tests in 0.001s OK注意输出显示运行了3 个测试尽管只写了一个名为test_amazing_code_test_one()的测试函数它分别在cpu、cuda:0、cuda:1三个设备上运行。这正是调用add_function_test(..., devicesdevices)的结果。关键 caveat仅注册并不足以保证测试真的在不同设备上运行——测试函数体必须自行使用device参数确保数据在该设备上分配、kernel 在该设备上启动。例如def test_amazing_code_test_one(test, device): with wp.ScopedDevice(device): score wp.zeros(1, dtypefloat, requires_gradTrue)或等价地def test_amazing_code_test_one(test, device): score wp.zeros(1, dtypefloat, requires_gradTrue, devicedevice)get_test_devices()同样定义于 warp/tests/unittest_utils.py按模式返回设备列表默认模式test_mode unique_or_2x总是包含 CPUGPU 则每个架构选一个若系统只有一个 GPU 架构且存在第二块 GPU则再加一块用于多 GPU 测试。其他模式包括basic仅 CPU 第一块 GPU、uniqueCPU 各唯一架构 GPU与all所有设备。检查预期行为由于使用了测试注册函数add_function_test()测试函数中的test参数实际指向测试类实例而测试类总是继承自unittest.TestCase。unittest库还提供了断言异常的方法测试触发错误的代码路径同样重要assertRaises()与assertRaisesRegex()可用于验证一段代码是否正确抛出异常。当需要比较 Warp 数组与期望结果时以下辅助函数很有用assert_np_equal()接收两个 NumPy 数组以及一个默认为 0 的可选绝对容差tol。容差为 0 时用np.testing.assert_array_equal()比较否则将两个数组展平后用np.testing.assert_allclose()比较assert_array_equal()接收两个 Warp 数组各自转成 CPU 上的 NumPy 数组后用np.testing.assert_equal()比较wp.expect_eq()与前两个不同它在Warp kernel 内部完成比较数据可留在 GPU 上。当数组特别大、CPU 上的逐元素比较慢到不可接受时这一点很关键。跳过测试Warp 需要在包括 macOS 在内的多个操作系统上测试而 macOS 不支持 NVIDIA GPU。当某个测试在任何设备上都无法执行时有以下机制可将其标记为跳过unittest自身提供了跳过测试的方法若测试函数通过add_function_test()注册可以向device参数传入空列表此时add_function_test会把该方法替换为skip_test_func在unittest框架中被正式标记为 skipped而非凭空消失最后一种常用做法是干脆不调用add_function_test。例如 warp/tests/interop 下的 test_torch.py、test_jax.py、test_dlpack.py 都采用此法。但这种做法不推荐因为测试在unittest框架中不会被标记为 skipped而是被当作不存在——它既不出现在 skipped 计数中也不出现在 passed 计数中容易让人意识不到某个测试被跳过了。除了需要 CUDA 的情况常见的跳过测试场景还有当前环境未安装usd-core安装的 JAX 版本过旧系统可用 CUDA 设备不足两块例如多 GPU 测试所需。无需设备的测试有时测试函数不依赖任何特定设备只想运行一次。此时有两个选择仍用add_function_test()注册但传入devicesNone函数只会向测试类注册一次或者完全不用add_function_test()直接在测试类内部定义测试方法class TestAmazingCode(unittest.TestCase): def test_amazing_code_no_device(self): self.assertEqual(True, True)对部分开发者来说后一种写法可读性更好避免了add_function_test(..., deviceNone)的间接性。毕竟add_function_test()的存在意义是让一个测试函数在多个设备上运行而不是为每个设备各写一个函数。基准测试Warp 使用airspeed velocityASV做性能基准测试。基准脚本位于 asv/benchmarks 目录按api/、codegen/、examples/、fem/、sparse/、tile/等子目录组织还包含atomics.py、bvh_build.py、floordiv.py、memory_access.py、texture.py等独立基准ASV 配置在 asv.conf.json基准目录asv/benchmarks、环境目录asv/env、结果目录asv/results、HTML 输出目录asv/html、默认基准超时 120 秒。运行基准测试对当前 commit 运行全部基准uvx --python 3.12 asv run -e --launch-method spawn HEAD^!对当前 commit 运行特定基准类uvx --python 3.12 asv run -e --launch-method spawn -b BenchmarkClassName HEAD^!对一段 commit 区间从older_commit到newer_commit两端包含运行特定基准类uvx --python 3.12 asv run -e --launch-method spawn -b BenchmarkClassName older_commit..newer_commit为什么要用--launch-method spawn在 Linux 上ASV 默认使用forkserver它通过os.fork()隔离每次基准运行并用os._exit()终止子进程。由于os._exit()绕过 Python 正常的解释器关闭流程TemporaryDirectory的 finalizer 永远不会执行NVRTC 预编译头目录/tmp/wp_pch_*、/tmp/__nvrtc_auto_pch_*会在/tmp中持续累积。这些目录在重启后会被清理所以主要影响长时间运行的机器。传入--launch-method spawn即可避免该问题。结语一份高质量的 Warp 贡献本质上是符合项目规范的小步改动规划阶段先在 Issues/Discussions 检索并说明动机每个 commit 都带 DCO sign-offPython 侧过 Ruff、C 侧过 clang-format全部由uvx pre-commit run --all-files统一把关新测试通过add_function_test()注册并加入default_suite()用assert_np_equal()/assert_array_equal()/wp.expect_eq()验证行为影响性能的改动用 ASV 在 commit 区间上量化对比最终以干净、聚焦的 PR 提交到main分支。这套工作流既保护了 Warp 复杂的 Python/CUDA 混合代码库质量也让社区贡献者有章可循。【免费下载链接】warpA Python framework for GPU-accelerated simulation, robotics, and machine learning.项目地址: https://gitcode.com/GitHub_Trending/warp/warp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考