# 機能設計書 13-高速数学演算（FastMath）

## 概要

本ドキュメントは、Julia言語における高速数学演算（FastMath）機能の設計を記述する。@fastmathマクロにより、IEEE 754の厳密なセマンティクスを緩和した高速な数学演算最適化を提供する。

### 本機能の処理概要

FastMathモジュールは、@fastmathマクロを通じて式中の数学演算関数をfast版に変換するメタプログラミング機能を提供する。LLVMのFast-Mathフラグ（nnan, ninf, nsz, arcp, fast）を活用し、コンパイラによる積極的な最適化を可能にする。

**業務上の目的・背景**：科学技術計算やシミュレーションでは、IEEE 754の厳密なNaN/Inf処理や符号付きゼロの区別が不要な場合がある。@fastmathはこれらの厳密性を緩和することで、コンパイラが再結合（reassociation）、逆数による除算置換、ベクトル化などの最適化を適用でき、大幅な性能向上を実現する。

**機能の利用シーン**：（1）大規模数値シミュレーションの内側ループの高速化、（2）NaN/Inf が発生しないことが保証されるデータ処理、（3）浮動小数点演算の再結合による精度と速度のトレードオフ、（4）SIMD最適化を最大限に活用したい場合。

**主要な処理内容**：
1. @fastmathマクロによる式変換（演算子をfast版に置換）
2. 基本算術演算のfast版（add_fast, sub_fast, mul_fast, div_fast等）
3. 比較演算のfast版（eq_fast, lt_fast, le_fast等）
4. 数学関数のfast版（sin_fast, cos_fast, exp_fast, log_fast等）
5. 複素数演算のfast版
6. リダクション演算のfast版（maximum_fast, minimum_fast）
7. 非数値型へのフォールバック（元の関数をそのまま呼び出し）
8. 型昇格付きの汎用ディスパッチ

**関連システム・外部連携**：LLVM Fast-Mathフラグに直接対応。Core.Intrinsicsの*_fast関数（sqrt_llvm_fast, add_float_fast等）を使用。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Juliaプロンプト（julia>） | 参照画面 | REPL上で@fastmath式を実行 |

## 機能種別

計算処理（最適化された数学演算）/ メタプログラミング（マクロによる式変換）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| expr | Expr | Yes | @fastmathに渡される式 | Julia式として有効であること |

### 入力データソース

Julia式からの直接入力。@fastmathマクロ呼び出し時にコンパイル時変換される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | Any | fast版演算の計算結果（元の演算と同じ型） |

### 出力先

演算結果は通常の式評価と同様にメモリ上に返却。

## 処理フロー

### 処理シーケンス

```
1. @fastmathマクロ展開
   └─ make_fastmath(expr)でAST変換
2. 演算子の置換
   └─ fast_opディクショナリで通常演算子をfast版にマッピング
3. 複合代入の書き換え
   └─ rewrite_opで+=, -=等を通常の代入+fast演算に変換
4. リテラル冪乗の特殊処理
   └─ x^n（nが整数リテラル）をpow_fast(x, Val(n))に変換
5. 実行時ディスパッチ
   └─ FloatTypes向けはLLVM intrinsics、その他は型昇格→フォールバック
```

### フローチャート

```mermaid
flowchart TD
    A["@fastmath expr"] --> B[make_fastmath AST変換]
    B --> C{式の種類}
    C -->|関数呼び出し :call| D[fast_opで演算子置換]
    C -->|複合代入 +=等| E[rewrite_opで書き換え]
    C -->|冪乗 x^n| F[pow_fast with Val]
    C -->|その他| G[再帰的に子ノードを変換]
    D --> H[fast版関数呼び出し]
    E --> H
    F --> H
    H --> I{引数の型}
    I -->|FloatTypes| J[LLVM fast intrinsics]
    I -->|ComplexTypes| K[fast版複素数演算]
    I -->|Number| L[型昇格後ディスパッチ]
    I -->|非数値型| M[元の関数にフォールバック]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | nnan | NaN引数・結果を仮定しない最適化を許可 | @fastmath内の全演算 |
| BR-02 | ninf | Inf引数・結果を仮定しない最適化を許可 | @fastmath内の全演算 |
| BR-03 | nsz | 符号付きゼロの区別を無視可能 | @fastmath内の全演算 |
| BR-04 | arcp | 除算を逆数乗算に置換可能 | @fastmath内の除算 |
| BR-05 | fast | 代数的等価変換（再結合等）を許可 | @fastmath内の全演算 |
| BR-06 | フォールバック | 非数値型では元の関数を呼び出す | 数値型以外の引数 |

### 計算ロジック

- fast_opディクショナリ：40以上の関数マッピング（+=>add_fast, sin=>sin_fast等）
- rewrite_opディクショナリ：+=, -=, *=, /=, ^= の5種を書き換え
- FloatTypes（Float16/Float32/Float64）向けはCore.Intrinsicsの*_float_fast関数を使用
- 複素数（ComplexF32/ComplexF64）向けは@fastmathブロック内で定義された専用実装
- isinf_fast(x) = false, isnan_fast(x) = false, isfinite_fast(x) = true の前提

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 未定義動作 | NaN/Infが実際に発生した場合の結果は未定義 | NaN/Infが発生しないデータで使用 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- LLVM Fast-Mathフラグにより、コンパイラが積極的な最適化（SIMD化、再結合、定数畳み込み）を適用可能
- Float16/Float32/Float64向けの算術演算はLLVM intrinsicsで直接実装（オーバーヘッドなし）
- 非数値型へのフォールバックは元の関数を直接呼び出すため追加コストなし

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

- NaN/Infの未定義動作により、入力データの事前検証が重要
- 暗号学的な浮動小数点演算では使用を避けること（定数時間実行が保証されない）

## 備考

- @fastmathはLLVMの-ffast-mathフラグに対応
- マクロ展開はコンパイル時に行われ、実行時オーバーヘッドなし
- exp2_fast, exp_fast, exp10_fastはBase.Math内の専用実装を使用

---

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

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

### 推奨読解順序

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

FastMathモジュールの設定テーブルを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | fastmath.jl | `base/fastmath.jl` | fast_opディクショナリ（35-93行目）：通常関数からfast版へのマッピング |
| 1-2 | fastmath.jl | `base/fastmath.jl` | rewrite_opディクショナリ（95-100行目）：複合代入演算子の書き換え |

**読解のコツ**: fast_opはDict{Symbol,Symbol}で40以上のマッピングを定義。これがmake_fastmathでのAST変換の核となる。

#### Step 2: マクロ展開（AST変換）を理解する

@fastmathマクロの式変換ロジック。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | fastmath.jl | `base/fastmath.jl` | make_fastmath(expr::Expr)（102-133行目）：AST再帰変換 |
| 2-2 | fastmath.jl | `base/fastmath.jl` | @fastmathマクロ定義（156-158行目） |

**主要処理フロー**:
1. **102-111行目**: :quoteは変換しない。:callで^演算子の整数リテラル冪乗をpow_fast+Valに変換
2. **112-123行目**: rewrite_opで複合代入を通常の代入+演算に書き換え
3. **124行目**: 子ノードに再帰的にmake_fastmathを適用
4. **126-132行目**: Symbol版make_fastmath：fast_opでシンボルを置換

#### Step 3: fast版演算の実装を理解する

LLVM intrinsicsとフォールバック実装。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | fastmath.jl | `base/fastmath.jl` | FloatTypes向けLLVM intrinsics（165-172行目） |
| 3-2 | fastmath.jl | `base/fastmath.jl` | 比較演算fast版（180-185行目） |
| 3-3 | fastmath.jl | `base/fastmath.jl` | NaN/Inf/subnormal判定の前提（187-190行目） |
| 3-4 | fastmath.jl | `base/fastmath.jl` | 複素数演算fast版（196-241行目） |
| 3-5 | fastmath.jl | `base/fastmath.jl` | フォールバック・型昇格（246-291行目） |

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

```
@fastmath expr
    |
    +-- make_fastmath(expr)           [AST変換]
    |       +-- fast_op[symbol]       [演算子マッピング]
    |       +-- rewrite_op[head]      [複合代入書き換え]
    |       +-- make_fastmath(子ノード) [再帰変換]
    |
    +-- add_fast(x, y)               [実行時ディスパッチ]
    |       +-- FloatTypes: add_float_fast(x, y)  [LLVM intrinsic]
    |       +-- ComplexTypes: T(real(x)+real(y), imag(x)+imag(y))
    |       +-- Number: promote → add_fast
    |       +-- Other: +(x, y)       [フォールバック]
    |
    +-- sin_fast(x)                  [数学関数]
            +-- FloatTypes: sin_fast(x)
            +-- Other: sin(x)        [フォールバック]
```

### データフロー図

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

@fastmath expr   ──────> make_fastmath(AST変換) ────────> 変換済みExpr
Float64 x, y     ──────> add_float_fast (LLVM) ────────> Float64 結果
ComplexF64 x, y  ──────> 手動fast版計算 ──────────────> ComplexF64 結果
Integer x, y     ──────> +(x, y) フォールバック ───────> Integer 結果
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| fastmath.jl | `base/fastmath.jl` | ソース | FastMathモジュール全体（マクロ定義、fast版関数、フォールバック） |
| math.jl | `base/math.jl` | ソース | exp2_fast, exp_fast, exp10_fastの実装 |
| essentials.jl | `base/essentials.jl` | ソース | Core.Intrinsicsの*_float_fast関数の定義元 |
