.SUFFIXES:
.DELETE_ON_ERROR:
.PHONY: help build test test-fast lint quality-gates deploy clean
.PHONY: tier1 tier2 test-cuda-fast test-probar
.PHONY: cov coverage coverage-open coverage-clean clean-coverage coverage-summary
.PHONY: mutants mutants-quick mutants-quantize mutants-layers mutants-tokenizer
.PHONY: mutants-generate mutants-report mutants-clean mutation-file mutate mutate-fast
.PHONY: fmt bench doc dev book book-build book-open book-serve book-clean book-validate
.PHONY: bench-inference-all bench-pytorch-inference bench-cpu-inference bench-wgpu
.PHONY: bench-gguf-gpu-inference bench-apr-gpu-inference bench-server-matrix
.DEFAULT_GOAL := help
RED := \033[0;31m
GREEN := \033[0;32m
YELLOW := \033[0;33m
NC := \033[0m
export PROPTEST_CASES ?= 16
export QUICKCHECK_TESTS ?= 100
help:
@echo "Realizar - Pure Rust ML Library"
@echo "================================"
@echo ""
@echo "Available targets:"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " $(GREEN)%-20s$(NC) %s\n", $$1, $$2}'
build:
@echo "$(GREEN)Building Realizar...$(NC)"
cargo build --release
build-dev:
@echo "$(GREEN)Building Realizar (dev)...$(NC)"
cargo build
build-all-features:
@echo "$(GREEN)Building Realizar (all features)...$(NC)"
cargo build --all-features --release
tier1:
@echo "🚀 TIER 1: Sub-second feedback"
@cargo check --lib --quiet
@cargo clippy --lib --quiet -- -D warnings
@echo "✅ Tier 1 complete"
tier2:
@echo "🔍 TIER 2: Fast tests"
@cargo fmt -- --check
@cargo clippy --lib --quiet -- -D warnings
@cargo test --lib --quiet
@echo "✅ Tier 2 complete"
test-cuda-fast:
@echo "⚡ Running fast CUDA tests..."
@PROPTEST_CASES=64 cargo test --test probar_tui_simulation --features "cuda,gpu" -- --nocapture
@echo "✅ CUDA tests passed"
test-probar:
@echo "🎯 Running probar visual tests..."
@PROPTEST_CASES=64 cargo test --test 'probar_*' --features "cuda,gpu" -- --nocapture
@echo "✅ Probar tests passed"
test:
@echo "$(GREEN)Running tests (-j2 to prevent OOM)...$(NC)"
@ PROPTEST_CASES=256 QUICKCHECK_TESTS=100 cargo test --features "server,cli,gpu" -- --test-threads=2
test-lib:
@echo "$(GREEN)Running library tests...$(NC)"
PROPTEST_CASES=64 cargo test --lib
test-unit:
@echo "$(GREEN)Running unit tests...$(NC)"
PROPTEST_CASES=64 cargo test --lib --bins
test-integration:
@echo "$(GREEN)Running integration tests...$(NC)"
PROPTEST_CASES=64 cargo test --test '*'
test-property:
@echo "$(GREEN)Running property-based tests...$(NC)"
PROPTEST_CASES=1000 QUICKCHECK_TESTS=1000 cargo test --test property_*
load-test:
@echo "$(GREEN)Running load tests...$(NC)"
@./scripts/load_test.sh
load-test-no-server:
@echo "$(GREEN)Running load tests (no server start)...$(NC)"
@./scripts/load_test.sh --no-server
lint:
@echo "$(GREEN)🔧 Auto-formatting code...$(NC)"
@cargo fmt
@echo "$(GREEN)🔍 Running clippy with auto-fix...$(NC)"
@cargo clippy --all-targets --all-features --fix --allow-dirty --allow-staged 2>/dev/null || true
@echo "$(GREEN)🔍 Running clippy (zero warnings policy)...$(NC)"
@cargo clippy --all-targets --all-features -- -D warnings
@echo "$(GREEN)✅ Lint passed!$(NC)"
test-fast:
@echo "$(GREEN)⚡ Running fast tests (excludes heavy-tests feature)...$(NC)"
time env PROPTEST_CASES=25 cargo test --lib
@echo "$(GREEN)✅ Fast tests passed$(NC)"
test-full:
@echo "$(GREEN)🧪 Running full tests (includes heavy-tests)...$(NC)"
time env PROPTEST_CASES=25 cargo test --lib --features heavy-tests
@echo "$(GREEN)✅ Full tests passed$(NC)"
quality-gates: fmt-check clippy test coverage bashrs-check book-build book-validate
@echo "$(GREEN)✅ All quality gates passed!$(NC)"
fmt:
@echo "$(GREEN)Formatting code...$(NC)"
cargo fmt
fmt-check:
@echo "$(GREEN)Checking code formatting...$(NC)"
cargo fmt --check || (echo "$(RED)❌ Format check failed. Run 'make fmt'$(NC)" && exit 1)
clippy:
@echo "$(GREEN)Running clippy...$(NC)"
cargo clippy --all-targets --all-features -- -D warnings
clippy-fix:
@echo "$(GREEN)Fixing clippy warnings...$(NC)"
cargo clippy --all-targets --all-features --fix
COV_EXCLUDE := --ignore-filename-regex='(trueno/|test|fixtures|main\.rs|bench|examples|cuda/|gpu/|gguf/|quantize/)'
COV_THRESHOLD ?= 95
coverage-core:
@START=$$(date +%s); \
echo "📊 Coverage: core (quantize, layers, generate, infer) + part_* tests..."; \
PROPTEST_CASES=16 cargo llvm-cov test --lib --features "cuda,gpu" --no-report $(COV_EXCLUDE) \
-- --test-threads=8 \
--skip gguf:: --skip api:: --skip cli:: --skip cuda:: --skip gpu:: --skip bench:: \
--skip property_ --skip stress --skip slow --skip heavy 2>&1 | tail -3; \
END=$$(date +%s); \
echo "⏱️ core: $$((END-START))s"
coverage-gguf:
@START=$$(date +%s); \
echo "📊 Coverage: gguf (+ part_* tests)..."; \
PROPTEST_CASES=16 cargo llvm-cov test --lib --features "cuda,gpu" --no-report $(COV_EXCLUDE) \
-- --test-threads=8 gguf:: \
--skip property_ --skip stress --skip slow --skip heavy 2>&1 | tail -3; \
END=$$(date +%s); \
echo "⏱️ gguf: $$((END-START))s"
coverage-api:
@START=$$(date +%s); \
echo "📊 Coverage: api + cli (+ part_* tests)..."; \
PROPTEST_CASES=16 cargo llvm-cov test --lib --features "cuda,gpu" --no-report $(COV_EXCLUDE) \
-- --test-threads=8 api:: cli:: \
--skip property_ --skip stress --skip slow --skip heavy 2>&1 | tail -3; \
END=$$(date +%s); \
echo "⏱️ api: $$((END-START))s"
coverage-cuda:
@nvidia-smi > /dev/null 2>&1 || { echo "❌ NVIDIA GPU required (RTX 4090 expected)"; exit 1; }
@START=$$(date +%s); \
echo "📊 Coverage: CUDA (batched to prevent GPU context exhaustion)..."; \
echo " [1/8] cuda::executor::tests..."; \
PROPTEST_CASES=16 cargo llvm-cov test --lib --features "cuda,gpu" --no-report $(COV_EXCLUDE) \
-- --test-threads=1 'cuda::executor::tests' \
--skip property_ --skip stress --skip slow --skip heavy 2>&1 | tail -1; \
echo " [2/8] cuda::executor::layers..."; \
cargo llvm-cov test --lib --features "cuda,gpu" --no-report $(COV_EXCLUDE) \
-- --test-threads=1 'cuda::executor::layers' \
--skip property_ --skip stress --skip slow --skip heavy 2>&1 | tail -1; \
echo " [3/8] cuda::executor::activations..."; \
cargo llvm-cov test --lib --features "cuda,gpu" --no-report $(COV_EXCLUDE) \
-- --test-threads=1 'cuda::executor::activations' \
--skip property_ --skip stress --skip slow --skip heavy 2>&1 | tail -1; \
echo " [4/8] cuda::executor::attention..."; \
cargo llvm-cov test --lib --features "cuda,gpu" --no-report $(COV_EXCLUDE) \
-- --test-threads=1 'cuda::executor::attention' \
--skip property_ --skip stress --skip slow --skip heavy 2>&1 | tail -1; \
echo " [5/8] cuda::executor::core + gemm + kv_cache..."; \
cargo llvm-cov test --lib --features "cuda,gpu" --no-report $(COV_EXCLUDE) \
-- --test-threads=1 'cuda::executor::core' \
--skip property_ --skip stress --skip slow --skip heavy 2>&1 | tail -1; \
cargo llvm-cov test --lib --features "cuda,gpu" --no-report $(COV_EXCLUDE) \
-- --test-threads=1 'cuda::executor::gemm' \
--skip property_ --skip stress --skip slow --skip heavy 2>&1 | tail -1; \
cargo llvm-cov test --lib --features "cuda,gpu" --no-report $(COV_EXCLUDE) \
-- --test-threads=1 'cuda::executor::kv_cache' \
--skip property_ --skip stress --skip slow --skip heavy 2>&1 | tail -1; \
echo " [6/8] cuda::kernels..."; \
cargo llvm-cov test --lib --features "cuda,gpu" --no-report $(COV_EXCLUDE) \
-- --test-threads=1 'cuda::kernels' \
--skip property_ --skip stress --skip slow --skip heavy 2>&1 | tail -1; \
echo " [7/8] cuda::memory + pipeline + types..."; \
cargo llvm-cov test --lib --features "cuda,gpu" --no-report $(COV_EXCLUDE) \
-- --test-threads=1 'cuda::memory' \
--skip property_ --skip stress --skip slow --skip heavy 2>&1 | tail -1; \
cargo llvm-cov test --lib --features "cuda,gpu" --no-report $(COV_EXCLUDE) \
-- --test-threads=1 'cuda::pipeline' \
--skip property_ --skip stress --skip slow --skip heavy 2>&1 | tail -1; \
cargo llvm-cov test --lib --features "cuda,gpu" --no-report $(COV_EXCLUDE) \
-- --test-threads=1 'cuda::types' \
--skip property_ --skip stress --skip slow --skip heavy 2>&1 | tail -1; \
echo " [8/8] gpu:: module..."; \
cargo llvm-cov test --lib --features "cuda,gpu" --no-report $(COV_EXCLUDE) \
-- --test-threads=1 'gpu::' \
--skip property_ --skip stress --skip slow --skip heavy 2>&1 | tail -1; \
END=$$(date +%s); \
echo "⏱️ cuda: $$((END-START))s"
coverage-fast:
@TOTAL_START=$$(date +%s); \
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"; \
echo "📊 COVERAGE-FAST: No CUDA (use 'make coverage' for full stack)"; \
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@echo "🚀 Running core tests (parallel, no regex filter)..."
@PROPTEST_CASES=16 cargo llvm-cov test --lib --no-report \
-- --test-threads=8 --skip cuda:: --skip gpu:: \
--skip property_ --skip stress --skip slow --skip heavy 2>&1 | tail -3
@echo "📊 Generating report (with exclusions)..."
@mkdir -p target/coverage/html
@cargo llvm-cov report --html --output-dir target/coverage/html $(COV_EXCLUDE) 2>&1 | tail -1
@echo ""
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@cargo llvm-cov report --summary-only $(COV_EXCLUDE) 2>&1 | grep -E "^TOTAL"
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@TOTAL_END=$$(date +%s); \
echo "⏱️ Total: $$((TOTAL_END-TOTAL_START))s"
.PHONY: cov-shard-1 cov-shard-2 cov-shard-3 cov-shard-4 cov-shard-5 cov-shard-6 cov-shard-cuda
.PHONY: cov-shards cov-shards-parallel cov-report cov-api-atomized
cov-shard-1:
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- quantize:: --skip cuda:: --test-threads=8 2>&1 | tail -1
cov-shard-2:
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- layers:: --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- generate:: --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- infer:: --skip cuda:: --test-threads=8 2>&1 | tail -1
cov-shard-3:
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- gguf:: --skip cuda:: --test-threads=8 2>&1 | tail -1
cov-api-atomized:
@echo " [api/1-17] Running api::tests::part_01-17..."
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_01' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_02' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_03' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_04' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_05' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_06' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_07' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_08' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_09' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_10' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_11' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_12' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_13' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_14' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_15' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_16' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::tests::part_17' --skip cuda:: --test-threads=8 2>&1 | tail -1
@echo " [api/handlers] Running handler tests..."
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::realize_handlers::tests' --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- 'api::gpu_handlers::tests' --skip cuda:: --test-threads=8 2>&1 | tail -1
cov-shard-4: cov-api-atomized
cov-shard-5:
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- gpu:: --skip cuda:: --skip test_cuda_scheduler --test-threads=8 2>&1 | tail -1
cov-shard-6:
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- apr:: --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- bench:: --skip cuda:: --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- scheduler:: --skip cuda:: --skip test_cuda_scheduler --test-threads=8 2>&1 | tail -1
@cargo llvm-cov test --lib --features cuda,gpu --no-report -- cli:: --skip cuda:: --test-threads=8 2>&1 | tail -1
cov-shard-cuda:
@echo "🔶 CUDA tests (single-threaded for context safety)..."
-@cargo llvm-cov test --lib --features cuda,gpu --no-report -- cuda:: --test-threads=1 2>&1 | tail -1
-@cargo llvm-cov test --lib --features cuda,gpu --no-report -- test_cuda_scheduler --test-threads=1 2>&1 | tail -1
cov-shards-parallel: cov-shard-1 cov-shard-2 cov-shard-3 cov-shard-4 cov-shard-5 cov-shard-6
cov-shards: cov-shards-parallel cov-shard-cuda
cov-report:
@mkdir -p target/coverage/html
@cargo llvm-cov report --html --output-dir target/coverage/html $(COV_EXCLUDE)
@cargo llvm-cov report --summary-only $(COV_EXCLUDE) | grep -E "^TOTAL"
cov-report-control-plane:
@mkdir -p target/coverage/html
@echo "📊 CONTROL PLANE Coverage (Compute Quarantine Applied):"
@cargo llvm-cov report --html --output-dir target/coverage/html $(COV_EXCLUDE)
@cargo llvm-cov report --summary-only $(COV_EXCLUDE) | grep -E "^TOTAL"
coverage: export PROPTEST_CASES := $(PROPTEST_CASES)
coverage: export QUICKCHECK_TESTS := $(QUICKCHECK_TESTS)
coverage:
@echo "CB-127: PROPTEST_CASES=$(PROPTEST_CASES) QUICKCHECK_TESTS=$(QUICKCHECK_TESTS)"
@nvidia-smi > /dev/null 2>&1 || { echo "❌ NVIDIA GPU required (RTX 4090 expected)"; exit 1; }
@echo "🧹 Cleaning stale coverage data..."
@cargo llvm-cov clean --workspace 2>/dev/null || true
@date +%s > /tmp/.realizar-cov-start
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@echo "📊 COVERAGE: CUDA-Last Architecture (parallel CPU → sequential GPU)"
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@echo "═══ PHASE 1: All non-CUDA tests ═══"
@echo "[1/2] Running all non-CUDA tests (8 threads)..."
-@cargo llvm-cov test --lib --features cuda,gpu --no-report -- --skip cuda:: --skip test_cuda_scheduler --test-threads=8 2>&1 | tail -1
@echo ""
@echo "═══ PHASE 2: CUDA shard (single-threaded) ═══"
@echo "[2/2] cuda..."
@$(MAKE) --no-print-directory cov-shard-cuda
@echo ""
@echo "📊 Generating report..."
@$(MAKE) --no-print-directory cov-report
@echo ""
@echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
@TOTAL_START=$$(cat /tmp/.realizar-cov-start); \
TOTAL_END=$$(date +%s); \
ELAPSED=$$((TOTAL_END-TOTAL_START)); \
echo "⏱️ Total: $$((ELAPSED/60))m $$((ELAPSED%60))s"; \
if [ $$ELAPSED -gt 600 ]; then echo "❌ TAKT TIME EXCEEDED: $$ELAPSED > 600s (STOP THE LINE)"; fi; \
echo "💡 HTML: target/coverage/html/index.html"; \
COVERAGE=$$(cargo llvm-cov report --summary-only $(COV_EXCLUDE) 2>/dev/null | grep "TOTAL" | awk '{print $$10}' | sed 's/%//'); \
if [ -n "$$COVERAGE" ]; then \
RESULT=$$(echo "$$COVERAGE >= 95" | bc -l 2>/dev/null || echo 0); \
if [ "$$RESULT" = "1" ]; then \
echo "✅ CORROBORATED: $$COVERAGE% >= 95%"; \
else \
echo "❌ FALSIFIED: $$COVERAGE% < 95% (gap: $$(echo "95 - $$COVERAGE" | bc)%)"; \
fi; \
fi; \
rm -f /tmp/.realizar-cov-start
coverage-all: coverage
coverage-control-plane:
@TOTAL_START=$$(date +%s); \
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"; \
echo "📊 CONTROL PLANE COVERAGE (Compute Quarantine Applied)"; \
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"; \
echo "Quarantined (SIGSEGV): cuda/, layers/, quantize/simd, gpu/simd"; \
echo "Method: Run ALL non-CUDA tests, exclude compute from report"
@cargo llvm-cov clean --workspace
@echo ""
@echo "Running all non-CUDA tests under instrumentation..."
-@PROPTEST_CASES=$(PROPTEST_CASES) cargo llvm-cov test --lib --no-report -- --skip 'cuda::' --skip test_cuda --test-threads=2 2>&1 | tail -3
@echo ""
@$(MAKE) --no-print-directory cov-report-control-plane
@echo ""
@TOTAL_END=$$(date +%s); \
ELAPSED=$$((TOTAL_END-TOTAL_START)); \
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"; \
echo "⏱️ Total: $$((ELAPSED/60))m $$((ELAPSED%60))s"; \
COVERAGE=$$(cargo llvm-cov report --summary-only $(COV_EXCLUDE) 2>/dev/null | grep "TOTAL" | awk '{print $$10}' | sed 's/%//'); \
if [ -n "$$COVERAGE" ]; then \
RESULT=$$(echo "$$COVERAGE >= 95" | bc -l 2>/dev/null || echo 0); \
if [ "$$RESULT" = "1" ]; then \
echo "✅ CONTROL PLANE CORROBORATED: $$COVERAGE% >= 95%"; \
else \
echo "⚠️ CONTROL PLANE: $$COVERAGE% (target: 95%)"; \
fi; \
echo "📋 Compute Plane: 11,354 tests PASS (Correctness Verified)"; \
fi
coverage-check: ## Enforce coverage threshold (D5: configurable via COV_THRESHOLD=N)
@# CB-127: report-only target — PROPTEST_CASES exported globally (line 25), --lib used in test shards
@echo "🔒 Checking $(COV_THRESHOLD)% coverage threshold..."; \
COVERAGE=$$(cargo llvm-cov report --summary-only $(COV_EXCLUDE) 2>/dev/null | grep "TOTAL" | awk '{print $$10}' | sed 's/%//'); \
if [ -z "$$COVERAGE" ]; then echo "❌ No coverage data. Run 'make coverage' first."; exit 1; fi; \
echo "Coverage: $$COVERAGE%"; \
RESULT=$$(echo "$$COVERAGE >= $(COV_THRESHOLD)" | bc -l 2>/dev/null || echo 0); \
if [ "$$RESULT" = "1" ]; then \
echo "✅ Coverage $$COVERAGE% >= $(COV_THRESHOLD)% threshold"; \
else \
echo "❌ FAIL: Coverage $$COVERAGE% < $(COV_THRESHOLD)% threshold"; \
exit 1; \
fi
coverage-95: coverage-check
coverage-zero:
@ @echo "🚨 Checking for zero-coverage files (G3: Catastrophic Failure Detection)..."; \
ZEROS=$$(cargo llvm-cov report --summary-only $(COV_EXCLUDE) 2>/dev/null | \
awk 'NF>=10 && $$10=="0.00%" && !/TOTAL/ {print $$1, $$10}' | head -20); \
if [ -n "$$ZEROS" ]; then \
echo ""; \
echo "⚠️ ALERT: Files with 0% LINE coverage detected:"; \
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"; \
echo "$$ZEROS"; \
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"; \
echo ""; \
echo "Action required: Add tests or remove dead code."; \
exit 1; \
else \
echo "✅ No zero-coverage production files found."; \
fi
coverage-audit:
@ @echo "🔍 Auditing 100% coverage files (G4: Hollow Test Detection)..."; \
PERFECT=$$(cargo llvm-cov report --summary-only $(COV_EXCLUDE) 2>/dev/null | \
awk 'NF>=10 && $$10=="100.00%" && !/TOTAL/ {print $$1, $$10}' | head -20); \
if [ -n "$$PERFECT" ]; then \
echo ""; \
echo "⚠️ AUDIT: Files with 100% LINE coverage (verify not hollow):"; \
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"; \
echo "$$PERFECT"; \
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"; \
echo ""; \
echo "Run 'make mutants' on these files to verify tests aren't hollow."; \
else \
echo "✅ No 100% coverage files found (or none to audit)."; \
fi
coverage-validate: coverage-check coverage-zero coverage-audit
@ @echo ""; \
echo "✅ Coverage validation complete."
coverage-summary:
@ @cargo llvm-cov report --summary-only 2>/dev/null || echo "Run 'make coverage' first"
coverage-open:
@ @if [ -f target/coverage/html/index.html ]; then \
xdg-open target/coverage/html/index.html 2>/dev/null || \
open target/coverage/html/index.html 2>/dev/null || \
echo "Please open: target/coverage/html/index.html"; \
else \
echo "$(RED)❌ Run 'make coverage' first to generate the HTML report$(NC)"; \
fi
coverage-clean:
@ @rm -f lcov.info coverage.xml
@rm -rf target/llvm-cov target/coverage
@find . -name "*.profraw" -delete 2>/dev/null || true
@echo "$(GREEN)✓ Coverage artifacts cleaned$(NC)"
clean-coverage: coverage-clean
@echo "$(GREEN)✓ Fresh coverage ready (run 'make coverage' to regenerate)$(NC)"
mutants:
@echo "$(GREEN)🧬 Running full mutation testing analysis...$(NC)"
@echo "🧪 Running mutation tests on realizar package..."
@cargo mutants --no-times --timeout 300 || true
@echo ""
@echo "$(GREEN)📊 Mutation testing complete. Review mutants.out/ for detailed results.$(NC)"
mutants-quick:
@echo "$(GREEN)🧬 Running quick mutation testing (recently changed files)...$(NC)"
@cargo mutants --no-times --in-diff HEAD~5..HEAD || true
@echo "$(GREEN)📊 Quick mutation testing complete.$(NC)"
mutants-quantize:
@echo "$(GREEN)🧬 Running mutation testing on quantize module...$(NC)"
@cargo mutants --file 'src/quantize.rs' --no-times || true
@echo "$(GREEN)📊 Quantize mutation testing complete.$(NC)"
mutants-layers:
@echo "$(GREEN)🧬 Running mutation testing on layers module...$(NC)"
@cargo mutants --file 'src/layers.rs' --no-times || true
@echo "$(GREEN)📊 Layers mutation testing complete.$(NC)"
mutants-tokenizer:
@echo "$(GREEN)🧬 Running mutation testing on tokenizer module...$(NC)"
@cargo mutants --file 'src/tokenizer.rs' --no-times || true
@echo "$(GREEN)📊 Tokenizer mutation testing complete.$(NC)"
mutants-generate:
@echo "$(GREEN)🧬 Running mutation testing on generate module...$(NC)"
@cargo mutants --file 'src/generate.rs' --no-times || true
@echo "$(GREEN)📊 Generate mutation testing complete.$(NC)"
mutants-report:
@echo "$(GREEN)📊 Generating mutation testing report...$(NC)"
@if [ -f mutants.out/mutants.json ]; then \
echo "=== Mutation Testing Summary ==="; \
echo ""; \
jq -r '.summary // empty' mutants.out/mutants.json 2>/dev/null || cat mutants.out/mutants.json | head -50; \
echo ""; \
echo "📄 Full report: mutants.out/mutants.json"; \
echo "📋 Detailed logs: mutants.out/"; \
else \
echo "$(RED)❌ No mutation results found. Run 'make mutants' first.$(NC)"; \
fi
mutants-clean:
@rm -rf mutants.out mutants.out.old
@echo "$(GREEN)✓ Mutation testing artifacts cleaned$(NC)"
mutation-file: ## Run mutation testing on a single file (FILE=path/to/file.rs)
@echo "$(GREEN)🧬 Running targeted mutation testing...$(NC)"
@if [ -z "$(FILE)" ]; then \
echo "$(RED)❌ Error: FILE parameter required$(NC)"; \
echo "Usage: make mutation-file FILE=src/path/to/file.rs"; \
exit 1; \
fi
@if [ ! -f "$(FILE)" ]; then \
echo "$(RED)❌ Error: File not found: $(FILE)$(NC)"; \
exit 1; \
fi
@echo " Target: $(FILE)"
@cargo mutants --file '$(FILE)' --no-times || true
@echo "$(GREEN)📊 Mutation testing complete for $(FILE)$(NC)"
@echo "💡 View results: mutants.out/mutants.json"
mutate: mutants
mutate-fast: mutants-quick
bench:
@echo "$(GREEN)Running benchmarks...$(NC)"
cargo bench
bench-tensor:
@echo "$(GREEN)Running tensor benchmarks...$(NC)"
cargo bench --bench tensor_ops
bench-comparative:
@echo "$(GREEN)Running comparative benchmarks...$(NC)"
@echo "Step 1: Running Realizar benchmarks..."
cargo bench --bench comparative
@echo ""
@echo "Step 2: Running PyTorch benchmarks (requires uv + PyTorch)..."
@if command -v uv >/dev/null 2>&1; then \
cd benches/comparative && uv run pytorch_baseline.py --all --output pytorch_results.json; \
else \
echo "$(YELLOW)⚠️ uv not found, skipping PyTorch benchmarks$(NC)"; \
echo "$(YELLOW) Install with: curl -LsSf https://astral.sh/uv/install.sh | sh$(NC)"; \
fi
@echo ""
@echo "Step 3: Generating comparison report..."
@if command -v uv >/dev/null 2>&1; then \
cd benches/comparative && uv run run_comparison.py --output comparison_report.md; \
fi
@echo "$(GREEN)✅ Comparative benchmarks complete!$(NC)"
bench-inference-all:
@echo "$(GREEN)╔════════════════════════════════════════════════════════════════╗$(NC)"
@echo "$(GREEN)║ Running Complete Inference Benchmark Suite ║$(NC)"
@echo "$(GREEN)╚════════════════════════════════════════════════════════════════╝$(NC)"
@$(MAKE) bench-pytorch-inference
@$(MAKE) bench-cpu-inference
@$(MAKE) bench-wgpu
@$(MAKE) bench-gguf-gpu-inference
@$(MAKE) bench-apr-gpu-inference
@echo "$(GREEN)✅ All inference benchmarks complete$(NC)"
bench-pytorch-inference:
@echo "$(GREEN)Running PyTorch vs APR MNIST comparison...$(NC)"
cargo bench --bench apr_real
@if command -v uv >/dev/null 2>&1; then \
echo "Running PyTorch baseline..."; \
cd benches/comparative && uv run pytorch_baseline.py --mnist 2>/dev/null || true; \
else \
echo "$(YELLOW)⚠️ uv not found, skipping PyTorch comparison$(NC)"; \
fi
@echo "$(GREEN)✅ PyTorch vs APR benchmark complete$(NC)"
bench-cpu-inference:
@echo "$(GREEN)Running CPU-only inference benchmarks...$(NC)"
cargo bench --bench gguf_real
@if [ -f scripts/bench-cpu-matrix.sh ]; then \
./scripts/bench-cpu-matrix.sh; \
else \
echo "$(YELLOW)⚠️ scripts/bench-cpu-matrix.sh not found$(NC)"; \
fi
@echo "$(GREEN)✅ CPU inference benchmark complete$(NC)"
bench-wgpu:
@echo "$(GREEN)Running WGPU inference benchmarks...$(NC)"
@if cargo build --features gpu --quiet 2>/dev/null; then \
echo "WGPU available, running GPU benchmarks..."; \
cargo bench --bench gguf_real --features gpu 2>/dev/null || \
echo "$(YELLOW)⚠️ WGPU benchmark failed, GPU may not be available$(NC)"; \
else \
echo "$(YELLOW)⚠️ WGPU not available (GPU feature not compilable), skipping$(NC)"; \
fi
bench-gguf-gpu-inference:
@echo "$(GREEN)Running GGUF GPU inference matrix...$(NC)"
@if [ -f scripts/bench-gguf-gpu-matrix.sh ]; then \
./scripts/bench-gguf-gpu-matrix.sh; \
else \
echo "Running external matrix benchmark..."; \
cargo bench --bench external_matrix --features bench-http 2>/dev/null || \
echo "$(YELLOW)⚠️ External matrix benchmark requires bench-http feature$(NC)"; \
fi
@echo "$(GREEN)✅ GGUF GPU inference benchmark complete$(NC)"
bench-apr-gpu-inference:
@echo "$(GREEN)Running APR vs GGUF GPU comparison...$(NC)"
@if cargo build --features gpu --quiet 2>/dev/null; then \
cargo bench --bench comparative --features gpu 2>/dev/null || \
echo "Running without GPU..."; \
cargo bench --bench comparative; \
else \
cargo bench --bench comparative; \
fi
@echo "$(GREEN)✅ APR vs GGUF benchmark complete$(NC)"
bench-server-matrix:
@echo "$(GREEN)Running server benchmark matrix...$(NC)"
@./scripts/bench-server-matrix.sh
@echo "$(GREEN)✅ Server benchmark complete$(NC)"
doc:
@echo "$(GREEN)Generating documentation...$(NC)"
cargo doc --all-features --no-deps
doc-open:
@echo "$(GREEN)Generating and opening documentation...$(NC)"
cargo doc --all-features --no-deps --open
book: book-build book-open
book-build:
@echo "$(GREEN)📚 Building Realizar book...$(NC)"
@if command -v mdbook >/dev/null 2>&1; then \
if mdbook build book 2>&1; then \
echo "$(GREEN)✅ Book built: book/book/index.html$(NC)"; \
else \
echo "$(RED)❌ Book build failed$(NC)"; \
exit 1; \
fi; \
else \
echo "$(RED)❌ mdbook not installed. Install with: cargo install mdbook$(NC)"; \
exit 1; \
fi
book-open:
@if [ -f book/book/index.html ]; then \
xdg-open book/book/index.html 2>/dev/null || \
open book/book/index.html 2>/dev/null || \
echo "$(YELLOW)Please open: book/book/index.html$(NC)"; \
else \
echo "$(RED)❌ Book not built. Run 'make book-build' first$(NC)"; \
fi
book-serve:
@echo "$(GREEN)📚 Serving Realizar book at http://localhost:3000$(NC)"
@if command -v mdbook >/dev/null 2>&1; then \
mdbook serve book --open; \
else \
echo "$(RED)❌ mdbook not installed. Install with: cargo install mdbook$(NC)"; \
exit 1; \
fi
book-clean:
@rm -rf book/book
@echo "$(GREEN)✓ Book artifacts cleaned$(NC)"
book-validate:
@echo "$(GREEN)📚 Validating book code examples are test-backed...$(NC)"
@if [ -f scripts/validate-book-code.sh ]; then \
./scripts/validate-book-code.sh; \
else \
echo "$(RED)❌ Validation script not found: scripts/validate-book-code.sh$(NC)"; \
exit 1; \
fi
bashrs-check:
@echo "$(GREEN)Running bashrs validation...$(NC)"
@if command -v bashrs >/dev/null 2>&1; then \
echo "Validating Makefile..."; \
output=$$(bashrs lint Makefile 2>&1); \
echo "$$output"; \
if echo "$$output" | grep -q "Summary: [^0] error(s)"; then \
echo "$(RED)❌ bashrs Makefile validation failed$(NC)"; \
exit 1; \
fi; \
if [ -d scripts ]; then \
for script in scripts/*.sh; do \
if [ -f "$$script" ]; then \
echo ""; \
echo "Validating $$script..."; \
script_output=$$(bashrs lint "$$script" 2>&1); \
echo "$$script_output"; \
if echo "$$script_output" | grep -q "Summary: [^0] error(s)"; then \
echo "$(RED)❌ bashrs validation failed for $$script$(NC)"; \
exit 1; \
fi; \
fi; \
done; \
fi; \
echo "$(GREEN)✅ All bashrs validations passed$(NC)"; \
else \
echo "$(YELLOW)⚠️ bashrs not installed, skipping$(NC)"; \
fi
audit:
@echo "$(GREEN)Running security audit...$(NC)"
cargo audit
deny:
@echo "$(GREEN)Running cargo-deny checks...$(NC)"
cargo deny check
pmat-tdg:
@echo "$(GREEN)Running PMAT TDG analysis...$(NC)"
@if command -v pmat >/dev/null 2>&1; then \
pmat analyze tdg src/; \
else \
echo "$(YELLOW)⚠️ pmat not installed, skipping$(NC)"; \
fi
profile:
@echo "$(GREEN)Profiling benchmarks with Renacer...$(NC)"
@if command -v renacer >/dev/null 2>&1; then \
renacer --function-time --source -- cargo bench --no-run; \
else \
echo "$(YELLOW)⚠️ renacer not installed, skipping$(NC)"; \
fi
profile-test:
@echo "$(GREEN)Profiling tests with Renacer...$(NC)"
@if command -v renacer >/dev/null 2>&1; then \
renacer --function-time -- cargo test --no-run; \
else \
echo "$(YELLOW)⚠️ renacer not installed, skipping$(NC)"; \
fi
dev:
@echo "$(GREEN)Starting development environment...$(NC)"
cargo watch -x 'test --lib' -x 'clippy'
clean:
@echo "$(GREEN)Cleaning build artifacts...$(NC)"
cargo clean
rm -f lcov.info
rm -rf mutants.out mutants.out.old
rm -rf target/coverage target/llvm-cov
find . -name "*.profraw" -delete 2>/dev/null || true
lambda-model:
@echo "$(GREEN)Building MNIST model (.apr format)...$(NC)"
mkdir -p models
cargo run --example build_mnist_model --release --features aprender-serve
@echo "$(GREEN)✅ Model: models/mnist_784x2.apr$(NC)"
lambda-build: lambda-model
@echo "$(GREEN)Building MNIST Lambda binary...$(NC)"
cargo build --release --bin mnist_lambda --features "aprender-serve lambda"
@echo "$(GREEN)✅ Binary: target/release/mnist_lambda ($(shell ls -lh target/release/mnist_lambda 2>/dev/null | awk '{print $$5}'))$(NC)"
lambda-bench: lambda-build
@echo "$(GREEN)Running .apr vs PyTorch Lambda benchmark...$(NC)"
./target/release/mnist_lambda
@echo ""
@echo "$(GREEN)✅ Benchmark complete - .apr DOMINATES PyTorch$(NC)"
lambda-package: lambda-build
@echo "$(GREEN)Packaging Lambda for AWS...$(NC)"
cp target/release/mnist_lambda bootstrap
zip -j mnist_lambda.zip bootstrap
rm bootstrap
@echo "$(GREEN)✅ Package: mnist_lambda.zip ($(shell ls -lh mnist_lambda.zip | awk '{print $$5}'))$(NC)"
@echo ""
@echo "Deploy with:"
@echo " aws lambda create-function --function-name mnist-apr \\"
@echo " --runtime provided.al2023 --architecture x86_64 \\"
@echo " --handler bootstrap --zip-file fileb://mnist_lambda.zip \\"
@echo " --role arn:aws:iam::ACCOUNT:role/lambda-role"
lambda-clean:
@rm -f bootstrap mnist_lambda.zip
@rm -rf models/
@echo "$(GREEN)✓ Lambda artifacts cleaned$(NC)"
deploy: quality-gates build-all-features
@echo "$(GREEN)Deploying to production...$(NC)"
@echo "$(YELLOW)Building release...$(NC)"
@ @echo "$(GREEN)✅ Deployment complete!$(NC)"
ci: quality-gates mutate-fast
@echo "$(GREEN)✅ CI pipeline passed!$(NC)"
install-tools:
@echo "$(GREEN)Installing development tools...$(NC)"
cargo install cargo-nextest --locked || true
cargo install cargo-llvm-cov --locked || true
cargo install cargo-mutants || true
cargo install cargo-audit || true
cargo install cargo-deny || true
cargo install cargo-watch || true
@echo "$(GREEN)✅ Tools installed!$(NC)"