cupynumeric-migration-readiness について
cupynumeric-migration-readinessは、cuPyNumericへの移行前にNumPyコードを評価する読み取り専用スキルです。スケーリングパターンとAPI対応状況を分類し、移行判断に役立つ所見とリファクタリング案を提示します。
主な機能
- 01NumPyソースの静的レビュー
- 02GPUスケーリングパターンの分類
- 03API対応マニフェストの照合
- 04構造化された移行判定
- 05リファクタリング案の提示
活用シーン
- 01GPU移行前のコード評価
- 02スケーリングを妨げるNumPyパターンの特定
- 03移植前のリファクタリング計画
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ nvidia/ skills --skill cupynumeric-migration-readinessインストール後、Claude Code で/cupynumeric-migration-readinessを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.gitignoreBENCHMARK.mdassets/api-support.mdsample_report.mdassets/examples/blocks_scaling.pyneeds_refactor.pyscales_well.pyevals/evals.jsonevals/files/api_gap_hotpath.pyblocks_scaling.pyconvergence_loop.pycupy_mixed.pydense_linalg.pydense_with_scipy_boundary.pygraph_workload.pyitem_sync.pyjacobi_heat.pymany_blocks.pymonte_carlo_bs.pymonte_carlo_good.pyneeds_refactor.pyscales_well.pysequential_recurrence.pysparse_sklearn.pytiny_array.pyunlisted_api.pyview_mutation.pyreferences/case-studies.mddecision-framework.mdexecution-model.md詳細
cuPyNumeric 移行準備状況
目的
このスキルは移行中ではなく、移行前に使用してください。 次の1つの質問に答えます。ユーザーが現在使用している 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 ワークロードは、引き続き対象範囲内です。評価し、ゲート 4 を通じて推奨されませんという判定を返してください。これは判定であり、依頼を断るものではありません。
手順
以下の5つのステップを順番にすべて実行してください。ユーザーのコードを読み、意味に基づいて推論します。一度きりの文章による判定を出してはいけません。
ステップ 1 — コンテキストの収集
コードをスキャンする前に情報を引き出してください。以下の項目には典型的なワークロードに合わせたデフォルト値があります。ユーザーから具体的な情報が提示されない場合はデフォルト値を使用し、質問への回答を待って処理を止めないでください。
- ソースの場所。 パスが指定されていない場合は、現在の作業ディレクトリをデフォルトにします。
- 実行時のホットパス配列の概算サイズ。 デフォルトは3,000万~5,000万要素です。ユーザーの数値(またはこのデフォルト値)を、ゲート 2 の規模区分(GPUあたり65Kが下限、単一 GPU で実際に高速化するには1,000万以上、マルチ GPU では1億以上)に対応付けます。
- 対象ハードウェア。 デフォルトは単一ノードの GPU 1~4基です。マルチノードと想定する前に確認してください。CPU のみで実行する場合は、FBMEM ではなくノードあたりの RAM を尋ねます。
- 主な計算パターン。 ステンシル/GEMM/モンテカルロ法/リダクション/SciPy との混在。ユーザーに指定を依頼してください。指定がない場合は、ステップ 3 でコードから推定します。
評価の冒頭で、適用したデフォルト値を明示し、ユーザーが訂正できるようにしてください。値を特定できない場合は、その旨を明確に伝え、定性的な評価のみを進めてください。上記のデフォルト値以外の数値を捏造してはいけません。
ステップ 2 — API サポートマニフェストを読み込む
上流の NumPy と cuPyNumeric の比較表をコミットしたスナップショットである assets/api-support.md を読みます。コードが呼び出す NumPy API ごとに該当行を探し、先頭の記号を確認します。
✓✓ numpy.X— 実装済みで、マルチ GPU で動作します(最適な経路です)。✓ numpy.X— 実装済みですが、シングル GPU/CPU 専用です(マルチノードでは注意が必要です)。🟡 numpy.X — <note>— 部分的にサポートされています。注記を確認してください。✗ numpy.X— cuPyNumeric の分散実行経路では実装されていません。呼び出し時の挙動はバージョンによって異なります(サポート対象外の API の一部はホスト NumPy にフォールバックし、ほかは例外を発生させます)。いずれにしても、ホットパスでの使用は移行を妨げます。ホスト NumPy へのサイレントなフォールバックが起きるとユーザーに約束してはいけません。
Fetched: 行の日付が約 90 日以上前の場合は、スナップショットを更新します。利用可能なスクリプトのセクションを参照してください。
ステップ 3 — コードを意味的に読み取る
references/idioms-that-scale.md と references/idioms-that-block.md(詳しい根拠と R コードはこちら)に照らし合わせて、ユーザーのファイルを Read と Grep で調べ、配列演算の各箇所を分類します。正規表現だけに頼らず、意味を読み取ってください。問題を指摘する前に、arr が cupynumeric 配列(または cupynumeric にエイリアスされた np.*)に由来することを確認し、そのアクセスがホットループ内にあるかを確認します。次のルールを適用してください。
- 要素ごとのループを指摘します(
for i in range(n): arr[i] = ...)。ベクトル化された本体を持つエポック/ステップ/ファイルのループは問題ありません。両者を区別してください。 - スカラー同期を指摘します — ホットループ内で 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)は許容します(shape の参照です。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 を引用してください。
- 判定を一文で — 下記の「判定フレームワーク」を参照してください。
- 動作する点(SCALES の指摘) — 代表的な行を引用し、インポートの置き換え後に何が高速化するかをユーザーに示してください。
- 阻害要因(BLOCKS の指摘) — それぞれを
idioms-that-block.mdとrefactor-recipes.mdのレシピに関連付けてください。 - 修正可能な点(REFACTOR の指摘) — レシピごとにまとめてください。一つのレシピで複数の箇所を修正できることもよくあります。
- 互換性/コストに関する注記(INFO の指摘) — SciPy との境界、シングル GPU のみ対応する linalg/FFT、
--gpus Nに対する RNG の構成。 - API サポートの不足 — コードが呼び出している API のうち、マニフェストによると未実装、またはシングル GPU のみ対応のもの。
- 判定フレームワークの要約 —
references/decision-framework.mdのゲート 1~6 を合格/不合格/不確実で示してください。 - 推奨する次の手順 — どのレシピを先に適用するか、最初に一つのモジュールを移植するかどうか、cuPyNumeric Doctor に相談するタイミング。
8 つのセクションすべてを必ず記載してください。判定が READY または NOT RECOMMENDED の場合も同様です。空のセクションには、1 行で 「このコードには該当なし」 または 「該当なし — 判定を参照」 と記載してください。見出しを省略しないでください。見出しはレポートの採点における構造上の要件です。実例については 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 を有効にして実行し、出力で確認すべき点は以下のとおりです。」で評価を締めくくってください。
判定フレームワーク
スコアではなく、見つかった項目の種類から判定を定性的に割り当てます。
| 判定 | 条件 | 対応 |
|---|---|---|
| READY | BLOCKS なし、REFACTOR が少数またはなし | インポートを置き換え、ベンチマークを実施します |
| LIGHT REFACTOR | レシピで修正可能なパターンが少数(R201~R206)、または単純な BLOCKS が 1~2 件 | refactor-recipes.md のレシピを 1~3 件適用し、READY になるまで再確認します |
| SIGNIFICANT REFACTOR | ホットパスに複数の BLOCKS がある、または R108(mpi4py)が 1 件でもある — 除外ではなく書き換えが必要です | 実プロジェクトでは、モジュールあたり 1~3 エンジニア週を見込みます |
| NOT RECOMMENDED | 該当する失敗は 2 種類のみです:Gate 2(配列が 65,536 要素の下限未満)または Gate 4(計算パターンが不適切)。BLOCKS が多数あっても、この判定にはなりません | 先に構造を変更するか、別のランタイムを使用します |
以下を順に適用します。最初に該当したものを採用します。
- Gate 4 に失敗(sparse / graph / ML / sequential / string)→ NOT RECOMMENDED。
- Gate 2 に失敗(ホットパスの配列が GPU あたり 65,536 要素未満で、現実的なバッチ処理の手段がない)→ NOT RECOMMENDED。
- R108(
mpi4py)が1 件でもある → SIGNIFICANT REFACTOR(コストとなるのは並列処理レイヤーの書き換えであり、除外ではありません)。 - ホットパス全体に 複数の BLOCKS(R101~R111)がある → SIGNIFICANT REFACTOR(件数が増えてもこれ以上の判定にはなりません — 各 BLOCKS には文書化されたレシピがあります)。
- レシピで修正可能な BLOCKS が 1~2 件(例:R101~R104 の要素ループ/同期)→ LIGHT REFACTOR。
- REFACTOR パターンのみ(R201~R206)→ LIGHT REFACTOR。レシピに沿った機械的な修正で対応できます。
- BLOCKS も REFACTOR もない → READY。
- ホットパスで使用する API がマニフェストにない → 1 段階下げます(SIGNIFICANT は SIGNIFICANT のままで、NOT RECOMMENDED にはなりません)。単一 GPU 専用 API が問題になるのはマルチノードの場合のみです。
件数ではなく、見つかった項目の種類を重視してください。 ホットループ内の R101 1 件は R001 の 10 件より重大です。R001 がもたらすはずだったスケーリングを損なうためです。一方、BLOCKS が多数あって R108 もある場合でも、判定は依然として SIGNIFICANT であり、NOT RECOMMENDED ではありません — 各段階はエンジニアリングコストを示すもので、絶望度を示すものではありません。NOT RECOMMENDED となるのは、サイズまたは計算パターンの失敗がある場合です。フレームワーク全体については、references/decision-framework.md を参照してください。
スケーリングするものと妨げになるもの(一目で確認)
- SCALES(そのまま使用) — ベクトル化された要素単位の演算、リダクション、matmul / einsum、
np.where、GPU あたりのサイズが大きいステンシルのスライスarr[1:-1, 1:-1]、out=、ブールマスクによるインデックス指定。 - BLOCKS(移行前に取り除く) — 要素ループ、
np.vectorize、for row in arr、ホットループ内の.item()/.tolist()/bool(arr)、ループ内でリダクションを行うif/while、arr[::2]、dtype=object、mpi4py、order=、min/max/sum(arr)。 - REFACTOR(レシピを適用) — ループ内でのメモリ割り当て、ループ内での
x = x + yによる再束縛、ループ内でのvstack/hstack/concatenate、np.nonzero()とインデックス指定の組み合わせ、diag/flip/flattenのビュー変更、ホットループ内のreshape。 - INFO(コストに関する注記であり、妨げにはなりません) — 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 は実行しません。 ランタイムは不要です。移植前のチェックを行います。実際の高速化の測定は、移行後に実施します。
- リファクタリング済みのコードを自動生成しません。 変更が必要な箇所を特定し、レシピを案内します。適用するのはユーザー(または後続のエージェント)です。
- ワークロードをプロファイリングしません。 実行時の測定には
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 にあります。
信頼できる上流の参考資料
- 比較表(
assets/api-support.mdの参照元):https://docs.nvidia.com/cupynumeric/latest/api/comparison.html - ベストプラクティス、Doctor、プロファイリング、NumPy との違い、Legate ランチャー — https://docs.nvidia.com/cupynumeric/latest/(`user/practices.html`、`user/doctor.html`、`user/profiling_debugging.html`、`user/differences.html`)および https://docs.nvidia.com/legate/latest/manual/usage/running.html を参照してください。
- ソースコード:https://github.com/nv-legate/cupynumeric
利用可能なスクリプト
| スクリプト | 目的 | 引数 |
|---|---|---|
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 します |
| 修正可能な BLOCK が多数あるのに NOT RECOMMENDED と判定される | ヒューリスティックが順不同で適用された | 次の順序で再適用します:Gate 4 → Gate 2 → R108 → BLOCKS → REFACTOR。数ではなく、種類を考慮します |
| カーネルの作成、または移行後のプロファイリング | 対象範囲外 | 対応を断り、適切な案内先を示します(「使用するタイミング」を参照)。判定は行いません |