# 機能設計書 100-プロファイラクライアント

## 概要

本ドキュメントは、TensorFlowにおけるプロファイラクライアント（Profiler Client）機能の設計を記述する。リモートプロファイリングのクライアントインタフェースを提供する。

### 本機能の処理概要

**業務上の目的・背景**：分散学習やリモート環境でのモデル実行において、プロファイリングを遠隔から実行する必要がある。本機能は、gRPCプロファイラサーバーに対してオンデマンドのプロファイリングリクエストを送信し、CPU/GPU/TPU上のモデル実行をリモートからトレース・モニタリングするクライアントAPIを提供する。

**機能の利用シーン**：Cloud TPU上でのモデルのリモートプロファイリング、マルチGPU/マルチワーカー環境での分散プロファイリング、継続的なTPUモニタリングなどに使用される。

**主要な処理内容**：
1. `trace()` - gRPCサーバーへのプロファイリングリクエスト送信（トレース収集）
2. `monitor()` - gRPCサーバーへのモニタリングリクエスト送信（軽量モニタリング）

**関連システム・外部連携**：gRPCプロファイラサービス（profiler_service.proto）、TensorBoard、Cloud TPUと連携する。

**権限による制御**：特になし。gRPCアドレスへのネットワークアクセスが必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はAPI機能であり、直接関連する画面はない。TensorBoard Profileタブで結果を可視化 |

## 機能種別

リモートプロファイリングクライアント

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| service_addr | string | Yes | gRPCアドレス（カンマ区切り複数対応） | grpc://プレフィックス付き |
| logdir | string | Yes（trace） | プロファイルデータ保存先 | アクセス可能なパス |
| duration_ms | int | Yes | トレース/モニタリング期間（ミリ秒） | > 0 |
| worker_list | string | No（trace） | TPUワーカーリスト | カンマ区切り |
| num_tracing_attempts | int | No（trace） | トレースリトライ回数（デフォルト: 3） | - |
| options | ProfilerOptions | No（trace） | プロファイラオプション | - |
| level | int | No（monitor） | モニタリングレベル（1-2、デフォルト: 1） | 1-2 |

### 入力データソース

gRPCプロファイラサーバーからのトレースデータ。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| プロファイルデータ（trace） | ファイル | logdirに保存されるプロファイルデータ |
| モニタリング結果（monitor） | string | パフォーマンスサマリー文字列 |

### 出力先

- trace: logdirディレクトリ（TensorBoard互換）
- monitor: 文字列として返却

## 処理フロー

### 処理シーケンス

```
1. gRPCアドレスの正規化
   └─ "grpc://" プレフィックスの除去
2. オプションの変換
   └─ ProfilerOptions namedtuple → dict変換
3. gRPCリクエストの送信
   └─ _pywrap_profiler_plugin.trace() or monitor()
4. レスポンスの受信（ブロッキング）
   └─ trace: プロファイルデータをlogdirに保存
   └─ monitor: パフォーマンスサマリーを返却
```

### フローチャート

```mermaid
flowchart TD
    A[trace/monitor呼び出し] --> B[gRPCアドレス正規化]
    B --> C{操作種別?}
    C -->|trace| D[バリデーション: duration_ms > 0]
    D --> E[options → dict変換]
    E --> F[_pywrap_profiler_plugin.trace呼出]
    F --> G[gRPCリクエスト送信 - ブロッキング]
    G --> H[プロファイルデータをlogdirに保存]
    C -->|monitor| I[_pywrap_profiler_plugin.monitor呼出]
    I --> J[gRPCリクエスト送信 - ブロッキング]
    J --> K[パフォーマンスサマリー文字列を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-100-01 | duration_ms正値 | duration_msは0より大きい必要がある | trace |
| BR-100-02 | ブロッキング呼出 | trace/monitorは全サーバーからの応答またはタイムアウトまでブロック | 常時 |
| BR-100-03 | リトライ | トレースイベントが取得できない場合、自動リトライ（デフォルト3回） | trace |
| BR-100-04 | 複数ホスト | 複数gRPCアドレスをカンマ区切りで指定可能 | trace |
| BR-100-05 | grpcプレフィックス | service_addrの"grpc://"プレフィックスは自動除去 | 常時 |
| BR-100-06 | TPU専用monitor | monitor機能は現在Cloud TPUのみサポート | monitor |

### 計算ロジック

該当なし。リモートプロファイリングリクエストの送受信。

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| InvalidArgumentError | パラメータ不正 | duration_ms <= 0 | 正の値を指定 |
| UnavailableError | トレース失敗 | リトライ後もトレースイベントが取得できない | サーバー状態・ネットワーク確認 |

### リトライ仕様

- trace: num_tracing_attempts（デフォルト3回）の自動リトライ
- monitor: リトライなし（ユーザ側でループ制御）

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

該当なし。

## パフォーマンス要件

- ブロッキング呼び出しのため、duration_msの間スレッドがブロックされる
- 複数ホストプロファイリングでは全ホストからの応答を待つ

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

- gRPC通信は認証なし（デフォルト）
- プロファイルデータにはモデル構造情報が含まれる可能性がある
- logdirが共有ストレージの場合、アクセス制御に注意

## 備考

- monitor機能はCloud TPU専用であり、GPUでは利用不可
- TensorBoard起動後、localhost:6006/#profile でプロファイル結果を確認可能
- delay_msオプションで全ホストのプロファイリング開始タイミングを同期可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | profiler_client.py | `tensorflow/python/profiler/profiler_client.py` | `trace()`関数（25-136行目） |
| 1-2 | profiler_client.py | `tensorflow/python/profiler/profiler_client.py` | `monitor()`関数（139-170行目） |

**主要処理フロー**:
1. **123-124行目**: `trace()` - duration_ms <= 0 のバリデーション
2. **127行目**: options → dict変換（namedtuple._asdict()）
3. **128-136行目**: `_pywrap_profiler_plugin.trace()`呼び出し（アドレス正規化、logdir、worker_list、duration_ms、リトライ回数、opts）
4. **168-170行目**: `monitor()` - `_pywrap_profiler_plugin.monitor()`呼び出し

#### Step 2: ユーティリティを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | profiler_client.py | `tensorflow/python/profiler/profiler_client.py` | `_strip_prefix()`と`_strip_addresses()`関数（173-178行目） |

**主要処理フロー**:
- **173-174行目**: `_strip_prefix` - "grpc://"プレフィックスの除去
- **177-178行目**: `_strip_addresses` - カンマ区切りアドレスの各要素からプレフィックス除去

**読解のコツ**: trace()内では`_strip_addresses()`が使われ複数アドレスを処理するが、monitor()内では`_strip_prefix()`が使われ単一アドレスのみ処理する点に注目。

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

```
tf.profiler.experimental.client.trace(service_addr, logdir, duration_ms, ...)
    │
    ├─ バリデーション: duration_ms > 0
    ├─ _strip_addresses(service_addr, "grpc://")
    │      └─ _strip_prefix(addr, "grpc://") x N
    ├─ options._asdict() → dict
    └─ _pywrap_profiler_plugin.trace(
           stripped_addrs, logdir, worker_list,
           True, duration_ms, num_tracing_attempts, opts)

tf.profiler.experimental.client.monitor(service_addr, duration_ms, level)
    │
    ├─ _strip_prefix(service_addr, "grpc://")
    └─ _pywrap_profiler_plugin.monitor(
           stripped_addr, duration_ms, level, True)
```

### データフロー図

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

service_addr (grpc://...)  ───▶  _strip_addresses()         ───▶  正規化アドレス
logdir                     ───▶
duration_ms                ───▶  _pywrap_profiler_plugin     ───▶  gRPCリクエスト送信
options                    ───▶  .trace()                         │
                                                                  ▼
                                 gRPCプロファイラサーバー     ───▶  プロファイルデータ
                                                                  → logdir保存
                                                                  → TensorBoard

service_addr               ───▶  _pywrap_profiler_plugin     ───▶  パフォーマンス
duration_ms                ───▶  .monitor()                        サマリー文字列
level                      ───▶
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| profiler_client.py | `tensorflow/python/profiler/profiler_client.py` | ソース | trace/monitor クライアントAPI |
| _pywrap_profiler_plugin.py | `tensorflow/python/profiler/internal/_pywrap_profiler_plugin.py` | バインディング | C++プロファイラプラグインのPythonバインディング |
| profiler_v2.py | `tensorflow/python/profiler/profiler_v2.py` | ソース | ProfilerOptionsの定義元 |
