💻 Modül 6 · Yazılım Yığını · Bölüm 6.7 · 10 dk okuma

Derleyici: Model → Analog Mapping

FP32 ağırlıklarından crossbar adreslerine — SIDRA compiler'ın işi.

Bu bölümde öğreneceklerin

  • Compiler'ın 5 ana aşamasını (parse, quantize, map, optimize, emit) tanımla
  • Ağırlık matrisini crossbar'lara bölme stratejisini açıkla
  • Operator fusion, layer ordering, memory planning optimize'larını söyle
  • Compiler'ın gürültü, IR drop, termal modelini nasıl içerdiğini anla
  • Derleme süresi ve verilerini Y1 için tahmin et

Açılış: Yüksek Seviyeden Silikon Adresine

PyTorch model: FP32 tensor’lar, soyut operasyonlar. SIDRA donanım: her hücrenin kesin bir (cluster, CU, crossbar, row, col) adresi.

Aradaki boşluğu compiler kapatır. Görevleri:

  1. Model parse et (PyTorch → graph).
  2. Quantize (FP32 → INT8).
  3. Map (ağırlıkları hücrelere yerleştir).
  4. Optimize (fusion, scheduling, IR drop compensation).
  5. Emit (binary, driver format).

Bu bölüm her aşamayı detayla.

Sezgi: 5 Aşama

[PyTorch Model]
    ↓ parse
[IR (Intermediate Representation) — computation graph]
    ↓ quantize
[INT8 weights + activations]
    ↓ map
[Cell assignments (cluster/CU/crossbar/row/col)]
    ↓ optimize
[Fused operations, scheduled layers, pre-distorted weights]
    ↓ emit
[SIDRA binary (.sidra file)]
    ↓ driver load
[Çip üzerinde ISPP ile programlandı]

Klasik derleyici (GCC gibi) ama hedef donanım SIDRA.

Formalizm: Compiler Aşamaları

L1 · Başlangıç

Aşama 1: Parse.

PyTorch model → FX graph (PyTorch’un IR’ı) veya ONNX → SIDRA IR.

SIDRA IR node’ları:

  • MatMul: ağırlık matrisi + input tensor.
  • Conv2D: filtre + input.
  • Activation: ReLU, GELU, etc.
  • LayerNorm, Softmax.

Aşama 2: Quantize.

FP32 → INT8. Her tensor için min/max analysis (calibration data ile):

def calibrate(model, calib_data):
    for batch in calib_data:
        for layer in model.layers:
            stats[layer.name].update(layer.output.min(), layer.output.max())
    return stats

def quantize_weight(w_fp32, stats):
    scale = (stats.max - stats.min) / 255
    w_int8 = round((w_fp32 - stats.min) / scale).clip(0, 255)
    return w_int8, scale, stats.min

Sonuç: her ağırlık 8-bit + per-tensor scale factor.

Aşama 3: Map.

Ağırlık matrisi WRM×NW \in \mathbb{R}^{M \times N}, her crossbar 256×256. Büyük matrisi parçala:

M = 768, N = 768 → 3 × 3 = 9 crossbar.

Her parça WijW_{ij} bir crossbar’a. Hücre adresleri:

for i in range(M_blocks):
    for j in range(N_blocks):
        crossbar_id = allocate_crossbar()
        for r in range(256):
            for c in range(256):
                cell_addr = (cluster, cu, crossbar_id, r, c)
                write_map[(i*256+r, j*256+c)] = cell_addr
L2 · Tam

Aşama 4: Optimize.

4.1 Operator fusion:

Linear + BN + ReLU tek fused op’a:

y = ReLU(BN(Wx + b))  →  y = fused_linear_bn_relu(W', b', x)

BN parametrelerini W’ye absorb. Compute engine tek-saat çevrimi.

4.2 Layer ordering:

Katmanları crossbar’lara yerleştirken veri hareketi minimize. Arka arkaya layer’lar aynı cluster’da.

4.3 IR drop compensation (Modül 5.12):

Uzun WL üstündeki hücrelere programlama düzeltmesi:

for row in range(256):
    for col in range(256):
        ir_drop = estimate_ir_drop(row, col, activity)
        w_compensated = w_target * (1 + ir_drop)
        program_cell(cell_addr, w_compensated)

4.4 Gürültü-aware (Modül 5.10):

Hassas katmanlar (output yakın) → averaging. Geri kalan tek okuma.

4.5 Redundancy:

Kritik ağırlıklar 3 kopya (TMR). Non-kritik 1 kopya.

Aşama 5: Emit.

Binary format:

Header: magic, version, model_id, metadata
Section 1: Cell programs (address + target_G for each)
Section 2: Layer graph (execution order, dependencies)
Section 3: Activation LUTs
Section 4: Runtime parameters

Tipik Y1 model binary: 500 MB (419M hücre × 8 bit + overhead).

L3 · Derin

Compiler simulator loop:

Compiler digital twin (Modül 6.8) kullanarak pre-deployment model testi:

compiler_output = compile(model)
simulator.load(compiler_output)
accuracy = simulator.benchmark(test_data)
if accuracy < target:
    # Re-compile with stronger quantization-aware, more averaging, etc.
    model = qat_retrain(model)
    compiler_output = compile(model)

Layer-wise quantization:

Tüm katmanlar aynı bit derinliği değil. Hassas katmanlar INT16, geri kalan INT8. Compiler otomatik:

for layer in model.layers:
    if layer.sensitivity > threshold:
        layer.bit_depth = 16
    else:
        layer.bit_depth = 8

Multi-chip scheduling:

Büyük model (örn. GPT-3) tek Y1’e sığmaz. Compiler model partition eder:

Chip 1: Layers 1-4
Chip 2: Layers 5-8
...

PCIe üzerinden chip-to-chip iletişim. Latency bottleneck.

Compile süresi:

Y1 model compile:

  • Parse: 0.1 sn.
  • Quantize + calibrate: 10-60 sn (calibration data’ya göre).
  • Map + optimize: 5-30 sn.
  • Emit: 1 sn.
  • Toplam: 30-100 sn.

Compile bir kez yapılır, output cache’lenir.

SIDRA IR:

LLVM tarzı SSA (Static Single Assignment) form. Optimizasyon pass’leri ile:

  • Dead code elimination.
  • Constant folding.
  • Layer merging.
  • Dataflow optimization.

Gelecek (Y10+ compiler):

  • Auto-quantization: her layer’da en uygun bit derinliği.
  • Training time compiler: eğitim sırasında hardware-aware gradient.
  • Multi-objective optimization: hız, enerji, doğruluk Pareto.

Deney: MNIST Modelini Compile Et

import sidra

# 1. PyTorch model
model = torch.load("mnist_mlp.pth")  # 2-layer MLP, 100K params

# 2. Calibration data
calib_data = [img for img, _ in mnist_test[:100]]

# 3. Compile
compiled = sidra.compile(
    model,
    calib_data=calib_data,
    target_device="y1",
    optimization_level=2
)

print(f"Compiled size: {compiled.size_bytes / 1024 / 1024:.1f} MB")
print(f"Crossbars used: {compiled.crossbar_count}")
print(f"Expected accuracy: {compiled.simulated_accuracy:.2%}")
# Output:
# Compiled size: 0.5 MB
# Crossbars used: 4
# Expected accuracy: 97.5%

# 4. Deploy
chip = sidra.Chip(0)
chip.deploy(compiled)

# 5. Inference
for img, label in mnist_test:
    pred = chip.infer(img)
    # 25 µs/inference

Compile süresi: 30 saniye. Deploy (ISPP): 1 saniye. Inference: 25 µs/sample.

Kısa Sınav

1/6Compiler'ın 5 aşaması nedir?

Laboratuvar Görevi

Compiler optimization impact.

Model: ResNet-18 ImageNet.

Karşılaştırma:

OptimizationHızEnerjiDoğruluk
None%75.0
Op fusion1.3×0.9×%75.0
Quantize-aware1.1×%75.2
IR drop comp%75.5
Noise-injection training1.1×%76.0
Hepsi1.5×0.8×%76.0

Compile süresi: None 30 sn, Hepsi 120 sn (4× uzun ama deploy sonrası kazanç büyük).

Özet Kart

  • 5 aşama: Parse → Quantize → Map → Optimize → Emit.
  • Ana optimize’lar: op fusion, IR drop comp, noise-aware, redundancy.
  • Compile süresi: 30-100 sn/model (bir kez).
  • Binary boyutu: ~500 MB Y1 (tüm hücre program).
  • Simulator loop: pre-deploy doğruluk garanti.

Vizyon: Compiler'ın Geleceği

  • Y1: offline compile, PyTorch input.
  • Y3: auto-quantization, layer-wise bit depth.
  • Y10: hardware-aware training compiler.
  • Y100: multi-objective (speed/energy/accuracy Pareto).
  • Y1000: AI-generated compiler (compiler kendi kendini iyileştirir).

Türkiye için: compiler yazılım mühendisliği bilgi birikimi. Türk Compilers araştırma grupları (ODTÜ, Boğaziçi) bu alanda güçlü.

Daha İleri