# 画面設計書 10-OVICベンチマーク画面

## 概要

本ドキュメントは、OVIC BenchmarkアプリにおけるOvicBenchmarkerActivity（OVICベンチマーク画面）の画面設計書である。On-device Visual/Image Classification (OVIC) のベンチマークを実行し、推論時間や精度をTextViewに表示する画面について記述する。

### 本画面の処理概要

**業務上の目的・背景**：TensorFlow Liteモデルのオンデバイス推論性能をベンチマーク計測するために本画面が必要である。OVIC（On-device Visual/Image Classification）コンペティションに向けて、画像分類モデルと物体検出モデルの推論速度（平均レイテンシ）を計測・表示する目的で設計されている。テスト画像を反復的に推論し、Wall Time（3000ms）または最大イテレーション数（100回）に達するまでベンチマークを実行する。

**画面へのアクセス方法**：Androidランチャーから直接起動される。ランチャーActivityとして登録されている。

**主要な操作・処理内容**：
1. 分類ベンチマーク（classifyPressedボタン）: OvicClassifierBenchmarkerによる量子化モデルの分類推論ベンチマーク
2. 検出ベンチマーク（detectPressedボタン）: OvicDetectorBenchmarkerによる検出モデルの検出推論ベンチマーク
3. テスト画像（test_image_224.jpg）の読み込み・デコード
4. CPUアフィニティの設定（BIG_CORE_MASK=16でビッグコアにバインド）
5. 反復推論実行（Wall Time 3000ms / 最大100イテレーション）
6. 平均レイテンシの計算・TextViewへの表示

**画面遷移**：Androidランチャーから起動される。他の画面への遷移機能は持たない。

**権限による表示制御**：特別な権限は不要（カメラ不使用、assetsファイルのみ使用）。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 81 | TFLite推論エンジン | 主機能 | OvicClassifierBenchmarker/OvicDetectorBenchmarkerを通じてTFLiteモデルのベンチマーク推論を反復実行 |
| 80 | TFLiteモデル変換 | 補助機能 | quantized_model.lite / detect.liteのTFLite形式モデルファイルを読み込み |
| 52 | 画像変換操作（Image Operations） | 補助機能 | テスト画像（test_image_224.jpg）のデコード・Bitmap変換を実行 |

## 画面種別

ベンチマーク実行画面（ボタン操作＋結果表示）

## URL/ルーティング

Androidネイティブアプリのため、URLベースのルーティングは存在しない。パッケージ: `ovic.demo.app`、クラス: `OvicBenchmarkerActivity`。

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 説明 |
|--------|----------|---------|------|
| ベンチマークタイプ選択 | 入力 | ボタン押下 | classifyPressed（分類）/ detectPressed（検出） |
| モデルファイル | 入力 | MappedByteBuffer | assetsからメモリマップされたTFLiteモデル |
| ラベルファイル | 入力 | InputStream | assetsのラベルテキストファイル |
| テスト画像 | 入力 | Bitmap | test_image_224.jpgのデコード済みBitmap |
| ベンチマーク結果 | 出力 | String | モデルパス、平均レイテンシ（ms）、イテレーション数 |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|---------|------|
| 結果テキスト | TextView (textView) | ベンチマーク結果（モデル名、平均レイテンシ、イテレーション数） |
| 分類ボタン | Button (classifyPressed) | 分類ベンチマーク開始ボタン（onClick: classifyPressed） |
| 検出ボタン | Button (detectPressed) | 検出ベンチマーク開始ボタン（onClick: detectPressed） |

## イベント仕様

### 1-分類ベンチマーク実行イベント（classifyPressed）

classifyPressedボタン（onClick属性）押下時に発火する。

処理フロー:
1. benchmarkSession(true)を呼び出し
2. initializeTest(true): OvicClassifierBenchmarkerを生成、labelPath="labels.txt"、testImagePath="test_image_224.jpg"、modelPath="quantized_model.lite"を設定
3. AssetFileDescriptorからMappedByteBufferにモデルを読み込み
4. setProcessorAffinity(BIG_CORE_MASK=16)でCPUアフィニティを設定
5. ループ: MAX_ITERATIONS(100)回まで、doTestIteration()を反復
6. doTestIteration(): benchmarker.shouldStop()チェック→benchmarker.getReadyToTest()→loadTestBitmap()→benchmarker.processBitmap()
7. テキスト表示: "Classification benchmark: {modelPath}: Average latency={avg}ms after {iter} runs."

### 2-検出ベンチマーク実行イベント（detectPressed）

detectPressedボタン（onClick属性）押下時に発火する。

処理フロー:
1. benchmarkSession(false)を呼び出し
2. initializeTest(false): OvicDetectorBenchmarkerを生成、labelPath="coco_labels.txt"、testImagePath="test_image_224.jpg"、modelPath="detect.lite"
3. 以降は分類ベンチマークと同様のフロー

### 3-CPUアフィニティ設定

setProcessorAffinity(mask)でtasksetコマンドを実行し、プロセスを指定CPUコアにバインドする。設定後は/proc/self/statusからCpus_allowedを読み取って確認する。

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

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

本画面はデータベースを使用しない。

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

## メッセージ仕様

| メッセージID | メッセージ内容 | 種別 | 表示条件 |
|-------------|--------------|------|---------|
| MSG-01 | "{type} benchmark: {model}: Average latency={avg}ms after {iter} runs." | 情報 | ベンチマーク正常完了時 |
| MSG-02 | "Benchmarker failed to run on more than one images." | エラー | ベンチマーク実行回数が0の場合 |
| MSG-03 | CPUアフィニティ設定失敗メッセージ | 警告 | tasksetコマンド実行失敗時 |

## 例外処理

| 例外状態 | 処理内容 |
|---------|---------|
| モデルファイル読み込み失敗（IOException） | Log.e()でエラーログ出力、例外を再スロー |
| ベンチマーク未初期化でのdoTestIteration() | RuntimeException("Benchmarker has not been initialized.")をスロー |
| getReadyToTest()失敗 | RuntimeException("Failed to get the benchmarker ready.")をスロー |
| processBitmap()失敗 | RuntimeException("Failed to run test.")をスロー |
| CPUアフィニティ設定失敗 | IOExceptionをスロー、メッセージに失敗理由を表示 |
| InterruptedException | displayTextにメッセージ追記、ベンチマーク継続 |

## 備考

- WALL_TIME: 3000ms（ベンチマーク実行の最大壁時間）
- MAX_ITERATIONS: 100（最大イテレーション回数）
- BIG_CORE_MASK: 16（Pixel 2のビッグコア用マスク）
- WAIT_TIME_FOR_AFFINITY: 1000ms
- 分類用モデル: `quantized_model.lite`、ラベル: `labels.txt`
- 検出用モデル: `detect.lite`、ラベル: `coco_labels.txt`
- テスト画像: `test_image_224.jpg`
- レイテンシ計算: getTotalRuntimeNano() * 1.0e-6 / iterCount (ナノ秒→ミリ秒変換)
- レイアウト: `activity_main.xml`
- CPUアフィニティ: Runtime.exec("taskset -a -p {mask} {pid}")で設定（root権限要）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | OvicBenchmarker.java | `tensorflow/lite/java/ovic/src/main/java/org/tensorflow/ovic/OvicBenchmarker.java` | shouldStop(), readyToTest(), getReadyToTest(), processBitmap(), getLastResultString(), getTotalRuntimeNano()の各メソッド |

**読解のコツ**: OvicBenchmarkerはabstractクラスで、OvicClassifierBenchmarkerとOvicDetectorBenchmarkerが具体実装。WALL_TIMEはコンストラクタ引数として渡される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | OvicBenchmarkerActivity.java | `tensorflow/lite/java/ovic/demo/app/OvicBenchmarkerActivity.java` | onCreate()（75-81行目）: シンプルなUI初期化 |
| 2-2 | OvicBenchmarkerActivity.java | 同上 | benchmarkSession()（154-207行目）: ベンチマーク実行のメインフロー |

**主要処理フロー**:
1. **77行目**: setContentView(R.layout.activity_main)
2. **80行目**: textView取得
3. **154-160行目**: initializeTest()呼び出し（分類/検出の切り替え）
4. **168-172行目**: setProcessorAffinity(BIG_CORE_MASK)
5. **176-190行目**: ベンチマークループ（MAX_ITERATIONS回）
6. **193-206行目**: 結果テキスト生成・TextView表示

#### Step 3: ベンチマーク初期化を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | OvicBenchmarkerActivity.java | 同上 | initializeTest()（88-109行目）: OvicBenchmarker生成、モデルファイルのメモリマップ読み込み |
| 3-2 | OvicBenchmarkerActivity.java | 同上 | doTestIteration()（111-144行目）: 1回のテスト実行（shouldStop→getReadyToTest→processBitmap） |

#### Step 4: CPUアフィニティ設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | OvicBenchmarkerActivity.java | 同上 | setProcessorAffinity()（211-245行目）: tasksetコマンドでCPUバインド、readCpusAllowedMask()で確認 |

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

```
OvicBenchmarkerActivity (extends Activity)
    |
    +-- onCreate()
    |       +-- setContentView(activity_main)
    |       +-- textView取得
    |
    +-- classifyPressed() / detectPressed()
            +-- benchmarkSession(isClassification)
                    +-- initializeTest(isClassification)
                    |       +-- OvicClassifierBenchmarker() / OvicDetectorBenchmarker()
                    |       +-- AssetFileDescriptor → MappedByteBuffer
                    |
                    +-- setProcessorAffinity(BIG_CORE_MASK)
                    |       +-- Runtime.exec("taskset ...")
                    |       +-- readCpusAllowedMask() [確認]
                    |
                    +-- [ループ] doTestIteration()
                    |       +-- benchmarker.shouldStop()
                    |       +-- benchmarker.getReadyToTest()
                    |       +-- loadTestBitmap()
                    |       +-- benchmarker.processBitmap()
                    |
                    +-- textView.setText(結果)
```

### データフロー図

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

ボタン押下 -------> initializeTest ------> OvicBenchmarker生成
(classify/detect)  (モデル/ラベル設定)     (Classifier/Detector)
                                                  |
テスト画像 -------> loadTestBitmap ------> Bitmap デコード
(test_image_224.jpg) (BitmapFactory)              |
                                                  v
モデルファイル ----> MappedByteBuffer ----> benchmarker.processBitmap()
(.lite)            (FileChannel.map)       [MAX_ITERATIONS回 or WALL_TIME]
                                                  |
                                                  v
                                          getTotalRuntimeNano()
                                                  |
                                          平均レイテンシ計算
                                                  |
                                          TextView表示
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| OvicBenchmarkerActivity.java | `tensorflow/lite/java/ovic/demo/app/OvicBenchmarkerActivity.java` | ソース | ベンチマーク画面のメインActivity |
| OvicBenchmarker.java | `tensorflow/lite/java/ovic/src/main/java/org/tensorflow/ovic/OvicBenchmarker.java` | ソース | ベンチマーカー抽象基底クラス |
| OvicClassifierBenchmarker.java | `tensorflow/lite/java/ovic/src/main/java/org/tensorflow/ovic/OvicClassifierBenchmarker.java` | ソース | 分類ベンチマーカー |
| OvicDetectorBenchmarker.java | `tensorflow/lite/java/ovic/src/main/java/org/tensorflow/ovic/OvicDetectorBenchmarker.java` | ソース | 検出ベンチマーカー |
| activity_main.xml | `tensorflow/lite/java/ovic/demo/app/res/layout/activity_main.xml` | レイアウト | ベンチマーク画面レイアウト |
| quantized_model.lite | `assets/quantized_model.lite` | モデル | 量子化分類モデル |
| detect.lite | `assets/detect.lite` | モデル | 検出モデル |
| test_image_224.jpg | `assets/test_image_224.jpg` | データ | テスト用画像 |
| labels.txt | `assets/labels.txt` | データ | 分類ラベルファイル |
| coco_labels.txt | `assets/coco_labels.txt` | データ | 検出ラベルファイル |
