# 機能設計書 13-デバイス管理（Device Management）

## 概要

本ドキュメントは、TensorFlowにおけるデバイス（CPU/GPU/TPU等）の指定・配置戦略を管理するDeviceSpec機能に関する設計書である。デバイス文字列のパース、DeviceSpecオブジェクトの生成・結合、デバイススコープによる演算配置制御の仕様を詳述する。

### 本機能の処理概要

デバイス管理機能は、TensorFlowの演算をどのハードウェアデバイス上で実行するかを指定するためのDeviceSpecクラスを提供する。ジョブ名、レプリカ番号、タスク番号、デバイスタイプ、デバイスインデックスの5つのコンポーネントでデバイスを特定する。

**業務上の目的・背景**：分散学習やマルチGPU環境では、テンソルと演算を適切なデバイスに配置することがパフォーマンスに直結する。DeviceSpecはデバイス指定文字列（例: `/job:worker/device:GPU:0`）を構造化して管理し、デバイススコープによる階層的な配置制御を可能にする。

**機能の利用シーン**：`tf.device()`コンテキストマネージャでの演算配置、分散学習でのパラメータサーバ/ワーカー指定、GPU/TPUへの特定テンソルの配置、デバイス文字列の構築・パース・結合。

**主要な処理内容**：
1. デバイス文字列（"/job:ps/device:GPU:0"）のパースとDeviceSpecオブジェクト生成
2. DeviceSpecの5コンポーネント（job, replica, task, device_type, device_index）管理
3. DeviceSpec同士の結合（make_merged_spec）
4. DeviceSpecコンポーネントの置換（replace）
5. デバイス文字列のキャッシュによるパース高速化

**関連システム・外部連携**：分散学習フレームワーク（ParameterServer、AllReduce）、GPU/TPUランタイム、gRPC分散実行環境。

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

## 関連画面

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

## 機能種別

メタデータ管理 / 構成管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| job | string | No | ジョブ名（例: "ps", "worker"） | 文字列変換 |
| replica | int | No | レプリカインデックス | 整数変換 |
| task | int | No | タスクインデックス | 整数変換 |
| device_type | string | No | デバイスタイプ（"CPU", "GPU", "TPU", "CUSTOM", "EPU"） | _VALID_DEVICE_TYPESに含まれるか |
| device_index | int | No | デバイスインデックス | 整数変換 |
| spec | string | No | デバイス文字列（from_string用） | パース結果の妥当性 |

### 入力データソース

プログラムコード内のデバイス指定文字列、分散環境のTF_CONFIG、クラスタリゾルバの出力。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DeviceSpec | DeviceSpecV2/DeviceSpecV1 | デバイス仕様オブジェクト |
| to_string() | string | "/job:name/replica:id/task:id/device:TYPE:id" 形式の文字列 |

### 出力先

`tf.device()`コンテキストマネージャ、Op配置ポリシー。

## 処理フロー

### 処理シーケンス

```
1. DeviceSpec生成（コンストラクタまたはfrom_string）
   └─ 各コンポーネントの型変換・正規化
2. デバイス文字列のパース（from_string の場合）
   └─ キャッシュ確認 → パース → キャッシュ格納
3. 文字列表現の生成
   └─ _components_to_string で各コンポーネントを結合
4. DeviceSpec結合（make_merged_spec）
   └─ 上書き優先度に基づくコンポーネント結合
```

### フローチャート

```mermaid
flowchart TD
    A[DeviceSpec生成] --> B{from_string?}
    B -->|Yes| C[_string_to_components]
    B -->|No| D[コンストラクタ直接]
    C --> E{キャッシュヒット?}
    E -->|Yes| F[キャッシュから返却]
    E -->|No| G[文字列パース]
    G --> H[コンポーネント抽出]
    H --> I[キャッシュ格納]
    I --> J[DeviceSpec生成]
    D --> J
    J --> K[_components_to_string]
    K --> L[DeviceSpec完成]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 有効デバイスタイプ | CPU, GPU, TPU, CUSTOM, EPU + プラグインデバイス | device_type指定時 |
| BR-02 | 大文字正規化 | "cpu", "gpu"は自動的に大文字に変換 | device_type設定時 |
| BR-03 | 結合優先度 | make_merged_specでは引数のDeviceSpecが優先 | None以外のコンポーネント |
| BR-04 | 不変性（V2） | DeviceSpecV2は不変オブジェクト | TF2 |
| BR-05 | 可変性（V1） | DeviceSpecV1はセッター経由で変更可能 | TF1互換 |
| BR-06 | ワイルドカード | device_indexの"*"は任意のデバイスを表す | デバイス文字列パース時 |

### 計算ロジック

特になし（データ構造の管理が主目的）。

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

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ValueError | 複数デバイスタイプ | 1つのDeviceSpec文字列に複数のデバイスタイプが含まれる | 1つのデバイスタイプのみ指定する |
| ValueError | 不明属性 | パース時に認識できない属性が含まれる | 正しいデバイス文字列形式を使用する |

### リトライ仕様

該当なし。

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

該当なし。

## パフォーマンス要件

- `_STRING_TO_COMPONENTS_CACHE`による文字列パース結果のキャッシュ
- `_COMPONENTS_TO_STRING_CACHE`による文字列生成結果のキャッシュ
- ハッシュ値の事前計算によるDict/Set操作の高速化

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

- デバイス文字列は信頼できるソースからのみ受け取るべき
- 不正なデバイス指定はValueErrorとして処理される

## 備考

- EPUはTPU embeddingを表す内部デバイスタイプ（将来変更の可能性あり）
- プラグインデバイスは`pywrap_tfe.TF_ListPluggablePhysicalDevices()`で動的に取得
- TF1のDeviceSpecV1は可変、TF2のDeviceSpecV2は不変

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | device_spec.py | `tensorflow/python/framework/device_spec.py` | _VALID_DEVICE_TYPES定義（21行目）、キャッシュ変数（26-27行目） |

**読解のコツ**: DeviceSpecは5つのコンポーネント（job, replica, task, device_type, device_index）で構成される。`__slots__`（104-105行目）で厳密にスロットが制限されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | device_spec.py | `tensorflow/python/framework/device_spec.py` | DeviceSpecV2クラス（47-418行目） |

**主要処理フロー**:
1. **107-134行目**: __init__ - 各コンポーネントの初期化と文字列生成
2. **136-143行目**: to_string - キャッシュされた文字列表現の返却
3. **145-158行目**: from_string - 文字列からDeviceSpecを生成するクラスメソッド
4. **215-264行目**: make_merged_spec / replace - DeviceSpecの結合・置換

#### Step 3: 文字列パース処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | device_spec.py | `tensorflow/python/framework/device_spec.py` | _string_to_components（316-367行目）、_components_to_string（370-393行目） |

**主要処理フロー**:
- **327-329行目**: キャッシュヒットチェック
- **335行目**: "/"で分割し、さらに":"で分割
- **336行目**: _get_valid_device_types()で有効デバイスタイプを取得
- **341-363行目**: job/replica/task/device_type/device_indexの個別パース
- **366行目**: パース結果をキャッシュに格納

#### Step 4: V1互換実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | device_spec.py | `tensorflow/python/framework/device_spec.py` | DeviceSpecV1クラス（420-485行目） |

**主要処理フロー**:
- **425-448行目**: プロパティセッター - V1では各コンポーネントが変更可能
- **465-469行目**: parse_from_string - V1ではselfを変更して返す
- **471-481行目**: merge_from - V1でのデバイスマージ（selfを変更）

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

```
DeviceSpec(job, replica, task, device_type, device_index)
    |
    +-- _as_str_or_none / _as_int_or_none / _as_device_str_or_none
    |
    +-- _components_to_string(job, replica, task, device_type, device_index)
    |       +-- _COMPONENTS_TO_STRING_CACHE チェック
    |
    +-- hash(to_string())

DeviceSpec.from_string(spec)
    |
    +-- _string_to_components(spec)
    |       +-- _STRING_TO_COMPONENTS_CACHE チェック
    |       +-- _get_valid_device_types()
    |       |       +-- pywrap_tfe.TF_ListPluggablePhysicalDevices()
    |       +-- 文字列パース（"/"と":"で分割）
    |
    +-- DeviceSpec(*components)

DeviceSpec.make_merged_spec(dev)
    |
    +-- _get_combined_properties(dev)
    |       +-- 各コンポーネントのNoneチェックによる優先度判定
    |
    +-- DeviceSpec(*combined)
```

### データフロー図

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

"/job:ps/device:GPU:0"  --> _string_to_components --> (job, replica, task, type, idx)
                             |                              |
                             v                              v
                        キャッシュ検索            DeviceSpec.__init__
                             |                              |
                             v                              v
                        文字列パース             _components_to_string
                                                           |
                                                           v
                                                "/job:ps/device:GPU:0"
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| device_spec.py | `tensorflow/python/framework/device_spec.py` | ソース | DeviceSpec V1/V2の主要実装 |
| pywrap_tfe | `tensorflow/python/pywrap_tfe` | C++バインディング | プラグインデバイスリスト取得 |
| context.py | `tensorflow/python/eager/context.py` | ソース | tf.device()コンテキスト管理 |
| ops.py | `tensorflow/python/framework/ops.py` | ソース | Op配置でのDeviceSpec利用 |
