# 機能設計書 108-リスト操作（List Operations）

## 概要

本ドキュメントは、TensorFlowにおけるTensorListの生成・要素追加・取得・変換・結合などの操作機能の設計を記述する。

### 本機能の処理概要

**業務上の目的・背景**：動的長のテンソルシーケンスを扱う必要がある場面（RNNの可変長出力、動的バッチ処理、ループ内でのテンソル蓄積など）において、固定形状のテンソルでは対応できない。TensorListは可変長のテンソルコレクションを表現するvariant型のデータ構造であり、本機能はその操作を提供する。

**機能の利用シーン**：tf.while_loopでのテンソル蓄積、動的RNNの出力収集、可変長シーケンスのバッチ処理、TensorArrayの内部実装。

**主要な処理内容**：
1. 空のTensorListの生成（EmptyTensorList）
2. 予約済みTensorListの生成（TensorListReserve）
3. テンソルからのTensorList生成（TensorListFromTensor）
4. 要素のプッシュ（TensorListPushBack、TensorListPushBackBatch）
5. 要素のポップ（TensorListPopBack）
6. インデックスによる要素取得（TensorListGetItem）
7. インデックスによる要素設定（TensorListSetItem）
8. リストのスタック化（TensorListStack）
9. リストの結合（TensorListConcat、TensorListConcatV2）
10. リストの分割（TensorListSplit）
11. リストのサイズ変更（TensorListResize）
12. リストの長さ取得（TensorListLength）
13. 要素形状の取得（TensorListElementShape）
14. 散布・収集操作（TensorListScatter、TensorListScatterV2、TensorListScatterIntoExistingList、TensorListGather）
15. リスト結合（TensorListConcatLists）

**関連システム・外部連携**：tf.while_loop、AutoGraph、TensorArray。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能に関連する画面は登録されていない |

## 機能種別

データ構造操作（動的リスト管理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| element_shape | shape_type (int32/int64) | Yes（生成時） | 要素テンソルの形状 | - |
| max_num_elements | int32 | Yes（EmptyTensorList） | 最大要素数 | - |
| num_elements | int32 | Yes（Reserve） | 予約要素数 | - |
| element_dtype | type | Yes | 要素のデータ型 | 有効なTensorFlow型 |
| input_handle | variant | Yes（操作時） | TensorListハンドル | 有効なvariant |
| tensor | element_dtype | Yes（追加時） | 追加するテンソル | element_dtypeと一致 |
| index | int32 | Yes（Get/Set時） | アクセスインデックス | - |
| indices | int32 | Yes（Gather/Scatter時） | インデックスリスト | 1次元 |
| size | int32 | Yes（Resize） | 新しいサイズ | スカラー |
| resize_if_index_out_of_bounds | bool | No | 範囲外時自動リサイズ（デフォルト: false） | - |

### 入力データソース

計算グラフ内のテンソルデータ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| handle/output_handle | variant | TensorListハンドル（スカラー） |
| tensor/item/values | element_dtype | 取得したテンソル要素 |
| length | int32 | リストの長さ（スカラー） |
| element_shape | shape_type | 要素の形状ベクトル |
| lengths | int64 | Concat時の各要素長 |

### 出力先

計算グラフ内の後続Opへの入力。

## 処理フロー

### 処理シーケンス

```
[リスト生成]
1. EmptyTensorList / TensorListReserve / TensorListFromTensor
   └─ element_shape と element_dtype を指定して variant ハンドルを生成

[要素操作]
2. TensorListPushBack: 末尾に要素を追加
3. TensorListPopBack: 末尾の要素を取り出し
4. TensorListGetItem: インデックスで要素取得
5. TensorListSetItem: インデックスで要素設定

[一括変換]
6. TensorListStack: リスト全体をテンソルに変換（先頭にリスト長の次元追加）
7. TensorListConcat: リスト全体を第0次元で結合
8. TensorListSplit: テンソルをリストに分割

[散布・収集]
9. TensorListScatter: テンソルからインデックス指定でリストに分配
10. TensorListGather: リストからインデックス指定で収集
```

### フローチャート

```mermaid
flowchart TD
    A[EmptyTensorList / Reserve] --> B[TensorListハンドル]
    B --> C{操作種別}
    C -->|追加| D[PushBack]
    C -->|取り出し| E[PopBack]
    C -->|取得| F[GetItem]
    C -->|設定| G[SetItem]
    C -->|変換| H[Stack / Concat]
    D --> B
    E --> B
    G --> B
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-108-01 | 型一致 | PushBack/PopBack/GetItem/SetItemでelement_dtypeがリストの型と一致する必要がある | 全要素操作 |
| BR-108-02 | 形状互換 | 追加する要素の形状はリストのelement_shapeとマージ可能である必要がある | PushBack/SetItem |
| BR-108-03 | ハンドルデータ検証 | handle_dataが存在する場合、サイズ1でdtypeが一致する必要がある | 全操作 |
| BR-108-04 | Stackの出力形状 | TensorListStackの出力は[num_elements] + element_shapeの形状となる | Stack時 |
| BR-108-05 | Scatterの入力制約 | tensorはランク1以上、indicesはランク1 | ScatterIntoExistingList |

### 計算ロジック

TensorListStackの出力形状 = [num_elements (or Unknown)] + element_shape。TensorListConcatの出力は第0次元がUnknown（結合後の総長）、残りの次元はelement_shapeのサブシェイプ。

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArgument | 型不一致 | リストのelement_dtypeと操作のelement_dtypeが不一致 | 型を合わせる |
| InvalidArgument | ハンドルエラー | variant dataのサイズが不正（1でない） | 正しいTensorListハンドルを使用 |
| InvalidArgument | 入力エラー | PopBack時にリストが非リスト型 | TFT_ARRAY型のリストを使用 |

### リトライ仕様

自動リトライは行われない。

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

TensorListはイミュータブルなデータ構造であり、各操作は新しいvariantハンドルを返す。トランザクション管理は不要。

## パフォーマンス要件

- PushBack/PopBackはO(1)の計算量
- Stack/Concatはリスト全体のコピーを含むためO(n)

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

- 特になし

## 備考

- TensorListはvariant型で表現され、FullTypeDef（TFT_ARRAY）による型追跡が行われる
- SetTypeConstructorでUnaryTensorContainer(TFT_ARRAY)が設定される
- SetForwardTypeFnで型推論が前方伝播される
- V2版のConcat/Scatterはシェイプをテンソル入力として受け取る（V1はアトリビュート）

---

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

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

### 推奨読解順序

#### Step 1: ヘルパー関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | list_ops.cc | `tensorflow/core/ops/list_ops.cc` | ヘルパー関数定義（27-56行目） |

**主要処理フロー**:
- **27-45行目**: VerifyHandleData - ハンドルデータの有効性検証（サイズ1、dtype一致）
- **47-50行目**: IsValidTensorListHandleData - ハンドルデータの存在と有効性チェック
- **53-56行目**: GetElementShapeFromHandleData - ハンドルデータから要素形状を取得

**読解のコツ**: TensorListのハンドルデータは`vector<ShapeAndType>`で表現され、サイズ1で要素の形状とデータ型を保持する。FullTypeDef(TFT_ARRAY)による型システムとの統合に注意。

#### Step 2: 基本Op登録を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | list_ops.cc | `tensorflow/core/ops/list_ops.cc` | 全20個のTensorList Op登録定義 |

**主要処理フロー**:
- **58-78行目**: EmptyTensorList - element_shape/max_num_elements入力、variant出力、FullTypeDef設定
- **80-118行目**: TensorListPushBack - ハンドルデータ検証、dtype一致チェック、形状マージ
- **171-174行目**: TensorListLength - スカラーint32出力
- **176-214行目**: TensorListPopBack - TFT_ARRAY型チェック、要素形状復元
- **216-263行目**: TensorListStack - num_elements属性、要素形状+先頭次元で出力形状構成
- **419-439行目**: TensorListReserve - element_shape/num_elements入力
- **441-471行目**: TensorListGetItem - ハンドルデータからの形状推論
- **490-522行目**: TensorListSetItem - resize_if_index_out_of_bounds属性

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

```
EmptyTensorList / TensorListReserve / TensorListFromTensor
    └─ variant(TFT_ARRAY) ハンドル生成
        │
        ├─ TensorListPushBack
        │      ├─ IsValidTensorListHandleData()
        │      ├─ dtype一致チェック
        │      └─ 形状マージ
        │
        ├─ TensorListPopBack
        │      ├─ IsValidTensorListHandleData()
        │      └─ TFT_ARRAY型チェック
        │
        ├─ TensorListGetItem / TensorListSetItem
        │      └─ インデックスアクセス
        │
        ├─ TensorListStack
        │      └─ [num_elements] + element_shape → テンソル
        │
        ├─ TensorListConcat / TensorListConcatV2
        │      └─ TensorListConcatShapeInference()
        │
        ├─ TensorListScatter / TensorListGather
        │      └─ インデックスベースの散布・収集
        │
        └─ TensorListConcatLists
               └─ 2つのリストの結合
```

### データフロー図

```
[生成]                    [操作]                    [変換]

EmptyTensorList ──▶ PushBack ──▶ PushBack ──▶ Stack ──▶ テンソル
                    (要素追加)    (要素追加)    (リスト→テンソル)

TensorListFromTensor ◀─────────────────────── テンソル → リスト

TensorListScatter ◀──── テンソル + indices ──▶ リスト
TensorListGather ──── リスト + indices ──▶ テンソル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| list_ops.cc | `tensorflow/core/ops/list_ops.cc` | ソース | TensorList Op登録定義（20 Ops） |
