# 画面設計書 12-デリゲート性能ベンチマーク（レイテンシ）画面

## 概要

本ドキュメントは、TFLite Benchmarkツールアプリにおける「デリゲート性能ベンチマーク（レイテンシ）画面」（BenchmarkLatencyActivity）の画面設計書である。本画面はIntent経由でTFLite設定ファイルと引数を受け取り、各種デリゲートのレイテンシベンチマークを実行するUIなしのActivityである。

### 本画面の処理概要

**業務上の目的・背景**：TensorFlow Liteのデリゲート（GPU、NNAPI、Hexagonなど）の推論レイテンシ性能を比較・評価するためのベンチマークツールである。デリゲート開発者やモデル最適化エンジニアが、異なるアクセラレーション設定間のレイテンシ差異を定量的に計測し、PASS/PASS_WITH_WARNING/FAILの判定結果を得ることを目的とする。TFLite Benchmark Toolベースのレイテンシ測定を実行し、CSV・JSON・HTMLの3形式でレポートを出力する。

**画面へのアクセス方法**：本Activityは`android:noHistory="true"`が設定されたUIなしのActivityであり、adbコマンドまたは外部アプリケーションからIntent経由で起動する。`--tflite_settings_files`キーでTFLiteSettings JSONファイルパスの配列を、`--args`キーで追加引数の配列を渡す。

**主要な操作・処理内容**：
1. Intent Bundleから`--tflite_settings_files`キーでTFLiteSettings JSONファイルパス配列を取得する
2. Intent Bundleから`--args`キーで追加引数配列を取得する（オプション）
3. BenchmarkLatencyImplインスタンスを生成し、initialize()で結果フォルダ作成とデフォルトレイテンシ基準のロードを行う
4. benchmark()でassetsフォルダ内の.tfliteモデルファイルに対してレイテンシベンチマークを実行する
5. 各モデル・各デリゲート設定について、startup overhead latencyとaverage inference latencyを計測する
6. 結果をCSV・JSON・HTMLの3形式で`delegate_performance_result/latency/`に出力する
7. finish()でActivityを終了する

**画面遷移**：外部Intent（adbまたはアプリ）から起動され、ベンチマーク完了後にfinish()で自動終了する。他の画面への遷移は存在しない。

**権限による表示制御**：UIが存在しないため表示制御はない。`READ_EXTERNAL_STORAGE`と`WRITE_EXTERNAL_STORAGE`権限がモデルファイル読み込みと結果出力に必要である。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 81 | TFLite推論エンジン | 主機能 | BenchmarkLatencyImplを通じてTFLite Benchmark Toolベースのレイテンシベンチマークを実行 |
| 82 | TFLiteデリゲート | 主機能 | TFLite設定ファイル経由で各種デリゲートのレイテンシ性能を計測・比較 |

## 画面種別

UIなし（バックグラウンド処理）。noHistory指定。

## URL/ルーティング

- パッケージ名: `org.tensorflow.lite.benchmark.delegateperformance`
- Activity名: `.BenchmarkLatencyActivity`
- Intent起動: `adb shell am start -n org.tensorflow.lite.benchmark.delegateperformance/.BenchmarkLatencyActivity --esa --tflite_settings_files "/path/to/settings1.json,/path/to/settings2.json" --esa --args "--num_threads=4"`

## 入出力項目

| 項目名 | 型 | I/O | 必須 | 説明 |
|--------|-----|-----|------|------|
| --tflite_settings_files | String[] (Bundle Extra) | 入力 | はい | TFLiteSettings JSONファイルパスの配列。デリゲート設定を定義する |
| --args | String[] (Bundle Extra) | 入力 | いいえ | 追加のベンチマーク引数配列。nullの場合は空配列として扱われる |
| report.csv | ファイル | 出力 | - | delegate_performance_result/latency/にCSV形式のパフォーマンスレポートを出力 |
| report.json | ファイル | 出力 | - | delegate_performance_result/latency/に詳細パフォーマンス結果をJSON形式で出力 |
| report.html | ファイル | 出力 | - | delegate_performance_result/latency/にHTML形式のパフォーマンスレポートを出力 |
| ログ出力 | Logcat | 出力 | - | TAG `TfLiteBenchmarkLatency` / `TfLiteLatencyImpl` でベンチマーク進行と結果をログ出力 |

## 表示項目

UIなしのため表示項目は存在しない。ベンチマーク結果はファイルおよびLogcatに出力される。

## イベント仕様

### 1-Activity起動（onCreate）

1. `getIntent().getExtras()`でBundleを取得する
2. Bundleから`--tflite_settings_files`キーでString配列を取得する
3. Bundleから`--args`キーでString配列を取得する
4. BenchmarkLatencyImplインスタンスを生成する（context、tfliteSettingsJsonFiles、argsを渡す）
5. `impl.initialize()`を呼び出す
   - tfliteSettingsJsonFilesのnull/空チェックを行う
   - `delegate_performance_result/latency/`に結果フォルダを作成する
   - JsonWriter、CsvWriter、HtmlWriterをBenchmarkReportに追加する
   - `proto/default_latency_criteria.binarypb`からデフォルトレイテンシ基準をロードする
6. 初期化成功時に`impl.benchmark()`を呼び出す
   - TFLiteSettings JSONファイルをロードし、TfLiteSettingsListEntryリストを構築する（デフォルトデリゲートが先頭に追加される）
   - assetsの`latency/`フォルダ内の各.tfliteモデルに対してベンチマークを実行する
   - 各モデルについて、モデル固有のレイテンシ基準をロード（なければデフォルトにフォールバック）する
   - DelegatePerformanceBenchmark.runLatencyBenchmark()でネイティブレイヤーのベンチマークを実行する
   - LatencyBenchmarkReportで結果を解析し、ModelBenchmarkReportを生成する
   - 全モデルの結果を集約し、CSV・JSON・HTMLレポートをエクスポートする
7. 初期化失敗時はエラーログを出力する
8. `finish()`でActivityを終了する

## データベース更新仕様

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

本画面はデータベース操作を行わない。

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

## メッセージ仕様

| メッセージID | レベル | メッセージ内容 | 出力条件 |
|-------------|--------|--------------|---------|
| M-01 | INFO | "Create benchmark latency activity." | Activity起動時 |
| M-02 | INFO | "Running latency benchmark with model: {name}, settings: {path}, args: {args}" | 各モデル・設定の組み合わせでベンチマーク実行時 |
| M-03 | INFO | "Latency benchmark result for {target}: {result}" | ベンチマーク完了時にテストターゲットの結果を出力 |
| M-04 | ERROR | "Failed to initialize the latency benchmarking." | 初期化失敗時 |
| M-05 | ERROR | "No TFLiteSettings file provided." | tfliteSettingsJsonFilesがnullまたは空の場合 |
| M-06 | ERROR | "Failed to create result folder latency in files directory." | 結果フォルダ作成失敗時 |
| M-07 | ERROR | "Failed to load default latency criteria default_latency_criteria" | デフォルトレイテンシ基準ロード失敗時 |

## 例外処理

| 例外 | 発生条件 | 処理 |
|------|---------|------|
| IOException | 結果フォルダ作成失敗 | initialize()がfalseを返し、ベンチマーク未実行でfinish() |
| IOException | デフォルトレイテンシ基準ファイルのロード失敗 | initialize()がfalseを返し、ベンチマーク未実行でfinish() |
| IOException | assetsフォルダからのモデルファイル一覧取得失敗 | benchmark()が早期リターンし、finish() |
| IOException | モデルファイルのオープン失敗 | 該当モデルのベンチマークをスキップし、次のモデルに進む |

## 備考

- 本Activityは`android:noHistory="true"`が設定されており、タスク履歴に残らない
- minSdkVersion: 23、targetSdkVersion: 33
- レイテンシベンチマークの判定メトリクスは以下の2種類：
  - startup overhead latency = 初期化時間 + 平均ウォームアップ時間 - 平均推論時間
  - average inference latency = ベンチマーク実行中の推論の平均時間
- TfLiteSettingsListEntryリストは、テストターゲットデリゲートがリスト末尾に配置される（システムレベル初期化の影響を回避するため）
- デフォルトデリゲート（CPU）が常に参照用として先頭に追加される
- ネイティブライブラリ: `delegate_performance_benchmark`

---

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

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

### 推奨読解順序

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

本画面で扱う主要なデータ構造は、TFLiteSettings JSONファイル、レイテンシ基準（LatencyCriteria）、およびベンチマーク結果（LatencyResults）である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AndroidManifest.xml | `tensorflow/lite/tools/benchmark/experimental/delegate_performance/android/AndroidManifest.xml` | Activity宣言、noHistory=true、READ/WRITE_EXTERNAL_STORAGE権限、SDK version設定を確認（18-55行目） |

**読解のコツ**: AndroidManifest.xmlでBenchmarkLatencyActivityとBenchmarkAccuracyActivityが同一アプリ内で宣言されていることを把握する。

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

BenchmarkLatencyActivityのonCreateがエントリーポイントである。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | BenchmarkLatencyActivity.java | `tensorflow/lite/tools/benchmark/experimental/delegate_performance/android/src/main/java/org/tensorflow/lite/benchmark/delegateperformance/BenchmarkLatencyActivity.java` | onCreate内でIntent解析→BenchmarkLatencyImpl生成→initialize()→benchmark()→finish()のフローを確認（38-55行目） |

**主要処理フロー**:
1. **39行目**: ログ出力 "Create benchmark latency activity."
2. **42行目**: `Intent intent = getIntent()` でIntentを取得
3. **44行目**: `--tflite_settings_files`キーでString[]を取得
4. **45行目**: `--args`キーでString[]を取得
5. **47-48行目**: BenchmarkLatencyImplインスタンスを生成
6. **49行目**: `impl.initialize()`で初期化
7. **50行目**: 初期化成功時に`impl.benchmark()`を実行
8. **54行目**: `finish()`でActivity終了

#### Step 3: 実装クラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | BenchmarkLatencyImpl.java | `tensorflow/lite/tools/benchmark/experimental/delegate_performance/android/src/main/java/org/tensorflow/lite/benchmark/delegateperformance/BenchmarkLatencyImpl.java` | initialize()での結果フォルダ作成とレイテンシ基準ロード（91-118行目）、benchmark()でのモデル反復ベンチマーク実行とレポートエクスポート（121-149行目）を確認 |

**主要処理フロー**:
- **91-118行目**: initialize() - 結果フォルダ作成、JSON/CSV/HTMLライター追加、デフォルトレイテンシ基準ロード
- **121-149行目**: benchmark() - TfLiteSettings読み込み、assetsからモデルリスト取得、モデルごとにベンチマーク実行、レポートエクスポート
- **157-187行目**: benchmarkModel() - 個別モデルのベンチマーク実行、各デリゲート設定でrunLatencyBenchmark()を呼び出し

#### Step 4: ネイティブブリッジを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | DelegatePerformanceBenchmark.java | `tensorflow/lite/tools/benchmark/experimental/delegate_performance/android/src/main/java/org/tensorflow/lite/benchmark/delegateperformance/DelegatePerformanceBenchmark.java` | ネイティブライブラリロード（42-44行目）、runLatencyBenchmark()でのJNI呼び出しとLatencyResultsの解析（73-114行目）、TfLiteSettingsリスト構築ロジック（142-176行目）を確認 |

**主要処理フロー**:
- **42-44行目**: 静的初期化子で`delegate_performance_benchmark`ネイティブライブラリをロード
- **73-114行目**: runLatencyBenchmark() - TfLiteSettingsのバイト配列変換、latencyBenchmarkNativeRun()のJNI呼び出し、LatencyResultsの解析
- **142-176行目**: loadTfLiteSettingsList() - デフォルトデリゲートを先頭に追加、テストターゲットをリスト末尾に配置（逆順で追加）

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

```
BenchmarkLatencyActivity.onCreate()
    |
    +-- getIntent().getExtras()                    [Intent引数取得]
    |
    +-- new BenchmarkLatencyImpl(context, files, args)
    |
    +-- BenchmarkLatencyImpl.initialize()
    |       |
    |       +-- DelegatePerformanceBenchmark.createResultFolder()
    |       +-- JsonWriter.create() / CsvWriter.create() / HtmlWriter.create()
    |       +-- loadLatencyCriteria()               [デフォルト基準ロード]
    |
    +-- BenchmarkLatencyImpl.benchmark()
    |       |
    |       +-- DelegatePerformanceBenchmark.loadTfLiteSettingsList()
    |       |       +-- loadTfLiteSettingsJsonNative()   [JNI]
    |       |
    |       +-- benchmarkModel() [for each .tflite]
    |       |       |
    |       |       +-- tryLoadLatencyCriteria()
    |       |       +-- DelegatePerformanceBenchmark.runLatencyBenchmark()
    |       |       |       +-- latencyBenchmarkNativeRun()   [JNI]
    |       |       +-- LatencyBenchmarkReport.parseResults()
    |       |       +-- LatencyBenchmarkReport.create()
    |       |
    |       +-- report.export()                     [CSV/JSON/HTMLレポート出力]
    |
    +-- finish()                                    [Activity終了]
```

### データフロー図

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

Intent Bundle              -->  BenchmarkLatencyActivity        -->  Logcat (TAG: TfLiteBenchmarkLatency)
  --tflite_settings_files        .onCreate()
  --args                             |
                                BenchmarkLatencyImpl
                                     |
assets/latency/*.tflite    -->  .benchmark()                    -->  delegate_performance_result/latency/
                                     |                                  report.csv
proto/*.binarypb           -->  .initialize()                          report.json
  (latency criteria)                 |                                  report.html
                                DelegatePerformanceBenchmark
                                .runLatencyBenchmark() [JNI]    -->  LatencyResults (proto)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| BenchmarkLatencyActivity.java | `tensorflow/lite/tools/benchmark/experimental/delegate_performance/android/src/main/java/org/tensorflow/lite/benchmark/delegateperformance/BenchmarkLatencyActivity.java` | ソース | メインActivity。Intent解析とBenchmarkLatencyImplへの処理委譲 |
| BenchmarkLatencyImpl.java | `tensorflow/lite/tools/benchmark/experimental/delegate_performance/android/src/main/java/org/tensorflow/lite/benchmark/delegateperformance/BenchmarkLatencyImpl.java` | ソース | レイテンシベンチマーク実装。初期化・ベンチマーク実行・レポート生成 |
| DelegatePerformanceBenchmark.java | `tensorflow/lite/tools/benchmark/experimental/delegate_performance/android/src/main/java/org/tensorflow/lite/benchmark/delegateperformance/DelegatePerformanceBenchmark.java` | ソース | ネイティブJNIブリッジ、TfLiteSettingsロード、結果フォルダ管理 |
| AndroidManifest.xml | `tensorflow/lite/tools/benchmark/experimental/delegate_performance/android/AndroidManifest.xml` | 設定 | Activity宣言、権限、SDK version設定 |
