# 機能設計書 17-OpenMP

## 概要

本ドキュメントは、LLVMプロジェクトにおけるOpenMP（LLVM OpenMP Runtime Library）の機能設計書である。OpenMPは、共有メモリ並列プログラミングのためのAPI規格であり、LLVMのOpenMPランタイムはこの規格に準拠したランタイムライブラリを提供する。

### 本機能の処理概要

LLVM OpenMPランタイムは、OpenMP指示文（#pragma omp）によって記述された並列処理を実行するために必要なランタイムサポートを提供する。スレッド管理、同期、タスク実行、データ共有などの機能を実装している。

**業務上の目的・背景**：マルチコアプロセッサの普及により、並列プログラミングの重要性が増している。OpenMPは、既存のシーケンシャルコードに指示文を追加するだけで並列化できる手軽さから、科学技術計算やHPC（High Performance Computing）分野で広く使用されている。LLVM OpenMPランタイムは、Clangコンパイラと連携して、高性能な並列実行を実現する。

**機能の利用シーン**：
- 科学技術計算の並列化
- データ処理パイプラインの並列化
- ループの自動並列化
- タスク並列処理
- GPUオフロード（offload/libomptarget経由）

**主要な処理内容**：
1. **並列リージョン**：parallel構文による並列実行
2. **ワークシェアリング**：for/sections/singleによる作業分散
3. **タスク並列**：task/taskloop構文
4. **同期**：critical/atomic/barrier等
5. **データ環境**：private/shared/reduction等
6. **SIMD**：simd構文によるベクトル化
7. **デバイスオフロード**：target構文（offloadサブプロジェクト経由）

**関連システム・外部連携**：
- Clang：-fopenmpオプションでOpenMP有効化
- LLVM：OpenMPトランスフォーメーションパス
- offload：GPUオフロード用ランタイム
- pthreads：スレッド実装基盤

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | ランタイムライブラリのため画面なし |

## 機能種別

並列処理ランタイム / OpenMP実装

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| -fopenmp | flag | Yes | OpenMP有効化 | - |
| OMP_NUM_THREADS | env | No | スレッド数指定 | 正の整数 |
| OMP_SCHEDULE | env | No | スケジュール方式 | 有効な値 |
| OMP_STACKSIZE | env | No | スレッドスタックサイズ | サイズ指定 |
| OMP_PROC_BIND | env | No | スレッドアフィニティ | true/false/master/close/spread |

### 入力データソース

- OpenMP指示文を含むソースコード
- 環境変数による実行時設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| libomp.a | 静的ライブラリ | リンク時に結合 |
| libomp.so / libomp.dylib | 動的ライブラリ | 実行時にロード |
| libomptarget.so | 動的ライブラリ | オフロード用 |

### 出力先

- インストールディレクトリのlib/

## 処理フロー

### 処理シーケンス（並列forループ例）

```
1. parallel for指示文の検出
   └─ Clangがコードをトランスフォーム
   └─ __kmpc_fork_call等のランタイム呼び出しを生成

2. 並列リージョン開始
   └─ __kmpc_fork_callでスレッドチームを作成
   └─ ワーカースレッドが作業を分担

3. forループの分割
   └─ __kmpc_for_static_initでループ範囲を分配
   └─ 各スレッドが担当範囲を実行

4. 並列リージョン終了
   └─ 暗黙のバリアで同期
   └─ スレッドチームを解散（または再利用のため待機）
```

### フローチャート

```mermaid
flowchart TD
    A[#pragma omp parallel for] --> B[Clangによるコード変換]
    B --> C[__kmpc_fork_call]
    C --> D[スレッドチーム作成]
    D --> E[__kmpc_for_static_init]
    E --> F[各スレッドがループ実行]
    F --> G{全スレッド完了?}
    G -->|No| F
    G -->|Yes| H[暗黙バリア]
    H --> I[並列リージョン終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | OpenMP規格準拠 | OpenMP規格に準拠 | 常時 |
| BR-02 | スレッドプール | スレッドは再利用される | デフォルト |
| BR-03 | フォーク・ジョイン | 並列リージョンはfork-joinモデル | 常時 |
| BR-04 | メモリモデル | OpenMPメモリモデルに従う | 常時 |

### 計算ロジック

**スケジューリング**：
- static：均等分割（デフォルト）
- dynamic：動的割り当て
- guided：ガイド付き（チャンクサイズ減少）
- auto：実装依存
- runtime：実行時指定

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | デッドロック | 不適切な同期 | コードを修正 |
| - | データ競合 | 不適切な共有 | データ属性を修正 |
| - | リソース不足 | スレッド作成失敗 | リソースを確保 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- スレッドプールによるオーバーヘッド削減
- 効率的なワークスティーリング（タスク並列）
- NUMA対応

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

- スレッド間のデータ分離
- スタックオーバーフロー対策

## 備考

- Intel OpenMP Runtime (libomp)をベースに開発
- OpenMP 5.x規格の多くの機能をサポート
- GPUオフロードはoffloadサブプロジェクトで対応

---

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

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

### 推奨読解順序

#### Step 1: 全体構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | CMakeLists.txt | `openmp/CMakeLists.txt` | ビルド構成 |
| 1-2 | runtime/README.txt | `openmp/runtime/README.txt` | ランタイム概要 |

#### Step 2: ランタイムライブラリを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | runtime/src/ | `openmp/runtime/src/` | ランタイム実装 |
| 2-2 | kmp.h | `openmp/runtime/src/kmp.h` | 内部データ構造 |

#### Step 3: API実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | kmp_runtime.cpp | `openmp/runtime/src/kmp_runtime.cpp` | ランタイムエントリ |
| 3-2 | kmp_sched.cpp | `openmp/runtime/src/kmp_sched.cpp` | スケジューリング |

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

```
ユーザーコード (#pragma omp parallel for)
    │
    └─ Clangによる変換
           │
           └─ __kmpc_fork_call() [kmp_runtime.cpp]
                  │
                  ├─ スレッドチーム作成/取得
                  │      └─ __kmp_fork_call()
                  │
                  └─ ワーカースレッド実行
                         │
                         ├─ __kmpc_for_static_init()
                         │      └─ ループ範囲計算
                         │
                         ├─ ユーザーコード実行
                         │
                         └─ __kmpc_for_static_fini()
                                └─ 暗黙バリア
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CMakeLists.txt | `openmp/CMakeLists.txt` | 設定 | ビルド設定 |
| runtime/ | `openmp/runtime/` | ソース群 | ランタイム |
| runtime/src/ | `openmp/runtime/src/` | ソース群 | ランタイム実装 |
| kmp.h | `openmp/runtime/src/kmp.h` | ヘッダー | 内部構造 |
| kmp_runtime.cpp | `openmp/runtime/src/kmp_runtime.cpp` | ソース | ランタイム |
| kmp_sched.cpp | `openmp/runtime/src/kmp_sched.cpp` | ソース | スケジューリング |
| kmp_taskdeps.cpp | `openmp/runtime/src/kmp_taskdeps.cpp` | ソース | タスク依存 |
| kmp_barrier.cpp | `openmp/runtime/src/kmp_barrier.cpp` | ソース | バリア |
| libompd/ | `openmp/libompd/` | ソース群 | デバッグサポート |
| tools/ | `openmp/tools/` | ツール群 | ツール |
