# 機能設計書 11-定数生成（Constant Operations）

## 概要

本ドキュメントは、TensorFlowにおける定数テンソルの生成機能に関する設計書である。`tf.constant`をはじめとする定数生成操作の内部実装、Eager/Graph両モードでの動作、型変換・形状処理の仕様を詳述する。

### 本機能の処理概要

定数生成機能は、Python/NumPyの値からTensorFlowの不変テンソル（定数テンソル）を生成する機能である。生成された定数テンソルは計算グラフ内で`Const`ノードとして埋め込まれ、推論・学習における固定値の提供に使用される。

**業務上の目的・背景**：機械学習モデルの構築においては、固定されたハイパーパラメータ、マスク値、初期定数、ラベルデータなど不変の値をテンソルとして扱う必要がある。`tf.constant`はこの基本的な要件を満たすAPIであり、全てのTensorFlowプログラムの基盤となる。

**機能の利用シーン**：モデル定義時のバイアス初期値設定、テスト用の固定入力データ作成、数学定数（円周率等）の定義、形状情報のテンソル変換、SavedModelへのシリアライズ/デシリアライズ時のテンソル復元など。

**主要な処理内容**：
1. Python値（スカラー、リスト、NumPy配列）からEagerTensorまたはグラフ定数ノードへの変換
2. データ型（dtype）の自動推論または明示指定による型変換
3. 形状（shape）指定によるリシェイプまたはブロードキャスト充填
4. TensorShape/DimensionからTensorへの自動変換登録
5. ProtoBufを介した定数テンソルのシリアライズ/デシリアライズ

**関連システム・外部連携**：NumPy配列との相互変換、ProtoBuf（TensorProto）によるシリアライゼーション、SavedModel内での定数埋め込み。

**権限による制御**：特になし。全てのユーザが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能は画面に直接関連しない基盤機能である |

## 機能種別

計算処理 / データ変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| value | Python scalar, list, numpy.ndarray, EagerTensor | Yes | 定数テンソルの値 | EagerTensorの場合はdtype一致チェック |
| dtype | tf.DType | No | 出力テンソルのデータ型 | 指定時は値との互換性チェック |
| shape | TensorShape, list, tuple | No | 出力テンソルの形状 | 要素数の整合性チェック |
| name | string | No | テンソルの名前（デフォルト: "Const"） | - |
| verify_shape | bool（v1のみ） | No | 形状の厳密検証フラグ | True時は形状不一致でTypeError |

### 入力データソース

Python値リテラル、NumPy配列、既存のEagerTensor、ProtoBuf（TensorProto）からのデコード。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| tensor | tf.Tensor (EagerTensor) / ops.Operation | Eagerモードでは即値のEagerTensor、Graphモードではグラフ内のConstノード |

### 出力先

呼び出し元のPythonコンテキスト。計算グラフに`Const`ノードとして埋め込まれる。

## 処理フロー

### 処理シーケンス

```
1. tf.constant(value, dtype, shape, name) 呼び出し
   └─ _constant_impl を呼び出し
2. 実行モード判定
   └─ context.context().executing_eagerly() でEager/Graph判定
3. [Eagerモード] _constant_eager_impl 実行
   └─ convert_to_eager_tensor で値をEagerTensorに変換
   └─ shape指定があればリシェイプまたはFill操作で形状調整
4. [Graphモード] ops._create_graph_constant 実行
   └─ 計算グラフにConstノードを作成
5. テンソル返却
```

### フローチャート

```mermaid
flowchart TD
    A[tf.constant 呼び出し] --> B{Eagerモード?}
    B -->|Yes| C[convert_to_eager_tensor]
    B -->|No| D[ops._create_graph_constant]
    C --> E{shape指定あり?}
    E -->|No| F[EagerTensor返却]
    E -->|Yes| G{要素数一致?}
    G -->|一致| H[_eager_reshape]
    G -->|1要素| I{bool型?}
    I -->|Yes| J[CPU上でFill後Identity]
    I -->|No| K[_eager_fill]
    G -->|不一致| L[TypeError]
    H --> F
    J --> F
    K --> F
    D --> M[グラフConstノード返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 型推論 | dtype未指定時はvalue値の型から自動推論 | dtype=None |
| BR-02 | スカラーブロードキャスト | 値が1要素の場合、shape全体にFill | num_elements == 1 かつ shape指定あり |
| BR-03 | bool型CPU制約 | bool型のFill操作はCPU上で実行後にコピー | dtype == bool かつ Fill必要 |
| BR-04 | NumPyコピー | NumPy配列入力時はコピーを作成（参照共有回避） | isinstance(value, np.ndarray) |
| BR-05 | v2ブロードキャスト許可 | v2 APIではスカラーのブロードキャストが許可される | allow_broadcast=True（v2） |

### 計算ロジック

- 形状リシェイプ: `num_elements(value) == num_elements(shape)` の場合、Reshape操作
- スカラー充填: `num_elements(value) == 1` の場合、Fill操作で指定shapeに拡張

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

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

該当なし（本機能はインメモリでのテンソル生成であり、データベース操作は行わない）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| TypeError | 型不一致 | 既存EagerTensorのdtypeが指定dtypeと不一致 | 正しいdtypeを指定する |
| TypeError | 形状不一致 | verify_shape=Trueで形状が異なる | 値の形状を正しく設定する |
| TypeError | 非サポート形状 | 要素数が1でもshape要素数でもない | 値を正しい形状で提供する |
| ValueError | 部分的TensorShape | 未確定次元を含むTensorShapeの変換 | 完全確定TensorShapeを使用する |

### リトライ仕様

該当なし（同期的なテンソル生成のためリトライ不要）。

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

該当なし（データベーストランザクションは使用しない）。

## パフォーマンス要件

- Eager実行時は即座にEagerTensorを返却（マイクロ秒オーダー）
- Graph構築時はConstノードの追加のみ（グラフ構築コスト）
- NumPy配列の場合はメモリコピーが発生する

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

- 大きな定数テンソルの生成はメモリ枯渇の原因となり得る
- SavedModel内の定数テンソルには任意のデータが含まれ得るため、信頼できないモデルの読み込みに注意が必要

## 備考

- `tf.constant`と`tf.convert_to_tensor`の違い: `tf.constant`はshape引数をサポートし、シンボリックテンソルの通過を許可しない
- `tf.constant`と`tf.fill`の違い: `tf.constant`はグラフ構築時に値を埋め込むが、`tf.fill`は実行時に展開される
- プロファイリングトレース対応: `trace.Trace("tf.constant")`によるプロファイリング情報出力

---

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

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

### 推奨読解順序

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

まず、テンソルの基本的なデータ構造と型定義を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | dtypes.py | `tensorflow/python/framework/dtypes.py` | DTypeクラスの定義、型のインターンテーブル（_INTERN_TABLE）、NumPyとの型マッピング |
| 1-2 | tensor_shape.py | `tensorflow/python/framework/tensor_shape.py` | TensorShape、Dimensionクラスの定義 |
| 1-3 | types_pb2 | `tensorflow/core/framework/types.proto` | Protocol Bufferによるデータ型定義 |

**読解のコツ**: TensorFlowの型システムはProtocol Buffer定義（types.proto）をベースとし、Python側のDTypeクラスがそれをラップしている。`_INTERN_TABLE`（557行目〜）がその橋渡しを担う。

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

処理の起点となる`tf.constant`関数の定義を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | constant_op.py | `tensorflow/python/framework/constant_op.py` | tf.constant関数（v1/v2）と内部実装_constant_impl |

**主要処理フロー**:
1. **177-277行目**: `constant`関数（v2 API）- ユーザ向けエントリーポイント
2. **111-174行目**: `constant_v1`関数（v1 API）- verify_shapeパラメータ付き
3. **280-294行目**: `_constant_impl` - Eager/Graph分岐の中核ロジック
4. **297-326行目**: `_constant_eager_impl` - Eager実行時の実装

#### Step 3: Eager実行パスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | constant_op.py | `tensorflow/python/framework/constant_op.py` | convert_to_eager_tensor関数（75-108行目） |

**主要処理フロー**:
- **92-96行目**: NumPy配列の場合はcopy()でメモリ独立化
- **97-101行目**: 既存EagerTensorのdtype検証
- **107-108行目**: ctx.ensure_initialized()後にops.EagerTensorを生成

#### Step 4: 形状調整処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | constant_op.py | `tensorflow/python/framework/constant_op.py` | _eager_reshape（44-53行目）、_eager_fill（56-64行目）、_eager_identity（67-72行目） |

**主要処理フロー**:
- **44-53行目**: Reshape操作のEager実装 - execute.executeで"Reshape" Opを直接呼び出し
- **56-64行目**: Fill操作のEager実装 - 指定shape全体をスカラー値で充填
- **314-320行目**: bool型のFill処理 - CPU上で実行後にGPUへコピー

#### Step 5: シリアライズ/デシリアライズを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | constant_op.py | `tensorflow/python/framework/constant_op.py` | _ConstantTensorCodec（394-429行目）、_NumpyCodec（432-458行目） |

**主要処理フロー**:
- **400-416行目**: do_encode - EagerTensorまたはConst OpからTensorProtoに変換
- **421-426行目**: do_decode - TensorProtoからconstant()を通じてテンソル復元

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

```
tf.constant(value, dtype, shape, name)
    |
    +-- _constant_impl(value, dtype, shape, name, verify_shape, allow_broadcast)
         |
         +-- [Eager] _constant_eager_impl(ctx, value, dtype, shape, verify_shape)
         |       |
         |       +-- convert_to_eager_tensor(value, ctx, dtype)
         |       |       +-- ops.EagerTensor(value, device_name, dtype)
         |       |
         |       +-- _eager_reshape(tensor, shape, ctx)
         |       |       +-- execute.execute("Reshape", ...)
         |       |
         |       +-- _eager_fill(dims, value, ctx)
         |       |       +-- execute.execute("Fill", ...)
         |       |
         |       +-- _eager_identity(tensor, ctx)
         |               +-- execute.execute("Identity", ...)
         |
         +-- [Graph] ops._create_graph_constant(value, dtype, shape, name, ...)

tensor_conversion_registry.register_tensor_conversion_function
    +-- _tensor_shape_tensor_conversion_function (TensorShape -> Tensor)
    +-- _dimension_tensor_conversion_function (Dimension -> Tensor)

nested_structure_coder.register_codec
    +-- _ConstantTensorCodec (Tensor <-> TensorProto)
    +-- _NumpyCodec (np.ndarray <-> TensorProto)
```

### データフロー図

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

Python値/NumPy配列  ---> convert_to_eager_tensor ----> EagerTensor
                          |                              |
                          v                              v
                    dtype推論/変換              shape調整（Reshape/Fill）
                          |                              |
                          v                              v
TensorProto         ---> _ConstantTensorCodec --------> tf.Tensor
(SavedModel)              do_decode                   （復元された定数）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| constant_op.py | `tensorflow/python/framework/constant_op.py` | ソース | 定数生成の主要実装 |
| constant_tensor_conversion.py | `tensorflow/python/framework/constant_tensor_conversion.py` | ソース | 組み込み型のテンソル変換関数登録 |
| dtypes.py | `tensorflow/python/framework/dtypes.py` | ソース | データ型定義・変換 |
| ops.py | `tensorflow/python/framework/ops.py` | ソース | EagerTensorクラス、_create_graph_constant |
| tensor_shape.py | `tensorflow/python/framework/tensor_shape.py` | ソース | TensorShape/Dimensionクラス |
| tensor_util.py | `tensorflow/python/framework/tensor_util.py` | ソース | make_tensor_proto、MakeNdarray |
| execute.py | `tensorflow/python/eager/execute.py` | ソース | Eager Op実行エンジン |
| context.py | `tensorflow/python/eager/context.py` | ソース | 実行コンテキスト管理 |
| nested_structure_coder.py | `tensorflow/python/saved_model/nested_structure_coder.py` | ソース | 構造化データのコーデック管理 |
| types.proto | `tensorflow/core/framework/types.proto` | 定義 | Protocol Bufferデータ型定義 |
