mcpField
C
cupynumeric-migration-readiness

cupynumeric-migration-readiness

github.com/nvidia开发3.8k1.9k 次安装今天更新
代码仓库

关于 cupynumeric-migration-readiness

cupynumeric-migration-readiness 是一项只读技能,用于在迁移到 cuPyNumeric 前评估 NumPy 代码。它分类分析扩展性模式和 API 支持情况,并给出发现与重构建议,帮助团队判断迁移准备度。

主要功能

  1. 01静态检查 NumPy 源码
  2. 02分类评估 GPU 扩展模式
  3. 03核对 API 支持清单
  4. 04生成结构化迁移结论
  5. 05提供重构方案指引

适用场景

  1. 01评估 GPU 迁移前的代码
  2. 02发现阻碍扩展的 NumPy 模式
  3. 03规划移植前的代码重构

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/nvidia/skills --skill cupynumeric-migration-readiness

安装后在 Claude Code 中输入/cupynumeric-migration-readiness确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

.gitignore
BENCHMARK.md
assets/
api-support.md
sample_report.md
assets/examples/
blocks_scaling.py
needs_refactor.py
scales_well.py
evals/
evals.json
evals/files/
api_gap_hotpath.py
blocks_scaling.py
convergence_loop.py
cupy_mixed.py
dense_linalg.py
dense_with_scipy_boundary.py
graph_workload.py
item_sync.py
jacobi_heat.py
many_blocks.py
monte_carlo_bs.py
monte_carlo_good.py
needs_refactor.py
scales_well.py
sequential_recurrence.py
sparse_sklearn.py
tiny_array.py
unlisted_api.py
view_mutation.py
references/
case-studies.md
decision-framework.md
execution-model.md

详细介绍

cuPyNumeric 迁移就绪度

目的

请在迁移前使用此技能,而不是迁移过程中。 回答一个问题:用户现有的哪些 NumPy API 能在 cuPyNumeric 上扩展,哪些需要重构,才能避免投入数周工程时间后才发现问题? 为此,请阅读源代码,按照各 NumPy 惯用模式在 Legate/NVIDIA GPU 堆栈上的预期多 GPU 扩展能力进行分类,交叉参考随附的 API 支持清单,并给出结构化结论,说明每项发现的理由并提供对应的方案指引。

这是静态、只读的评估。 使用 Read、Grep 和 Glob 检查用户的源代码。请勿执行用户代码、修改或写入文件,也不要输出环境变量或机密信息。下方显示的 legate 和 cuPyNumeric Doctor 命令是建议用户运行的命令,并非此技能要执行的操作。

如果你从未使用过此技能,请先查看 references/getting-started.md。

何时使用此技能

当用户即将将 NumPy 代码迁移到 GPU,并询问其代码能否在 cuPyNumeric/GPU 上扩展、是否应该迁移、哪些部分会受益、移植前需要修改什么,或移植是否值得时,请使用此技能;用户提及移植前评估、扩展性分析、惯用模式分析、GPU 重构规划,或识别适用于 GPU 的 NumPy 反模式时,也请使用。

当请求不是迁移前评估时,请婉拒并引导用户:

  • 迁移后的性能分析/性能剖析(“已经移植了,为什么这么慢?”)→ 引导用户使用 legate --profile,并参考上游的性能分析与调试指南。
  • 自定义 CUDA/内核编写(“编写/优化 CUDA 内核”)

如果用户确实想迁移图、稀疏计算、ML 或 NLP 工作负载,仍然属于适用范围:评估该工作负载,并通过 Gate 4 给出不建议迁移的结论。这是评估结论,而非婉拒。

说明

按顺序执行以下全部五个步骤。请阅读用户代码并从语义层面进行推理;不要只输出一句笼统结论。

步骤 1 — 收集背景信息

扫描代码前先收集以下信息。每项都设有适用于典型工作负载的默认值——用户未主动提供具体信息时使用默认值,不要因提问而阻塞流程。

  • 源代码位置。 用户未提供路径时,默认为当前工作目录。
  • 运行时热路径数组的大致大小。 默认为 3,000 万至 5,000 万个元素。将用户提供的数字(或此默认值)映射到 Gate 2 各级别(每个 GPU 至少 6.5 万;真正实现单 GPU 加速需 1,000 万以上;多 GPU 需 1 亿以上)。
  • 目标硬件。 默认为单节点配备 1–4 个 GPU。假定使用多节点前请先确认。仅使用 CPU 时,询问每个节点的 RAM,而不是 FBMEM。
  • 主要计算模式。 随机点阵 / GEMM / 蒙特卡洛 / 归约 / 与 SciPy 混合。请用户说明;否则在步骤 3 中根据代码推断。

在评估开头说明所采用的默认值,方便用户更正。如果某项信息无法确定,请明确说明,并继续进行定性评估——除了上述默认值外,不要编造数字。

第 2 步 — 加载 API 支持清单

阅读 assets/api-support.md,这是已提交的上游 NumPy 与 cuPyNumeric 对比表快照。对于代码调用的每个 NumPy API,找到对应行并查看开头的符号:

  • ✓✓ numpy.X — 已实现,且支持多 GPU(最佳路径)。
  • ✓ numpy.X — 已实现,但仅支持单 GPU/CPU(多节点时需注意)。
  • 🟡 numpy.X — <note> — 部分支持;请阅读说明。
  • ✗ numpy.X — cuPyNumeric 分布式路径尚未实现。调用时的行为因版本而异(某些不支持的 API 会转由主机 NumPy 处理,其他则会引发异常)——无论哪种情况,在热路径中使用都会阻碍迁移。不要向用户承诺会静默回退到主机 NumPy。

如果 Fetched: 行显示的时间已超过约 90 天,请刷新快照——请参阅 Available Scripts 部分。

第 3 步 — 从语义上阅读代码

使用 Read 和 Grep 检查用户的文件,并根据 references/idioms-that-scale.md 和 references/idioms-that-block.md 对数组运算的每个部分进行分类(完整的理由和 R 编码见其中)。从语义上阅读,不要只靠正则表达式:标记前,先确认 arr 可追溯到 cupynumeric 数组(或别名为它的 np.*),并检查该访问是否位于热循环中。遵循以下规则:

  • 将元素循环标记为阻碍项(for i in range(n): arr[i] = ...);循环体经过向量化的 epoch/step/file 循环可视为正常——应区分两者。
  • 标记标量同步——在热循环中对 cuPyNumeric 数组调用 .item() / float() / int() / bool() / complex()(每次迭代都会同步到主机);边界处允许使用。
  • 标记归约条件——对数组归约结果进行 if/while 判断(while np.max(err) > tol:)会在每次迭代时同步。
  • 将循环中的可提升分配标记为可修复的低效操作。
  • 标记运行时代码中用于分区/通信数组数据、且与 cupynumeric 并用的 mpi4py(R108)——但要先确认它会在热路径中调用 MPI;README、构建脚本或备用启动器中的 grep 命中可忽略。
  • 将 reshape / asarray / flatten 上的 order= 标记为 R109——无论该版本会发出警告还是静默忽略,都要标记。
  • 在多 GPU 场景下,对 np.random.* 的 INFO 始终引用 R304:默认情况下,跨 GPU 无法实现逐位一致的可复现性(--gpus N / LEGATE_GPUS 是 Legate 启动器参数)。
  • 标记数组上的 Python 内置函数(sum/max/min/any/iter(arr))——会回退到主机迭代(R110;上游最佳实践)。允许使用 len(arr)(查询形状;为确保对 0 维数组的安全性,优先使用 arr.shape[0] / arr.size)。
  • 标记热循环中混用 cupy 和 cupynumeric 的情况(R111);这两个运行时不共享 GPU 内存,因此每次切换都会经过主机 NumPy。
  • 查询代码调用的每个 NumPy API,确认其是否列在 assets/api-support.md 中(符号说明见第 2 步)。

若要深入了解“为什么”,请阅读 references/gpu-stack.md(内存、SM、通信、分派)和 references/execution-model.md(延迟执行、同步点、映射器)。

步骤 4 — 生成结构化评估报告

按以下顺序提交报告。每项发现都引用 file:line,方便用户定位。

  1. 结论:用一句话概述——参见下方的“结论框架”。
  2. 可正常工作的部分(SCALES 发现):引用有代表性的代码行,让用户了解替换导入语句后哪些部分会加速。
  3. 阻碍项(BLOCKS 发现):每项都关联到 idioms-that-block.md 和 refactor-recipes.md 中的一项方案。
  4. 可修复项(REFACTOR 发现):按方案分组;一项方案通常可以修复多个位置。
  5. 兼容性 / 成本说明(INFO 发现):SciPy 边界、仅支持单 GPU 的 linalg / FFT,以及 RNG 布局与 --gpus N 的关系。
  6. API 支持缺口:代码调用的 API 中,按清单标注为未实现或仅支持单 GPU 的 API。
  7. 决策框架摘要:列出 references/decision-framework.md 中的 Gate 1–6,并标记为通过 / 未通过 / 不确定。
  8. 建议的后续步骤:说明应优先应用哪些方案、是否先移植一个模块,以及何时启用 cuPyNumeric Doctor。

必须包含全部 8 个部分,即使结论是 READY 或 NOT RECOMMENDED。对于空白部分,单独一行写上 “此代码无相关内容” 或 “不适用 — 参见结论”;不要省略标题。标题是评估报告的固定结构。示例报告请参见 assets/sample_report.md。

步骤 5 — 移交 cuPyNumeric Doctor 进行运行时验证

用户应用方案并确保代码可以运行后,指导他们运行 cuPyNumeric Doctor:

CUPYNUMERIC_DOCTOR=1 CUPYNUMERIC_DOCTOR_FORMAT=json CUPYNUMERIC_DOCTOR_FILENAME=doctor-report.json legate --gpus 1 main.py

cuPyNumeric Doctor 可以捕获源代码审查无法发现的运行时问题(标量 .item 访问、ndarray 迭代、高级索引、nonzero 误用、导入 mpi4py、对视图进行原地操作)。以这句话结束评估:“现在启用 cuPyNumeric Doctor 运行;以下是需要关注的输出内容。”

评估框架

根据发现的类型定性给出评估结果,而非依据分数:

评估结果适用情况操作
就绪没有阻塞项;重构项很少或没有替换导入;进行基准测试
轻度重构存在少量可通过配方修复的模式(R201–R206),或一两个简单的阻塞项应用 refactor-recipes.md 中的 1–3 个配方;重新检查,直至就绪
重大重构热路径中有多个阻塞项,或存在任何 R108(mpi4py)——需要重写,但不代表不适用面向真实项目;每个模块预留 1–3 个工程师周
不建议仅有两种失败情况:门槛 2(数组低于 65,536 的下限)或门槛 4(计算模式不适用)。大量阻塞项不会导致此结果先调整结构,或改用其他运行时

按以下顺序应用;满足的第一项即为结果:

  1. 门槛 4 未通过(稀疏/图/ML/序列/字符串)→ 不建议。
  2. 门槛 2 未通过(热路径数组每个 GPU 少于 65,536 个元素,且没有可行的批处理方案)→ 不建议。
  3. 存在任何 R108(mpi4py)→ 重大重构(成本在于重写并行层,而非不适用)。
  4. 热路径中存在多个阻塞项(R101–R111)→ 重大重构(数量不会使结果进一步升级——每个阻塞项都有对应的配方)。
  5. 存在一两个可通过配方修复的阻塞项(例如,R101–R104 元素循环/同步)→ 轻度重构。
  6. 只有重构模式(R201–R206)→ 轻度重构;配方都是机械性的。
  7. 没有阻塞项,也没有重构项 → 就绪。
  8. 热路径上有清单中未列出的 API → 降低一个等级(重大重构仍为重大重构,绝不会变成不建议)。仅适用于单 GPU 的 API 只对多节点场景有影响。

权衡发现的类型,而非数量。 热循环中的一个 R101 就比十个 R001 影响更大——它会破坏 R001 原本能够实现的扩展性。反过来,大量阻塞项加上 R108,仍然属于重大重构,而非不建议——等级衡量的是工程成本,而非绝望程度。只有未满足规模或计算模式要求时,才判定为不建议。完整框架见:references/decision-framework.md。

哪些可扩展,哪些会阻塞(一览)

  • 可扩展(保持原样)——向量化逐元素运算、归约、矩阵乘法/einsum、np.where、每个 GPU 上数据量较大的切片式模板计算 arr[1:-1, 1:-1]、out=、布尔掩码索引。
  • 阻塞项(迁移前移除)——元素循环、np.vectorize、for row in arr、热循环中的 .item()/.tolist()/bool(arr)、循环中的归约型 if/while、arr[::2]、dtype=object、mpi4py、order=、min/max/sum(arr)。
  • 重构项(应用配方)——循环内分配内存、循环中重新绑定 x = x + y、循环中的 vstack/hstack/concatenate、np.nonzero() 加索引、对 diag/flip/flatten 视图进行变更、热循环中的 reshape。
  • 信息项(成本提示,不构成阻塞)——SciPy 导入、单设备上的 linalg.qr/svd、单次变换的 fft.*、按规模阈值判断的 linalg.solve/cholesky。

完整分类见 idioms-that-scale.md 和 idioms-that-block.md。清单中未列出的 API 请直接略过(它们不在上游表格的范围内——标出只会造成干扰)。

阅读顺序

规范的按序阅读指南位于 references/getting-started.md — 阅读一次以了解概况。

对于非简单的评估,必读内容包括 idioms-that-block.md、refactor-recipes.md 和 decision-framework.md;其余内容(idioms-that-scale.md、gpu-stack.md、execution-model.md、partitioning-and-balance.md、case-studies.md)按需阅读。

局限性

  • 不会运行 cuPyNumeric。 无需运行时;这是移植前检查。实际加速测量会在迁移后进行。
  • 不会自动生成重构后的代码。 它会指出需要修改的内容并提供相应方案;由用户(或后续 Agent)应用这些方案。
  • 不会对工作负载进行性能分析。 如需测量运行时性能,请使用 legate.timing.time() 和上游的性能分析与调试指南。
  • 不能替代判断。 模式匹配可能会漏掉日志记录中的隐式同步、隐藏 .tolist() 的装饰器,以及依赖运行时数据的分区不匹配。也请阅读源代码,尤其是在边界情况下。

示例

对捆绑的 assets/examples/ 测试样例进行的完整评估(仅作示例,不是模板):

结论:轻度重构。 scales_well.py 可顺利转换;needs_refactor.py 需要将一次分配移到循环外;blocks_scaling.py 每次迭代都会通过 .item() 同步。

有效部分: scales_well.py:23-31(模板 R005)、:40-44(归约 R002)、:18-22(逐元素 R001)。 阻碍因素: blocks_scaling.py:51-58(R104 — 热循环中的 .item())→ RR-sync。 可修复项: needs_refactor.py:21-28(R201 — 循环内分配)→ RR-alloc。 下一步: 应用相应方案;重新检查,直至达到 READY;首次实际运行时启用 CUPYNUMERIC_DOCTOR=1。

完整的评估报告见 assets/sample_report.md。

权威上游参考资料

可用脚本

脚本用途参数
scripts/fetch_api_support.py将上游对比表抓取到 assets/api-support.md。仅使用 Python 标准库;可独立运行。源 URL 固定为 NVIDIA 官方文档中的规范对比页面,无法覆盖。--default-path、--from-file PATH、--out PATH、--print

用户运行此命令以刷新清单(python scripts/fetch_api_support.py --default-path)。

捆绑的参考资料和资源

references/ 文件列在上文的必读顺序中(R 代码范围:idioms-that-scale.md = R001–R007 / R301–R305;idioms-that-block.md = R101–R111 / R201–R206)。资源:assets/api-support.md(已提交的 API 快照,在步骤 2 中加载)、assets/sample_report.md 和 assets/examples/*.py(完整报告和测试样例)。

故障排查

症状原因修复方法
清单中的 Fetched: 行超过约 90 天快照过期运行 fetch_api_support.py --default-path(由用户运行)
清单缺失或抓取器失败上游 HTML 已更改针对该评估,使用 WebFetch 获取对比表
对许多可修复的 BLOCKS 给出 NOT RECOMMENDED启发式规则的应用顺序错误按顺序重新应用:Gate 4 → Gate 2 → R108 → BLOCKS → REFACTOR;权衡类型,而非数量
内核编写或迁移后的性能分析超出范围拒绝并引导用户(参见“适用场景”)——不做判定

评论

支持 Markdown