# CUDA Events - eBPF-based CUDA API Tracing [eunomia-bpf](https://eunomia.dev) の eBPF チュートリアル「CUDA Events」は、CUDA アプリケーションが GPU とやり取りする CUDA API 呼び出しを、eBPF の uprobe を使ってリアルタイムにトレースする方法を実装例とともに解説する。(Source: [[.raw/articles/cuda-events-2026-07-04.md]]) ## 目的と位置づけ GPU 上での処理は非同期かつ独自のメモリ空間を持つため、従来のデバッグ・プロファイリングツールでは内部状態へのアクセスが困難だった。本チュートリアルは、CUDA ランタイムライブラリ `libcudart.so` への uprobe で API 呼び出しを傍受し、メモリ割当サイズ、転送方向と量、カーネル起動パラメータ、API 戻り値、タイミング情報を収集する。これによりアプリケーションコードの改変やプロプライエタリツールに依存せず、GPU 利用のマクロ視図を得る。(Source: [[.raw/articles/cuda-events-2026-07-04.md]]) ただし、CPU 側トレースには限界がある。`cudaLaunchKernel` は GPU への作業投入に過ぎず、カーネル内部のスレッド動作やメモリアクセスパターンは見えない。このデバイス内観測には、本チュートリアルが参照する [eGPU](https://dl.acm.org/doi/10.1145/3723851.3726984) や [bpftime GPU examples](https://github.com/bpftime/bpftime) のような PTX 注入型アプローチが必要である。(Source: [[.raw/articles/cuda-events-2026-07-04.md]]) ## トレース対象となる CUDA 関数 本チュートリアルで計測対象とした CUDA ランタイム API は以下の通り。(Source: [[.raw/articles/cuda-events-2026-07-04.md]]) ### メモリ管理 - `cudaMalloc` — デバイスメモリ割当。要求サイズと成否を記録。 - `cudaFree` — デバイスメモリ解放。メモリリークや二重解放の検出に役立つ。 ### データ転送 - `cudaMemcpy` — ホスト・デバイス間またはデバイス内のコピー。`kind` パラメータで `cudaMemcpyHostToDevice`(1)、`cudaMemcpyDeviceToHost`(2)、`cudaMemcpyDeviceToDevice`(3) を区別する。 ### カーネル実行 - `cudaLaunchKernel` — GPU カーネルの起動。gridDim/blockDim/共有メモリ量/ストリームを捕捉する。 ### ストリームと同期 - `cudaStreamCreate` — 非同期実行用ストリームの生成。 - `cudaStreamSynchronize` — ストリーム内の処理完了待ち。ボトルネック特定の同期点。 ### イベント - `cudaEventCreate` / `cudaEventRecord` / `cudaEventSynchronize` — タイミング計測と同期用イベント。 ### デバイス管理 - `cudaGetDevice` / `cudaSetDevice` — 現在または指定の GPU デバイス。 ## アーキテクチャ トレーサは 3 ファイルで構成される。(Source: [[.raw/articles/cuda-events-2026-07-04.md]]) 1. **`cuda_events.h`** — カーネル空間とユーザ空間の通信用 `struct event` と `enum cuda_event_type` を定義。 2. **`cuda_events.bpf.c`** — eBPF プログラム。各 CUDA API の enter/return に uprobe/uretprobe を設定。 3. **`cuda_events.c`** — libbpf で eBPF をロードし、ring buffer からイベントを読み出して表示するユーザ空間アプリケーション。 `struct event` は PID、プロセス名、イベント種別、union によるイベント固有データ、`is_return` フラグ、戻り値、詳細文字列を持つ。union を使うことで、同時に必要なデータは 1 種類のみであることを利用して省スペース化している。(Source: [[.raw/articles/cuda-events-2026-07-04.md]]) ## 実装の要点 ### ring buffer ```c struct { __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, 256 * 1024); } rb SEC(".maps"); ``` eBPF プログラムは 256 KiB の ring buffer にイベントを投入する。これによりイベントのバーストでもデータ欠落を抑えられる。(Source: [[.raw/articles/cuda-events-2026-07-04.md]]) ### uprobe/uretprobe `cudaMalloc` の例: ```c SEC("uprobe") int BPF_KPROBE(cuda_malloc_enter, void **ptr, size_t size) { return submit_malloc_event(size, false, 0); } SEC("uretprobe") int BPF_KRETPROBE(cuda_malloc_exit, int ret) { return submit_malloc_event(0, true, ret); } ``` enter プローブで要求サイズ、return プローブでエラーコードを取得する。このパターンを各 CUDA API について繰り返す。(Source: [[.raw/articles/cuda-events-2026-07-04.md]]) ### ユーザ空間の表示 `handle_event` は ring buffer からイベントを受け取り、時刻・プロセス名・PID・イベント種別・enter/exit・詳細を整形して出力する。`cuda_error_str` 関数で 100 以上ある CUDA エラーコードを人間可読な文字列に変換する。(Source: [[.raw/articles/cuda-events-2026-07-04.md]]) ## 実行例とベンチマーク ```bash make sudo ./cuda_events -p ./basic02 ``` 典型的な出力は「メモリ割当 → ホストからデバイスへ転送(kind=1) → カーネル起動 → デバイスからホストへ転送(kind=2) → メモリ解放」という CUDA アプリケーションのライフサイクルを反映する。(Source: [[.raw/articles/cuda-events-2026-07-04.md]]) ベンチマークでは 1,048,576 バイト(1,024 KiB)、10,000 イテレーションで、トレーサなしと有りの平均レイテンシを比較した。 | 操作 | トレーサなし | トレーサ有り | |---|---|---| | cudaMalloc | 113.14 µs | 119.81 µs | | cudaMemcpyH2D | 365.85 µs | 367.16 µs | | cudaLaunchKernel | 7.82 µs | 8.77 µs | | cudaMemcpyD2H | 393.55 µs | 383.66 µs | 本チュートリアルは「トレーサが CUDA API 呼び出しあたり約 2 µs のオーバーヘッドを追加する」と結論づけている。これは多くの用途で無視できるレベルである。(Source: [[.raw/articles/cuda-events-2026-07-04.md]]) ## コマンドラインオプション - `-v`: 冗長出力 - `-t`: タイムスタンプ非表示 - `-r`: 関数出口のみ非表示(入口だけ表示) - `-p PATH`: CUDA ランタイムライブラリまたは対象アプリケーションのパス - `-d PID`: 特定プロセスのみトレース ## 次のステップ 本チュートリアルは、GPU ドライバ拡張の [gpu_ext](https://github.com/eunomia-bpf/gpu_ext) や [bpftime](https://github.com/bpftime/bpftime) を使ったデバイス内計装へ発展させることができる。さらに他の CUDA API、OpenCL、ROCm への拡張も示唆している。(Source: [[.raw/articles/cuda-events-2026-07-04.md]]) ## 関連 - 概念: [[CUDA API トレース]] / [[CUDA]] / [[uprobe]] / [[eBPF]] / [[GPU観測性]] / [[動的計装]] - エンティティ: [[eunomia-bpf]] / [[bpftime]] / [[libbpf]] / [[NVIDIA]] / [[yunwei37]] - ソース: [[@2025__HCDS__eGPU - Extending eBPF Programmability and Observability to GPUs]] / [[@2025__eBPF__eInfer - Unlocking Fine-Grained Tracing for Distributed LLM Inference with eBPF]] / [[@2026__arXiv__ProfInfer - An eBPF-based Fine-Grained LLM Inference Profiler]] / [[@2021__yuuk.io__Linux eBPF Tracing Technology]]