# 機能設計書 16-Memory（メモリバッファ）

## 概要

本ドキュメントは、Julia言語におけるMemory（メモリバッファ）機能の設計を記述する。GenericMemory / Memory / AtomicMemoryによる低レベルメモリバッファ管理を提供する。

### 本機能の処理概要

GenericMemory{kind, T, addrspace}はJulia 1.11で導入された固定サイズのDenseVectorであり、ArrayやBigFloat等の内部バッファとして使用される低レベルメモリ管理プリミティブである。:not_atomicと:atomicの2つのモードを提供し、スレッドセーフなメモリアクセスも可能にする。

**業務上の目的・背景**：Julia 1.11以前はArrayが直接メモリバッファを管理していたが、Julia 1.11でMemory型が導入され、メモリバッファ管理と配列インタフェースの責務が分離された。これにより、ArrayのリサイズやBigFloatのインライン格納など、異なるデータ構造が同一のメモリバッファ基盤を共有できるようになった。AtomicMemoryは並行プログラミングでのロックフリーデータ構造の基盤を提供する。

**機能の利用シーン**：（1）Arrayの内部バッファとしての使用、（2）BigFloatのインラインデータ格納、（3）アトミック操作が必要な並行データ構造の基盤、（4）低レベルのメモリ操作（unsafe_wrap等）、（5）GPUメモリなどの拡張アドレス空間対応。

**主要な処理内容**：
1. GenericMemory{kind, T, addrspace}型定義（Core定義のビルトイン型）
2. Memory{T} = GenericMemory{:not_atomic, T, Core.CPU} 型エイリアス
3. AtomicMemory{T} = GenericMemory{:atomic, T, Core.CPU} 型エイリアス
4. GenericMemoryRef参照型によるポインタベースのアクセス
5. memoryindex/memoryrefによるインデックス操作
6. _unsetindex!によるメモリスロットの未初期化化
7. アトミックアクセス関数（getindex_atomic, setindex_atomic!等）

**関連システム・外部連携**：Cランタイム（src/genericmemory.c）でのメモリ割り当て。Core.AddrSpaceによるGPU等の拡張アドレス空間対応設計。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 直接的な画面関連なし（内部基盤機能） |

## 機能種別

データ管理（低レベルメモリバッファ）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| T | Type | Yes | 要素型 | - |
| n | Integer | Yes | 要素数 | 0以上 |
| kind | Symbol | No | :not_atomic または :atomic | 2値のみ |

### 入力データソース

Julia内部でのメモリ確保要求。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| memory | GenericMemory{kind,T,addrspace} | 確保されたメモリバッファ |
| ref | GenericMemoryRef | メモリ参照 |

### 出力先

GC管理下のヒープメモリ。

## 処理フロー

### 処理シーケンス

```
1. Memory確保
   └─ Core内部でメモリ割り当て → GC管理下に配置
2. 要素アクセス
   └─ memoryrefでGenericMemoryRefを生成 → getindex/setindex!
3. アトミックアクセス（AtomicMemory）
   └─ getindex_atomic / setindex_atomic! で:monotonicオーダーリングアクセス
4. 未初期化化
   └─ _unsetindex!でスロットを未定義状態に戻す
```

### フローチャート

```mermaid
flowchart TD
    A[Memory確保要求] --> B{kind?}
    B -->|:not_atomic| C[Memory{T}(undef, n)]
    B -->|:atomic| D[AtomicMemory{T}(undef, n)]
    C --> E[GCヒープに確保]
    D --> E
    E --> F{アクセス方法}
    F -->|通常| G[getindex/setindex!]
    F -->|アトミック| H[getindex_atomic/setindex_atomic!]
    F -->|参照| I[memoryref → GenericMemoryRef]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 固定サイズ | Memoryは生成後にサイズ変更不可 | 全Memory操作 |
| BR-02 | アトミック保証 | AtomicMemoryの個別要素アクセスはアトミック | :atomic kind |
| BR-03 | デフォルトモノトニック | AtomicMemoryのデフォルトオーダーリングは:monotonic | getindex_atomic |
| BR-04 | IndexLinear | GenericMemoryはIndexLinearスタイル | インデックスアクセス |
| BR-05 | CPU限定 | 現状ではaddrspace=Core.CPUのみサポート | Julia 1.11時点 |

### 計算ロジック

- memoryrefoffset: GenericMemoryRefからインデックスオフセットを取得
- datatype_arrayelem/datatype_layoutsize: 型レベルの要素配置情報取得
- _unsetindex!: 要素型がポインタ含有かどうかで処理分岐

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | BoundsError | インデックスが範囲外 | 有効なインデックスを使用 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 固定サイズによりリサイズオーバーヘッドなし
- GenericMemoryRefによるポインタベースアクセスで間接参照を最小化
- AtomicMemoryは:monotonicオーダーリングで最小限の同期コスト

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

- AtomicMemoryの並行アクセスは@atomicマクロまたは低レベルインタフェース関数を使用すること
- Memory{T}への並行書き込みはスレッドセーフではない
- unsafe_wrap等で外部メモリをラップする場合はライフタイム管理に注意

## 備考

- Julia 1.11で導入された新しい型
- AtomicMemoryの低レベルインタフェースはJulia 1.12で追加
- アドレス空間（addrspace）はGPU等のバックエンドによる拡張を想定した設計

---

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

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

### 推奨読解順序

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

GenericMemory/Memory/AtomicMemoryの型定義と基本概念。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | genericmemory.jl | `base/genericmemory.jl` | GenericMemory{kind,T,addrspace}の型ドキュメント（5-24行目） |
| 1-2 | genericmemory.jl | `base/genericmemory.jl` | Memory{T}型エイリアス（27-34行目） |
| 1-3 | genericmemory.jl | `base/genericmemory.jl` | AtomicMemory{T}型エイリアス（36-58行目） |

**読解のコツ**: GenericMemoryはCore定義のビルトイン型で、3つの型パラメータ（kind: Symbol, T: 要素型, addrspace）を持つ。Memory{T}とAtomicMemory{T}はそのエイリアス。

#### Step 2: 基本操作を理解する

インデックスアクセスとメモリ参照。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | genericmemory.jl | `base/genericmemory.jl` | IndexStyle, parent, memoryindex（64-88行目） |
| 2-2 | genericmemory.jl | `base/genericmemory.jl` | _unsetindex!の実装（91-100行目） |

**主要処理フロー**:
- **64行目**: IndexStyle(::Type{<:GenericMemory}) = IndexLinear()
- **66行目**: parent(ref::GenericMemoryRef) = ref.mem
- **87行目**: memoryindex(ref) = memoryrefoffset(ref) で1-basedインデックス取得
- **91-100行目**: _unsetindex!で要素スロットの未初期化化

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

```
Memory{T}(undef, n)
    |
    +-- Core内部メモリ割り当て [GCヒープ]
    |
    +-- getindex(mem, i)
    |       +-- @boundscheck
    |       +-- memoryref(mem, i) → GenericMemoryRef
    |
    +-- memoryref(mem, i)
    |       +-- GenericMemoryRef(mem, i)
    |
    +-- _unsetindex!(mem, i)
            +-- memoryref(mem, i)
            +-- datatype_arrayelem / datatype_layoutsize
            +-- memset / atomic_pointerset
```

### データフロー図

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

Type T, size n   ──────> Core メモリ割り当て     ──────> Memory{T}
Memory, index    ──────> memoryref → getindex    ──────> 要素 T
Memory, val, idx ──────> memoryref → setindex!   ──────> Memory（変更済み）
AtomicMemory, i  ──────> getindex_atomic(:mono)  ──────> 要素 T（アトミック読み取り）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| genericmemory.jl | `base/genericmemory.jl` | ソース | GenericMemory/Memory/AtomicMemory型定義と基本操作 |
| array.jl | `base/array.jl` | ソース | ArrayがMemoryを内部バッファとして使用 |
| mpfr.jl | `base/mpfr.jl` | ソース | BigFloatがMemory{Limb}をインラインデータ格納に使用 |
| atomics.jl | `base/atomics.jl` | ソース | @atomicマクロによるAtomicMemoryアクセス |
| src/genericmemory.c | `src/genericmemory.c` | Cソース | メモリ割り当てのCランタイム実装 |
