# 機能設計書 61-RaggedTensor数学演算

## 概要

本ドキュメントは、TensorFlowにおけるRaggedTensorに対する数学演算（セグメント集約等）を提供する機能の設計を記述する。

### 本機能の処理概要

RaggedTensor数学演算は、不揃いな長さを持つテンソル（RaggedTensor）に対して数学的な演算操作を行う機能である。RaggedTensorは各次元の要素数が異なるデータ（例：可変長文のバッチ、不規則な時系列データ）を効率的に表現するためのデータ構造であり、本機能はそのRaggedTensorに対して範囲生成（RaggedRange）やセグメント集約等の数学演算を提供する。

**業務上の目的・背景**：自然言語処理や時系列分析など、入力データの長さが不揃いなケースは機械学習において頻出する。従来はパディング（ゼロ埋め）で長さを揃えていたが、メモリ効率が悪く計算コストも増大する。RaggedTensorの数学演算機能により、パディングなしで効率的に可変長データの数学処理を実行できる。

**機能の利用シーン**：可変長シーケンスのバッチ処理において、各シーケンスに対する連番生成（RaggedRange）、セグメント単位の合計・平均・最大値計算、不揃いな配列に対する要素ごとの演算が必要な場合に利用される。

**主要な処理内容**：
1. RaggedRange: 指定されたstart、limit、deltaから不揃いな長さの連番テンソルを生成する
2. セグメント集約: RaggedTensorの行単位での集約演算（合計、平均等）
3. 形状推論: 入力テンソルの形状から出力テンソルの形状を静的に推論する

**関連システム・外部連携**：TensorFlowコアフレームワークのOp登録システムと形状推論システムに統合される。C++カーネル実装とPython APIの両層で動作する。

**権限による制御**：特になし。TensorFlowの標準的なOp実行権限に従う。

## 関連画面

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

## 機能種別

計算処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| starts | T (bfloat16, float, double, int32, int64) | Yes | 各行の開始値 | ランク0またはランク1 |
| limits | T | Yes | 各行の終了値 | ランク0またはランク1 |
| deltas | T | Yes | 各行の増分値 | ランク0またはランク1、ゼロ不可 |
| T | DType属性 | No | データ型 (デフォルト: DT_INT32) | bfloat16, float, double, int32, int64 のいずれか |
| Tsplits | DType属性 | No | 分割インデックスの型 (デフォルト: DT_INT64) | int32, int64 のいずれか |

### 入力データソース

TensorFlowの計算グラフ内で前段の操作から供給されるテンソルデータ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| rt_nested_splits | Tsplits | RaggedTensorの行分割インデックス。各行の開始位置を示すベクトル |
| rt_dense_values | T | RaggedTensorのフラット化された値。全行の値を連結したランク1テンソル |

### 出力先

TensorFlowの計算グラフ内で後段の操作に供給される。

## 処理フロー

### 処理シーケンス

```
1. 入力テンソル（starts, limits, deltas）の受け取り
   └─ 各入力がランク0（スカラー）またはランク1（ベクトル）であることを確認
2. 入力形状の検証
   └─ ランク1の入力同士の次元が一致することを確認
3. 行数の決定
   └─ ランク1入力の次元数から行数を決定（全スカラーの場合は1行）
4. 各行の値の計算
   └─ 各行について starts[i] から limits[i] まで deltas[i] 刻みで値を生成
5. rt_nested_splits の計算
   └─ 各行の開始位置を累積的に記録（要素数 = 行数 + 1）
6. rt_dense_values の構築
   └─ 全行の値を連結してフラットなランク1テンソルを生成
```

### フローチャート

```mermaid
flowchart TD
    A[入力受け取り: starts, limits, deltas] --> B{入力ランクの検証}
    B -->|ランク0 or 1| C{ランク1入力の次元一致?}
    B -->|ランク2以上| E[エラー: InvalidArgument]
    C -->|Yes| D[行数の決定]
    C -->|No| E
    D --> F[各行の値を計算]
    F --> G[rt_nested_splits 構築]
    F --> H[rt_dense_values 構築]
    G --> I[出力]
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-61-01 | 入力ランク制約 | 全入力テンソルはランク0またはランク1でなければならない | 常時 |
| BR-61-02 | 次元一致制約 | ランク1の入力テンソル同士は同一次元でなければならない | ランク1入力が複数ある場合 |
| BR-61-03 | スカラー入力時の行数 | 全入力がスカラーの場合、結果は1行のRaggedTensorとなる | 全入力がランク0の場合 |
| BR-61-04 | splits次元計算 | rt_nested_splitsの次元は行数+1となる | 常時 |

### 計算ロジック

RaggedRangeの各行iについて:
```
row_values[i] = [starts[i], starts[i] + deltas[i], starts[i] + 2*deltas[i], ...]
  (starts[i] + k*deltas[i] < limits[i] の間)
```

rt_nested_splits[0] = 0, rt_nested_splits[i+1] = rt_nested_splits[i] + len(row_values[i])

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

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

データベース操作は行わない。本機能はインメモリのテンソル演算である。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArgument | 入力ランクエラー | 入力テンソルのランクが2以上 | 入力テンソルをランク0または1に変換する |
| InvalidArgument | 次元不一致エラー | ランク1入力同士の次元が異なる | 入力テンソルの次元を揃える |
| InvalidArgument | ゼロ増分エラー | deltasに0が含まれる | 非ゼロの増分値を指定する |

### リトライ仕様

リトライ不要。計算エラーは入力データの修正により解決する。

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

該当なし。テンソル演算はトランザクション管理の対象外。

## パフォーマンス要件

C++カーネル実装により高速に動作する。GPU/TPUアクセラレータでの実行も可能。出力サイズは入力パラメータに依存し、大量の行を生成する場合はメモリ使用量に注意が必要。

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

特別なセキュリティ要件はない。TensorFlowの標準的なメモリ管理とアクセス制御に従う。

## 備考

- RaggedTensor数学演算はTensorFlow 2.0以降で正式サポートされている
- `ragged_math_ops.cc`は主にRaggedRangeオペレーションを定義しており、他のRaggedTensor数学演算は`ragged_array_ops.cc`や標準の数学演算カーネルと組み合わせて実現される

---

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

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

### 推奨読解順序

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

RaggedTensorは「rt_nested_splits（行分割インデックス）」と「rt_dense_values（フラット化された値）」の2つのテンソルで構成される。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ragged_math_ops.cc | `tensorflow/core/ops/ragged_math_ops.cc` | RaggedRangeオペレーションの入出力定義を理解する |

**読解のコツ**: TensorFlow C++ Opの定義では`REGISTER_OP`マクロを使用する。`.Input()`で入力テンソル、`.Output()`で出力テンソル、`.Attr()`で属性（型パラメータ等）を定義する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ragged_math_ops.cc | `tensorflow/core/ops/ragged_math_ops.cc` | REGISTER_OPマクロによるOp登録（31-39行目） |

**主要処理フロー**:
1. **31-39行目**: `REGISTER_OP("RaggedRange")`でOpを登録。入力としてstarts, limits, deltasを受け取り、出力としてrt_nested_splitsとrt_dense_valuesを返す
2. **37行目**: サポートするデータ型をAttrで定義（bfloat16, float, double, int32, int64）
3. **38行目**: 分割インデックスの型をAttrで定義（int32, int64）
4. **39行目**: 形状推論関数`RaggedRangeShapeFn`を設定

#### Step 3: 形状推論ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ragged_math_ops.cc | `tensorflow/core/ops/ragged_math_ops.cc` | RaggedRangeShapeFn関数（45-79行目） |

**主要処理フロー**:
- **47-52行目**: 全入力テンソルのランクが最大1であることを検証
- **55-64行目**: ランク1入力同士の次元が一致することをMergeで確認
- **67-73行目**: rt_nested_splitsの出力次元を計算（行数+1、不明な場合はUnknownDim）
- **74行目**: rt_nested_splitsの出力形状を1次元ベクトルとして設定
- **77行目**: rt_dense_valuesの出力形状をランク1の不明サイズとして設定

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

```
REGISTER_OP("RaggedRange")
    │
    └─ RaggedRangeShapeFn (形状推論)
           │
           ├─ WithRankAtMost (入力ランク検証)
           ├─ Merge (次元一致検証)
           └─ set_output (出力形状設定)
```

### データフロー図

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

starts (T, rank 0/1) ──▶                              ──▶ rt_nested_splits (Tsplits)
limits (T, rank 0/1) ──▶  RaggedRange Op カーネル      ──▶ rt_dense_values (T)
deltas (T, rank 0/1) ──▶
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ragged_math_ops.cc | `tensorflow/core/ops/ragged_math_ops.cc` | ソース | RaggedRange Opの登録と形状推論関数の定義 |
| ragged_array_ops.cc | `tensorflow/core/ops/ragged_array_ops.cc` | ソース | RaggedTensorの配列操作Op定義（関連機能） |
| ragged_conversion_ops.cc | `tensorflow/core/ops/ragged_conversion_ops.cc` | ソース | RaggedTensorの変換操作Op定義（関連機能） |
