# 機能設計書 142-C++ API

## 概要

本ドキュメントは、TensorFlowのC++ API（`tensorflow/cc/`）の機能設計を記載する。C++ APIは、C++言語からTensorFlowの計算グラフを構築し、セッションを実行するための高水準APIである。Scopeによる名前空間管理、型安全なOp構築関数、自動勾配計算、訓練コーディネーションなどの機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：C++はパフォーマンスクリティカルなアプリケーション（組込みシステム、ゲームエンジン、ハイパフォーマンスコンピューティング等）で広く使用されている。C++ APIは、PythonランタイムのオーバーヘッドなしにTensorFlowの計算グラフを構築・実行する手段を提供し、本番環境でのモデル推論やC++アプリケーションへの組み込みを容易にする。また、C APIの上位層として、より安全で使いやすいインタフェースを実現する。

**機能の利用シーン**：
- C++アプリケーションからの直接的なモデル推論実行
- パフォーマンスが要求される推論サーバの構築
- TensorFlow内部のOp実装からの利用（C APIの実装がC++ APIを内部で使用）
- カスタム勾配関数の実装
- 訓練パイプラインのC++実装

**主要な処理内容**：
1. Scopeによる名前空間管理とグラフ構築コンテキスト管理
2. 型安全なOp構築（Const、MatMul、Add等のラッパー関数）
3. ClientSessionによるグラフの実行
4. AddSymbolicGradientsによる自動勾配計算
5. Coordinatorによる訓練スレッドの管理
6. QueueRunnerによるデータ入力パイプライン管理
7. WhileLoopによる制御フロー構築
8. cc_op_genによるOp定義からのC++コード自動生成

**関連システム・外部連携**：TensorFlowコアランタイム（`tensorflow/core/`）、C API（`tensorflow/c/`）、各種Op定義

**権限による制御**：C++ APIレベルでの権限制御はなく、プロセスの実行権限に依存する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はライブラリAPIであり、画面との直接の関連はない |

## 機能種別

ライブラリAPI / 計算処理 / グラフ構築

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| scope | Scope | Yes | グラフ構築コンテキスト | ok()がtrueであること |
| inputs | Input / InputList | Yes | Op入力テンソル参照 | 型・形状の整合性 |
| session_options | SessionOptions | No | セッション設定 | - |
| fetch_outputs | vector<Output> | Yes (Run時) | 取得対象のテンソル | グラフに存在すること |
| feed_inputs | FeedType | No (Run時) | 入力値のマッピング | 型の一致 |

### 入力データソース

- C++コード上で構築されるOp（Const、Placeholder等）
- フィードテンソル（ClientSession::Runの引数）
- Protocol Bufferでシリアライズされた設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| outputs | vector<Tensor> | セッション実行結果のテンソルベクタ |
| grad_outputs | vector<Output> | 勾配計算結果のOutput参照ベクタ |
| gdef | GraphDef | シリアライズされたグラフ定義 |
| status | absl::Status | 操作結果のステータス |

### 出力先

- 呼び出し元のメモリ空間

## 処理フロー

### 処理シーケンス

```
1. スコープ初期化
   └─ Scope::NewRootScope() でルートスコープを生成
2. グラフ構築
   ├─ Const() / Placeholder() 等で定数・入力ノードを作成
   ├─ MatMul() / Add() 等で演算ノードを作成
   └─ NewSubScope() でサブスコープを作成し名前空間を管理
3. セッション作成・実行
   ├─ ClientSession session(scope) でセッション生成
   └─ session.Run({feeds}, {fetches}, &outputs) で実行
4. 結果取得
   └─ vector<Tensor> outputs から結果テンソルを取得
```

### フローチャート

```mermaid
flowchart TD
    A[Scope::NewRootScope] --> B[Op構築 Const/Placeholder/MatMul等]
    B --> C{Scope::ok?}
    C -->|Yes| D[ClientSession生成]
    C -->|No| E[エラーハンドリング]
    D --> F[session.Run実行]
    F --> G{Status OK?}
    G -->|Yes| H[出力テンソル取得]
    G -->|No| E
    H --> I[結果利用]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-142-01 | スコープ共有 | 子スコープはルートスコープのGraph、Status、ShapeRefinerを共有する | NewSubScope呼び出し時 |
| BR-142-02 | スレッド安全性 | Scopeオブジェクトはスレッドセーフではない。同一Scopeへの並行Op構築は不可 | マルチスレッド環境 |
| BR-142-03 | 名前一意性 | 同一スコープ内でOp名が重複する場合、自動的にサフィックス(_1, _2等)が付与される | Op構築時 |
| BR-142-04 | エラー伝播 | Scopeのステータスがエラーの場合、以降のOp構築は自動的にスキップされる | Scope::ok()がfalse時 |

### 計算ロジック

C++ API自体は計算ロジックを持たず、各OpのC++ラッパー関数がTensorFlowコアのOpカーネルに処理を委譲する。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArgument | 引数不正 | 型不一致、形状不一致 | 入力の型・形状を確認 |
| NotFound | 未検出 | 存在しないOp名の参照 | Op名の確認 |
| FailedPrecondition | 前提条件不成立 | 未初期化の変数への操作 | 変数の初期化を先に実行 |
| Internal | 内部エラー | ランタイム内部エラー | ログ確認 |

### リトライ仕様

C++ APIレベルでのリトライ機構はない。

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

該当なし。

## パフォーマンス要件

- Op構築はグラフノードの追加のみで軽量
- ClientSession::Runの実行パフォーマンスはPython APIと同等（ランタイムが同一のため）
- C++直接呼び出しによりPythonインタプリタのオーバーヘッドが排除される

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

- C APIと同様、信頼できないGraphDefのロードは任意コード実行リスクがある
- メモリ管理はRAII（unique_ptr等）を活用しているが、Output/Operationの参照はグラフの生存期間に依存

## 備考

- C++ APIのOp関数（MatMul、Add等）は `cc_op_gen` ツールによりOp定義から自動生成される
- `tensorflow/cc/ops/standard_ops.h` をインクルードすることで全標準Opにアクセス可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ops.h | `tensorflow/cc/framework/ops.h` | Operation、Output、Input、InputList等のコアデータ型。Operationはノードへの参照（42-67行目）、OutputはOperation+インデックス（70-93行目）、InputはOp入力を表すユニオン型（104-256行目） |
| 1-2 | scope.h | `tensorflow/cc/framework/scope.h` | Scopeクラスの定義。名前空間管理・グラフ構築コンテキスト。98-248行目でScope全メソッドを確認 |

**読解のコツ**: `Input` クラスは暗黙変換コンストラクタを多数持ち（`NOLINT(runtime/explicit)` コメント付き）、スカラ値、テンソル、Output等から暗黙変換できる。これによりOp構築コードが簡潔になる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | client_session.h | `tensorflow/cc/client/client_session.h` | ClientSessionクラス。グラフ実行のエントリーポイント。57-158行目でRun/MakeCallable/RunCallable等のメソッドを確認 |
| 2-2 | client_session.cc | `tensorflow/cc/client/client_session.cc` | ClientSessionの実装。内部でtensorflow::Session（DirectSession）を使用 |

**主要処理フロー**:
1. **68-69行目**: コンストラクタでScopeのGraphからセッションを生成
2. **81-82行目**: Run()でfetch_outputsを実行し結果をvector<Tensor>に格納
3. **97-101行目**: Run()のフルバージョン（RunOptions、RunMetadata対応）
4. **118-119行目**: MakeCallable()でサブグラフハンドルを作成

#### Step 3: グラフ構築層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | scope.cc | `tensorflow/cc/framework/scope.cc` | Scope実装。NewRootScope()でGraphとShapeRefinerを生成、NewSubScope()で名前プレフィックスを追加 |
| 3-2 | const_op.h | `tensorflow/cc/ops/const_op.h` | 定数テンソル生成Op |
| 3-3 | standard_ops.h | `tensorflow/cc/ops/standard_ops.h` | 全標準Opのインクルード集約ヘッダ |

#### Step 4: 勾配計算を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | gradients.h | `tensorflow/cc/framework/gradients.h` | AddSymbolicGradients関数の宣言。32-43行目で2つのオーバーロード（初期勾配あり/なし）を確認 |
| 4-2 | gradients.cc | `tensorflow/cc/framework/gradients.cc` | 勾配計算の実装。バックプロパゲーションアルゴリズム |
| 4-3 | grad_op_registry.h | `tensorflow/cc/framework/grad_op_registry.h` | Op別の勾配関数レジストリ |

#### Step 5: 訓練コーディネーションを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | coordinator.h | `tensorflow/cc/training/coordinator.h` | Coordinatorクラスの定義。74-132行目でRequestStop/Join/ReportStatus等のメソッドを確認 |
| 5-2 | queue_runner.h | `tensorflow/cc/training/queue_runner.h` | QueueRunnerクラスの定義。データキューの管理 |

#### Step 6: Op自動生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | cc_op_gen.h | `tensorflow/cc/framework/cc_op_gen.h` | Op定義からC++コードを自動生成するジェネレータ |
| 6-2 | cc_op_gen.cc | `tensorflow/cc/framework/cc_op_gen.cc` | ジェネレータの実装 |

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

```
ユーザーC++コード
    |
    +-- Scope::NewRootScope()
    |       +-- new Graph()
    |       +-- new ShapeRefiner()
    |
    +-- Const(scope, value) / MatMul(scope, a, b) / ...
    |       +-- Scope::GetUniqueNameForOp()
    |       +-- NodeBuilder(...).Finalize(scope.graph())
    |       +-- Scope::DoShapeInference()
    |
    +-- ClientSession(scope)
    |       +-- NewSession(scope.graph())
    |           +-- DirectSession / GrpcSession
    |
    +-- session.Run(feeds, fetches, &outputs)
    |       +-- Session::Run()
    |           +-- Executor::RunAsync()
    |
    +-- AddSymbolicGradients(scope, outputs, inputs, &grads)
    |       +-- GradOpRegistry::Lookup()
    |       +-- 各Opの勾配関数
    |
    +-- Coordinator::Join()
            +-- RunnerInterface::Join()
            +-- QueueRunner::Join()
```

### データフロー図

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

C++スカラ/配列 -------> Const(scope, val) -------> Output (グラフノード参照)
                             |
Output (a, b) ---------> MatMul(scope, a, b) ----> Output
                             |
FeedType(feeds) -------> session.Run() -----------> vector<Tensor>(結果)
                             |
Output(y, x) ----------> AddSymbolicGradients() --> vector<Output>(勾配)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ops.h | `tensorflow/cc/framework/ops.h` | ソース(ヘッダ) | Operation/Output/Input等のコアデータ型定義 |
| scope.h | `tensorflow/cc/framework/scope.h` | ソース(ヘッダ) | Scopeクラス定義（グラフ構築コンテキスト） |
| scope.cc | `tensorflow/cc/framework/scope.cc` | ソース(実装) | Scope実装 |
| client_session.h | `tensorflow/cc/client/client_session.h` | ソース(ヘッダ) | ClientSessionクラス定義（セッション実行） |
| client_session.cc | `tensorflow/cc/client/client_session.cc` | ソース(実装) | ClientSession実装 |
| gradients.h | `tensorflow/cc/framework/gradients.h` | ソース(ヘッダ) | 自動勾配計算API |
| gradients.cc | `tensorflow/cc/framework/gradients.cc` | ソース(実装) | 勾配計算実装 |
| grad_op_registry.h | `tensorflow/cc/framework/grad_op_registry.h` | ソース(ヘッダ) | 勾配関数レジストリ |
| gradient_checker.h | `tensorflow/cc/framework/gradient_checker.h` | ソース(ヘッダ) | 勾配チェッカー（テスト用） |
| while_gradients.h | `tensorflow/cc/framework/while_gradients.h` | ソース(ヘッダ) | WhileLoop勾配 |
| const_op.h | `tensorflow/cc/ops/const_op.h` | ソース(ヘッダ) | 定数Op |
| while_loop.h | `tensorflow/cc/ops/while_loop.h` | ソース(ヘッダ) | WhileLoop構築API |
| standard_ops.h | `tensorflow/cc/ops/standard_ops.h` | ソース(ヘッダ) | 全標準Opインクルード |
| coordinator.h | `tensorflow/cc/training/coordinator.h` | ソース(ヘッダ) | 訓練コーディネータ |
| coordinator.cc | `tensorflow/cc/training/coordinator.cc` | ソース(実装) | コーディネータ実装 |
| queue_runner.h | `tensorflow/cc/training/queue_runner.h` | ソース(ヘッダ) | キューランナー |
| queue_runner.cc | `tensorflow/cc/training/queue_runner.cc` | ソース(実装) | キューランナー実装 |
| cc_op_gen.h | `tensorflow/cc/framework/cc_op_gen.h` | ソース(ヘッダ) | Op C++コード自動生成 |
| cc_op_gen.cc | `tensorflow/cc/framework/cc_op_gen.cc` | ソース(実装) | Op自動生成実装 |
| BUILD | `tensorflow/cc/BUILD` | ビルド設定 | Bazelビルドルール |
