# 機能設計書 10-関数操作（Functional Operations）

## 概要

本ドキュメントは、TensorFlowのコアフレームワークにおける関数操作（Functional Operations）機能の設計を記述する。高階関数・関数呼び出し・リモート関数呼び出しなどの関数操作を提供する。

### 本機能の処理概要

関数操作機能は、TensorFlowの計算グラフ内で関数を第一級オブジェクトとして扱うための操作群を提供する。SymbolicGradientによる勾配関数の呼び出し、RemoteCallによるリモート関数実行、If/While/Case/Forなどの高階制御フロー関数、PartitionedCall/StatefulPartitionedCallによる関数パーティショニング実行など、関数をベースとしたグラフ構築パターンを実現する。

**業務上の目的・背景**：TensorFlow 2.xのtf.functionデコレータは、Python関数をTensorFlowグラフ関数にトレースしてコンパイルする。これらのグラフ関数はFunctional Opsを通じて呼び出される。分散学習でのリモート関数呼び出し、条件付き関数実行、勾配計算のための記号微分など、関数を単位とした計算の組み合わせが本機能の核心である。

**機能の利用シーン**：(1) tf.functionによる関数トレーシングと実行、(2) SymbolicGradientによる自動微分、(3) RemoteCallによるリモートデバイスでの関数実行、(4) If/While/Case/ForによるグラフレベルのHigh-order制御フロー、(5) PartitionedCallによるマルチデバイス関数分割実行。

**主要な処理内容**：
1. SymbolicGradient: 関数の記号的勾配計算
2. RemoteCall: リモートデバイスでの関数呼び出し
3. If / StatelessIf / _If: 条件付き関数実行
4. Case / StatelessCase: 多分岐関数実行
5. While / StatelessWhile / _While: ループ関数実行
6. For: 範囲ベースのループ関数実行
7. PartitionedCall / StatefulPartitionedCall: パーティション化関数呼び出し
8. ToBool: テンソルからブール値への変換
9. FakeParam: 関数のプレースホルダパラメータ
10. DeviceIndex: デバイスインデックス取得

**関連システム・外部連携**：tf.function/def_function.py（機能No.88）と密接に連携する。分散ランタイム（機能No.115）のRemoteCall機能を通じたクロスデバイス関数呼び出しをサポートする。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はコアAPIのため直接的な画面関連はなし |

## 機能種別

計算処理（関数呼び出し・高階制御フロー）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input / args | list[tf.Tensor] | Yes | 関数への入力テンソルリスト | Tin属性と一致 |
| cond | tf.Tensor | If時 | 条件テンソル | Tcond属性の型 |
| f / then_branch / else_branch / body | func | Yes | 実行する関数 | 有効な関数属性 |
| Tin | list[type] | Yes | 入力テンソルの型リスト | - |
| Tout | list[type] | Yes | 出力テンソルの型リスト | - |
| target | tf.Tensor(string) | RemoteCall時 | リモートデバイス指定 | - |
| output_shapes | list[shape] | No | 出力形状ヒント | If/While/Case時 |

### 入力データソース

tf.functionデコレータによる自動生成、またはPython API直接呼び出し。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| output | list[tf.Tensor] | 関数の出力テンソルリスト（Tout型） |

### 出力先

呼び出し元のPythonコードに返却される。

## 処理フロー

### 処理シーケンス

```
1. 関数操作opの作成
   └─ f/then_branch/else_branch/body属性に関数を登録
2. 入力テンソルの型チェック
   └─ Tin属性との一致を検証
3. 関数の実行
   └─ ローカル: PartitionedCall / リモート: RemoteCall
4. 出力テンソルの型チェック
   └─ Tout属性との一致を検証
5. output_shapes属性による形状推論
   └─ 設定されていない場合はUnknownShape
```

### フローチャート

```mermaid
flowchart TD
    A[関数操作op作成] --> B{操作種別}
    B -->|If| C[cond評価]
    C -->|True| D[then_branch実行]
    C -->|False| E[else_branch実行]
    B -->|While| F[cond評価]
    F -->|True| G[body実行→condに戻る]
    F -->|False| H[結果返却]
    B -->|PartitionedCall| I[関数f実行]
    B -->|RemoteCall| J[リモートデバイスで関数f実行]
    D --> K[output返却]
    E --> K
    G --> F
    I --> K
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 入出力型一致 | 関数の実際の入出力型がTin/Tout属性と一致 | 常時 |
| BR-02 | SymbolicGradient入出力関係 | len(inputs) >= len(outputs)、出力形状は入力の先頭と同じ | SymbolicGradient時 |
| BR-03 | Stateful/Stateless区別 | StatelessIf/StatelessWhile/StatelessCaseは副作用なし | 最適化パス時 |
| BR-04 | output_shapes優先 | output_shapes属性が設定されている場合はそれを形状推論結果とする | If/While/Case時 |
| BR-05 | ToBool変換規則 | スカラー数値: 0=False、非スカラー: 空=False | ToBool時 |

### 計算ロジック

- SymbolicGradient: (u,v) = f(x,y,z) に対し、∂(x,y,z)/∂(u,v) を計算
- If: output = cond ? then_branch(input) : else_branch(input)
- While: while cond(input): input = body(input); return input
- Case: output = branches[branch_index](input)

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

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

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

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArgumentError | 型不一致 | 入出力テンソルの型がTin/Tout と不一致 | 正しい型を指定する |
| InvalidArgumentError | 入出力数エラー | SymbolicGradientで len(inputs) < len(outputs) | 入力数を確認する |
| InvalidArgumentError | output_shapes不整合 | output_shapesの数がnum_outputsと不一致 | output_shapesの数を揃える |
| NotFoundError | 関数なし | 指定された関数が見つからない | 有効な関数名を指定する |

### リトライ仕様

RemoteCall操作はネットワーク障害時にリトライが必要な場合がある（アプリケーション側で制御）。

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

該当なし。StatefulPartitionedCallは副作用を持つ場合があるが、トランザクション管理は呼び出し側の責任である。

## パフォーマンス要件

- PartitionedCallは関数をインライン展開可能であること（最適化パス）
- RemoteCallはgRPC通信のオーバーヘッドを最小化すること

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

- RemoteCallのターゲットデバイスが信頼できるものであること
- 関数のサンドボックス化（未実装の場合は注意）

## 備考

- _If/_Whileは内部用opでありドキュメント付き、If/Whileが公開版
- StatelessIf/StatelessWhile/StatelessCaseは副作用がないことを宣言し、最適化パスでの並べ替えを許可する
- FakeParamは関数のプレースホルダで、グラフ構築時にのみ使用される

---

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

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

### 推奨読解順序

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

関数操作で使用される関数属性（func型）とTin/Tout型リストの仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | functional_ops.cc | `tensorflow/core/ops/functional_ops.cc` | func属性、Tin/Tout属性の定義パターン |

**読解のコツ**: TensorFlowの関数はfunc型属性として登録される。`.Attr("f: func")`のように宣言され、グラフ定義のFunctionDefとして保持される。

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

C++のop定義から各関数操作の仕様を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | functional_ops.cc | `tensorflow/core/ops/functional_ops.cc` | 全op定義 |

**主要処理フロー**:
- **24-53行目**: `SymbolicGradient` op登録 - 入力の先頭と出力の形状を対応させる
- **55-63行目**: `RemoteCall` op登録 - SetIsStateful、UnknownShape
- **66-91行目**: `_If` op登録 - 内部用条件分岐（docstring付き）
- **93行目以降**: `IfShapeInferenceFn` - output_shapes属性ベースの形状推論
- **113行目**: `StatelessIf` op登録
- **125行目**: `If` op登録 - 公開版条件分岐
- **158行目**: `StatelessCase` op登録
- **168行目**: `Case` op登録
- **180行目**: `_While` op登録 - 内部用ループ
- **235行目**: `While` op登録 - 公開版ループ
- **246行目**: `StatelessWhile` op登録
- **256行目**: `ToBool` op登録
- **262行目**: `For` op登録
- **274行目**: `PartitionedCall` op登録
- **285行目**: `StatefulPartitionedCall` op登録
- **302行目**: `FakeParam` op登録
- **316行目**: `DeviceIndex` op登録

#### Step 3: 形状推論の仕組みを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | functional_ops.cc | `tensorflow/core/ops/functional_ops.cc` | IfShapeInferenceFn, WhileShapeInferenceFn |

**読解のコツ**: 関数操作の形状推論は、output_shapes属性が設定されていればそれを使用し、設定されていなければUnknownShapeを返す。SymbolicGradientは特殊で、入力テンソルの形状を出力に対応させる（resource型の場合はhandle情報を使用）。

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

```
tf.function(f)(args)
    |
    +-- def_function.py (ConcreteFunction)
            |
            +-- StatefulPartitionedCall(args, f=concrete_function)
            |       +-- C++ StatefulPartitionedCall kernel
            |               +-- FunctionDef実行
            |
            +-- PartitionedCall(args, f=concrete_function) [副作用なし版]

tf.cond(pred, true_fn, false_fn)  [Graph mode / tf.function内]
    |
    +-- If(cond, input, then_branch=true_fn, else_branch=false_fn)
            +-- IfShapeInferenceFn (output_shapes属性)
```

### データフロー図

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

args (Tin)         -->  functional_ops.cc          -->  output (Tout)
func属性                (関数属性の解決)
                            |
                    FunctionDef
                    (グラフ関数定義)
                            |
                    Kernel実行
                    (ローカル/リモート)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| functional_ops.cc | `tensorflow/core/ops/functional_ops.cc` | ソース | C++ op定義 |
| gen_functional_ops.py | `tensorflow/python/ops/gen_functional_ops.py` | 自動生成 | Python バインディング |
| def_function.py | `tensorflow/python/eager/def_function.py` | ソース | tf.functionデコレータ |
| function.py | `tensorflow/python/eager/function.py` | ソース | ConcreteFunction実装 |
| function.h | `tensorflow/core/framework/function.h` | ヘッダ | FunctionDef C++定義 |
| common_shape_fns.h | `tensorflow/core/framework/common_shape_fns.h` | ヘッダ | 形状推論関数 |
