File size: 8,945 Bytes
9425aed | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | cmake_minimum_required(VERSION 3.20)
project(sov_rtx LANGUAGES C)
option(SOV_BUILD_CUDA "Enable PTX validation targets" ON)
if(WIN32 AND CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
set(SOV_ZERO_LIBC_DEFAULT ON)
else()
set(SOV_ZERO_LIBC_DEFAULT OFF)
endif()
option(SOV_ZERO_LIBC
"Build the supported GNU/Clang zero-CRT Windows entry point"
${SOV_ZERO_LIBC_DEFAULT})
option(SOV_BUILD_FORTRAN_REFERENCE
"Build the optional Fortran 2018 transformer reference" OFF)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
set(SOV_PTX_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/cuda")
set(SOV_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
set(SOV_PTX_BLOB_SOURCE "${SOV_GENERATED_DIR}/sov_ptx_blobs.c")
file(MAKE_DIRECTORY "${SOV_GENERATED_DIR}")
# Convert PTX bytes to a C array at configure time. The final zero byte is
# included in both the array and *_len so every loader can validate the
# complete bounded text-image contract before calling cuModuleLoadData.
function(sov_ptx_to_c_source input_path symbol output_variable)
if(NOT EXISTS "${input_path}")
message(FATAL_ERROR "Required PTX source is missing: ${input_path}")
endif()
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${input_path}")
file(READ "${input_path}" ptx_text)
if(ARGC GREATER 3)
string(REGEX REPLACE "\\.target[ \t]+sm_[0-9]+"
".target ${ARGV3}" ptx_text "${ptx_text}")
endif()
string(HEX "${ptx_text}" ptx_hex)
string(LENGTH "${ptx_hex}" ptx_hex_length)
if(ptx_hex_length EQUAL 0)
message(FATAL_ERROR "PTX source is empty: ${input_path}")
endif()
math(EXPR ptx_byte_count "${ptx_hex_length} / 2")
math(EXPR ptx_buffer_size "${ptx_byte_count} + 1")
math(EXPR ptx_last_offset "${ptx_hex_length} - 2")
set(generated_text "const unsigned char ${symbol}[] = {\n ")
set(bytes_on_line 0)
foreach(offset RANGE 0 ${ptx_last_offset} 2)
string(SUBSTRING "${ptx_hex}" ${offset} 2 byte_hex)
string(APPEND generated_text "0x${byte_hex},")
math(EXPR bytes_on_line "${bytes_on_line} + 1")
if(bytes_on_line EQUAL 16)
string(APPEND generated_text "\n ")
set(bytes_on_line 0)
endif()
endforeach()
string(APPEND generated_text
"0x00\n};\n"
"const unsigned int ${symbol}_len = ${ptx_buffer_size}u;\n")
set(${output_variable} "${generated_text}" PARENT_SCOPE)
endfunction()
sov_ptx_to_c_source("${SOV_PTX_DIR}/flash_attention.ptx"
flash_attention_ptx flash_ptx_source)
sov_ptx_to_c_source("${SOV_PTX_DIR}/gemm.ptx"
gemm_ptx gemm_ptx_source)
file(WRITE "${SOV_PTX_BLOB_SOURCE}"
"/* Generated by CMake. Do not edit. */\n"
"${flash_ptx_source}\n"
"${gemm_ptx_source}\n")
add_library(sov_rtx STATIC
src/loader/gguf.c
src/kv_allocator.c
src/sampler.c
src/cuda_validation_chain.c
src/rowm_cuda_validation.c
src/cuda_gemm_dispatch.c
src/cuda_kernels.c
windows_rtx/cuda_driver_loader.c
windows_rtx/power_handler.c
"${SOV_PTX_BLOB_SOURCE}"
)
target_include_directories(sov_rtx PUBLIC include PRIVATE src)
if(SOV_BUILD_FORTRAN_REFERENCE)
enable_language(Fortran)
add_library(sov_rtx_fortran_reference STATIC
src/fortran/transformer_kernel.f90)
set_property(TARGET sov_rtx_fortran_reference PROPERTY Fortran_STANDARD 2018)
set_property(TARGET sov_rtx_fortran_reference PROPERTY Fortran_STANDARD_REQUIRED ON)
endif()
if(SOV_ZERO_LIBC)
if(NOT WIN32)
message(FATAL_ERROR "SOV_ZERO_LIBC is supported only on Windows")
endif()
if(MSVC OR NOT CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
message(FATAL_ERROR
"SOV_ZERO_LIBC currently requires GNU or Clang because main.c "
"uses that compiler family's x86-64 inline assembly")
endif()
target_compile_options(sov_rtx PRIVATE
-ffreestanding -fno-builtin -fno-stack-protector)
add_executable(sov_main windows_rtx/main.c)
target_link_libraries(sov_main PRIVATE sov_rtx)
target_compile_options(sov_main PRIVATE
-ffreestanding -fno-builtin -fno-stack-protector)
target_link_options(sov_main PRIVATE -nostdlib -Wl,--entry=sov_main)
add_executable(sov_gguf_zero_crt_link_smoke tests/gguf_zero_crt_link_smoke.c)
target_link_libraries(sov_gguf_zero_crt_link_smoke PRIVATE sov_rtx kernel32)
target_compile_options(sov_gguf_zero_crt_link_smoke PRIVATE
-ffreestanding -fno-builtin -fno-stack-protector)
target_link_options(sov_gguf_zero_crt_link_smoke PRIVATE
-nostdlib -Wl,--entry=sov_main)
endif()
if(SOV_BUILD_CUDA)
find_program(PTXAS_EXECUTABLE NAMES ptxas)
if(PTXAS_EXECUTABLE)
set(flash_cubin "${SOV_GENERATED_DIR}/flash_attention.cubin")
set(gemm_cubin "${SOV_GENERATED_DIR}/gemm.cubin")
add_custom_command(OUTPUT "${flash_cubin}"
COMMAND "${PTXAS_EXECUTABLE}" -arch=sm_89
"${SOV_PTX_DIR}/flash_attention.ptx" -o "${flash_cubin}"
DEPENDS "${SOV_PTX_DIR}/flash_attention.ptx"
VERBATIM COMMENT "Validating flash_attention.ptx for sm_89")
add_custom_command(OUTPUT "${gemm_cubin}"
COMMAND "${PTXAS_EXECUTABLE}" -arch=sm_89
"${SOV_PTX_DIR}/gemm.ptx" -o "${gemm_cubin}"
DEPENDS "${SOV_PTX_DIR}/gemm.ptx"
VERBATIM COMMENT "Validating gemm.ptx for sm_89")
add_custom_target(validate_ptx DEPENDS "${flash_cubin}" "${gemm_cubin}")
else()
add_custom_target(validate_ptx
COMMAND "${CMAKE_COMMAND}" -E echo
"ptxas not found; cuModuleLoadData will validate PTX at runtime"
VERBATIM)
endif()
endif()
include(CTest)
if(BUILD_TESTING)
add_executable(sov_rtx_host_tests
tests/test_kv_sampler_host.c
src/kv_allocator.c
src/sampler.c)
target_include_directories(sov_rtx_host_tests BEFORE PRIVATE tests/host_include)
target_include_directories(sov_rtx_host_tests PRIVATE include src)
add_test(NAME sov_rtx_host_tests COMMAND sov_rtx_host_tests)
add_executable(sov_gguf_host_tests
tests/test_gguf_host.c
src/loader/gguf.c)
target_include_directories(sov_gguf_host_tests PRIVATE include)
add_test(NAME sov_gguf_host_tests COMMAND sov_gguf_host_tests)
add_executable(sov_cuda_validation_chain_host_tests
tests/test_cuda_validation_chain_host.c
src/cuda_validation_chain.c)
target_include_directories(sov_cuda_validation_chain_host_tests PRIVATE include)
add_test(NAME sov_cuda_validation_chain_host_tests
COMMAND sov_cuda_validation_chain_host_tests)
add_executable(sov_cuda_kernels_host_tests
tests/test_cuda_kernels_host.c
src/cuda_validation_chain.c
src/cuda_kernels.c)
target_include_directories(sov_cuda_kernels_host_tests BEFORE PRIVATE tests/host_include)
target_include_directories(sov_cuda_kernels_host_tests PRIVATE include src)
add_test(NAME sov_cuda_kernels_host_tests COMMAND sov_cuda_kernels_host_tests)
if(WIN32)
set(SOV_CUDA_SM86_SOURCE "${SOV_GENERATED_DIR}/sov_cuda_sm86.c")
sov_ptx_to_c_source("${SOV_PTX_DIR}/flash_attention.ptx"
flash_attention_ptx flash_sm86 sm_86)
sov_ptx_to_c_source("${SOV_PTX_DIR}/gemm.ptx"
gemm_ptx gemm_sm86 sm_86)
file(WRITE "${SOV_CUDA_SM86_SOURCE}"
"/* Generated test-only sm_86 PTX blobs. */\n"
"${flash_sm86}\n" "${gemm_sm86}\n")
add_executable(sov_cuda_reference_gpu_test
tests/test_cuda_reference_gpu.c
src/kv_allocator.c
src/cuda_validation_chain.c
src/rowm_cuda_validation.c
src/cuda_gemm_dispatch.c
src/cuda_kernels.c
windows_rtx/cuda_driver_loader.c
"${SOV_CUDA_SM86_SOURCE}")
target_include_directories(sov_cuda_reference_gpu_test PRIVATE include src)
target_compile_definitions(sov_cuda_reference_gpu_test
PRIVATE SOV_CUDA_COMPILED_PTX_TARGET=86)
if(NOT MSVC)
target_link_libraries(sov_cuda_reference_gpu_test PRIVATE m)
endif()
add_test(NAME sov_cuda_reference_gpu_test
COMMAND sov_cuda_reference_gpu_test)
set_tests_properties(sov_cuda_reference_gpu_test
PROPERTIES LABELS gpu SKIP_RETURN_CODE 77)
endif()
endif()
add_custom_target(cmm_info
COMMAND "${CMAKE_COMMAND}" -E echo
"C-- scheduler: src/c--/scheduler.cmm (GHC C-- backend)"
VERBATIM)
|