cmake_minimum_required(VERSION 3.25) project(kimodo LANGUAGES CXX) set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) option(KIMODO_BUILD_TESTS "Build Kimodo tests" ON) option(KIMODO_ENABLE_VULKAN "Enable GGML Vulkan backend when GGML is available" ON) option(KIMODO_ENABLE_FUZZERS "Build libFuzzer parser targets" OFF) set(KIMODO_GGML_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ggml" CACHE PATH "Pinned GGML submodule source directory") set(KIMODO_ROOT_PARITY_MODEL "${CMAKE_CURRENT_SOURCE_DIR}/models/kimodo-smplx-rp-v1-f32.gguf" CACHE FILEPATH "F32 motion GGUF required by parity tests") set(KIMODO_ROOT_PARITY_FIXTURE "${CMAKE_CURRENT_SOURCE_DIR}/fixtures/smplx-zero-embedding" CACHE PATH "Fixture directory required by motion parity tests") set(KIMODO_LLM_TEXT_BUNDLE "${CMAKE_CURRENT_SOURCE_DIR}/generated/llm2vec-text-bundle" CACHE PATH "Native LLM2Vec GGUF component bundle required by text parity tests") set(KIMODO_LLM_TEXT_FIXTURE "${CMAKE_CURRENT_SOURCE_DIR}/fixtures/llm2vec-real-prompt" CACHE PATH "Captured LLM2Vec fixture required by text parity tests") set(KIMODO_MULTIPROMPT_FIXTURE "" CACHE PATH "Optional extracted upstream multi-prompt fixture for raw trajectory parity") add_library(kimodo src/capi.cpp src/model.cpp src/gguf.cpp src/diffusion.cpp src/motion_rep.cpp src/motion_decode.cpp) add_library(kimodo::kimodo ALIAS kimodo) target_include_directories(kimodo PUBLIC "$") target_compile_definitions(kimodo PRIVATE KIMODO_BUILD KIMODO_SHARED) set_target_properties(kimodo PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN YES) add_executable(kmd-inspect src/inspect.cpp) target_link_libraries(kmd-inspect PRIVATE kimodo) if(MSVC) target_compile_options(kimodo PRIVATE /W4 /permissive-) else() target_compile_options(kimodo PRIVATE -Wall -Wextra -Wpedantic -Wconversion -Wshadow) endif() if(EXISTS "${KIMODO_GGML_SOURCE_DIR}/CMakeLists.txt") # GGML is a pinned submodule: portable outside Nix, patchable, and kept # current independently of a distribution package. set(GGML_BUILD_TESTS OFF CACHE BOOL "" FORCE) set(GGML_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) set(GGML_NATIVE OFF CACHE BOOL "" FORCE) set(GGML_VULKAN ${KIMODO_ENABLE_VULKAN} CACHE BOOL "" FORCE) set(GGML_BACKEND_DL OFF CACHE BOOL "" FORCE) set(BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE) add_subdirectory("${KIMODO_GGML_SOURCE_DIR}" "${CMAKE_BINARY_DIR}/ggml" EXCLUDE_FROM_ALL) set(KIMODO_HAVE_GGML TRUE) target_link_libraries(kimodo PRIVATE ggml) target_compile_definitions(kimodo PRIVATE KIMODO_HAVE_GGML=1) if(KIMODO_ENABLE_VULKAN AND TARGET ggml-vulkan) target_link_libraries(kimodo PRIVATE ggml-vulkan) target_compile_definitions(kimodo PRIVATE $<$:KIMODO_HAVE_GGML_VULKAN=1>) endif() target_link_libraries(kmd-inspect PRIVATE ggml) target_compile_definitions(kmd-inspect PRIVATE KIMODO_HAVE_GGML=1) target_sources(kimodo PRIVATE src/ggml_weights.cpp src/denoiser.cpp src/sequence.cpp) target_sources(kimodo PRIVATE src/llm_tokenizer.cpp src/llm_text_encoder.cpp) add_executable(kmd-sample-fixture src/sample_fixture.cpp) target_sources(kmd-sample-fixture PRIVATE src/gguf.cpp src/ggml_weights.cpp src/denoiser.cpp src/diffusion.cpp src/motion_rep.cpp src/motion_decode.cpp) target_include_directories(kmd-sample-fixture PRIVATE src) target_link_libraries(kmd-sample-fixture PRIVATE ggml $) target_compile_definitions(kmd-sample-fixture PRIVATE KIMODO_HAVE_GGML=1 $<$:KIMODO_HAVE_GGML_VULKAN=1>) add_executable(kmd-generate src/generate.cpp) target_link_libraries(kmd-generate PRIVATE kimodo) add_executable(kmd-encode src/encode.cpp) target_sources(kmd-encode PRIVATE src/llm_text_encoder.cpp src/llm_tokenizer.cpp) target_include_directories(kmd-encode PRIVATE src) target_link_libraries(kmd-encode PRIVATE ggml $) target_compile_definitions(kmd-encode PRIVATE KIMODO_HAVE_GGML=1 $<$:KIMODO_HAVE_GGML_VULKAN=1>) add_executable(kimodo-llm-layer-parity tests/llm_layer_parity.cpp) target_link_libraries(kimodo-llm-layer-parity PRIVATE ggml $) target_include_directories(kimodo-llm-layer-parity PRIVATE src) target_compile_definitions(kimodo-llm-layer-parity PRIVATE $<$:KIMODO_HAVE_GGML_VULKAN=1>) add_executable(kimodo-llm-final-norm-parity tests/llm_final_norm_parity.cpp) target_link_libraries(kimodo-llm-final-norm-parity PRIVATE ggml $) target_compile_definitions(kimodo-llm-final-norm-parity PRIVATE $<$:KIMODO_HAVE_GGML_VULKAN=1>) add_executable(kimodo-llm-tokenizer-test tests/llm_tokenizer_test.cpp src/llm_tokenizer.cpp) target_include_directories(kimodo-llm-tokenizer-test PRIVATE src) target_link_libraries(kimodo-llm-tokenizer-test PRIVATE ggml) add_executable(kimodo-llm-embedding-parity tests/llm_embedding_parity.cpp) target_link_libraries(kimodo-llm-embedding-parity PRIVATE ggml $) add_executable(kimodo-multiprompt-fixture-parity tests/multiprompt_fixture_parity.cpp) target_sources(kimodo-multiprompt-fixture-parity PRIVATE src/gguf.cpp src/ggml_weights.cpp src/denoiser.cpp src/sequence.cpp src/motion_rep.cpp src/diffusion.cpp) target_include_directories(kimodo-multiprompt-fixture-parity PRIVATE src) target_link_libraries(kimodo-multiprompt-fixture-parity PRIVATE ggml $) target_compile_definitions(kimodo-multiprompt-fixture-parity PRIVATE KIMODO_HAVE_GGML=1 $<$:KIMODO_HAVE_GGML_VULKAN=1>) add_executable(kimodo-stage-fixture-parity tests/stage_fixture_parity.cpp) target_sources(kimodo-stage-fixture-parity PRIVATE src/gguf.cpp src/ggml_weights.cpp src/denoiser.cpp src/motion_rep.cpp src/diffusion.cpp) target_include_directories(kimodo-stage-fixture-parity PRIVATE src) target_link_libraries(kimodo-stage-fixture-parity PRIVATE ggml $) target_compile_definitions(kimodo-stage-fixture-parity PRIVATE KIMODO_HAVE_GGML=1 $<$:KIMODO_HAVE_GGML_VULKAN=1>) add_executable(kimodo-llm-text-session-parity tests/llm_text_session_parity.cpp src/llm_text_encoder.cpp src/llm_tokenizer.cpp) target_include_directories(kimodo-llm-text-session-parity PRIVATE src) target_link_libraries(kimodo-llm-text-session-parity PRIVATE ggml $) target_compile_definitions(kimodo-llm-text-session-parity PRIVATE KIMODO_HAVE_GGML=1 $<$:KIMODO_HAVE_GGML_VULKAN=1>) endif() include(CTest) if(BUILD_TESTING AND KIMODO_BUILD_TESTS) add_executable(kimodo-capi-test tests/capi_test.cpp) target_link_libraries(kimodo-capi-test PRIVATE kimodo) add_test(NAME kimodo-capi-test COMMAND kimodo-capi-test "${KIMODO_ROOT_PARITY_MODEL}" "${KIMODO_LLM_TEXT_BUNDLE}") add_executable(kimodo-diffusion-test tests/diffusion_test.cpp) target_sources(kimodo-diffusion-test PRIVATE src/diffusion.cpp) target_include_directories(kimodo-diffusion-test PRIVATE src) target_link_libraries(kimodo-diffusion-test PRIVATE kimodo) add_test(NAME kimodo-diffusion-test COMMAND kimodo-diffusion-test) find_package(Python3 COMPONENTS Interpreter QUIET) if(Python3_Interpreter_FOUND) add_test(NAME kimodo-converter-test COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/tests/converter_test.py") endif() if(KIMODO_HAVE_GGML) add_test(NAME kimodo-llm-text-session-cpu COMMAND "${CMAKE_COMMAND}" -E env KIMODO_BACKEND=cpu "$" "${KIMODO_LLM_TEXT_BUNDLE}" "${KIMODO_LLM_TEXT_FIXTURE}") add_test(NAME kimodo-llm-text-session-vulkan COMMAND kimodo-llm-text-session-parity "${KIMODO_LLM_TEXT_BUNDLE}" "${KIMODO_LLM_TEXT_FIXTURE}") add_executable(kimodo-root-parity tests/root_parity.cpp src/motion_rep.cpp) target_include_directories(kimodo-root-parity PRIVATE src) target_link_libraries(kimodo-root-parity PRIVATE kimodo ggml $) add_test(NAME kimodo-root-parity COMMAND kimodo-root-parity "${KIMODO_ROOT_PARITY_MODEL}" "${KIMODO_ROOT_PARITY_FIXTURE}" root) add_test(NAME kimodo-body-parity COMMAND kimodo-root-parity "${KIMODO_ROOT_PARITY_MODEL}" "${KIMODO_ROOT_PARITY_FIXTURE}" body) add_executable(kimodo-fixture-sampler-parity tests/fixture_sampler_parity.cpp) target_include_directories(kimodo-fixture-sampler-parity PRIVATE src) target_link_libraries(kimodo-fixture-sampler-parity PRIVATE kimodo) add_test(NAME kimodo-fixture-sampler-parity COMMAND kimodo-fixture-sampler-parity "${KIMODO_ROOT_PARITY_FIXTURE}") add_executable(kimodo-ggml-weights-test tests/ggml_weights_test.cpp) target_sources(kimodo-ggml-weights-test PRIVATE src/gguf.cpp src/ggml_weights.cpp) target_include_directories(kimodo-ggml-weights-test PRIVATE src) target_link_libraries(kimodo-ggml-weights-test PRIVATE kimodo ggml $) target_compile_definitions(kimodo-ggml-weights-test PRIVATE KIMODO_HAVE_GGML=1 $<$:KIMODO_HAVE_GGML_VULKAN=1>) add_test(NAME kimodo-ggml-weights-test COMMAND kimodo-ggml-weights-test "${KIMODO_ROOT_PARITY_MODEL}") add_executable(kimodo-denoiser-runtime-test tests/denoiser_runtime_test.cpp) target_sources(kimodo-denoiser-runtime-test PRIVATE src/gguf.cpp src/ggml_weights.cpp src/denoiser.cpp src/motion_rep.cpp src/diffusion.cpp) target_include_directories(kimodo-denoiser-runtime-test PRIVATE src) target_link_libraries(kimodo-denoiser-runtime-test PRIVATE kimodo ggml $) target_compile_definitions(kimodo-denoiser-runtime-test PRIVATE KIMODO_HAVE_GGML=1 $<$:KIMODO_HAVE_GGML_VULKAN=1>) add_test(NAME kimodo-denoiser-runtime-root COMMAND kimodo-denoiser-runtime-test "${KIMODO_ROOT_PARITY_MODEL}" "${KIMODO_ROOT_PARITY_FIXTURE}" root) add_test(NAME kimodo-denoiser-runtime-body COMMAND kimodo-denoiser-runtime-test "${KIMODO_ROOT_PARITY_MODEL}" "${KIMODO_ROOT_PARITY_FIXTURE}" body) add_test(NAME kimodo-denoiser-runtime-full COMMAND kimodo-denoiser-runtime-test "${KIMODO_ROOT_PARITY_MODEL}" "${KIMODO_ROOT_PARITY_FIXTURE}" full) add_executable(kimodo-decode-test tests/decode_test.cpp) target_sources(kimodo-decode-test PRIVATE src/gguf.cpp src/ggml_weights.cpp src/motion_decode.cpp) target_include_directories(kimodo-decode-test PRIVATE src) target_link_libraries(kimodo-decode-test PRIVATE kimodo ggml $) target_compile_definitions(kimodo-decode-test PRIVATE KIMODO_HAVE_GGML=1 $<$:KIMODO_HAVE_GGML_VULKAN=1>) add_test(NAME kimodo-decode-test COMMAND kimodo-decode-test "${KIMODO_ROOT_PARITY_MODEL}" "${KIMODO_ROOT_PARITY_FIXTURE}") add_executable(kimodo-generate-smoke tests/generate_smoke.cpp) target_link_libraries(kimodo-generate-smoke PRIVATE kimodo) add_test(NAME kimodo-generate-smoke COMMAND kimodo-generate-smoke "${KIMODO_ROOT_PARITY_MODEL}") add_executable(kimodo-sampler2-test tests/sampler2_test.cpp) target_sources(kimodo-sampler2-test PRIVATE src/gguf.cpp src/ggml_weights.cpp src/denoiser.cpp src/motion_rep.cpp src/diffusion.cpp) target_include_directories(kimodo-sampler2-test PRIVATE src) target_link_libraries(kimodo-sampler2-test PRIVATE kimodo ggml $) target_compile_definitions(kimodo-sampler2-test PRIVATE KIMODO_HAVE_GGML=1 $<$:KIMODO_HAVE_GGML_VULKAN=1>) if(IS_DIRECTORY "${KIMODO_MULTIPROMPT_FIXTURE}") add_test(NAME kimodo-multiprompt-fixture-parity COMMAND kimodo-multiprompt-fixture-parity "${KIMODO_ROOT_PARITY_MODEL}" "${KIMODO_MULTIPROMPT_FIXTURE}") endif() endif() endif() if(KIMODO_ENABLE_FUZZERS) if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang") message(FATAL_ERROR "KIMODO_ENABLE_FUZZERS requires Clang/libFuzzer") endif() add_executable(kimodo-gguf-fuzz fuzz/gguf_fuzz.cpp src/gguf.cpp) target_include_directories(kimodo-gguf-fuzz PRIVATE include src) target_compile_options(kimodo-gguf-fuzz PRIVATE -fsanitize=fuzzer,address,undefined) target_link_options(kimodo-gguf-fuzz PRIVATE -fsanitize=fuzzer,address,undefined) endif()