# SPDX-License-Identifier: AGPL-3.0-or-later # Copyright (C) 2026 David (Corey) Herrera # Foundry Blackhole backend — Phase 3 host-side conversion tests. # # Nothing here touches the card: the block-float comparison runs against the # committed reference vectors in ../reference/ (regenerate: `make bfp-reference`). Everything builds and runs on the # Mac, which is also where the real conversion runs (spec §8.4). # # `make red` exists because a green test nobody has watched fail is not # evidence (coding-best-practices.md §9). It rebuilds from scratch: Apple ships # GNU make 3.81, whose one-second mtime granularity silently skips a rebuild of # a source edited in the same second as its object, so a mutation loop that # relies on incremental make can be testing the PREVIOUS binary. CC ?= cc CONVERT := .. TT := ../.. BUILD := build CFLAGS := -std=c99 -O1 -g \ -Wall -Wextra -Werror -pedantic \ -Wshadow -Wconversion -Wstrict-prototypes -Wformat=2 \ -fstack-protector-strong \ -I$(CONVERT) -I$(TT) -I$(CONVERT)/reference # macOS puts libm inside libSystem, so this suite linked on the Mac without it # and failed to link on the card host the first time anyone tried — the same shape of # gap as the MADV_DONTNEED one in ft_gguf_map.c. The converter uses sqrt() for # every error figure it reports, so this is not optional anywhere. LDLIBS := -lm BFP_SOURCES := $(CONVERT)/ft_bfp.c $(TT)/ft_tt_tilize.c test_bfp.c BFP_TARGET := $(BUILD)/test_bfp CONVERT_SOURCES := $(CONVERT)/ft_bfp.c \ $(CONVERT)/ft_float_convert.c \ $(CONVERT)/ft_gguf_map.c \ $(CONVERT)/ft_gguf_dequant.c \ $(CONVERT)/ft_tt_precision_ledger.c \ $(CONVERT)/ft_tt_weight_convert.c \ $(TT)/ft_tt_tilize.c \ test_convert.c CONVERT_TARGET := $(BUILD)/test_convert CACHE_SOURCES := $(CONVERT)/ft_bfp.c \ $(CONVERT)/ft_float_convert.c \ $(CONVERT)/ft_gguf_map.c \ $(CONVERT)/ft_gguf_dequant.c \ $(CONVERT)/ft_tt_precision_ledger.c \ $(CONVERT)/ft_tt_weight_convert.c \ $(CONVERT)/ft_tt_capacity_plan.c \ $(CONVERT)/ft_tt_artifact_provenance.c \ $(CONVERT)/ft_tt_artifact_cache.c \ $(TT)/ft_tt_tilize.c \ test_artifact_cache.c CACHE_TARGET := $(BUILD)/test_artifact_cache .PHONY: all check red clean bfp-reference all: $(BFP_TARGET) $(CONVERT_TARGET) $(CACHE_TARGET) $(BUILD): mkdir -p $(BUILD) # One direct cc per program on purpose: whole-program builds cannot serve a # stale object out of the GNU make 3.81 same-second staleness trap. $(BFP_TARGET): $(BFP_SOURCES) | $(BUILD) $(CC) $(CFLAGS) $(BFP_SOURCES) -o $@ $(LDLIBS) $(CONVERT_TARGET): $(CONVERT_SOURCES) | $(BUILD) $(CC) $(CFLAGS) $(CONVERT_SOURCES) -o $@ $(LDLIBS) $(CACHE_TARGET): $(CACHE_SOURCES) | $(BUILD) $(CC) $(CFLAGS) $(CACHE_SOURCES) -o $@ $(LDLIBS) check: $(BFP_TARGET) $(CONVERT_TARGET) $(CACHE_TARGET) ./$(BFP_TARGET) ./$(CONVERT_TARGET) ./$(CACHE_TARGET) # Full rebuild, then run. Use this for every red/green pass. red: clean $(BFP_TARGET) $(CONVERT_TARGET) $(CACHE_TARGET) -./$(BFP_TARGET) -./$(CONVERT_TARGET) -./$(CACHE_TARGET) # Regenerate ../reference/ft_bfp_reference_vectors.h. The generator refuses to # write unless its independent reference agrees with ft_bfp.c on every word. bfp-reference: | $(BUILD) $(CC) $(CFLAGS) $(CONVERT)/reference/generate_bfp_reference.c $(CONVERT)/ft_bfp.c -o $(BUILD)/generate_bfp_reference $(LDLIBS) ./$(BUILD)/generate_bfp_reference $(BUILD)/ft_bfp_reference_vectors.h cp $(BUILD)/ft_bfp_reference_vectors.h $(CONVERT)/reference/ft_bfp_reference_vectors.h clean: rm -rf $(BUILD)