ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Genesis 开发规范全景解析:内核编写、数据访问与测试纪律的工程实践指南

Genesis 开发规范全景解析:内核编写、数据访问与测试纪律的工程实践指南 物理引擎具身智能机器人人工智能【免费下载链接】genesis-worldSimulation platform for general-purpose robotics embodied AI learning.项目地址https://gitcode.com/GitHub_Trending/genesi/genesis-world点击查看免费下载导读本文以仓库根目录的 CLAUDE.mdGenesis Development Guidelines为绝对主体系统讲解 Genesis 仿真平台面向协作者与 AI 编码助手的全套开发准则覆盖基础编码纪律、Quadrants 内核编写、批量数据访问、公开 API 设计、代码风格与测试方法论。文章在完整继承规范全部要点的基础上结合genesis/源码实现、tests/测试套件与pyproject.toml配置逐一佐证帮助读者理解每条规范的底层动机并能在实际开发、测试与代码评审中直接落地。规范文档的定位与整体结构CLAUDE.md是 Genesis 项目面向 AI 编码助手如 Claude和贡献者的权威开发准则其姊妹文档 CODING_GUIDELINES.md 是面向人类贡献者的补充约定二者共同维护仓库的代码质量基线。全文按主题分为 11 个板块板块核心关注点Miscellaneous基础编码纪律类型、命名、异常、遗留代码清理Priorities冲突时的取舍优先级Data AccessQuadrants 与 torch/numpy 之间的数据转换与零拷贝Kernelsqd.kernel/qd.func的可微分写法与参数约定API Design公开 API 的自洽性与易用性约束Style文档字符串、注释、命名与排版Testing Guidelines测试组织、物理断言、步数与容差预算Git Worktree 测试可编辑安装模式下测错引擎的陷阱集群测试Slurm 包装器gs-srun下的测试实践Apple 软件渲染器在本地复现 macOS CI 渲染失败Tooling Contributingruff、pre-commit、PR 标题规范从源码结构看这些规范并非孤立的写作要求而是直接对应仓库的真实架构Quadrants 作为底层计算内核提供可自动微分autodiff的张量/字段抽象与qd.kernel装饰器见 array_class.pyGenesis 在其上封装了面向用户的求解器、实体与场景 API。规范的核心矛盾因此始终是内核层追求极致性能与可微分性用户层追求清晰、稳定、可预测的公开 API。基础编码纪律Miscellaneous强类型数据用 dataclass / NamedTuple 取代 dict规范明令禁止用普通 dict 打包属性要求使用强类型命名数据结构dataclasses 或简单 NamedTuple。唯一的例外是刚体资产解析器产生的中间信息因为格式声称的内容在解析完成前是不完整、无结构的所以允许以普通 dict 形式在解析器与消费它的解析逻辑之间传递但任何内置对象不得持有它。这一约束在源码中有清晰体现genesis/engine/solvers/rigid/rigid_solver.py中所有求解器状态字段都是声明式的 Quadrants 字段定义例如qpos0V(dtypegs.qd_float, shape(solver.n_qs_, _B))、n_awake_dofsV(dtypegs.qd_int, shape(_B,))见 array_class.py。Quadrants 数据类的 dtype 定义集中在 array_class.py而 genesis/init.py 统一导出了qd_float、qd_int等类型。禁止 getattr / hasattr用 None 初始化与 isinstance 判断动态属性探测会破坏类型可推导性规范要求一律改用None初始化配合isinstance(...)判断且判断应直接写在if语句中不引入临时变量。领域对象命名的正确性语义领域对象只有三个名词entity、link、geom禁止自创 body、object、piece 等新词。这不仅是风格问题更是正确性提示刚体单位是 link因此必须按entity.links→link.geoms的层级迭代几何体而不是按 entity 聚合。规范同时要求把has_any_rigid_coupling这类属性型实例方法转换为 property见 rigid_solver.py 的使用方式。类型转换的零容忍原则float()/int()/.astype()/np.asarray()/dtype一律禁止除非严格必要——即外部接口强制要求 dtype如 igl 的 float64/int64、内核参数的原生 Python 类型且不得重复转换已被后续步骤转换过的值。numpy 标量天然支持索引、比较与算术运算。torch 张量转 numpy 必须走 misc.py 的tensor_to_array内部先tensor_to_cpu处理 GPU→CPU 迁移禁止手写detach().cpu().numpy()需要指定 dtype 时通过tensor_to_array(x, dtype...)参数传入而不是链式.astype。异常与 assert 的分界能由用户输入触发的情况抛异常代码内部流程不变量、无公开 API 暴露的情况用assert。破坏物理正确性的关键错误必须抛异常必要时 re-raise 澄清错误信息绝不允许用 warning 掩盖。NaN 必须通过现有的 errno 机制中止仿真可定义新错误码同样不接受 warning。清理与去重规范要求删除全部遗留代码不保留 deprecation / legacy 兼容层、删除未使用的辅助函数如has_coupling_type、不允许代码重复、禁止注释掉的 print一律改为 logging debug trace、禁止按最大尺寸预分配必须精确分配所需内存。优先级质量优先于一致性当从 PR、外部项目或旧实现移植代码时代码质量优先于源码一致性Genesis 的约定永远优先于原代码风格原逻辑只作为参考而非实现风格。在构建/初始化路径上可维护性优先只要性能合理即可坚持使用公开 API在运行时热路径上效率优先最小化 GPU-CPU 传输、使用批量操作。数据访问规范Data Access这是规范中技术含量最高、与底层运行机制绑定最紧的部分核心对象是 Quadrants 字段。统一转换入口qd_to_numpy / qd_to_torch禁止直接调用 Quadrants 数据实例的.to_numpy()/.to_torch()方法必须使用genesis.utils.misc提供的qd_to_numpy/qd_to_torch。源码实现见 misc.py显示transposeTrue时应始终传入把批维移到最前[B, n, dim]与公开 getter 约定对齐copyFalse仅在 CPU 后端且启用零拷贝时受支持GPU 数据转 numpy 必然需要拷贝转换应提升到循环之前一次调用后索引本地数组禁止在紧循环内反复调用qd_to_numpy需要子集时把切片作为qd_to_numpy的输入参数而不是先转换再切片不要给qd_to_torch/qd_to_numpy传copy参数当返回值是全新算术结果、无内部别名外泄时让方法自行决定零拷贝或拷贝只有裸字段视图可能逃逸并被修改时才用copyTrue。零拷贝写入路径的规则需要被写入的qd_to_torch视图必须先绑定到具名局部变量如flags_t qd_to_torch(..., copyFalse)后再flags_t[mask] ...禁止通过匿名链修改只读场景则相反可以放心内联链式操作如qd_to_torch(f).T.reshape(...).gather(...)。零拷贝访问器应原样透传选择selection写入属于拷贝语义的 setter每环境一个向量/标志/一行在gs.use_zerocopy成立时走视图路径。视图路径上禁止使用Scene._sanitize_envs_idx见 rigid_solver.py 等处的传统用法而应把选择原样交给indices_to_mask定义于 misc.py再以broadcast_tensormisc.py对view[mask].shape广播值、以assign_indexed_tensormisc.py执行写入。indices_to_mask从末尾计数的负边界是其已知缺口应在该函数内修复而不是逐个访问器绕开。零拷贝路径只依据gs.use_zerocopy分支见 genesis/init.py由环境变量GS_ENABLE_ZEROCOPY控制禁止 try/except 探测。构建期与运行期的数据获取分工构建/初始化期通过 entity/link/geom 公开 API 迭代entity.links、link.geoms、geom.init_verts、link.get_pos()等只有效率、简洁性或可维护性确实需要时才下沉到低层求解器字段。运行期批量转换用qd_to_numpy/qd_to_torch禁止逐字段索引field[i]优先用 torch 零拷贝更新其他求解器的内部状态numpy 零拷贝仅 CPU 后端支持。构建期应把 Python 引用entity、link 对象存入 dict 供运行期查找而不是每步从求解器字段重新推导。派生多个原始求解器字段的量应归属为单个向量化求解器 getter而不是由消费者自行组装或写专属逐元素qd.kernel再重索引——字段访问耦合与 batched/non-batched 处理应集中在单一经测试的位置。批量参数用envs_idxenv_idx if batched else None处理而不是针对批处理分支getter/setter 应对所有环境一次性处理IPC 相关的可退化为 for 循环禁止按 env idx 反复调用。Metal 流同步在一批 torch 零拷贝写入之后、下一个 Quadrants 内核读取缓冲区之前调用者需调用一次torch.mps.synchronize()。执行此类写入的辅助函数如qd_zero_grad内部从不自行同步这一责任在调用方。源码 misc.py 中确实可见 Metal 后端的同步处理注释与torch.mps.synchronize()调用。内核参数的数值类型禁止向内核参数传递 numpy 标量如numpy.float64——它会破坏 Quadrants fastcache 的弱引用机制。必须强转为原生 Python 类型float()、int()。Kernel 编写规范可微分的结构性要求每个内核都必须能被 Quadrants 的 autodiff 反向执行因此结构性禁令非常严格顶层只能由for循环组成禁止continue、禁止while门控用静态条件下置位、再由if测试的标志实现不能用提前continue遍历块时用for覆盖 dof 范围并做块起始测试条带步进用for i_chunk_ in range((n BLOCK_DIM - 1) // BLOCK_DIM)再以i i_chunk_ * BLOCK_DIM tid配合if i n门控手工编写反向内核被强烈反对除非有非常充分的理由如反转 autodiff 无法展开的迭代算法——约束求解、逆运动学。间接索引的绑定约束从字段读出的索引必须先绑定到临时变量再用于索引其他字段如i_r rigid_info.links_root_rank[i_l]然后rigid_info.roots_link_end[i_r]。a[b[i]]这类嵌套间接索引在内核与 func 中禁止。规范参数顺序Canonical Parameter Order所有 kernel 与 func 遵循固定参数顺序先是各类索引循环索引、envs_idx等索引张量、joint_idx等索引标量或范围起止然后是动态原生 Python 标量与定长 Quadrants 向量每调用值位置、四元数、穿透量接着是 kernel/func 专属张量然后依次是全部 state 结构体、info 结构体、静态配置再是实践中实为常量的参数形状整数、eps、容差最后是编译标志——先是静态的qd.template()布尔量再是运行时原生布尔量如write_L: bool保持动态以省去每种取值的一次编译。errno单独跟在最后一位。state/info/config 各组内部的组件顺序固定dyn、rigid、collider 含 mpr、gjk、support_field、sdf然后是 constraint。调用点按签名顺序传参。静态配置与运行时信息的边界静态配置只能容纳有界选择布尔、枚举、小固定集合内的整数。而可取任意值的整数环境数量、叶子/面数量、由此导出的位宽属于运行时信息——应为内核中的张量形状、info 张量或普通整数参数。静态整数会按值编译内核场景间一变值就破坏预编译刚性求解器从不对环境数量做键控即是参照。类型标注与命名每个 kernel 和 func 参数都必须有类型标量用原生 Python 类型int/float/bool定长向量/矩阵用qd.types.vector(n)/qd.types.matrix(n, m)类型多态辅助函数的参数可保持不标注。定长向量注解中不得写 dtype写qd.types.vector(3)绝不写qd.types.vector(3, dtypegs.qd_float)。新代码一律用自由函数qd.kernel不用qd.data_oriented类型多态参数使用 array_class.py 中的V_ANNOTATION。唯一例外是 FEM 求解器它延续旧的qd.data_oriented方法模式新增内核必须与之保持一致。内核/func 调用中同名参数按位传递self-named匿名常量裸字面量、尾部静态标志按关键字传递结构体成员与父结构体同传的 func 调用只能关键字传参因为 quadrants 的位置参数展开会复制成员。qd.func 内联与编译预算每个内核只内联一次它所调用的每个qd.func实例同一辅助函数被两个不同参数的分支调用会编译两次模板参数取两个值也会让被调方编译两次qd.static(range(R))下重函数体会编译 R 次。规范给出的对策在运行时分支挑选参数只调用一次、以运行时计数循环项重算廉价逐项值而非携带逐项寄存器、需要提前退出时用单次迭代for加breakcollider 的模式、可微内核中用if门包住顶层循环体break/continue被拒。CI 基准测得的编译时间是裁决标准低于 2% 无所谓8% 及以上必须处理中间地带酌情判断。此外纯读写数据访问器在热路径上应优先走零拷贝视图qd_to_torch(..., copyFalse)/qd_to_numpy(..., copyFalse)内核仅作回退——只为搬运/改写字段写微型内核用微秒级工作付出完整内核分发开销不值得。API 设计单一正确值的自动解析如果某选项在给定上下文中只有一个有效值如 IPCCoupler 下必须enable_collisionFalse不要强迫用户设置默认None初始化时解析为正确值用户显式给出冲突值时抛异常。解析逻辑可基于其他选项、场景内容甚至运行时状态但必须充分文档化。辅助函数的克制不为一两行直白逻辑更别说单表达式包装辅助函数无论有多少调用者直接内联需要名字时作为局部变量。单一用户场景的专属辅助函数single-use helper一律禁止除非它完全独立且通用数学函数、转换工具避免私有实例方法。单值返回值不得包进具名结构体一字段 NamedTuple/dataclass 是死样板只有真正多字段返回才用具名结构。数组输入的类型别名索引/数组输入选项必须使用项目的 array-like 类型别名IArrayType/OptionalIArrayType/FArrayType/Vec3FType等定义于 typing.py禁止裸tuple[int, ...]/list[...]。原因在源码中可见Options是严格 PydanticConfigDict(strictTrue)裸类型集合字段会拒绝用户自然传入的 list 与 numpy 数组如dofs_idx_local[0, 1]而别名携带strictFalse可将 array-like 输入强制转换为 tuple。模仿同级选项字段的类型写法如filter_link_idx: OptionalIArrayType。风格规范Style文档字符串以一句不超过 200 字符、不点名参数的短句开头更多内容空行后分段展开参数在各段中说明。描述现状而非历史该函数现在做什么不写曾做什么或为 X 添加了 Y若行为是某 bug 修复所需以当前不变量解释如必须处理 Z 情形以避免 Y。面向用户的选项文档必须陈述权衡cost AND benefit何时选何值只讲做什么而不讲代价的文档是无用的用 Genesis 术语说明不引用外部引擎如 MuJoCo与内部实现机制约束行、耦合、锥投影、内核、分解路径那些属于开发代码注释。函数级描述放 docstring禁止在函数体顶部放成块的#注释getter/方法开头写一大段#散文是错的——那是它的 docstring。文档字符串不得声明代码未提供的契约未保证的数组形状、内存布局。命名布尔变量/字段/属性以is_/has_前缀开头现在时优先is_fixed、is_convex、has_multi_island_structurewas_只用于真正的过去时标志宁取is_cached_loaded而非was_cached。裸名hibernated或did_did_fuse均非法。前缀问的是状态而非输入参数函数/方法/内核的布尔参数命名调用者请求什么refresh_position、scale_inertia、in_place不加前缀。变量名以名词开头命名其持有对象种类rejected_kinds、links_offset_pos不写裸形容词/分词rejected、left_out例外是布尔上述前缀与索引/循环变量i_type约定。容器避免泛化的all_前后缀宁可具体joints_xanchor、links_inertia_i、geoms_pos、entities_quat、verts_idx避免纯变量名赋值mass_mat_env mass_mat_all可变容器优先清空复用self.abd_data_by_link.clear()而非重新分配self.abd_data_by_link {}。使用flatten()、reshape((-1,))、ravel()代替 squashing 是不允许的且优先[..., 0, :]而非squash(axis-2)。ASCII only源码代码、注释、docstring不得出现非 ASCII 字符——写tau而非希腊字母、qddot而非带双点的 q、*而非中圆点、-/--而非 em dash、纯# ---而非制表符分隔线。缩写在每次 docstring/注释首次出现时全称拼出并括号标注缩写如 positive semi-definite (PSD)。注释注释解释为什么它保护的不变量、诱人替代方案的失败模式保持通用、现在时不锚定易腐细节测量值、基准数字、特定单测/示例。每条事实只存在于一个注释中其他站点交叉引用它并保留一行指向真源如 see nt_H in array_class.py。注释独立成行置于所注解代码上方尽量不尾随行内注释不写无用/循环注释不重述名字、类型、控制流已传达的信息不写同义反复。段落结尾不得以单字词单独成行行填充至 120 字符宽。已知上游 bug 记# FIXME:并命名 issue最多两行含 tracker 引用如# FIXME: quadrants#887 - ...与 workaround 的代价。其他硬性风格写朴素陈述句主语-动词-宾语用标准仿真词汇质量矩阵、Jacobian、逆权重、运动学树、子步不自造动词。不用分号连接散文不用破折号当括号写两个句子或用圆括号。局部变量以其是什么命名而非其被测属性场景变量叫scene_from_substeps不叫shorthand。禁止用浮点/!比较即使主机端值也如此用np.allclose(a, b, atolgs.EPS)或显式界。不写第三方对象的私有状态自持记录在旁并经 property 暴露。叙述是什么而非不是什么去掉 not X、unlike Y除非读者天然会做错误解读。导入分组标准库、通用第三方numpy/torch/tqdm…、其他第三方、自家库quadrants…、genesis 自身先绝对后相对组间空行、组内字母序改动一个导入就必须重整整个模块的导入。禁止导入别名Cloth而非ClothMaterial。匿名字面量按关键字传递以在调用点显其含义_adaptive_params(verts, faces, aggressiveness7)模块局部 qd.func 调用中的数值常量可保持位置传参。换行按嵌套层级全有或全无能一行放下≤120 字符必须单行溢出则整体收进单个续行再溢出则每个参数一行展开的外层调用中能单行放下的嵌套调用保持单行。嵌套数据字面量矩阵、坐标/边表是例外即便整体能放下也保持一行一行。一个if子句要么全是静态条件要么全是动态条件共享内存数组qd.simt.block.SharedArray用sh_前缀。禁止用快照相等比较检测状态变化Genesis 有专用变更检测设施solver 的 StateChange 订阅机制见 base_solver.py 中的StateChange枚举与mutates装饰器缓存运行数据再轮询对比新副本的做法被禁止设施缺失或粒度不足不是借口——扩展机制绝不退回到快照比较这是整个 PR 被拒的充分理由。非 solver 类materials、couplers、entities不得使用qd.data_oriented目录内命名保持一致如 IPC 示例统一ipc_*.py前缀。测试规范Testing Guidelines组织与命名测试按组件再按能力组织tests/下每组件一个目录rigid/、deformable/、particles/、ipc/、coupling/、sensors/、rendering/、parsers/、core/、integration/、benchmarks/每能力一个文件如 test_collision.py、test_imu.py。新测试进既有能力文件只有真正的新能力才开新文件。优先加强既有测试而非新写扩展场景与断言或用pytest.mark.parametrize加维度。测试以所验证的特性命名而非被仿真场景test_reject_offaxis_contact_on_authored_decomp而非test_stacking_tower_stability名字不以模块/文件夹名作前缀tests/sensors/test_temperature.py::test_grid_sensor_contact_and_reset绝不写test_temperature_grid_...。单元测试不得有 docstring——好的测试名胜过短 docstring代码注释仅在强动机下允许解释测试体无法传达的内容。绝不写钉死已知缺陷、验证 deprecation warning、或测试不提供能力的测试但拒绝无法处理的输入是行为应被断言若继续会损坏用户所得。打包测试Pack Tests一次场景构建一次测试只建一个场景宁可牺牲可读性也必须避免额外构建构建慢且计算重。偏好顺序一个综合场景多样实体与选项 同场景内不同配置实体 必须互不干扰的布置在同一场景内远距摆放 通过n_envs扫配置 参照仿真并排折叠进同一场景。注定被拒绝的场景构建零成本、不占预算一个测试里多个没问题。断言物理而非执行仿真无错跑完不是测试。检查有物理意义的量自由落体位移z z0 - 0.5*g*t^2、无地面穿透min_z -d_hat、静止时速度→0、接触阻止下落。无解析期望时可先跑一次取参考值硬编码用宽松容差断言并加FIXME注释请求日后替换为物理感知断言。用 assertions.py 的assert_allclose/assert_equal精确比较优先assert_equal等价于零 atol/rtoltol同时设置 atol 与 rtol 且适用于量级为 1 的量量级固定远离 1 的如0..255像素通道用atol。提交针对特定缺陷的测试前先故意破坏实现并观察断言失败。步数与容差预算步数预算是硬性约束按测得而非猜测的最少步数来定浮点敏感量加 10% 或进位到 50取更大者。层级100步无碍、100-300灰色需说明、300近乎禁止全测试套件仅允许 4-5 个。同时约束总 env 步数steps * n_envs500 步 × 16 env 的稳定期8000不可接受。批量测试用n_envs[0, 2]参数化多 env 是形状 bug 的藏身处且不添加 conftest fixture 已控制的死参数维度如backend。验证数学而非规模一个约束足以证明理论对 1 成立即对 1k 成立正确性不需要大/高 DOF 场景真实多体场景仅在验证单约束无法验证的东西端到端稳定性时才值得花步数。优先浮点稳健检查单次约束求解比较从固定状态一步稳健跨数值不同代码路径的多步轨迹比较不稳健fp32 误差累积、正确路径也会发散。跨引擎MuJoCo一致性是现实检查解析闭式是数学检查。回归测试是被动添加bug 浮现时不做推测性添加。梯度-有限差分FD容差钉在测得地板地板T max|ana - fd| / (1 |fd|)配置 eps 下取 CPU 与两个 GPU 架构最坏值容差取地板的 1.5x-5x值只能取自 {1, 2, 5}e-X。不追的地板是 fp64 的 1e-10 与 fp32 的 5e-5eps 按精度设置fp32 大、fp64 小。地板恰为 0 说明检查空洞——修 loss 而非容差与 eps 无关的残差是解析 bug绝非 FD 伪影。向物理精确收紧宽松容差掩盖真实行为差异收紧导致测试失败时深挖根因而非放宽用精确断言路径全 horizon、所有阶段验证修复不用廉价代理。精确解析动力学检查强制gs.integrator.Euler使有限差分qacc等于求解器结果并同时计入刚体转动惯量与隐式阻尼一阶修正effective_inertia I damping*dt见test_position_control。场景构建细则每个scene.add_entity/scene.add_sensor/gs.morphs.*/gs.options.*调用每行一个选项ruff 不强制需手写关键字参数遵循被调函数声明顺序add_entity(morph..., material..., surface...)关键字不授权重排。只设严格必需的选项默认值不显式设置除非计算读取该值gravity、dt必须显式设置以匹配断言。标量/list 直接传递control_dofs_force(TAU)、set_dofs_kp([...])、inverse_kinematics(pos[...], quat[...])不包np.full/np.array/单元素[...]一次性目标向量内联而非命名。自定义 MJCF/URDF 模型用xml.etree.ElementTree在 fixture 中构建返回ET.tostring(mjcf, encodingunicode)直接传给 morph 的fileFileMorph.file接受内联 XML 字符串见 conftest.py绝不写临时 XML 文件、绝不write_text/f-string 拼 XML。需落盘的临时资产用 session 级asset_tmp_pathfixturetmp_path仅 per-test无模块级测试常量/辅助/参数化场景列表参数从建好的模型读回get_dofs_armature、get_dofs_damping见 rigid_solver.py。重复样板藏进 fixture但无回报的间接层严格有害默认有害须以真实收益证明场景搭建留在测试体单测读起来像示例脚本宁重复也保持显式自洽不做过早分解。每步断言不做float(...)/.item()强转设计场景使断言无条件成立如预热循环把关节转起来再对整张张量.all()断言。每个调用scene.step()的测试取show_viewerfixture 并设置带相机视角的ViewerOptions便于启用 viewer 调试。需要接触的场景必须有可动物体双固定 geom 对在构建期被丢弃把固定实体沉入表面不会产生接触还会永久埋没其几何体渲染。FEM 实体位置entity.get_state().pos形状[B, n_verts, 3]用[..., 2]跨 env/顶点选 z刚体实体entity.get_pos()返回[B, 3]或[3]用np.atleast_1d(...)[..., 2]与.all()做多 env 检查。测试输出的纪律绝不内联过滤/截断测试输出pytest ... | tail/| grep过滤器夹在 pytest 与磁盘之间会毁掉失败名的唯一副本并掩盖退出码。重定向完整输出到日志文件再从文件提取。绝不删除或弱化既有断言/测量来压掉失败本地或 CI——连同数据上报并询问只在单机成立的阈值是校准问题。Bug 修复 PR 必须带回归测试在main上失败、带修复后通过加入已覆盖被破坏能力的那个测试。从 Git Worktree 运行测试可编辑安装的测错引擎陷阱包以可编辑模式指向主检出安装因此 worktree 的genesis/默认不被导入——worktree 的tests/实际跑的是主检出的genesis/引擎改动看似无效、所有结果作废。规范给出的识别症状引擎改动无效果、worktree 中新增的内核print()不输出、引擎变体 A/B 每臂位级相同——先按此陷阱排查再谈物理解释。正确做法从 worktree 调 pytest 时始终传PYTHONPATH$PWDcd worktree PYTHONPATH$PWD pytest -n 8 tests/rigid集群同理PYTHONPATH$WORKTREE pytest ...。每会话验证一次而非假设PYTHONPATH$PWD pytest -n 0 -s -k any test并print(genesis.__file__)确认打印路径以 worktree 开头。裸python script.py从 worktree 运行确实会选中 worktreecwd 先于可编辑路径因此同一目录下脚本与 pytest 可能跑不同引擎二者结果不可比较。并行运行时给 worktree 独立编译缓存QD_OFFLINE_CACHE_FILE_PATHscratch/quadrants GS_CACHE_FILE_PATHscratch/genesis。worktree 引擎不同于填充共享~/.cache的引擎每个内核都是新的xdist worker 竞争写同一缓存会损坏条目表现为上百个明明在作用域内的QuadrantsNameError、散布在单跑通过的测试中、第二次运行因坏条目持久而更糟。重定向缓存而非删除共享缓存。集群测试实践基于真实集群环境ssh genesis-coreweave代码路径/mnt/home/duburcqa/workspace/src/genesisGit 操作fetch/checkout/pull必须在登录节点完成不能在gs-srun内计算节点容器无法访问 GitHub。始终用gs-srunSlurm 包装器分配 GPU 节点绝不在登录节点直接跑 pytest/python绝不手动 source venv——容器镜像已带正确环境bash -lc登录 shell 自动配好。组合模式ssh genesis-coreweave bash -lc cd /mnt/home/duburcqa/workspace/src/genesis git pull gs-srun --partitionrtx-high --nodes1 --gpus1 bash -ilc \cd /mnt/home/duburcqa/workspace/src/genesis pytest -n 10 tests/ipc -v --no-header 21\。示例测试需-m examples覆盖 pyproject.toml 的默认标记过滤默认-m not (benchmarks or examples)。本地文件复制用scp local_path genesis-coreweave:remote_path后gs-srun运行。计算容器挂载/mnt/home不挂登录节点的/tmp登录节点/tmp下的脚本/补丁/输出目录在gs-srun下不可见一切暂存到/mnt/home/duburcqa。交互登录 shellbash -ilc设置noclobbercmd file在文件已存在时报 cannot overwrite existing file 且静默无输出固定路径再生成日志时先rm -f file或用| file。用bash -ilc source script.sh跑暂存脚本绝不bash -l script.sh容器 Python 环境只在交互登录 shell 初始化非交互bash -l在gs-srun下无 venvModuleNotFoundError: genesis。脚本暂存于/mnt/home后 source 之同时避开超长内联命令的嵌套引号问题。复现 Apple 软件渲染器失败GitHub Apple Silicon macOS runner 都是虚拟机虚拟化 GPU 无 OpenGL渲染回退到 Apple Software Renderer该渲染器半损坏。macOS 专属渲染失败源于测试触及其故障模式因此单元测试要谨慎依赖渲染特性。在本地任意 Mac 强制复现在任何 GL 上下文创建前劫持 pyglet 无条件追加的两个像素格式属性# force_sw.py - import before any GL context is created, e.g. pytest -p force_sw with PYTHONPATH set from pyglet.libs.darwin import cocoapy cocoapy.NSOpenGLPFAAllRenderers 70 # NSOpenGLPFARendererID cocoapy.NSOpenGLPFAMaximumPolicy 0x00020400 # kCGLRendererGenericFloatID这只影响 pyglet 创建的上下文离屏渲染须以PYOPENGL_PLATFORMpyglet路由回 pyglet 平台其 macOS 默认 CGLpyglet 对此一无所知。用与 macOS CI 相同的标志运行PYTHONPATHdir-with-force_sw.py PYOPENGL_PLATFORMpyglet GS_TORCH_FORCE_CPU_DEVICE1 pytest -p force_sw --dev --logical --backend cpu --forked testsCI 另选-m required and not slow。生效验证Genesis 日志输出 Software rendering context detected且scene.visualizer.is_software为 True。已知故障模式一相机视锥外的顶点几何被错误光栅化破坏像素比较——地面平面默认plane_size实际无限1km × 1km须给有限尺寸并置于视图内。已知故障模式二软件渲染后端因性能强制禁用阴影映射快照场景必须显式关阴影rasterizer 的shadowFalse硬件 GL 带阴影生成的快照永远无法匹配。工具链与贡献流程Lint/format 用 ruffcheck format行宽 120见 pyproject.toml经 pre-commit 执行pre-commit install后每次提交自动运行。PR 标题带括号标签[BUG FIX]、[FEATURE]、[MISC]默认会改变仿真物理不同模型或不同默认参数求解器内部重构属[MISC]、[CHANGING]、[BREAKING]API 破坏。提交标题是纯单行句、无标签PR 与提交标题都以句号结尾。PR 标题陈述对最终用户的收益而非实现实现细节进 PR 描述。贡献者须遵守 CODING_GUIDELINES.md 与.github/contributing/下的参考文档ARCHITECTURE、TESTING、CODING_CONVENTIONS、EXAMPLES、PULL_REQUESTS、USD_PARSER冲突时先问。结语把CLAUDE.md的规范与genesis/源码对照阅读可以清晰地看到一条贯穿始终的主线所有约束都服务于可自动微分的性能内核 稳定清晰的公开 API这一对目标。内核侧通过参数顺序、静态/运行时信息切分、qd.func内联与零拷贝视图换取编译速度与 GPU-CPU 传输的最小化用户侧通过强类型数据结构、类型别名、单一正确值自动解析与权衡式选项文档换取 API 的可预测性与自洽性测试侧则用打包场景、物理断言、步数与容差预算保证 CI 成本可控且断言真实有效。对于希望为 Genesis 贡献代码无论是人类开发者还是 AI 编码助手的读者这份指南既是一份可执行的检查清单也是理解仓库设计哲学的入门地图。赞分享物理引擎具身智能机器人人工智能【免费下载链接】genesis-worldSimulation platform for general-purpose robotics embodied AI learning.项目地址https://gitcode.com/GitHub_Trending/genesi/genesis-world点击查看免费下载相关推荐Genesis 编码规范实战指南仿真引擎内核开发的命名、内核编写与测试评审约定Genesis 编码规范实战指南仿真引擎内核开发的命名、内核编写与测试评审约定 本文以开源机器人仿真平台 Genesis 官方编码规范文档 CODING_GU物理引擎具身智能机器人人工智能Saleor 工程规范全景为横向扩展与并发安全而写的 Headless Commerce 内核开发指南Saleor 工程规范全景为横向扩展与并发安全而写的 Headless Commerce 内核开发指南 本文以仓库根目录 AGENTS.md https://后端电商Penpot monorepo 测试工程实践从 TDD 纪律到跨模块测试执行规范Penpot monorepo 测试工程实践从 TDD 纪律到跨模块测试执行规范 Penpot开源的设计协作与 UI/UX 平台采用多模块 monorep前端设计系统图形学协同办公上一篇Watermill SQLite Pub/Sub 实战CGO-free 双驱动ModernC / ZombieZen的事件持久化指南下一篇Wasp 用户名密码认证从零搭建自定义登录注册 UIwasp/client/auth 实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表