gem/CMakeLists.txt

452 lines
30 KiB
CMake

cmake_minimum_required(VERSION 3.24)
project(gem VERSION 0.1.0 LANGUAGES C)
include(CTest)
add_library(gem_engine STATIC src/gguf.c src/model.c src/mtp.c src/tokenizer.c src/ops.c src/runtime.c src/cpu.c
src/weights.c src/metal_layer.c src/inference.c src/sampler.c src/chat.c src/server.c src/resolve.c)
target_link_libraries(gem_engine PUBLIC m)
target_include_directories(gem_engine PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_compile_features(gem_engine PUBLIC c_std_11)
target_compile_definitions(gem_engine PRIVATE _POSIX_C_SOURCE=200809L)
target_compile_options(gem_engine PRIVATE -Wall -Wextra -Wpedantic -Werror)
if(APPLE)
enable_language(OBJC)
target_sources(gem_engine PRIVATE src/metal.m)
target_compile_options(gem_engine PRIVATE $<$<COMPILE_LANGUAGE:OBJC>:-fobjc-arc>)
target_link_libraries(gem_engine PUBLIC "-framework Foundation" "-framework Metal")
add_executable(gem src/main.c)
target_link_libraries(gem PRIVATE gem_engine)
target_compile_options(gem PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-kernel-bench src/kernel_bench.c)
target_link_libraries(gem-kernel-bench PRIVATE gem_engine)
target_compile_options(gem-kernel-bench PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-bench src/bench.c)
target_link_libraries(gem-bench PRIVATE gem_engine)
target_compile_options(gem-bench PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-logits src/logits.c)
target_link_libraries(gem-logits PRIVATE gem_engine)
target_compile_options(gem-logits PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-tree-check src/tree_check.c)
target_link_libraries(gem-tree-check PRIVATE gem_engine)
target_compile_options(gem-tree-check PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-sampler-bench src/sampler_bench.c)
target_link_libraries(gem-sampler-bench PRIVATE gem_engine)
target_compile_options(gem-sampler-bench PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-prefill-bench src/prefill_bench.c)
target_link_libraries(gem-prefill-bench PRIVATE gem_engine)
target_compile_options(gem-prefill-bench PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-attention-bench src/attention_bench.c)
target_link_libraries(gem-attention-bench PRIVATE gem_engine)
target_compile_options(gem-attention-bench PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-prefill-attention-profile src/prefill_attention_profile.c)
target_link_libraries(gem-prefill-attention-profile PRIVATE gem_engine)
target_compile_options(gem-prefill-attention-profile PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-long-attention-profile src/long_attention_profile.c)
target_link_libraries(gem-long-attention-profile PRIVATE gem_engine)
target_compile_options(gem-long-attention-profile PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-profile src/profile.c)
target_link_libraries(gem-profile PRIVATE gem_engine)
target_compile_options(gem-profile PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-decode-profile src/decode_profile.c)
target_link_libraries(gem-decode-profile PRIVATE gem_engine)
target_compile_options(gem-decode-profile PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-online-merge-check src/online_merge_check.c)
target_link_libraries(gem-online-merge-check PRIVATE gem_engine)
target_compile_options(gem-online-merge-check PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-decode-attention-profile src/decode_attention_profile.c)
target_link_libraries(gem-decode-attention-profile PRIVATE gem_engine)
target_compile_options(gem-decode-attention-profile PRIVATE
-Wall -Wextra -Wpedantic -Werror)
add_executable(gem-draft-gate src/draft_gate.c)
target_link_libraries(gem-draft-gate PRIVATE gem_engine)
target_compile_options(gem-draft-gate PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-mtp-bench src/mtp_bench.c)
target_link_libraries(gem-mtp-bench PRIVATE gem_engine)
target_compile_options(gem-mtp-bench PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-prefix-check src/prefix_check.c)
target_link_libraries(gem-prefix-check PRIVATE gem_engine)
target_compile_options(gem-prefix-check PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-long-prefix-ab src/long_prefix_ab.c)
target_link_libraries(gem-long-prefix-ab PRIVATE gem_engine)
target_compile_options(gem-long-prefix-ab PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-long-prefill-stage-profile src/long_prefill_stage_profile.c)
target_link_libraries(gem-long-prefill-stage-profile PRIVATE gem_engine)
target_compile_options(gem-long-prefill-stage-profile PRIVATE
-Wall -Wextra -Wpedantic -Werror)
add_executable(gem-metal-counter-info src/metal_counter_info.m)
target_link_libraries(gem-metal-counter-info PRIVATE "-framework Foundation" "-framework Metal")
target_compile_options(gem-metal-counter-info PRIVATE
-Wall -Wextra -Wpedantic -Werror -fobjc-arc)
add_executable(gem-metal-startup-profile src/metal_startup_profile.c)
target_link_libraries(gem-metal-startup-profile PRIVATE gem_engine)
target_compile_options(gem-metal-startup-profile PRIVATE
-Wall -Wextra -Wpedantic -Werror)
add_executable(gem-swa-first-divergence src/swa_first_divergence.c)
target_link_libraries(gem-swa-first-divergence PRIVATE gem_engine)
target_compile_options(gem-swa-first-divergence PRIVATE
-Wall -Wextra -Wpedantic -Werror)
add_executable(gem-swa-state-scan src/swa_state_scan.c)
target_link_libraries(gem-swa-state-scan PRIVATE gem_engine)
target_compile_options(gem-swa-state-scan PRIVATE -Wall -Wextra -Wpedantic -Werror)
endif()
add_executable(gem-inspect src/inspect.c)
target_link_libraries(gem-inspect PRIVATE gem_engine)
target_compile_options(gem-inspect PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-tokenize src/tokenize.c)
target_link_libraries(gem-tokenize PRIVATE gem_engine)
target_compile_options(gem-tokenize PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_executable(gem-logit-compare src/logit_compare.c)
target_link_libraries(gem-logit-compare PRIVATE m)
target_compile_features(gem-logit-compare PRIVATE c_std_11)
target_compile_options(gem-logit-compare PRIVATE -Wall -Wextra -Wpedantic -Werror)
option(GEM_BUILD_LEGACY_LAUNCHER "Build the transitional llama.cpp launcher" OFF)
if(GEM_BUILD_LEGACY_LAUNCHER)
set(GEM_LLAMA_SERVER "llama-server" CACHE STRING
"llama.cpp server executable used by the transitional launcher")
set(GEM_LLAMA_BENCH "llama-bench" CACHE STRING
"llama.cpp benchmark executable used by the transitional launcher")
set(GEM_HAX "hax" CACHE STRING "hax executable used by the transitional launcher")
add_executable(gem-legacy src/gem.c)
target_compile_features(gem-legacy PRIVATE c_std_11)
target_compile_definitions(gem-legacy PRIVATE
GEM_DEFAULT_LLAMA_SERVER="${GEM_LLAMA_SERVER}"
GEM_DEFAULT_LLAMA_BENCH="${GEM_LLAMA_BENCH}"
GEM_DEFAULT_HAX="${GEM_HAX}")
target_compile_options(gem-legacy PRIVATE -Wall -Wextra -Wpedantic -Werror)
endif()
if(BUILD_TESTING)
add_executable(gem-native-model-test tests/native_model_test.c)
target_link_libraries(gem-native-model-test PRIVATE gem_engine)
target_compile_definitions(gem-native-model-test PRIVATE _POSIX_C_SOURCE=200809L)
target_compile_options(gem-native-model-test PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_test(NAME gem.native_model COMMAND gem-native-model-test)
add_executable(gem-tokenizer-test tests/tokenizer_test.c)
target_link_libraries(gem-tokenizer-test PRIVATE gem_engine)
target_compile_definitions(gem-tokenizer-test PRIVATE _POSIX_C_SOURCE=200809L)
target_compile_options(gem-tokenizer-test PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_test(NAME gem.tokenizer COMMAND gem-tokenizer-test)
add_executable(gem-ops-test tests/ops_test.c)
target_link_libraries(gem-ops-test PRIVATE gem_engine)
target_compile_options(gem-ops-test PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_test(NAME gem.ops COMMAND gem-ops-test)
add_executable(gem-runtime-plan-test tests/runtime_plan_test.c)
target_link_libraries(gem-runtime-plan-test PRIVATE gem_engine)
target_compile_options(gem-runtime-plan-test PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_test(NAME gem.runtime_plan COMMAND gem-runtime-plan-test)
add_executable(gem-sampler-test tests/sampler_test.c)
target_link_libraries(gem-sampler-test PRIVATE gem_engine)
target_compile_options(gem-sampler-test PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_test(NAME gem.sampler COMMAND gem-sampler-test)
add_executable(gem-chat-test tests/chat_test.c)
target_link_libraries(gem-chat-test PRIVATE gem_engine)
target_compile_options(gem-chat-test PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_test(NAME gem.chat COMMAND gem-chat-test)
add_executable(gem-server-test tests/server_test.c)
target_link_libraries(gem-server-test PRIVATE gem_engine)
target_compile_options(gem-server-test PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_test(NAME gem.server COMMAND gem-server-test)
add_executable(gem-cpu-layer-test tests/cpu_layer_test.c)
target_link_libraries(gem-cpu-layer-test PRIVATE gem_engine)
target_compile_options(gem-cpu-layer-test PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_test(NAME gem.cpu_layer COMMAND gem-cpu-layer-test)
if(APPLE)
add_executable(gem-metal-test tests/metal_test.c)
target_link_libraries(gem-metal-test PRIVATE gem_engine)
target_compile_options(gem-metal-test PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_test(NAME gem.metal COMMAND gem-metal-test)
set_tests_properties(gem.metal PROPERTIES SKIP_RETURN_CODE 77)
add_executable(gem-attention-split-test tests/attention_split_test.c)
target_link_libraries(gem-attention-split-test PRIVATE gem_engine)
target_compile_options(gem-attention-split-test PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_test(NAME gem.attention_split COMMAND gem-attention-split-test)
set_tests_properties(gem.attention_split PROPERTIES SKIP_RETURN_CODE 77)
add_executable(gem-metal-layer-test tests/metal_layer_test.c)
target_link_libraries(gem-metal-layer-test PRIVATE gem_engine)
target_compile_options(gem-metal-layer-test PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_test(NAME gem.metal_layer COMMAND gem-metal-layer-test)
set_tests_properties(gem.metal_layer PROPERTIES SKIP_RETURN_CODE 77)
add_test(NAME gem.native_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.bench_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-bench>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.logits_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-logits>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.sampler_bench_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-sampler-bench>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.prefill_bench_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-prefill-bench>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.attention_bench_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-attention-bench>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.prefill_attention_profile_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-prefill-attention-profile>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.long_attention_profile_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-long-attention-profile>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.profile_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-profile>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.decode_profile_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-decode-profile>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.online_merge_check_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-online-merge-check>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.decode_attention_profile_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-decode-attention-profile>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.draft_gate_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-draft-gate>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.mtp_bench_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-mtp-bench>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.prefix_check_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-prefix-check>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.long_prefix_ab_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-long-prefix-ab>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.long_prefix_candidate_contract
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/long_prefix_candidate_contract.sh
$<TARGET_FILE:gem-long-prefix-ab>)
add_test(NAME gem.bq8_bk128_graph_gate_analysis
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/bq8_bk128_graph_gate_analysis.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/analyze-bq8-bk128-graph-gate.sh)
add_test(NAME gem.long_prefill_stage_profile_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-long-prefill-stage-profile>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.metal_counter_info_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-metal-counter-info>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.metal_startup_profile_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-metal-startup-profile>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.swa_first_divergence_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-swa-first-divergence>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.swa_state_scan_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-swa-state-scan>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
add_test(NAME gem.tokenize_dependency_guard
COMMAND ${CMAKE_COMMAND} -DNATIVE_BINARY=$<TARGET_FILE:gem-tokenize>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/native_dependency_guard.cmake)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.state/models/gemma-4-12B-it-Q4_0.gguf")
add_test(NAME gem.authentic_12b_print_config
COMMAND $<TARGET_FILE:gem> print-config
--model ${CMAKE_CURRENT_SOURCE_DIR}/.state/models/gemma-4-12B-it-Q4_0.gguf
--context 64 --kv-type f32)
set_tests_properties(gem.authentic_12b_print_config PROPERTIES
PASS_REGULAR_EXPRESSION
"\"model_size\":12.*\"attention_kernel\":\"rowwise-gqa4096\\+12b-full-online\\+rowwise-swa\"")
add_test(NAME gem.authentic_12b_print_config_f16_full
COMMAND $<TARGET_FILE:gem> print-config
--model ${CMAKE_CURRENT_SOURCE_DIR}/.state/models/gemma-4-12B-it-Q4_0.gguf
--context 131072 --kv-type f16-full)
set_tests_properties(gem.authentic_12b_print_config_f16_full PROPERTIES
PASS_REGULAR_EXPRESSION
"\"kv_type\":\"f16-full\".*\"kv_bytes\":2818572288.*\"attention_kernel\":\"rowwise-gqa4096-f16-full\\+12b-full-online-f16")
endif()
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.state/models/gemma-4-31B-it-Q4_0.gguf")
add_test(NAME gem.authentic_31b_print_config
COMMAND $<TARGET_FILE:gem> print-config
--model ${CMAKE_CURRENT_SOURCE_DIR}/.state/models/gemma-4-31B-it-Q4_0.gguf
--context 64 --kv-type f32)
set_tests_properties(gem.authentic_31b_print_config PROPERTIES
PASS_REGULAR_EXPRESSION
"\"model_size\":31.*\"attention_kernel\":\"rowwise-gqa4096\\+31b-full-online-bq8-bk64-matrix\\+rowwise-first-tile\\+batched-swa-row2-score\\+full-decode-value-dim32-split16@8192\"")
add_test(NAME gem.authentic_31b_print_config_f16_full
COMMAND $<TARGET_FILE:gem> print-config
--model ${CMAKE_CURRENT_SOURCE_DIR}/.state/models/gemma-4-31B-it-Q4_0.gguf
--context 131072 --kv-type f16-full)
set_tests_properties(gem.authentic_31b_print_config_f16_full PROPERTIES
PASS_REGULAR_EXPRESSION
"\"kv_type\":\"f16-full\".*\"kv_bytes\":12415139840.*\"attention_kernel\":\"rowwise-gqa4096-f16-full")
add_test(NAME gem.authentic_tokenize_cli
COMMAND ${CMAKE_COMMAND}
-DNATIVE_BINARY=$<TARGET_FILE:gem-tokenize>
-DMODEL=${CMAKE_CURRENT_SOURCE_DIR}/.state/models/gemma-4-31B-it-Q4_0.gguf
-DINPUT_FILE=${CMAKE_CURRENT_SOURCE_DIR}/tests/tokenize_cli_input.txt
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/tokenize_cli.cmake)
endif()
endif()
if(GEM_BUILD_LEGACY_LAUNCHER)
add_test(NAME gem.legacy_print_config
COMMAND gem-legacy print-config --model /tmp/gemma-4-31b.gguf)
add_test(NAME gem.legacy_serve_dry_run
COMMAND gem-legacy serve --dry-run --model /tmp/gemma-4-31b.gguf --port 9090)
add_test(NAME gem.legacy_bench_dry_run
COMMAND gem-legacy bench --dry-run --model /tmp/gemma-4-31b.gguf)
add_test(NAME gem.legacy_hax_dry_run
COMMAND gem-legacy hax --dry-run --port 9090 --model gemma-4-31b)
add_test(NAME gem.legacy_agent_dry_run
COMMAND gem-legacy agent --dry-run --port 9090 --model /tmp/gemma-4-31b.gguf)
add_test(NAME gem.legacy_command_contract
COMMAND ${CMAKE_COMMAND} -DGEM=$<TARGET_FILE:gem-legacy>
-P ${CMAKE_CURRENT_SOURCE_DIR}/tests/command_contract.cmake)
find_program(PYTHON3_EXECUTABLE python3)
find_program(CURL_EXECUTABLE curl)
if(PYTHON3_EXECUTABLE AND CURL_EXECUTABLE)
add_test(NAME gem.legacy_agent_lifecycle
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/agent_lifecycle.sh
$<TARGET_FILE:gem-legacy>
${CMAKE_CURRENT_SOURCE_DIR}/tests/fake_llama_server.py
${CMAKE_CURRENT_SOURCE_DIR}/tests/fake_hax.sh)
set_tests_properties(gem.legacy_agent_lifecycle PROPERTIES TIMEOUT 15)
endif()
endif()
find_program(JQ_EXECUTABLE jq)
if(JQ_EXECUTABLE)
add_test(NAME gem.benchmark_analysis
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/benchmark_analysis.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/analyze-benchmarks.sh
${CMAKE_CURRENT_SOURCE_DIR}/tests)
add_test(NAME gem.12b_servability_gate
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/12b_servability_gate.sh)
set_tests_properties(gem.12b_servability_gate PROPERTIES TIMEOUT 300)
add_test(NAME gem.kernel_benchmark_analysis
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/kernel_benchmark_analysis.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/analyze-kernel-benchmarks.sh
${CMAKE_CURRENT_SOURCE_DIR}/artifacts/2026-08-23-q4-matvec/buffer-copy.json
${CMAKE_CURRENT_SOURCE_DIR}/artifacts/2026-08-23-q4-matvec/buffer-persistent.json)
add_test(NAME gem.decode_residual_analysis
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/decode_residual_analysis.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/analyze-decode-residual.sh
${CMAKE_CURRENT_SOURCE_DIR}/artifacts/2026-08-26-long-decode-profile/full-model-stage-dim32-65536.json
${CMAKE_CURRENT_SOURCE_DIR}/artifacts/2026-08-26-long-decode-profile/dim32-abba-b2-65536.json)
add_test(NAME gem.decode_attention_analysis
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/decode_attention_analysis.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/analyze-decode-attention.sh
${CMAKE_CURRENT_SOURCE_DIR}/artifacts/2026-08-26-long-decode-profile/split-pv-dim32-split16-65536.json)
add_test(NAME gem.decode_attention_traffic_analysis
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/decode_attention_traffic_analysis.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/analyze-decode-attention-traffic.sh)
add_test(NAME gem.fused_split_kv_ceiling_analysis
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/fused_split_kv_ceiling_analysis.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/analyze-fused-split-kv-ceiling.sh)
add_test(NAME gem.fused_split_kv_resources_analysis
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/fused_split_kv_resources_analysis.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/analyze-fused-split-kv-resources.sh)
add_test(NAME gem.fused_split_kv_correctness_analysis
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/fused_split_kv_correctness_analysis.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/analyze-fused-split-kv-correctness.sh)
add_test(NAME gem.decode_host_overhead_analysis
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/decode_host_overhead_analysis.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/analyze-decode-host-overhead.sh)
add_test(NAME gem.online_merge_check
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/online_merge_check.sh
$<TARGET_FILE:gem-online-merge-check>)
add_test(NAME gem.online_merge_boundary_analysis
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/online_merge_boundary_analysis.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/analyze-online-merge-boundary.sh
${CMAKE_CURRENT_SOURCE_DIR}/artifacts/2026-08-27-fused-split-kv-cpu-boundary/8191.json
${CMAKE_CURRENT_SOURCE_DIR}/artifacts/2026-08-27-fused-split-kv-cpu-boundary/8192.json
${CMAKE_CURRENT_SOURCE_DIR}/artifacts/2026-08-27-fused-split-kv-cpu-boundary/8193.json
${CMAKE_CURRENT_SOURCE_DIR}/artifacts/2026-08-27-fused-split-kv-cpu-boundary/65536.json
${CMAKE_CURRENT_SOURCE_DIR}/artifacts/2026-08-27-fused-split-kv-cpu-boundary/131072.json)
add_test(NAME gem.decode_attention_abba_analysis
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/decode_attention_abba_analysis.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/analyze-decode-attention-abba.sh
${CMAKE_CURRENT_SOURCE_DIR}/artifacts/2026-08-26-long-decode-profile/split-pv-dim32-split16-65536.json)
add_test(NAME gem.prefill_stage_analysis
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/prefill_stage_analysis.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/analyze-prefill-stages.sh
${CMAKE_CURRENT_SOURCE_DIR}/artifacts/2026-08-25-long-prefill-stage-attribution/stage-production-4096.json)
add_test(NAME gem.metal_counter_info_analysis
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/metal_counter_info_analysis.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/analyze-metal-counter-info.sh)
add_test(NAME gem.prefill_stage_attribution_overlap
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/prefill_stage_attribution_overlap.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/run-prefill-stage-attribution.sh)
add_test(NAME gem.prefill_stage_attribution_runner
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/prefill_stage_attribution_runner.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/run-prefill-stage-attribution.sh
${CMAKE_CURRENT_SOURCE_DIR}/artifacts/2026-08-25-long-prefill-stage-attribution/stage-production-4096.json)
add_test(NAME gem.long_context_server_gate_audit
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/long_context_server_gate_audit.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/audit-long-context-server-gate.sh)
add_test(NAME gem.score_tile8_gate_overlap
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/score_tile8_gate_overlap.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/run-score-tile8-gate.sh)
add_test(NAME gem.score_tile8_decision_analysis
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/score_tile8_decision_analysis.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/analyze-score-tile8-decision.sh)
add_test(NAME gem.bq8_bk128_gate_analysis
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/bq8_bk128_gate_analysis.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/analyze-bq8-bk128-gate.sh)
add_test(NAME gem.run_when_host_clean
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/run_when_host_clean.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/run-when-host-clean.sh)
find_program(NC_EXECUTABLE nc)
find_program(LSOF_EXECUTABLE lsof)
if(NC_EXECUTABLE AND LSOF_EXECUTABLE)
add_test(NAME gem.long_context_server_gate_resume
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/long_context_server_gate_resume.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/long-context-server-gate.sh)
set_tests_properties(gem.long_context_server_gate_resume PROPERTIES TIMEOUT 15)
endif()
find_program(PYTHON3_STREAM_EXECUTABLE python3)
find_program(CURL_STREAM_EXECUTABLE curl)
if(PYTHON3_STREAM_EXECUTABLE AND CURL_STREAM_EXECUTABLE)
add_test(NAME gem.server_stream_probe
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/server_stream_probe.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/server-stream-probe.sh
${CMAKE_CURRENT_SOURCE_DIR}/tests/fake_llama_server.py)
set_tests_properties(gem.server_stream_probe PROPERTIES TIMEOUT 15)
add_test(NAME gem.server_prefill_cancel_gate
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/server_prefill_cancel_gate.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/server-prefill-cancel-gate.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/server-stream-probe.sh
${CMAKE_CURRENT_SOURCE_DIR}/tests/fake_prefill_cancel_server.py)
set_tests_properties(gem.server_prefill_cancel_gate PROPERTIES TIMEOUT 15)
endif()
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.state/models/gemma-4-31B-it-Q4_0.gguf")
add_test(NAME gem.make_long_prompt_31b
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/make_long_prompt.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/make-long-prompt.sh
${CMAKE_CURRENT_SOURCE_DIR}/.state/models/gemma-4-31B-it-Q4_0.gguf)
set_tests_properties(gem.make_long_prompt_31b PROPERTIES
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} TIMEOUT 30)
endif()
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.state/models/gemma-4-12B-it-Q4_0.gguf")
add_test(NAME gem.make_long_prompt_12b
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/make_long_prompt.sh
${CMAKE_CURRENT_SOURCE_DIR}/scripts/make-long-prompt.sh
${CMAKE_CURRENT_SOURCE_DIR}/.state/models/gemma-4-12B-it-Q4_0.gguf)
set_tests_properties(gem.make_long_prompt_12b PROPERTIES
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} TIMEOUT 30)
endif()
endif()
add_test(NAME gem.agent_mtp_autodiscovery
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/agent_mtp_autodiscovery.sh
$<TARGET_FILE:gem>)
set_tests_properties(gem.agent_mtp_autodiscovery PROPERTIES TIMEOUT 10)
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../hax/build/hax")
add_test(NAME gem.hax_project_memory
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/hax_project_memory.sh
"${CMAKE_CURRENT_SOURCE_DIR}/../hax/build/hax"
"${CMAKE_CURRENT_SOURCE_DIR}/../hax")
add_executable(gem-server-fixture tests/server_fixture.c)
target_link_libraries(gem-server-fixture PRIVATE gem_engine)
target_compile_options(gem-server-fixture PRIVATE -Wall -Wextra -Wpedantic -Werror)
add_test(NAME gem.hax_native_server
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/hax_native_server.sh
$<TARGET_FILE:gem-server-fixture>
"${CMAKE_CURRENT_SOURCE_DIR}/../hax/build/hax")
set_tests_properties(gem.hax_native_server PROPERTIES TIMEOUT 20)
endif()
endif()