# 機能設計書 47-データセット結合（Concatenate/Interleave）

## 概要

本ドキュメントは、TensorFlowにおけるデータセット結合機能の設計を記述する。複数のデータセットの結合（concatenate）およびインターリーブ（interleave）を提供する。

### 本機能の処理概要

本機能は、複数のtf.data.Datasetを結合する2つの主要な方法を提供する。concatenateは2つのデータセットを直列に連結し、interleaveは入力データセットの各要素からサブデータセットを生成し、それらをサイクリックに混ぜ合わせる。

**業務上の目的・背景**：機械学習では複数のデータソースを統合して学習に使用することが一般的である。異なるファイルのデータを単純に連結する場合はconcatenateを使用し、複数ファイルのI/Oを並列化しつつデータを混合する場合はinterleaveを使用する。特にinterleaveは、複数のTFRecordファイルからの並列読み込みに不可欠な機能である。

**機能の利用シーン**：（1）訓練データと追加データを連結する場面、（2）複数のTFRecordファイルから並列にデータを読み込む場面、（3）データの多様性を確保するためにソース間でデータを交互に取得する場面。

**主要な処理内容**：
1. _ConcatenateDataset: 2つのデータセットを直列に連結
2. _InterleaveDataset: map_funcで生成したサブデータセットをサイクリックに取得
3. _ParallelInterleaveDataset: 並列度を指定したインターリーブ
4. element_specの互換性検証（concatenate時）
5. cycle_length / block_lengthによるインターリーブパターン制御

**関連システム・外部連携**：tf.data.Dataset API（No.44）の変換操作の一つ。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面機能マッピングに本機能の関連画面なし |

## 機能種別

データ連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input_dataset | Dataset | Yes | 結合元のデータセット | 有効なDatasetオブジェクト |
| dataset_to_concatenate | Dataset | Yes | concatenateの結合先データセット | element_specが互換 |
| map_func | Callable | Yes | interleaveのマッピング関数 | Datasetを返す必要がある |
| cycle_length | int | No | 同時にインターリーブするサブデータセット数 | デフォルトAUTOTUNE |
| block_length | int | No | 各サブデータセットから連続取得する要素数 | デフォルト1 |
| num_parallel_calls | int | No | 並列度 | None/正の整数/AUTOTUNE |
| deterministic | bool | No | 決定論的順序保証 | None/True/False |
| name | string | No | データセットの名前 | None可 |

### 入力データソース

上流のtf.data.Datasetパイプラインからの出力。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| combined_dataset | tf.data.Dataset | 結合されたデータセット |

### 出力先

下流のtf.dataパイプラインに接続される。

## 処理フロー

### 処理シーケンス

```
1. concatenateの場合:
   └─ 両データセットのelement_specの互換性検証（common_supertype）
   └─ gen_dataset_ops.concatenate_datasetでvariant_tensor生成

2. interleaveの場合:
   └─ map_funcをStructuredFunctionWrapperでラップ
   └─ map_funcの出力がDatasetであることを検証
   └─ cycle_length/block_lengthをint64テンソルに変換
   └─ num_parallel_callsがNoneの場合: interleave_dataset Op
   └─ num_parallel_callsが指定の場合: parallel_interleave_dataset_v4 Op
```

### フローチャート

```mermaid
flowchart TD
    A{結合方法} -->|concatenate| B[element_spec互換性検証]
    A -->|interleave| C[map_funcのラップ]
    B --> D{互換?}
    D -->|Yes| E[concatenate_dataset Op]
    D -->|No| F[TypeError]
    C --> G[map_funcがDataset返却を検証]
    G --> H{num_parallel_calls?}
    H -->|None| I[interleave_dataset Op]
    H -->|指定| J[parallel_interleave_dataset_v4 Op]
    E --> K[結合Dataset返却]
    I --> K
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-47-01 | element_spec互換 | concatenateの2つのデータセットは互換性のあるelement_specを持つ必要がある | concatenate呼び出し時 |
| BR-47-02 | map_funcはDataset返却 | interleaveのmap_funcはDatasetオブジェクトを返す必要がある | interleave呼び出し時 |
| BR-47-03 | cycle_lengthデフォルト | cycle_lengthのデフォルトはAUTOTUNE | interleave呼び出し時 |
| BR-47-04 | block_lengthデフォルト | block_lengthのデフォルトは1 | interleave呼び出し時 |
| BR-47-05 | deterministic警告 | num_parallel_calls未指定時にdeterministicを指定すると警告 | interleave呼び出し時 |

### 計算ロジック

- **concatenate**: dataset_A の全要素の後に dataset_B の全要素を出力
- **interleave(cycle_length=C, block_length=B)**: C個のサブデータセットを並行して開き、各サブデータセットからB個ずつ要素を取得してサイクリックに出力

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

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

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

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| TypeError | 型不一致 | concatenateでelement_specが互換でない | 同じ型構造のデータセットを結合 |
| TypeError | 戻り値エラー | interleaveのmap_funcがDatasetを返さない | Datasetを返す関数を指定 |

### リトライ仕様

リトライ不要。

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

トランザクション管理なし。

## パフォーマンス要件

- interleaveはI/O並列化により、ファイル読込みスループットを大幅に向上
- parallel_interleaveではnum_parallel_calls=AUTOTUNEで最適な並列度を自動選択
- buffer_output_elementsとprefetch_input_elementsのデフォルトはAUTOTUNE

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

特になし。

## 備考

- concatenateのelement_specはmost_specific_common_supertypeで統合される
- interleaveのDEBUG_MODE時は並列化が無効化される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | concatenate_op.py | `tensorflow/python/data/ops/concatenate_op.py` | _ConcatenateDatasetの構造 |
| 1-2 | interleave_op.py | `tensorflow/python/data/ops/interleave_op.py` | _InterleaveDataset/_ParallelInterleaveDatasetの構造 |

**読解のコツ**: _ConcatenateDatasetはDatasetV2を直接継承し、_input_datasetsとして2つのデータセットを保持する。_InterleaveDatasetはUnaryDatasetを継承し、map_funcの出力仕様からelement_specを決定する。

#### Step 2: concatenateの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | concatenate_op.py | `tensorflow/python/data/ops/concatenate_op.py` | _ConcatenateDataset.__init__ |

**主要処理フロー**:
1. **34-38行目**: common_supertype関数でelement_specの互換性検証
2. **40-47行目**: map_structureによるelement_spec統合（TypeError時にエラー）
3. **52-54行目**: gen_dataset_ops.concatenate_datasetでvariant_tensor生成

#### Step 3: interleaveの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | interleave_op.py | `tensorflow/python/data/ops/interleave_op.py` | _interleave関数と_InterleaveDataset |

**主要処理フロー**:
- **27-56行目**: _interleave関数 - パラメータデフォルト設定とDataset選択
- **36-37行目**: block_lengthデフォルト1、cycle_lengthデフォルトAUTOTUNE
- **42-47行目**: num_parallel_callsがNoneの場合は_InterleaveDataset
- **49-56行目**: 指定の場合は_ParallelInterleaveDataset
- **71-72行目**: map_funcをStructuredFunctionWrapperでラップ
- **73-76行目**: 出力がDatasetSpecであることを検証
- **83-89行目**: gen_dataset_ops.interleave_datasetでvariant_tensor生成
- **103-150行目**: _ParallelInterleaveDataset - parallel_interleave_dataset_v4使用

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

```
dataset_a.concatenate(dataset_b)
    │
    └─ concatenate_op._concatenate(input, other, name)
           │
           └─ _ConcatenateDataset.__init__()
                  ├─ common_supertype(a_spec, b_spec)
                  └─ gen_dataset_ops.concatenate_dataset(a_variant, b_variant)

dataset.interleave(map_func, cycle_length, block_length)
    │
    └─ interleave_op._interleave(...)
           │
           ├─ [sequential] _InterleaveDataset.__init__()
           │      ├─ StructuredFunctionWrapper(map_func)
           │      ├─ DatasetSpec検証
           │      └─ gen_dataset_ops.interleave_dataset(...)
           │
           └─ [parallel] _ParallelInterleaveDataset.__init__()
                  ├─ StructuredFunctionWrapper(map_func)
                  └─ gen_dataset_ops.parallel_interleave_dataset_v4(...)
```

### データフロー図

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

concatenate:
Dataset_A ──────┐
                ├──▶ concatenate_dataset ──▶ [A全要素] ++ [B全要素]
Dataset_B ──────┘

interleave:
Dataset ──▶ map_func ──▶ SubDataset_1 ──┐
                         SubDataset_2 ──┼──▶ サイクリック混合出力
                         SubDataset_N ──┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| concatenate_op.py | `tensorflow/python/data/ops/concatenate_op.py` | ソース | _ConcatenateDatasetの実装 |
| interleave_op.py | `tensorflow/python/data/ops/interleave_op.py` | ソース | _InterleaveDataset/_ParallelInterleaveDatasetの実装 |
| dataset_ops.py | `tensorflow/python/data/ops/dataset_ops.py` | ソース | DatasetV2/UnaryDataset基底クラス |
| structured_function.py | `tensorflow/python/data/ops/structured_function.py` | ソース | StructuredFunctionWrapper |
| debug_mode.py | `tensorflow/python/data/ops/debug_mode.py` | ソース | DEBUG_MODEフラグ |
| gen_dataset_ops.py | `tensorflow/python/ops/gen_dataset_ops.py` | 自動生成 | C++カーネルバインディング |
