Foundry/Makefile

1275 lines
63 KiB
Makefile

# SPDX-License-Identifier: AGPL-3.0-or-later
# Copyright (C) 2026 David (Corey) Herrera
# Foundry Makefile
CC ?= clang
# CPU target. Default -march=native: fastest, but the binary only runs on a CPU
# with the build machine's instruction set, so build on the machine that runs it.
# PORTABLE=1 builds a binary you can copy between machines: -march=x86-64-v2 on
# x86-64 (SSE4.2, no AVX; runs on any x86-64 CPU since ~2009), the compiler's
# generic default elsewhere.
ifeq ($(PORTABLE),1)
ifneq ($(filter x86_64 amd64,$(shell uname -m)),)
ARCH_FLAGS = -march=x86-64-v2
else
ARCH_FLAGS =
endif
else
ARCH_FLAGS = -march=native
endif
CFLAGS = -Wall -Wextra -std=c11 -O3 $(ARCH_FLAGS) -ffast-math
CFLAGS += -I.
# On Linux, -std=c11 hides POSIX/GNU symbols (clock_gettime, M_PI, strdup, etc.)
ifneq ($(shell uname -s),Darwin)
CFLAGS += -D_GNU_SOURCE
endif
# Debug build (overrides optimization flags)
ifdef DEBUG
CFLAGS = -Wall -Wextra -std=c11 -O0 -g -DDEBUG
CFLAGS += -I.
ifneq ($(shell uname -s),Darwin)
CFLAGS += -D_GNU_SOURCE
endif
endif
# OpenMP (opt-in: make USE_OMP=1)
ifdef USE_OMP
CFLAGS += -fopenmp
LDFLAGS += -fopenmp
endif
# pthread thread pool (opt-in: make USE_THREADS=1)
# Alternative to OpenMP — same parallelism, no compiler dependency.
# OpenMP takes precedence if both are set.
ifdef USE_THREADS
ifndef USE_OMP
CFLAGS += -DUSE_THREADS -pthread
LDFLAGS += -pthread
THREADPOOL_SRC = threadpool/threadpool.c
endif
else
THREADPOOL_SRC =
endif
# BLAS acceleration (opt-in: make USE_BLAS=1)
ifdef USE_BLAS
CFLAGS += -DUSE_BLAS
ifeq ($(shell uname -s),Darwin)
CFLAGS += -DACCELERATE_NEW_LAPACK
LDFLAGS_BLAS = -framework Accelerate
else
CFLAGS += -DUSE_OPENBLAS
LDFLAGS_BLAS = -lopenblas
endif
else
LDFLAGS_BLAS =
endif
# Metal GPU backend (opt-in: make USE_METAL=1, macOS only)
ifdef USE_METAL
CFLAGS += -DUSE_METAL
LDFLAGS_METAL = -framework Metal -framework MetalPerformanceShaders -framework Foundation
# Core (device, pipeline cache, buffers, regions, dispatch) plus one unit per
# kernel family. A family unit carries its host dispatch AND its MSL source
# fragment, so adding a kernel touches one file. Add new families here.
METAL_SRC = metal/fm_metal.m \
metal/kernels/fm_kernel_registry.m \
metal/kernels/fm_kernel_ssm.m \
metal/kernels/fm_kernel_ssm_chunked.m \
metal/kernels/fm_kernel_moe.m \
metal/kernels/fm_kernel_attn.m \
metal/kernels/fm_kernel_probe.m \
metal/kernels/fm_kernel_gemm_f32.m \
metal/kernels/fm_kernel_wkv7.m \
metal/kernels/fm_kernel_norm.m \
metal/kernels/fm_kernel_elementwise.m \
metal/kernels/fm_kernel_rope.m \
metal/kernels/fm_kernel_convert.m \
metal/kernels/fm_kernel_matvec_q8.m \
metal/kernels/fm_kernel_matvec_q4_k.m \
metal/kernels/fm_kernel_matvec_q3_k.m \
metal/kernels/fm_kernel_matvec_q5_k.m \
metal/kernels/fm_kernel_matvec_q6_k.m \
metal/kernels/fm_kernel_matvec_q8_0.m
METAL_HDR = metal/fm_metal.h metal/fm_metal_internal.h $(wildcard metal/kernels/*.h)
# Objective-C needs its own flags: no -std=c11, add -fobjc-arc
OBJCFLAGS = -Wall -Wextra -O3 -ffast-math -fobjc-arc -DUSE_METAL -I.
ifdef DEBUG
OBJCFLAGS = -Wall -Wextra -O0 -g -DDEBUG -fobjc-arc -DUSE_METAL -I.
endif
else
LDFLAGS_METAL =
METAL_SRC =
METAL_HDR =
endif
# CUDA GPU backend (opt-in: make USE_CUDA=1, Linux only)
# Zero compile-time CUDA dependency — uses dlopen() at runtime.
# Mutually exclusive with Metal (Linux vs macOS).
ifdef USE_CUDA
CFLAGS += -DUSE_CUDA
LDFLAGS_CUDA = -ldl
CUDA_SRC = cuda/fc_cuda.c
else
LDFLAGS_CUDA =
CUDA_SRC =
endif
# Tenstorrent Blackhole GPU backend (opt-in: make USE_TT=1, Linux only)
# Host backend is C99 against tt-kmd ioctls and builds anywhere. Device kernels
# need SFPI (/opt/tenstorrent/sfpi), but their ELFs are pre-baked into
# tt/ft_tt_kernels.h — the same embedding trick cuda/ uses for PTX — so USE_TT=1
# needs no SFPI toolchain present. SFPI is needed only to REGENERATE that header
# via tt/build_tensix_*.sh, never to build against it.
ifdef USE_TT
CFLAGS += -DUSE_TT
LDFLAGS_TT =
# Host backend: device open, TLBs, NoC, launch, queue, per-op drivers, FTTW.
TT_SRC = tt/ft_tt_kmd.c \
tt/ft_tt_arch.c \
tt/ft_tt_arch_blackhole.c \
tt/ft_tt_device.c \
tt/ft_tt_tlb.c \
tt/ft_tt_arc_telemetry.c \
tt/ft_tt_coord.c \
tt/ft_tt_noc.c \
tt/ft_tt_buffer.c \
tt/ft_tt_elf.c \
tt/ft_tt_kernel_blob.c \
tt/ft_tt_launch.c \
tt/ft_tt_tilize.c \
tt/ft_tt_watchdog.c \
tt/ft_tt_queue.c \
tt/ft_tt_group.c \
tt/ft_tt_fttw.c \
tt/ft_tt_op_dispatch.c \
tt/ft_tt_op_matmul.c \
tt/ft_tt_op_memory.c \
tt/ft_tt_op_rms_norm.c \
tt/ft_tt_op_rope.c \
tt/ft_tt_op_sample.c \
tt/ft_tt_op_vector.c \
tt/ft_tt_op_attention.c \
tt/ft_tt_op_gdn.c \
tt/ft_tt_op_gdnc.c
# FTTW weight converter (GGUF in, tiled on-card artifact out) — part of this backend.
TT_CONVERT_SRC = tt/convert/ft_bfp.c \
tt/convert/ft_float_convert.c \
tt/convert/ft_gguf_dequant.c \
tt/convert/ft_gguf_map.c \
tt/convert/ft_tt_precision_ledger.c \
tt/convert/ft_tt_weight_convert.c
TT_HDR = $(wildcard tt/*.h) $(wildcard tt/convert/*.h)
else
LDFLAGS_TT =
TT_SRC =
TT_CONVERT_SRC =
TT_HDR =
endif
# Modules
MODULES = progress tensor tokenizer data safetensors lora quantization attention distributed eval optim hdc hybridmem threadpool rwkvx metal cuda tt rosa barswap pth ternarize
# Default target
all: $(MODULES)
# Progress module
progress: progress/progress.o
progress/progress.o: progress/progress.c progress/progress.h
$(CC) $(CFLAGS) -c $< -o $@
# Tensor module
tensor: tensor/tensor.o
tensor/tensor.o: tensor/tensor.c tensor/tensor.h
$(CC) $(CFLAGS) -c $< -o $@
# Tokenizer module
tokenizer: tokenizer/tokenizer.o
tokenizer/tokenizer.o: tokenizer/tokenizer.c tokenizer/tokenizer.h
$(CC) $(CFLAGS) -c $< -o $@
# Safetensors module
safetensors: safetensors/safetensors.o
safetensors/safetensors.o: safetensors/safetensors.c safetensors/safetensors.h
$(CC) $(CFLAGS) -c $< -o $@
# Test targets
test: test-progress test-tensor test-tokenizer test-safetensors test-lora test-data test-quantization test-export test-attention test-turboquant test-distributed test-eval test-optim test-hdc test-hybridmem test-threadpool test-rwkvx test-rx-train test-wkv7-bwd test-timemix-bwd test-block-bwd test-attn-bwd test-model-bwd test-rosa test-barswap test-pth test-ternarize test-q2-0-half-round
# Q2_0 activation-scale binary16 rounding (cuda_kernels/matvec_kquants.cu), exhaustive.
# Own flags: -ffast-math would fold the (v + 0.5f) - 0.5f subnormal rounding.
test-q2-0-half-round: cuda_kernels/tests/test_q2_0_half_round
./cuda_kernels/tests/test_q2_0_half_round
cuda_kernels/tests/test_q2_0_half_round: cuda_kernels/tests/test_q2_0_half_round.c
$(CC) -Wall -Wextra -std=c11 -O2 -o $@ $<
test-progress: progress/tests/test_progress
./progress/tests/test_progress
progress/tests/test_progress: progress/tests/test_progress.c progress/progress.c progress/progress.h
$(CC) $(CFLAGS) -o $@ progress/tests/test_progress.c progress/progress.c
test-tensor: tensor/tests/test_tensor
./tensor/tests/test_tensor
tensor/tests/test_tensor: tensor/tests/test_tensor.c tensor/tensor.c tensor/tensor.h $(METAL_SRC) $(CUDA_SRC)
$(CC) $(CFLAGS) -o $@ tensor/tests/test_tensor.c tensor/tensor.c $(METAL_SRC) $(CUDA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
test-tokenizer: tokenizer/tests/test_tokenizer
./tokenizer/tests/test_tokenizer
tokenizer/tests/test_tokenizer: tokenizer/tests/test_tokenizer.c tokenizer/tokenizer.c tokenizer/tokenizer.h
$(CC) $(CFLAGS) -o $@ tokenizer/tests/test_tokenizer.c tokenizer/tokenizer.c
test-safetensors: safetensors/tests/test_safetensors
./safetensors/tests/test_safetensors
safetensors/tests/test_safetensors: safetensors/tests/test_safetensors.c safetensors/safetensors.c safetensors/safetensors.h
$(CC) $(CFLAGS) -o $@ safetensors/tests/test_safetensors.c safetensors/safetensors.c
# LoRA module
lora: lora/lora.o
lora/lora.o: lora/lora.c lora/lora.h tensor/tensor.h safetensors/safetensors.h
$(CC) $(CFLAGS) -c $< -o $@
test-lora: lora/tests/test_lora
./lora/tests/test_lora
lora/tests/test_lora: lora/tests/test_lora.c lora/lora.c lora/lora.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h
$(CC) $(CFLAGS) -o $@ lora/tests/test_lora.c lora/lora.c tensor/tensor.c safetensors/safetensors.c -lm $(LDFLAGS_BLAS)
# Data module
data: data/data.o
data/data.o: data/data.c data/data.h
$(CC) $(CFLAGS) -c $< -o $@
test-data: data/tests/test_data
./data/tests/test_data
data/tests/test_data: data/tests/test_data.c data/data.c data/data.h
$(CC) $(CFLAGS) -o $@ data/tests/test_data.c data/data.c
# Byte-level enwik8 loader (RWKV-x scale test). Deliberately NOT wired into the
# default slow `test` target — it is a fast standalone check.
test-byte-data: data/tests/test_byte_dataset
./data/tests/test_byte_dataset
data/tests/test_byte_dataset: data/tests/test_byte_dataset.c data/fd_byte_dataset.c data/fd_byte_dataset.h
$(CC) $(CFLAGS) -o $@ data/tests/test_byte_dataset.c data/fd_byte_dataset.c
# Quantization module
quantization: quantization/quantization.o
quantization/quantization.o: quantization/quantization.c quantization/quantization.h
$(CC) $(CFLAGS) -c $< -o $@
test-quantization: quantization/tests/test_quantization
./quantization/tests/test_quantization
quantization/tests/test_quantization: quantization/tests/test_quantization.c quantization/quantization.c quantization/quantization.h
$(CC) $(CFLAGS) -o $@ quantization/tests/test_quantization.c quantization/quantization.c -lm $(LDFLAGS_BLAS)
test-export: quantization/tests/test_export
./quantization/tests/test_export
quantization/tests/test_export: quantization/tests/test_export.c quantization/export.c quantization/export.h quantization/quantization.c quantization/quantization.h safetensors/safetensors.c safetensors/safetensors.h
$(CC) $(CFLAGS) -o $@ quantization/tests/test_export.c quantization/export.c quantization/quantization.c safetensors/safetensors.c -lm $(LDFLAGS_BLAS)
examples/quantize_model: examples/quantize_model.c quantization/export.c quantization/export.h quantization/quantization.c quantization/quantization.h safetensors/safetensors.c safetensors/safetensors.h
$(CC) $(CFLAGS) -o $@ examples/quantize_model.c quantization/export.c quantization/quantization.c safetensors/safetensors.c -lm $(LDFLAGS_BLAS)
quantize-model: examples/quantize_model
# HDC module
hdc: hdc/hdc.o
hdc/hdc.o: hdc/hdc.c hdc/hdc.h tensor/tensor.h
$(CC) $(CFLAGS) -c $< -o $@
test-hdc: hdc/tests/test_hdc
./hdc/tests/test_hdc
hdc/tests/test_hdc: hdc/tests/test_hdc.c hdc/hdc.c hdc/hdc.h tensor/tensor.c tensor/tensor.h
$(CC) $(CFLAGS) -o $@ hdc/tests/test_hdc.c hdc/hdc.c tensor/tensor.c -lm $(LDFLAGS_BLAS)
# HybridMem module
hybridmem: hybridmem/hybridmem.o
hybridmem/hybridmem.o: hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.h tensor/tensor.h safetensors/safetensors.h
$(CC) $(CFLAGS) -c $< -o $@
test-hybridmem: hybridmem/tests/test_hybridmem
./hybridmem/tests/test_hybridmem
hybridmem/tests/test_hybridmem: hybridmem/tests/test_hybridmem.c hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h
$(CC) $(CFLAGS) -o $@ hybridmem/tests/test_hybridmem.c hybridmem/hybridmem.c hdc/hdc.c tensor/tensor.c safetensors/safetensors.c -lm $(LDFLAGS_BLAS)
# BAR Swap userspace library (kernel module builds separately on server)
barswap: barswap/barswap.o
barswap/barswap.o: barswap/barswap.c barswap/barswap.h barswap/bar_swap_ko/bar_swap.h
$(CC) $(CFLAGS) -c $< -o $@
test-barswap: barswap/tests/test_barswap
./barswap/tests/test_barswap
barswap/tests/test_barswap: barswap/tests/test_barswap.c barswap/barswap.c barswap/barswap.h barswap/bar_swap_ko/bar_swap.h
$(CC) $(CFLAGS) -o $@ barswap/tests/test_barswap.c barswap/barswap.c
barswap/tests/vram_persist: barswap/tests/vram_persist.c
$(CC) $(CFLAGS) -o $@ barswap/tests/vram_persist.c -ldl
vram-persist: barswap/tests/vram_persist
barswap/tests/compute_persist: barswap/tests/compute_persist.c barswap/barswap.c barswap/barswap.h barswap/bar_swap_ko/bar_swap.h
$(CC) $(CFLAGS) -o $@ barswap/tests/compute_persist.c barswap/barswap.c -ldl
compute-persist: barswap/tests/compute_persist
barswap/tests/xcard_persist: barswap/tests/xcard_persist.c barswap/barswap.c barswap/barswap.h barswap/bar_swap_ko/bar_swap.h
$(CC) $(CFLAGS) -o $@ barswap/tests/xcard_persist.c barswap/barswap.c -ldl
xcard-persist: barswap/tests/xcard_persist
barswap/tests/roundrobin_persist: barswap/tests/roundrobin_persist.c barswap/barswap.c barswap/barswap.h barswap/bar_swap_ko/bar_swap.h
$(CC) $(CFLAGS) -o $@ barswap/tests/roundrobin_persist.c barswap/barswap.c -ldl
roundrobin-persist: barswap/tests/roundrobin_persist
barswap/tests/gpu_switch_probe: barswap/tests/gpu_switch_probe.c barswap/barswap.c barswap/barswap.h barswap/bar_swap_ko/bar_swap.h
$(CC) $(CFLAGS) -o $@ barswap/tests/gpu_switch_probe.c barswap/barswap.c -ldl
gpu-switch-probe: barswap/tests/gpu_switch_probe
barswap/tests/worker_switch: barswap/tests/worker_switch.c barswap/barswap.c barswap/barswap.h barswap/bar_swap_ko/bar_swap.h
$(CC) $(CFLAGS) -o $@ barswap/tests/worker_switch.c barswap/barswap.c -ldl
worker-switch: barswap/tests/worker_switch
barswap/tests/gpu_owner: barswap/tests/gpu_owner.c barswap/gpu_owner.c barswap/gpu_owner_util.c barswap/barswap.c barswap/gpu_owner.h barswap/gpu_owner_util.h barswap/barswap.h barswap/bar_swap_ko/bar_swap.h
$(CC) $(CFLAGS) -o $@ barswap/tests/gpu_owner.c barswap/gpu_owner.c barswap/gpu_owner_util.c barswap/barswap.c -ldl
gpu-owner: barswap/tests/gpu_owner
# ROSA module (suffix automaton)
rosa: rosa/rosa.o
rosa/rosa.o: rosa/rosa.c rosa/rosa.h
$(CC) $(CFLAGS) -c $< -o $@
test-rosa: rosa/tests/test_rosa
./rosa/tests/test_rosa
rosa/tests/test_rosa: rosa/tests/test_rosa.c rosa/rosa.c rosa/rosa.h
$(CC) $(CFLAGS) -o $@ rosa/tests/test_rosa.c rosa/rosa.c
# Threadpool module
threadpool: threadpool/threadpool.o
threadpool/threadpool.o: threadpool/threadpool.c threadpool/threadpool.h
$(CC) $(CFLAGS) -pthread -c $< -o $@
test-threadpool: threadpool/tests/test_threadpool
./threadpool/tests/test_threadpool
threadpool/tests/test_threadpool: threadpool/tests/test_threadpool.c threadpool/threadpool.c threadpool/threadpool.h
$(CC) $(CFLAGS) -pthread -o $@ threadpool/tests/test_threadpool.c threadpool/threadpool.c
# Metal GPU backend module
ifdef USE_METAL
METAL_OBJ = $(METAL_SRC:.m=.o)
metal: $(METAL_OBJ)
# Every unit sees every kernel header (fm_metal.h includes them all), so they
# all depend on $(METAL_HDR) rather than on a hand-maintained subset.
%.o: %.m $(METAL_HDR)
$(CC) $(OBJCFLAGS) -c $< -o $@
test-metal: metal/tests/test_metal
./metal/tests/test_metal
metal/tests/test_metal: metal/tests/test_metal.c $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_metal.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-metal-fc: metal/tests/test_metal_fc
./metal/tests/test_metal_fc
metal/tests/test_metal_fc: metal/tests/test_metal_fc.c $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_metal_fc.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-metal-region: metal/tests/test_metal_region
./metal/tests/test_metal_region
metal/tests/test_metal_region: metal/tests/test_metal_region.c $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_metal_region.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-metal-q3-k: metal/tests/test_metal_q3_k
./metal/tests/test_metal_q3_k
metal/tests/test_metal_q3_k: metal/tests/test_metal_q3_k.c $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_metal_q3_k.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-metal-matvec-q5-k: metal/tests/test_metal_matvec_q5_k
./metal/tests/test_metal_matvec_q5_k
metal/tests/test_metal_matvec_q5_k: metal/tests/test_metal_matvec_q5_k.c metal/tests/gguf_test_reader.h $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_metal_matvec_q5_k.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-metal-matvec-q6-k: metal/tests/test_metal_matvec_q6_k
./metal/tests/test_metal_matvec_q6_k
metal/tests/test_metal_matvec_q6_k: metal/tests/test_metal_matvec_q6_k.c metal/tests/gguf_test_reader.h $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_metal_matvec_q6_k.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-metal-rope: metal/tests/test_metal_rope
./metal/tests/test_metal_rope
metal/tests/test_metal_rope: metal/tests/test_metal_rope.c metal/tests/fm_golden_vectors.h $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_metal_rope.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-metal-norm: metal/tests/test_metal_norm
./metal/tests/test_metal_norm
metal/tests/test_metal_norm: metal/tests/test_metal_norm.c metal/tests/fm_golden_vectors.h $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_metal_norm.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-metal-elementwise: metal/tests/test_metal_elementwise metal/tests/test_matvec_q8_0 metal/tests/test_matvec_q4_k metal/tests/bench_matvec_bandwidth metal/tests/test_metal_ssm metal/tests/test_metal_attn metal/tests/test_metal_moe metal/tests/test_metal_moe_experts metal/tests/bench_attn_split
./metal/tests/test_metal_elementwise
metal/tests/test_metal_elementwise: metal/tests/test_metal_elementwise.c $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_metal_elementwise.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-matvec-q8-0: metal/tests/test_matvec_q8_0
./metal/tests/test_matvec_q8_0
metal/tests/test_matvec_q8_0: metal/tests/test_matvec_q8_0.c $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_matvec_q8_0.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-matvec-q4-k: metal/tests/test_matvec_q4_k
./metal/tests/test_matvec_q4_k
metal/tests/test_matvec_q4_k: metal/tests/test_matvec_q4_k.c $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_matvec_q4_k.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
bench-matvec-bandwidth: metal/tests/bench_matvec_bandwidth
./metal/tests/bench_matvec_bandwidth
metal/tests/bench_matvec_bandwidth: metal/tests/bench_matvec_bandwidth.m metal/tests/gguf_test_reader.h $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/bench_matvec_bandwidth.m $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-metal-ssm: metal/tests/test_metal_ssm
./metal/tests/test_metal_ssm
metal/tests/test_metal_ssm: metal/tests/test_metal_ssm.c metal/tests/fm_golden_vectors.h $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_metal_ssm.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-metal-attn: metal/tests/test_metal_attn metal/tests/bench_attn_split
./metal/tests/test_metal_attn
metal/tests/test_metal_attn: metal/tests/test_metal_attn.c $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_metal_attn.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
metal/tests/bench_attn_split: metal/tests/bench_attn_split.c $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/bench_attn_split.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-metal-moe: metal/tests/test_metal_moe
./metal/tests/test_metal_moe
metal/tests/test_metal_moe: metal/tests/test_metal_moe.c metal/tests/fm_golden_vectors.h $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_metal_moe.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-metal-moe-experts: metal/tests/test_metal_moe_experts
./metal/tests/test_metal_moe_experts
metal/tests/test_metal_moe_experts: metal/tests/test_metal_moe_experts.c metal/tests/gguf_test_reader.h $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_metal_moe_experts.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-metal-gemm-batched: metal/tests/test_metal_gemm_batched
./metal/tests/test_metal_gemm_batched
metal/tests/test_metal_gemm_batched: metal/tests/test_metal_gemm_batched.c $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_metal_gemm_batched.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-gemm-q4-k: metal/tests/test_gemm_q4_k
./metal/tests/test_gemm_q4_k
metal/tests/test_gemm_q4_k: metal/tests/test_gemm_q4_k.c $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_gemm_q4_k.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
test-gemm-q4-k-f16: metal/tests/test_gemm_q4_k_f16
./metal/tests/test_gemm_q4_k_f16
metal/tests/test_gemm_q4_k_f16: metal/tests/test_gemm_q4_k_f16.c $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/test_gemm_q4_k_f16.c $(METAL_SRC) -lm $(LDFLAGS_METAL)
bench-dispatch: metal/tests/bench_dispatch
./metal/tests/bench_dispatch
metal/tests/bench_dispatch: metal/tests/bench_dispatch.m $(METAL_SRC) $(METAL_HDR)
$(CC) $(OBJCFLAGS) -o $@ metal/tests/bench_dispatch.m $(METAL_SRC) -lm $(LDFLAGS_METAL)
else
metal:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
test-metal:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
test-metal-fc:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
test-metal-gemm-batched:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
bench-dispatch:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
test-metal-region:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
test-metal-q3-k:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
test-metal-matvec-q5-k:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
test-metal-matvec-q6-k:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
test-metal-rope:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
test-metal-norm:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
test-metal-elementwise:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
test-matvec-q8-0:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
test-matvec-q4-k:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
bench-matvec-bandwidth:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
test-metal-ssm:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
test-metal-attn:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
test-metal-moe:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
test-metal-moe-experts:
@echo "Metal disabled. Build with USE_METAL=1 to enable."
endif
# CUDA GPU backend module
ifdef USE_CUDA
cuda: cuda/fc_cuda.o
cuda/fc_cuda.o: cuda/fc_cuda.c cuda/fc_cuda.h cuda/fc_cuda_ptx.h
$(CC) $(CFLAGS) -c $< -o $@
test-cuda: cuda/tests/test_cuda
./cuda/tests/test_cuda
cuda/tests/test_cuda: cuda/tests/test_cuda.c cuda/fc_cuda.c cuda/fc_cuda.h cuda/fc_cuda_ptx.h
$(CC) $(CFLAGS) -o $@ cuda/tests/test_cuda.c cuda/fc_cuda.c -lm -ldl
# Multi-die context isolation (run on a K80 host with >=2 dies)
test-cuda-multi: cuda/tests/test_multi_ctx
./cuda/tests/test_multi_ctx
cuda/tests/test_multi_ctx: cuda/tests/test_multi_ctx.c cuda/fc_cuda.c cuda/fc_cuda.h cuda/fc_cuda_ptx.h
$(CC) $(CFLAGS) -o $@ cuda/tests/test_multi_ctx.c cuda/fc_cuda.c -lm -ldl
# Grouped-MoE gate+up quant dispatch + CPU-replica parity (needs ONE K80 die).
# NOT in the top-level `test` list: that list runs on the Mac, where there is
# no CUDA driver. Same convention as test-cuda / test-cuda-multi above.
test-moe-expert-quants: cuda/tests/test_moe_expert_quants
./cuda/tests/test_moe_expert_quants
cuda/tests/test_moe_expert_quants: cuda/tests/test_moe_expert_quants.c cuda/fc_cuda.c cuda/fc_cuda.h cuda/fc_cuda_ptx.h
$(CC) $(CFLAGS) -o $@ cuda/tests/test_moe_expert_quants.c cuda/fc_cuda.c -lm -ldl
# Q4_0 KV append kernels (embedded PTX) vs a host quantizer, byte for byte (ONE K80 die).
test-kvq4-scale: cuda/tests/test_kvq4_scale
./cuda/tests/test_kvq4_scale
cuda/tests/test_kvq4_scale: cuda/tests/test_kvq4_scale.c cuda/fc_cuda.c cuda/fc_cuda.h cuda/fc_cuda_ptx.h
$(CC) $(CFLAGS) -o $@ cuda/tests/test_kvq4_scale.c cuda/fc_cuda.c -lm -ldl
# The micro-bench / bit-exact verifier the parity method above is taken from.
cuda/tests/bench_matvec: cuda/tests/bench_matvec.c cuda/fc_cuda.c cuda/fc_cuda.h cuda/fc_cuda_ptx.h
$(CC) $(CFLAGS) -o $@ cuda/tests/bench_matvec.c cuda/fc_cuda.c -lm -ldl
# Tensor-parallelism pricing. bench_split_scaling needs ONE die; bench_cross_die
# needs the TWO dies of one board (CUDA_VISIBLE_DEVICES=6,7) and must run alone
# on them — a busy sibling drops the other die's clock and corrupts the result.
cuda/tests/bench_split_scaling: cuda/tests/bench_split_scaling.c cuda/fc_cuda.c cuda/fc_cuda.h cuda/fc_cuda_ptx.h
$(CC) $(CFLAGS) -o $@ cuda/tests/bench_split_scaling.c cuda/fc_cuda.c -lm -ldl
cuda/tests/bench_cross_die: cuda/tests/bench_cross_die.c cuda/fc_cuda.c cuda/fc_cuda.h cuda/fc_cuda_ptx.h
$(CC) $(CFLAGS) -o $@ cuda/tests/bench_cross_die.c cuda/fc_cuda.c -lm -ldl
cuda/tests/bench_peer_stream: cuda/tests/bench_peer_stream.c cuda/fc_cuda.c cuda/fc_cuda.h cuda/fc_cuda_ptx.h
$(CC) $(CFLAGS) -o $@ cuda/tests/bench_peer_stream.c cuda/fc_cuda.c -lm -ldl
bench-tp: cuda/tests/bench_split_scaling cuda/tests/bench_cross_die cuda/tests/bench_peer_stream
else
cuda:
@echo "CUDA disabled. Build with USE_CUDA=1 to enable."
test-cuda:
@echo "CUDA disabled. Build with USE_CUDA=1 to enable."
test-cuda-multi:
@echo "CUDA disabled. Build with USE_CUDA=1 to enable."
test-moe-expert-quants:
@echo "CUDA disabled. Build with USE_CUDA=1 to enable."
test-kvq4-scale:
@echo "CUDA disabled. Build with USE_CUDA=1 to enable."
endif
# Tenstorrent Blackhole GPU backend module
ifdef USE_TT
TT_OBJ = $(TT_SRC:.c=.o) $(TT_CONVERT_SRC:.c=.o)
tt: $(TT_OBJ)
# Every unit sees every backend header (there is no single umbrella header, like
# METAL's fm_metal.h), so objects depend on the full header set rather than a
# hand-maintained per-file subset.
tt/%.o: tt/%.c $(TT_HDR)
$(CC) $(CFLAGS) -c $< -o $@
tt/convert/%.o: tt/convert/%.c $(TT_HDR)
$(CC) $(CFLAGS) -c $< -o $@
# On-card acceptance and off-hardware suites live in tt/tests/ and tt/convert/tests/,
# each with its own Makefile (16 total) — see tt/README.md. They are not aggregated
# here: several need PHASE1B=1 (opens the NoC fence) and the card host specifically,
# which is not true of anything else `make test` runs.
test-tt:
@echo "tt/ suites run from tt/tests/ and tt/convert/tests/ (see tt/README.md), not from the root Makefile."
else
tt:
@echo "Tenstorrent disabled. Build with USE_TT=1 to enable."
test-tt:
@echo "Tenstorrent disabled. Build with USE_TT=1 to enable."
endif
# Clean
clean:
rm -f cuda_kernels/tests/test_q2_0_half_round
rm -f progress/*.o
rm -f progress/tests/test_progress
rm -f tensor/*.o
rm -f tensor/tests/test_tensor
rm -f tokenizer/*.o
rm -f tokenizer/tests/test_tokenizer
rm -f data/*.o
rm -f data/tests/test_data
rm -f data/tests/test_byte_dataset
rm -f safetensors/*.o
rm -f safetensors/tests/test_safetensors
rm -f lora/*.o
rm -f lora/tests/test_lora
rm -f quantization/*.o
rm -f quantization/tests/test_quantization
rm -f quantization/tests/test_export
rm -f examples/quantize_model
rm -f attention/*.o
rm -f attention/tests/test_attention
rm -f attention/tests/test_turboquant
rm -f distributed/*.o
rm -f distributed/tests/test_distributed
rm -f eval/*.o
rm -f eval/tests/test_eval
rm -f optim/*.o
rm -f optim/tests/test_optim
rm -f hdc/*.o
rm -f hdc/tests/test_hdc
rm -f hybridmem/*.o
rm -f hybridmem/tests/test_hybridmem
rm -f swarm/*.o
rm -f swarm/tests/test_swarm
rm -f bin/swarm_coordinator bin/swarm_worker
rm -f bin/compare_helper
rm -rf tensor/testing_suite/compare/__pycache__
rm -f threadpool/*.o
rm -f threadpool/tests/test_threadpool
rm -f rwkvx/*.o
rm -f rwkvx/tests/test_rwkvx
rm -f examples/train_mlp
rm -f examples/bench_hybridmem
rm -f examples/rwkvx_generate
rm -f examples/test_hybridmem_retrieval
rm -f examples/test_attn_weights
rm -f examples/test_hdc_correlation
rm -f examples/test_pooling_loss
rm -f examples/test_precision_at_scale
rm -f examples/test_eviction_boundary
rm -f examples/test_multi_fact
rm -f examples/test_filler_sensitivity
rm -f examples/test_context_scaling
rm -f examples/test_false_positive
rm -f examples/test_contiguous_chunk
rm -f examples/test_query_vector
rm -f examples/test_rosa_db_index
rm -f examples/test_rosa_db_retrieve
rm -f examples/test_rosa_db_qa
rm -f examples/rwkvx_train
rm -f rwkvx/tests/test_rx_train
rm -f rwkvx/tests/test_wkv7_bwd
rm -f cuda_kernels/tests/test_wkv7_cuda cuda_kernels/tests/rx_pretrain_wkv7.o
rm -f cuda_kernels/tests/test_timemix_cuda cuda_kernels/tests/rx_pretrain_tm.o
rm -f cuda_kernels/tests/test_moba_attn_cuda cuda_kernels/tests/rx_pretrain_attn.o
rm -f rwkvx/tests/test_timemix_bwd
rm -f rwkvx/tests/test_block_bwd
rm -f rwkvx/tests/test_attn_bwd
rm -f rwkvx/tests/test_model_bwd
rm -f rwkvx/tests/test_overfit
rm -f rwkvx/tests/test_rfa_train
rm -f examples/rfa_train
rm -f examples/rfa_lora_merge
rm -f rwkvx/tests/test_rfa_parallel
rm -f rosa/*.o
rm -f rosa/tests/test_rosa
rm -f barswap/*.o
rm -f barswap/tests/test_barswap
rm -f barswap/tests/vram_persist
rm -f barswap/tests/compute_persist
rm -f barswap/tests/xcard_persist
rm -f barswap/tests/roundrobin_persist
rm -f barswap/tests/gpu_switch_probe
rm -f barswap/tests/worker_switch
rm -f barswap/tests/gpu_owner
rm -f pth/*.o
rm -f pth/tests/test_pth
rm -f examples/pth_convert
rm -f metal/*.o metal/kernels/*.o
rm -f metal/tests/test_metal metal/tests/test_metal_fc metal/tests/test_metal_gemm_batched metal/tests/test_metal_region metal/tests/test_metal_q3_k metal/tests/test_metal_matvec_q5_k metal/tests/test_metal_matvec_q6_k metal/tests/test_metal_rope metal/tests/test_metal_norm metal/tests/test_metal_elementwise
rm -f metal/tests/test_gemm_q4_k metal/tests/test_gemm_q4_k_f16 metal/tests/bench_dispatch
rm -f cuda/*.o
rm -f cuda/tests/test_cuda cuda/tests/test_multi_ctx
rm -f cuda/tests/test_moe_expert_quants cuda/tests/bench_matvec
rm -f tt/*.o
rm -f tt/convert/*.o
rm -f ternarize/*.o
rm -f ternarize/tests/test_ternarize
rm -f examples/ternarize_split
rm -f examples/ternarize_sweep
rm -f examples/ternarize_flip
rm -f examples/ternarize_merge
# PTH module (PyTorch .pth reader)
pth: pth/pth.o
pth/pth.o: pth/pth.c pth/pth.h
$(CC) $(CFLAGS) -c $< -o $@
test-pth: pth/tests/test_pth
./pth/tests/test_pth
pth/tests/test_pth: pth/tests/test_pth.c pth/pth.c pth/pth.h safetensors/safetensors.c safetensors/safetensors.h
$(CC) $(CFLAGS) -o $@ pth/tests/test_pth.c pth/pth.c safetensors/safetensors.c -lm
examples/pth_convert: examples/pth_convert.c pth/pth.c pth/pth.h safetensors/safetensors.c safetensors/safetensors.h
$(CC) $(CFLAGS) -o $@ examples/pth_convert.c pth/pth.c safetensors/safetensors.c -lm
pth-convert: examples/pth_convert
# Attention module
attention: attention/attention.o attention/turboquant.o
attention/attention.o: attention/attention.c attention/attention.h tensor/tensor.h
$(CC) $(CFLAGS) -c $< -o $@
# TurboQuant KV compression (tensor-free; raw float*/uint8_t* API).
attention/turboquant.o: attention/turboquant.c attention/turboquant.h attention/tq_codebooks.h
$(CC) $(CFLAGS) -c $< -o $@
test-attention: attention/tests/test_attention
./attention/tests/test_attention
attention/tests/test_attention: attention/tests/test_attention.c attention/attention.c attention/attention.h tensor/tensor.c tensor/tensor.h
$(CC) $(CFLAGS) -o $@ attention/tests/test_attention.c attention/attention.c tensor/tensor.c -lm $(LDFLAGS_BLAS)
test-turboquant: attention/tests/test_turboquant
./attention/tests/test_turboquant
attention/tests/test_turboquant: attention/tests/test_turboquant.c attention/turboquant.c attention/turboquant.h attention/tq_codebooks.h
$(CC) $(CFLAGS) -o $@ attention/tests/test_turboquant.c attention/turboquant.c -lm
# KV-quality report: cosine of attention output, full-precision vs compressed,
# across bit widths and synthetic K/V distributions. Not a pass/fail gate (it
# prints distortion figures), so it is run manually rather than from `test`.
validate-turboquant: attention/tests/validate_tq_attention
./attention/tests/validate_tq_attention
attention/tests/validate_tq_attention: attention/tests/validate_tq_attention.c attention/turboquant.c attention/turboquant.h attention/tq_codebooks.h
$(CC) $(CFLAGS) -o $@ attention/tests/validate_tq_attention.c attention/turboquant.c -lm
# Distributed module
distributed: distributed/distributed.o
distributed/distributed.o: distributed/distributed.c distributed/distributed.h tensor/tensor.h
$(CC) $(CFLAGS) -c $< -o $@
test-distributed: distributed/tests/test_distributed
./distributed/tests/test_distributed
distributed/tests/test_distributed: distributed/tests/test_distributed.c distributed/distributed.c distributed/distributed.h tensor/tensor.c tensor/tensor.h
$(CC) $(CFLAGS) -o $@ distributed/tests/test_distributed.c distributed/distributed.c tensor/tensor.c -lm $(LDFLAGS_BLAS)
# Eval module
eval: eval/eval.o
eval/eval.o: eval/eval.c eval/eval.h data/data.h tokenizer/tokenizer.h
$(CC) $(CFLAGS) -c $< -o $@
test-eval: eval/tests/test_eval
./eval/tests/test_eval
eval/tests/test_eval: eval/tests/test_eval.c eval/eval.c eval/eval.h data/data.c data/data.h tokenizer/tokenizer.c tokenizer/tokenizer.h
$(CC) $(CFLAGS) -o $@ eval/tests/test_eval.c eval/eval.c data/data.c tokenizer/tokenizer.c -lm $(LDFLAGS_BLAS)
# Optim module
optim: optim/optim.o
optim/optim.o: optim/optim.c optim/optim.h tensor/tensor.h
$(CC) $(CFLAGS) -c $< -o $@
test-optim: optim/tests/test_optim
./optim/tests/test_optim
optim/tests/test_optim: optim/tests/test_optim.c optim/optim.c optim/optim.h tensor/tensor.c tensor/tensor.h
$(CC) $(CFLAGS) -o $@ optim/tests/test_optim.c optim/optim.c tensor/tensor.c -lm $(LDFLAGS_BLAS)
# Examples
examples: rwkv-vocab examples/train_mlp examples/bench_hybridmem examples/rwkvx_generate examples/test_hybridmem_retrieval examples/test_attn_weights examples/test_hdc_correlation examples/test_pooling_loss examples/test_precision_at_scale examples/test_eviction_boundary examples/test_multi_fact examples/test_filler_sensitivity examples/test_context_scaling examples/test_false_positive examples/test_contiguous_chunk examples/test_query_vector
examples/train_mlp: examples/train_mlp.c tensor/tensor.c tensor/tensor.h optim/optim.c optim/optim.h progress/progress.c progress/progress.h
$(CC) $(CFLAGS) -o $@ examples/train_mlp.c tensor/tensor.c optim/optim.c progress/progress.c -lm $(LDFLAGS_BLAS)
train: examples/train_mlp
./examples/train_mlp
examples/bench_hybridmem: examples/bench_hybridmem.c hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h
$(CC) $(CFLAGS) -o $@ examples/bench_hybridmem.c hybridmem/hybridmem.c hdc/hdc.c tensor/tensor.c safetensors/safetensors.c -lm $(LDFLAGS_BLAS)
bench-hybridmem: examples/bench_hybridmem
./examples/bench_hybridmem
# RWKV-X inference module
rwkvx: rwkvx/rwkvx.o
rwkvx/rwkvx.o: rwkvx/rwkvx.c rwkvx/rwkvx.h tensor/tensor.h safetensors/safetensors.h hybridmem/hybridmem.h hdc/hdc.h
$(CC) $(CFLAGS) -c $< -o $@
# The RWKV World vocab is third-party data, fetched (pinned URL + sha256) rather
# than committed. Fails loudly if it cannot be fetched or does not verify.
.PHONY: rwkv-vocab
rwkv-vocab:
sh rwkvx/data/fetch_rwkv_vocab.sh
test-rwkvx: rwkv-vocab rwkvx/tests/test_rwkvx
./rwkvx/tests/test_rwkvx
rwkvx/tests/test_rwkvx: rwkvx/tests/test_rwkvx.c rwkvx/rwkvx.c rwkvx/rwkvx.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
$(CC) $(CFLAGS) -o $@ rwkvx/tests/test_rwkvx.c rwkvx/rwkvx.c tensor/tensor.c safetensors/safetensors.c hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
examples/rwkvx_generate: examples/rwkvx_generate.c rwkvx/rwkvx.c rwkvx/rwkvx.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
$(CC) $(CFLAGS) -o $@ examples/rwkvx_generate.c rwkvx/rwkvx.c tensor/tensor.c safetensors/safetensors.c hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
examples/test_hybridmem_retrieval: examples/test_hybridmem_retrieval.c rwkvx/rwkvx.c rwkvx/rwkvx.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
$(CC) $(CFLAGS) -o $@ examples/test_hybridmem_retrieval.c rwkvx/rwkvx.c tensor/tensor.c safetensors/safetensors.c hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
examples/test_attn_weights: examples/test_attn_weights.c rwkvx/rwkvx.c rwkvx/rwkvx.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
$(CC) $(CFLAGS) -o $@ examples/test_attn_weights.c rwkvx/rwkvx.c tensor/tensor.c safetensors/safetensors.c hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
examples/test_hdc_correlation: examples/test_hdc_correlation.c rwkvx/rwkvx.c rwkvx/rwkvx.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
$(CC) $(CFLAGS) -o $@ examples/test_hdc_correlation.c rwkvx/rwkvx.c tensor/tensor.c safetensors/safetensors.c hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
examples/test_pooling_loss: examples/test_pooling_loss.c hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h $(METAL_SRC) $(CUDA_SRC)
$(CC) $(CFLAGS) -o $@ examples/test_pooling_loss.c hybridmem/hybridmem.c hdc/hdc.c tensor/tensor.c safetensors/safetensors.c $(METAL_SRC) $(CUDA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
examples/test_precision_at_scale: examples/test_precision_at_scale.c hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h $(METAL_SRC) $(CUDA_SRC)
$(CC) $(CFLAGS) -o $@ examples/test_precision_at_scale.c hybridmem/hybridmem.c hdc/hdc.c tensor/tensor.c safetensors/safetensors.c $(METAL_SRC) $(CUDA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
examples/test_eviction_boundary: examples/test_eviction_boundary.c rwkvx/rwkvx.c rwkvx/rwkvx.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
$(CC) $(CFLAGS) -o $@ examples/test_eviction_boundary.c rwkvx/rwkvx.c tensor/tensor.c safetensors/safetensors.c hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
examples/test_multi_fact: examples/test_multi_fact.c rwkvx/rwkvx.c rwkvx/rwkvx.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
$(CC) $(CFLAGS) -o $@ examples/test_multi_fact.c rwkvx/rwkvx.c tensor/tensor.c safetensors/safetensors.c hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
examples/test_filler_sensitivity: examples/test_filler_sensitivity.c rwkvx/rwkvx.c rwkvx/rwkvx.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
$(CC) $(CFLAGS) -o $@ examples/test_filler_sensitivity.c rwkvx/rwkvx.c tensor/tensor.c safetensors/safetensors.c hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
examples/test_context_scaling: examples/test_context_scaling.c rwkvx/rwkvx.c rwkvx/rwkvx.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
$(CC) $(CFLAGS) -o $@ examples/test_context_scaling.c rwkvx/rwkvx.c tensor/tensor.c safetensors/safetensors.c hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
examples/test_false_positive: examples/test_false_positive.c rwkvx/rwkvx.c rwkvx/rwkvx.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
$(CC) $(CFLAGS) -o $@ examples/test_false_positive.c rwkvx/rwkvx.c tensor/tensor.c safetensors/safetensors.c hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
examples/test_contiguous_chunk: examples/test_contiguous_chunk.c rwkvx/rwkvx.c rwkvx/rwkvx.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
$(CC) $(CFLAGS) -o $@ examples/test_contiguous_chunk.c rwkvx/rwkvx.c tensor/tensor.c safetensors/safetensors.c hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
test-contiguous-chunk: examples/test_contiguous_chunk
examples/test_query_vector: examples/test_query_vector.c rwkvx/rwkvx.c rwkvx/rwkvx.h tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
$(CC) $(CFLAGS) -o $@ examples/test_query_vector.c rwkvx/rwkvx.c tensor/tensor.c safetensors/safetensors.c hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
# Model format converter (safetensors → .btw/.btv)
examples/model_convert: examples/model_convert.c convert/convert.c convert/convert.h safetensors/safetensors.c safetensors/safetensors.h quantization/quantization.c quantization/quantization.h tokenizer/tokenizer.c tokenizer/tokenizer.h
$(CC) $(CFLAGS) -o $@ examples/model_convert.c convert/convert.c safetensors/safetensors.c quantization/quantization.c tokenizer/tokenizer.c -lm $(LDFLAGS_BLAS)
model-convert: examples/model_convert
# ROSA-DB integration tests
ROSA_DB_DEPS = rosa/rosa.c rosa/rosa.h rwkvx/rwkvx.c rwkvx/rwkvx.h \
tensor/tensor.c tensor/tensor.h data/data.c data/data.h \
tokenizer/tokenizer.c tokenizer/tokenizer.h \
safetensors/safetensors.c safetensors/safetensors.h \
hybridmem/hybridmem.c hybridmem/hybridmem.h \
hdc/hdc.c hdc/hdc.h $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
ROSA_DB_SRC = rosa/rosa.c rwkvx/rwkvx.c tensor/tensor.c data/data.c \
tokenizer/tokenizer.c safetensors/safetensors.c \
hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
examples/test_rosa_db_index: examples/test_rosa_db_index.c $(ROSA_DB_DEPS)
$(CC) $(CFLAGS) -o $@ examples/test_rosa_db_index.c $(ROSA_DB_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_SQLITE) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
test-rosa-db-index: examples/test_rosa_db_index
examples/test_rosa_db_retrieve: examples/test_rosa_db_retrieve.c $(ROSA_DB_DEPS)
$(CC) $(CFLAGS) -o $@ examples/test_rosa_db_retrieve.c $(ROSA_DB_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_SQLITE) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
test-rosa-db-retrieve: examples/test_rosa_db_retrieve
examples/test_rosa_db_qa: examples/test_rosa_db_qa.c $(ROSA_DB_DEPS)
$(CC) $(CFLAGS) -o $@ examples/test_rosa_db_qa.c $(ROSA_DB_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_SQLITE) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
test-rosa-db-qa: examples/test_rosa_db_qa
# RFA (RWKV-7 + Full Attention hybrid) engine
RFA_DEPS = rwkvx/rfa.c rwkvx/rfa.h rwkvx/rwkvx.c rwkvx/rwkvx.h \
tensor/tensor.c tensor/tensor.h safetensors/safetensors.c safetensors/safetensors.h \
hybridmem/hybridmem.c hybridmem/hybridmem.h hdc/hdc.c hdc/hdc.h $(THREADPOOL_SRC)
RFA_SRC = rwkvx/rfa.c rwkvx/rwkvx.c tensor/tensor.c safetensors/safetensors.c \
hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC)
examples/rfa_generate: examples/rfa_generate.c $(RFA_DEPS)
$(CC) $(CFLAGS) -o $@ examples/rfa_generate.c $(RFA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS)
rfa-generate: examples/rfa_generate
# RFA training module
RFA_TRAIN_DEPS = rwkvx/rfa_train.c rwkvx/rfa_train.h rwkvx/rfa.c rwkvx/rfa.h \
rwkvx/rwkvx.c rwkvx/rwkvx.h \
tensor/tensor.c tensor/tensor.h lora/lora.c lora/lora.h \
optim/optim.c optim/optim.h \
safetensors/safetensors.c safetensors/safetensors.h \
hybridmem/hybridmem.c hybridmem/hybridmem.h \
hdc/hdc.c hdc/hdc.h $(THREADPOOL_SRC)
RFA_TRAIN_SRC = rwkvx/rfa_train.c rwkvx/rfa.c rwkvx/rwkvx.c tensor/tensor.c lora/lora.c \
optim/optim.c safetensors/safetensors.c hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC)
examples/rfa_train: examples/rfa_train.c $(RFA_TRAIN_DEPS)
$(CC) $(CFLAGS) -o $@ examples/rfa_train.c $(RFA_TRAIN_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS)
rfa-train: examples/rfa_train
# RFA LoRA merge tool
examples/rfa_lora_merge: examples/rfa_lora_merge.c $(RFA_TRAIN_DEPS)
$(CC) $(CFLAGS) -o $@ examples/rfa_lora_merge.c $(RFA_TRAIN_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS)
rfa-lora-merge: examples/rfa_lora_merge
test-rfa-train: rwkvx/tests/test_rfa_train
./rwkvx/tests/test_rfa_train
rwkvx/tests/test_rfa_train: rwkvx/tests/test_rfa_train.c $(RFA_TRAIN_DEPS)
$(CC) $(CFLAGS) -o $@ rwkvx/tests/test_rfa_train.c $(RFA_TRAIN_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS)
# RFA parallel training tests
test-rfa-parallel: rwkvx/tests/test_rfa_parallel
./rwkvx/tests/test_rfa_parallel
rwkvx/tests/test_rfa_parallel: rwkvx/tests/test_rfa_parallel.c $(RFA_TRAIN_DEPS)
$(CC) $(CFLAGS) -pthread -o $@ rwkvx/tests/test_rfa_parallel.c $(RFA_TRAIN_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) -pthread
rwkvx-generate: examples/rwkvx_generate
# RWKV-X training module
RWKVX_TRAIN_DEPS = rwkvx/rx_train.c rwkvx/rx_train.h rwkvx/rwkvx.c rwkvx/rwkvx.h \
tensor/tensor.c tensor/tensor.h lora/lora.c lora/lora.h \
optim/optim.c optim/optim.h data/data.c data/data.h \
tokenizer/tokenizer.c tokenizer/tokenizer.h \
safetensors/safetensors.c safetensors/safetensors.h \
hybridmem/hybridmem.c hybridmem/hybridmem.h \
hdc/hdc.c hdc/hdc.h $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
RWKVX_TRAIN_SRC = rwkvx/rx_train.c rwkvx/rwkvx.c tensor/tensor.c lora/lora.c \
optim/optim.c data/data.c tokenizer/tokenizer.c \
safetensors/safetensors.c hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
# SQLite support (opt-in: make HAS_SQLITE=1)
ifdef HAS_SQLITE
CFLAGS += -DHAS_SQLITE
LDFLAGS_SQLITE = -lsqlite3
else
LDFLAGS_SQLITE =
endif
examples/rwkvx_train: examples/rwkvx_train.c $(RWKVX_TRAIN_DEPS)
$(CC) $(CFLAGS) -o $@ examples/rwkvx_train.c $(RWKVX_TRAIN_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_SQLITE) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
rwkvx-train: examples/rwkvx_train
test-rx-train: rwkvx/tests/test_rx_train
./rwkvx/tests/test_rx_train
rwkvx/tests/test_rx_train: rwkvx/tests/test_rx_train.c $(RWKVX_TRAIN_DEPS)
$(CC) $(CFLAGS) -o $@ rwkvx/tests/test_rx_train.c $(RWKVX_TRAIN_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
# WKV7 backward-through-time gradient check (self-contained pretrain kernel)
test-wkv7-bwd: rwkvx/tests/test_wkv7_bwd
./rwkvx/tests/test_wkv7_bwd
rwkvx/tests/test_wkv7_bwd: rwkvx/tests/test_wkv7_bwd.c rwkvx/tests/wkv7_fixture.h rwkvx/rx_pretrain.c rwkvx/rx_pretrain.h
$(CC) $(CFLAGS) -o $@ rwkvx/tests/test_wkv7_bwd.c rwkvx/rx_pretrain.c -lm
# WKV7 fwd+bwd CUDA kernel (sm_37/K80) parity vs the CPU oracle rx_wkv7_*.
# Standalone nvcc build -- NOT the fc_cuda_ptx.h embed pipeline. Run on the
# K80 host (needs nvcc 11.4 + gcc-11 host compiler). Uses GPU 0.
WKV7_NVCC ?= /usr/local/cuda-11.4/bin/nvcc
WKV7_CUDA_ARCH ?= sm_37
WKV7_HOST_CC ?= gcc-11
test-wkv7-cuda: cuda_kernels/tests/test_wkv7_cuda
CUDA_VISIBLE_DEVICES=0 ./cuda_kernels/tests/test_wkv7_cuda
cuda_kernels/tests/test_wkv7_cuda: cuda_kernels/tests/test_wkv7_cuda.cu cuda_kernels/wkv7.cu rwkvx/tests/wkv7_fixture.h rwkvx/rx_pretrain.c rwkvx/rx_pretrain.h
$(WKV7_HOST_CC) -std=c11 -O3 $(ARCH_FLAGS) -ffast-math -D_GNU_SOURCE -I. -c rwkvx/rx_pretrain.c -o cuda_kernels/tests/rx_pretrain_wkv7.o
$(WKV7_NVCC) -arch=$(WKV7_CUDA_ARCH) -ccbin $(WKV7_HOST_CC) -Wno-deprecated-gpu-targets -isystem cuda_kernels/nvcc_shim -I. -O3 -o $@ cuda_kernels/tests/test_wkv7_cuda.cu cuda_kernels/tests/rx_pretrain_wkv7.o -lm
# GPU RWKV-7 time-mix block (cuBLAS projections + elementwise kernels + WKV7)
# parity vs the CPU oracle rx_timemix_*. K80 host; GPU 0; links cuBLAS.
CUDA_LIBDIR ?= /usr/local/cuda-11.4/lib64
test-timemix-cuda: cuda_kernels/tests/test_timemix_cuda
CUDA_VISIBLE_DEVICES=0 ./cuda_kernels/tests/test_timemix_cuda
cuda_kernels/tests/test_timemix_cuda: cuda_kernels/tests/test_timemix_cuda.cu cuda_kernels/timemix.cu cuda_kernels/wkv7.cu rwkvx/rx_pretrain.c rwkvx/rx_pretrain.h
$(WKV7_HOST_CC) -std=c11 -O3 $(ARCH_FLAGS) -ffast-math -D_GNU_SOURCE -I. -c rwkvx/rx_pretrain.c -o cuda_kernels/tests/rx_pretrain_tm.o
$(WKV7_NVCC) -arch=$(WKV7_CUDA_ARCH) -ccbin $(WKV7_HOST_CC) -Wno-deprecated-gpu-targets -isystem cuda_kernels/nvcc_shim -I. -O3 -o $@ cuda_kernels/tests/test_timemix_cuda.cu cuda_kernels/tests/rx_pretrain_tm.o -L$(CUDA_LIBDIR) -lcublas -lm
# GPU LayerNorm fwd+bwd parity vs the CPU oracle rx_layernorm_*. K80 host; GPU 0.
test-layernorm-cuda: cuda_kernels/tests/test_layernorm_cuda
CUDA_VISIBLE_DEVICES=0 ./cuda_kernels/tests/test_layernorm_cuda
cuda_kernels/tests/test_layernorm_cuda: cuda_kernels/tests/test_layernorm_cuda.cu cuda_kernels/layernorm.cu rwkvx/rx_pretrain.c rwkvx/rx_pretrain.h
$(WKV7_HOST_CC) -std=c11 -O3 $(ARCH_FLAGS) -ffast-math -D_GNU_SOURCE -I. -c rwkvx/rx_pretrain.c -o cuda_kernels/tests/rx_pretrain_ln.o
$(WKV7_NVCC) -arch=$(WKV7_CUDA_ARCH) -ccbin $(WKV7_HOST_CC) -Wno-deprecated-gpu-targets -isystem cuda_kernels/nvcc_shim -I. -O3 -o $@ cuda_kernels/tests/test_layernorm_cuda.cu cuda_kernels/tests/rx_pretrain_ln.o -lm
# GPU channel-mix (squared-ReLU FFN) fwd+bwd parity vs the CPU oracle rx_channelmix_*. K80 host; GPU 0; links cuBLAS.
test-channelmix-cuda: cuda_kernels/tests/test_channelmix_cuda
CUDA_VISIBLE_DEVICES=0 ./cuda_kernels/tests/test_channelmix_cuda
cuda_kernels/tests/test_channelmix_cuda: cuda_kernels/tests/test_channelmix_cuda.cu cuda_kernels/channelmix.cu rwkvx/rx_pretrain.c rwkvx/rx_pretrain.h
$(WKV7_HOST_CC) -std=c11 -O3 $(ARCH_FLAGS) -ffast-math -D_GNU_SOURCE -I. -c rwkvx/rx_pretrain.c -o cuda_kernels/tests/rx_pretrain_cm.o
$(WKV7_NVCC) -arch=$(WKV7_CUDA_ARCH) -ccbin $(WKV7_HOST_CC) -Wno-deprecated-gpu-targets -isystem cuda_kernels/nvcc_shim -I. -O3 -o $@ cuda_kernels/tests/test_channelmix_cuda.cu cuda_kernels/tests/rx_pretrain_cm.o -L$(CUDA_LIBDIR) -lcublas -lm
# GPU MoBA sparse-attention core (scores->softmax->AV) fwd+bwd parity vs the CPU
# oracle rx_attn_score_av_* (the exact core rx_attn_forward_seq/backward_full
# use). K80 host; GPU 0; cuBLAS for Q·Kᵀ / A·V / dQ,dK,dV gemms.
test-attn-cuda: cuda_kernels/tests/test_moba_attn_cuda
CUDA_VISIBLE_DEVICES=0 ./cuda_kernels/tests/test_moba_attn_cuda
cuda_kernels/tests/test_moba_attn_cuda: cuda_kernels/tests/test_moba_attn_cuda.cu cuda_kernels/moba_attn.cu rwkvx/rx_pretrain.c rwkvx/rx_pretrain.h
$(WKV7_HOST_CC) -std=c11 -O3 $(ARCH_FLAGS) -ffast-math -D_GNU_SOURCE -I. -c rwkvx/rx_pretrain.c -o cuda_kernels/tests/rx_pretrain_attn.o
$(WKV7_NVCC) -arch=$(WKV7_CUDA_ARCH) -ccbin $(WKV7_HOST_CC) -Wno-deprecated-gpu-targets -isystem cuda_kernels/nvcc_shim -I. -O3 -o $@ cuda_kernels/tests/test_moba_attn_cuda.cu cuda_kernels/tests/rx_pretrain_attn.o -L$(CUDA_LIBDIR) -lcublas -lm
# ============================================================
# Phase-2 completion gate: FULL RWKV-x training step on GPU (sm_37)
# ============================================================
# Embedding (gather + scatter-add), LM head (cuBLAS), fused log-softmax CE, and
# the assembled whole-model fwd+bwd, parity-checked vs the CPU oracle
# rx_pretrain_forward/backward on GPU 0. K80 host; cuBLAS; weights resident.
test-fullmodel-cuda: cuda_kernels/tests/test_fullmodel_cuda
CUDA_VISIBLE_DEVICES=0 ./cuda_kernels/tests/test_fullmodel_cuda
cuda_kernels/tests/test_fullmodel_cuda: cuda_kernels/tests/test_fullmodel_cuda.cu cuda_kernels/fullmodel.cu cuda_kernels/timemix.cu cuda_kernels/wkv7.cu cuda_kernels/channelmix.cu cuda_kernels/layernorm.cu cuda_kernels/moba_attn.cu rwkvx/rx_pretrain.c rwkvx/rx_pretrain.h
$(WKV7_HOST_CC) -std=c11 -O3 $(ARCH_FLAGS) -ffast-math -D_GNU_SOURCE -I. -c rwkvx/rx_pretrain.c -o cuda_kernels/tests/rx_pretrain_fm.o
$(WKV7_NVCC) -arch=$(WKV7_CUDA_ARCH) -ccbin $(WKV7_HOST_CC) -Wno-deprecated-gpu-targets -isystem cuda_kernels/nvcc_shim -I. -O3 -o $@ cuda_kernels/tests/test_fullmodel_cuda.cu cuda_kernels/tests/rx_pretrain_fm.o -L$(CUDA_LIBDIR) -lcublas -lm
# Isolated parity for the three new leaf kernels (embedding gather/scatter, LM
# head, fused log-softmax cross-entropy) vs the CPU oracle. Same binary serves
# test-embed-cuda and test-ce-cuda.
test-embed-cuda test-ce-cuda: cuda_kernels/tests/test_embed_ce_cuda
CUDA_VISIBLE_DEVICES=0 ./cuda_kernels/tests/test_embed_ce_cuda
cuda_kernels/tests/test_embed_ce_cuda: cuda_kernels/tests/test_embed_ce_cuda.cu cuda_kernels/fullmodel.cu rwkvx/rx_pretrain.c rwkvx/rx_pretrain.h
$(WKV7_HOST_CC) -std=c11 -O3 $(ARCH_FLAGS) -ffast-math -D_GNU_SOURCE -I. -c rwkvx/rx_pretrain.c -o cuda_kernels/tests/rx_pretrain_ec.o
$(WKV7_NVCC) -arch=$(WKV7_CUDA_ARCH) -ccbin $(WKV7_HOST_CC) -Wno-deprecated-gpu-targets -isystem cuda_kernels/nvcc_shim -I. -O3 -o $@ cuda_kernels/tests/test_embed_ce_cuda.cu cuda_kernels/tests/rx_pretrain_ec.o -L$(CUDA_LIBDIR) -lcublas -lm
# GPU optimizer-step kernels (SR4 int4-accumulator step + AdamW) parity vs the
# CPU optimizer. K80 host; GPU 0; elementwise, no cuBLAS. Links the REAL CPU
# oracle code: ternary_optim.c (SR4, self-contained) and optim.c (AdamW) via a
# minimal tensor shim. SR4 oracle built WITHOUT -ffast-math so its double
# mean|g| reduction stays strict-sequential -> bit-identical to the single-thread
# GPU reduction (the integer SR path is flag-immune by construction).
test-optim-cuda: cuda_kernels/tests/test_optim_cuda
CUDA_VISIBLE_DEVICES=0 ./cuda_kernels/tests/test_optim_cuda
cuda_kernels/tests/test_optim_cuda: cuda_kernels/tests/test_optim_cuda.cu cuda_kernels/optim.cu ternary_optim/ternary_optim.c ternary_optim/ternary_optim.h optim/optim.c optim/optim.h tensor/tensor.h cuda_kernels/tests/tensor_shim.c
$(WKV7_HOST_CC) -std=c11 -O3 -D_GNU_SOURCE -I. -c ternary_optim/ternary_optim.c -o cuda_kernels/tests/ternary_optim.o
$(WKV7_HOST_CC) -std=c11 -O3 $(ARCH_FLAGS) -ffast-math -D_GNU_SOURCE -I. -c optim/optim.c -o cuda_kernels/tests/optim_oracle.o
$(WKV7_HOST_CC) -std=c11 -O3 $(ARCH_FLAGS) -ffast-math -D_GNU_SOURCE -I. -c cuda_kernels/tests/tensor_shim.c -o cuda_kernels/tests/tensor_shim.o
$(WKV7_NVCC) -arch=$(WKV7_CUDA_ARCH) -ccbin $(WKV7_HOST_CC) -Wno-deprecated-gpu-targets -isystem cuda_kernels/nvcc_shim -I. -O3 -o $@ cuda_kernels/tests/test_optim_cuda.cu cuda_kernels/tests/ternary_optim.o cuda_kernels/tests/optim_oracle.o cuda_kernels/tests/tensor_shim.o -lm
# RWKV-7 time-mix block backward gradient check (fp64 finite differences)
test-timemix-bwd: rwkvx/tests/test_timemix_bwd
./rwkvx/tests/test_timemix_bwd
rwkvx/tests/test_timemix_bwd: rwkvx/tests/test_timemix_bwd.c rwkvx/rx_pretrain.c rwkvx/rx_pretrain.h
$(CC) $(CFLAGS) -o $@ rwkvx/tests/test_timemix_bwd.c rwkvx/rx_pretrain.c -lm
# RWKV-7 full block backward gradient check (fp64 finite differences)
test-block-bwd: rwkvx/tests/test_block_bwd
./rwkvx/tests/test_block_bwd
rwkvx/tests/test_block_bwd: rwkvx/tests/test_block_bwd.c rwkvx/rx_pretrain.c rwkvx/rx_pretrain.h
$(CC) $(CFLAGS) -o $@ rwkvx/tests/test_block_bwd.c rwkvx/rx_pretrain.c -lm
# Sparse (MoBA-style) attention block backward, base-weight grads (fp64 FD)
test-attn-bwd: rwkvx/tests/test_attn_bwd
./rwkvx/tests/test_attn_bwd
rwkvx/tests/test_attn_bwd: rwkvx/tests/test_attn_bwd.c rwkvx/rx_pretrain.c rwkvx/rx_pretrain.h
$(CC) $(CFLAGS) -o $@ rwkvx/tests/test_attn_bwd.c rwkvx/rx_pretrain.c -lm
# Whole-model RWKV-x forward+backward gradient check (fp64 finite differences)
test-model-bwd: rwkvx/tests/test_model_bwd
./rwkvx/tests/test_model_bwd
rwkvx/tests/test_model_bwd: rwkvx/tests/test_model_bwd.c rwkvx/rx_pretrain.c rwkvx/rx_pretrain.h rwkvx/rwkvx.c rwkvx/rwkvx.h tensor/tensor.c safetensors/safetensors.c hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC)
$(CC) $(CFLAGS) -DRX_LINK_ENGINE -o $@ rwkvx/tests/test_model_bwd.c rwkvx/rx_pretrain.c rwkvx/rwkvx.c tensor/tensor.c safetensors/safetensors.c hybridmem/hybridmem.c hdc/hdc.c $(THREADPOOL_SRC) $(METAL_SRC) $(CUDA_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS) $(LDFLAGS_METAL) $(LDFLAGS_CUDA)
# Overfit smoke: training loop with SR4/AdamW swappable optimizers.
# Standalone (slow optimization loop) — intentionally NOT in the `test` aggregate.
test-overfit: rwkvx/tests/test_overfit
./rwkvx/tests/test_overfit
rwkvx/tests/test_overfit: rwkvx/tests/test_overfit.c rwkvx/rx_pretrain.c rwkvx/rx_pretrain.h ternary_optim/ternary_optim.c ternary_optim/ternary_optim.h optim/optim.c optim/optim.h tensor/tensor.c tensor/tensor.h
$(CC) $(CFLAGS) -o $@ rwkvx/tests/test_overfit.c rwkvx/rx_pretrain.c ternary_optim/ternary_optim.c optim/optim.c tensor/tensor.c -lm $(LDFLAGS_BLAS)
# ============================================================
# Swarm module (custom extension)
# ============================================================
SWARM_SRC = swarm/protocol.c swarm/network.c swarm/coordinator.c swarm/worker.c swarm/config.c
SWARM_HDR = swarm/protocol.h swarm/network.h swarm/coordinator.h swarm/worker.h swarm/config.h
SWARM_OBJ = swarm/protocol.o swarm/network.o swarm/coordinator.o swarm/worker.o swarm/config.o
# Swarm object files
swarm: $(SWARM_OBJ)
swarm/protocol.o: swarm/protocol.c swarm/protocol.h
$(CC) $(CFLAGS) -c $< -o $@
swarm/network.o: swarm/network.c swarm/network.h swarm/protocol.h
$(CC) $(CFLAGS) -c $< -o $@
swarm/config.o: swarm/config.c swarm/config.h
$(CC) $(CFLAGS) -c $< -o $@
swarm/coordinator.o: swarm/coordinator.c swarm/coordinator.h swarm/protocol.h swarm/network.h tensor/tensor.h optim/optim.h
$(CC) $(CFLAGS) -c $< -o $@
swarm/worker.o: swarm/worker.c swarm/worker.h swarm/protocol.h swarm/network.h tensor/tensor.h
$(CC) $(CFLAGS) -c $< -o $@
# Swarm binaries
SWARM_DEPS = $(SWARM_SRC) $(SWARM_HDR) tensor/tensor.c tensor/tensor.h optim/optim.c optim/optim.h
bin/swarm_coordinator: swarm/coordinator_main.c $(SWARM_DEPS)
@mkdir -p bin
$(CC) $(CFLAGS) -o $@ swarm/coordinator_main.c $(SWARM_SRC) tensor/tensor.c optim/optim.c -lm $(LDFLAGS_BLAS)
bin/swarm_worker: swarm/worker_main.c $(SWARM_DEPS)
@mkdir -p bin
$(CC) $(CFLAGS) -o $@ swarm/worker_main.c $(SWARM_SRC) tensor/tensor.c optim/optim.c -lm $(LDFLAGS_BLAS)
swarm-bin: bin/swarm_coordinator bin/swarm_worker
# Swarm tests
test-swarm: swarm/tests/test_swarm
./swarm/tests/test_swarm
swarm/tests/test_swarm: swarm/tests/test_swarm.c $(SWARM_DEPS)
@mkdir -p swarm/tests
$(CC) $(CFLAGS) -o $@ swarm/tests/test_swarm.c $(SWARM_SRC) tensor/tensor.c optim/optim.c -lm $(LDFLAGS_BLAS)
# ============================================================
# Tensor Comparison Helper (for PyTorch parity testing)
# ============================================================
bin/compare_helper: tensor/testing_suite/compare_helper.c tensor/tensor.c tensor/tensor.h
@mkdir -p bin
$(CC) $(CFLAGS) -o $@ tensor/testing_suite/compare_helper.c tensor/tensor.c -lm $(LDFLAGS_BLAS)
compare-helper: bin/compare_helper
# Run comparison tests against PyTorch. Needs python3 with torch and numpy.
compare-test: bin/compare_helper
cd tensor/testing_suite && python3 run_all.py
compare-test-quick: bin/compare_helper
cd tensor/testing_suite && python3 run_all.py --quick
# ============================================================
# Ternarize module (post-training ternary quantization)
# ============================================================
TERNARIZE_SRC = ternarize/ternarize.c ternarize/ft_layer_ops.c \
quantization/quantization.c safetensors/safetensors.c \
convert/convert.c tensor/tensor.c tokenizer/tokenizer.c $(CUDA_SRC)
TERNARIZE_DEPS = ternarize/ternarize.c ternarize/ternarize.h \
ternarize/ft_layer_ops.c ternarize/ft_layer_ops.h \
quantization/quantization.c quantization/quantization.h \
safetensors/safetensors.c safetensors/safetensors.h \
convert/convert.c convert/convert.h \
tensor/tensor.c tensor/tensor.h \
tokenizer/tokenizer.c tokenizer/tokenizer.h $(CUDA_SRC)
ternarize: ternarize/ternarize.o ternarize/ft_layer_ops.o
ternarize/ternarize.o: ternarize/ternarize.c ternarize/ternarize.h ternarize/ft_layer_ops.h
$(CC) $(CFLAGS) -c $< -o $@
ternarize/ft_layer_ops.o: ternarize/ft_layer_ops.c ternarize/ft_layer_ops.h ternarize/ternarize.h
$(CC) $(CFLAGS) -c $< -o $@
test-ternarize: ternarize/tests/test_ternarize
./ternarize/tests/test_ternarize
ternarize/tests/test_ternarize: ternarize/tests/test_ternarize.c $(TERNARIZE_DEPS)
$(CC) $(CFLAGS) -o $@ ternarize/tests/test_ternarize.c $(TERNARIZE_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS_CUDA)
examples/ternarize_split: examples/ternarize_split.c $(TERNARIZE_DEPS)
$(CC) $(CFLAGS) -o $@ examples/ternarize_split.c $(TERNARIZE_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS_CUDA)
examples/ternarize_sweep: examples/ternarize_sweep.c $(TERNARIZE_DEPS)
$(CC) $(CFLAGS) -o $@ examples/ternarize_sweep.c $(TERNARIZE_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS_CUDA)
examples/ternarize_flip: examples/ternarize_flip.c $(TERNARIZE_DEPS)
$(CC) $(CFLAGS) -o $@ examples/ternarize_flip.c $(TERNARIZE_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS_CUDA)
examples/ternarize_merge: examples/ternarize_merge.c $(TERNARIZE_DEPS)
$(CC) $(CFLAGS) -o $@ examples/ternarize_merge.c $(TERNARIZE_SRC) -lm $(LDFLAGS_BLAS) $(LDFLAGS_CUDA)
ternarize-split: examples/ternarize_split
ternarize-sweep: examples/ternarize_sweep
ternarize-flip: examples/ternarize_flip
ternarize-merge: examples/ternarize_merge
.PHONY: bench-dispatch all clean test test-progress test-tensor test-tokenizer test-safetensors test-lora test-data test-byte-data test-quantization test-export test-attention test-turboquant validate-turboquant test-distributed test-eval test-optim test-hdc test-hybridmem test-threadpool test-rwkvx test-rx-train test-wkv7-bwd test-wkv7-cuda test-timemix-cuda test-layernorm-cuda test-channelmix-cuda test-attn-cuda test-timemix-bwd test-block-bwd test-attn-bwd test-model-bwd test-overfit test-rfa-train test-rfa-parallel test-rosa test-barswap test-pth test-swarm test-metal test-cuda test-cuda-multi test-tt test-ternarize vram-persist compute-persist xcard-persist roundrobin-persist gpu-switch-probe worker-switch gpu-owner examples train bench-hybridmem rwkvx-generate rwkvx-train rfa-generate rfa-train rfa-lora-merge quantize-model pth-convert swarm swarm-bin compare-helper compare-test compare-test-quick ternarize-split ternarize-sweep ternarize-flip ternarize-merge $(MODULES) test-fullmodel-cuda test-embed-cuda test-ce-cuda test-optim-cuda