# 機能設計書 109-llvm-gpu-loader

## 概要

本ドキュメントは、llvm-gpu-loader機能の設計仕様を記述する。llvm-gpu-loaderは、GPUプログラム（ELF形式）をGPUデバイス上で実行するためのローダーツールである。

### 本機能の処理概要

llvm-gpu-loaderは、LLVM libcプロジェクトと連携してGPUユニットテストを実行するために設計されたユーティリティである。AMD HSAまたはNVIDIA CUDA環境でGPU実行ファイル（ELF形式）をロードし、_startカーネルを起動して実行する。クロスコンパイル環境でのエミュレータワークフローに似たインターフェースを提供する。

**業務上の目的・背景**：LLVM libcプロジェクトでは、GPUターゲット（AMDGPU、NVPTX）向けのCライブラリ実装を開発している。これらの実装をテストするためには、GPU上でユニットテストを実行する必要がある。llvm-gpu-loaderは、この目的のために標準的なプログラム起動インターフェースを提供し、GPU上でのテスト実行を可能にする。

**機能の利用シーン**：LLVM libcのGPUユニットテスト実行、GPUプログラムの動作確認、クロスコンパイル環境でのテストに使用される。

**主要な処理内容**：
1. GPU実行ファイル（ELF形式）の読み込み
2. アーキテクチャ判定（AMDGCN/NVPTX）
3. GPU環境初期化（HSA/CUDA）
4. コマンドライン引数と環境変数のGPUメモリへの転送
5. _begin、_start、_endカーネルの実行
6. 実行結果の取得

**関連システム・外部連携**：AMD HSA Runtime、NVIDIA CUDA Driver、LLVM libcのGPU実装と連携する。

**権限による制御**：GPUデバイスへのアクセス権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLIインターフェース | 主画面 | コマンドライン実行 |

## 機能種別

実行処理 / ランタイム

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| gpu-executable | ファイルパス | Yes | GPU実行ファイル（ELF形式） | 有効なELF |
| program-arguments | 文字列リスト | No | GPUプログラムへの引数 | - |
| --threads-x | 整数 | No | X次元のスレッド数（デフォルト: 1） | - |
| --threads-y | 整数 | No | Y次元のスレッド数（デフォルト: 1） | - |
| --threads-z | 整数 | No | Z次元のスレッド数（デフォルト: 1） | - |
| --blocks-x | 整数 | No | X次元のブロック数（デフォルト: 1） | - |
| --blocks-y | 整数 | No | Y次元のブロック数（デフォルト: 1） | - |
| --blocks-z | 整数 | No | Z次元のブロック数（デフォルト: 1） | - |
| --threads | 整数 | No | --threads-xのエイリアス | - |
| --blocks | 整数 | No | --blocks-xのエイリアス | - |
| --print-resource-usage | フラグ | No | カーネルリソース使用量を表示 | - |

### 入力データソース

- GPU実行ファイル（ELF形式）
- コマンドライン引数
- 環境変数

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 終了コード | 整数 | GPUプログラムのmain関数戻り値 |
| 標準出力 | テキスト | GPUプログラムからの出力 |
| リソース使用量 | テキスト | --print-resource-usage時 |

### 出力先

標準出力、終了コード

## 処理フロー

### 処理シーケンス

```
1. 初期化
   └─ 引数解析
2. GPU実行ファイル読み込み
   └─ MemoryBuffer::getFileOrSTDIN
3. アーキテクチャ判定
   └─ ELFObjectFile::create、getArch()
4. GPU環境起動
   └─ アーキテクチャに応じたローダー呼び出し
5. カーネル実行
   └─ _begin → _start → _end
6. 結果取得
   └─ GPUメモリからの戻り値読み取り
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[引数解析]
    B --> C[ELFファイル読み込み]
    C --> D[アーキテクチャ判定]
    D --> E{AMDGCN?}
    E -->|Yes| F[load_amdhsa]
    E -->|No| G{NVPTX?}
    G -->|Yes| H[load_nvptx]
    G -->|No| I[エラー: 非サポートアーキテクチャ]
    F --> J[_begin/_start/_end実行]
    H --> J
    J --> K[戻り値取得]
    K --> L[終了]
    I --> M[エラー終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-109-1 | アーキテクチャ限定 | AMDGCNまたはNVPTXのみサポート | 常時 |
| BR-109-2 | デフォルト次元 | 全次元のデフォルト値は1 | オプション未指定時 |
| BR-109-3 | カーネル実行順序 | _begin → _start → _endの順で実行 | 常時 |

### 計算ロジック

特になし

## データベース操作仕様

### 操作別データベース影響一覧

データベースは使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ファイル読み込み失敗 | ELFファイルが無効 | エラーメッセージ、終了 |
| - | 非サポートアーキテクチャ | AMDGCN/NVPTX以外 | エラーメッセージ、終了 |
| - | GPU初期化失敗 | GPUデバイスアクセス不可 | エラーメッセージ、終了 |
| - | メモリ割り当て失敗 | GPUメモリ不足 | エラーメッセージ、終了 |

### リトライ仕様

なし

## トランザクション仕様

該当なし

## パフォーマンス要件

特に定義なし。

## セキュリティ考慮事項

GPUデバイスへのアクセス権限が必要。

## 備考

AMDHSA_SUPPORTまたはNVPTX_SUPPORTマクロでビルド時にサポート有無が決定される。

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | llvm-gpu-loader.h | `llvm/tools/llvm-gpu-loader/llvm-gpu-loader.h` | LaunchParameters、begin_args_t、start_args_t、end_args_t |

**読解のコツ**:
- LaunchParameters（19-26行目）: スレッド数とブロック数の6次元パラメータ
- begin_args_t（29-33行目）: _beginカーネルの引数（argc、argv、envp）
- start_args_t（36-41行目）: _startカーネルの引数（argc、argv、envp、ret）
- end_args_t（44行目）: _endカーネルの引数（空）

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | llvm-gpu-loader.cpp | `llvm/tools/llvm-gpu-loader/llvm-gpu-loader.cpp` | main関数（93-155行目） |

**主要処理フロー**:
1. **94行目**: シグナルハンドラ登録
2. **95-99行目**: 引数解析
3. **106-110行目**: ELFファイル読み込み
4. **112-119行目**: ELFオブジェクト作成とアーキテクチャ取得
5. **121-134行目**: AMDGCN処理（load_amdhsa呼び出し）
6. **135-148行目**: NVPTX処理（load_nvptx呼び出し）
7. **148-152行目**: 非サポートアーキテクチャエラー

#### Step 3: AMDHSAローダーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | amdhsa.cpp | `llvm/tools/llvm-gpu-loader/amdhsa.cpp` | load_amdhsa関数（332-593行目） |

**主要処理フロー**:
- **336-337行目**: HSA初期化
- **340-347行目**: メモリフォールトハンドラ登録
- **350-355行目**: GPUエージェントとCPUエージェント取得
- **358-376行目**: コードオブジェクト読み込みと実行可能ファイル作成
- **393-407行目**: メモリプール取得
- **421-437行目**: 引数と環境変数のGPUメモリへのコピー
- **462-491行目**: RPCクライアント初期化
- **536-549行目**: カーネル実行（_begin → _start → _end）
- **563-590行目**: リソース解放

### プログラム呼び出し階層図

```
main (93行目)
    │
    ├─ sys::PrintStackTraceOnErrorSignal (94行目)
    │
    ├─ ParseCommandLineOptions (96行目)
    │
    ├─ MemoryBuffer::getFileOrSTDIN (106行目)
    │
    ├─ ELF64LEObjectFile::create (116行目)
    │
    └─ アーキテクチャ分岐
           │
           ├─ load_amdhsa (127行目) [AMDGCN]
           │      ├─ hsa_init (336行目)
           │      ├─ get_agent<GPU/CPU> (352-355行目)
           │      ├─ hsa_code_object_reader_create_from_memory (359行目)
           │      ├─ hsa_executable_create_alt (364行目)
           │      ├─ hsa_executable_load_agent_code_object (370行目)
           │      ├─ copy_argument_vector (429行目)
           │      ├─ copy_environment (435行目)
           │      ├─ launch_kernel(_begin) (538行目)
           │      ├─ launch_kernel(_start) (544行目)
           │      ├─ launch_kernel(_end) (566行目)
           │      └─ hsa_shut_down (589行目)
           │
           └─ load_nvptx (140行目) [NVPTX]
                  └─ CUDA環境での同様の処理
```

### データフロー図

```
[入力]                    [処理]                    [出力]

GPU ELFファイル ───▶ llvm-gpu-loader ───▶ 終了コード
                        │
                        ├─ ELF解析
                        ├─ アーキテクチャ判定
                        │
コマンドライン引数 ───▶ GPUメモリ転送 ───▶ GPUカーネル引数
環境変数                │
                        │
                        └─ カーネル実行
                               │
                               ├─ _begin（初期化）
                               ├─ _start（main実行）
                               └─ _end（終了処理）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| llvm-gpu-loader.cpp | `llvm/tools/llvm-gpu-loader/llvm-gpu-loader.cpp` | ソース | メインエントリーポイント |
| llvm-gpu-loader.h | `llvm/tools/llvm-gpu-loader/llvm-gpu-loader.h` | ヘッダ | 共通データ構造とインターフェース |
| amdhsa.cpp | `llvm/tools/llvm-gpu-loader/amdhsa.cpp` | ソース | AMD HSAローダー実装 |
| nvptx.cpp | `llvm/tools/llvm-gpu-loader/nvptx.cpp` | ソース | NVIDIA CUDAローダー実装 |
| server.h | `llvm/tools/llvm-gpu-loader/server.h` | ヘッダ | RPCサーバーインターフェース |
| CMakeLists.txt | `llvm/tools/llvm-gpu-loader/CMakeLists.txt` | ビルド設定 | ビルド構成 |
