CMakeLists.txt 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. include(CheckCXXCompilerFlag)
  2. add_compile_definitions(GGML_SCHED_MAX_COPIES=${GGML_SCHED_MAX_COPIES})
  3. # enable libstdc++ assertions for debug builds
  4. if (CMAKE_SYSTEM_NAME MATCHES "Linux")
  5. add_compile_definitions($<$<CONFIG:Debug>:_GLIBCXX_ASSERTIONS>)
  6. endif()
  7. if (NOT MSVC)
  8. if (GGML_SANITIZE_THREAD)
  9. add_compile_options(-fsanitize=thread)
  10. link_libraries (-fsanitize=thread)
  11. endif()
  12. if (GGML_SANITIZE_ADDRESS)
  13. add_compile_options(-fsanitize=address -fno-omit-frame-pointer)
  14. link_libraries (-fsanitize=address)
  15. endif()
  16. if (GGML_SANITIZE_UNDEFINED)
  17. add_compile_options(-fsanitize=undefined)
  18. link_libraries (-fsanitize=undefined)
  19. endif()
  20. endif()
  21. function(ggml_get_flags CCID CCVER)
  22. set(C_FLAGS "")
  23. set(CXX_FLAGS "")
  24. if (CCID MATCHES "Clang")
  25. set(C_FLAGS -Wunreachable-code-break -Wunreachable-code-return)
  26. set(CXX_FLAGS -Wunreachable-code-break -Wunreachable-code-return -Wmissing-prototypes -Wextra-semi)
  27. if (
  28. (CCID STREQUAL "Clang" AND CCVER VERSION_GREATER_EQUAL 3.8.0) OR
  29. (CCID STREQUAL "AppleClang" AND CCVER VERSION_GREATER_EQUAL 7.3.0)
  30. )
  31. list(APPEND C_FLAGS -Wdouble-promotion)
  32. endif()
  33. elseif (CCID STREQUAL "GNU")
  34. set(C_FLAGS -Wdouble-promotion)
  35. set(CXX_FLAGS -Wno-array-bounds)
  36. if (CCVER VERSION_GREATER_EQUAL 8.1.0)
  37. list(APPEND CXX_FLAGS -Wextra-semi)
  38. endif()
  39. endif()
  40. set(GF_C_FLAGS ${C_FLAGS} PARENT_SCOPE)
  41. set(GF_CXX_FLAGS ${CXX_FLAGS} PARENT_SCOPE)
  42. endfunction()
  43. if (GGML_FATAL_WARNINGS)
  44. if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  45. list(APPEND C_FLAGS -Werror)
  46. list(APPEND CXX_FLAGS -Werror)
  47. elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
  48. add_compile_options(/WX)
  49. endif()
  50. endif()
  51. if (GGML_ALL_WARNINGS)
  52. if (NOT MSVC)
  53. list(APPEND WARNING_FLAGS -Wall -Wextra -Wpedantic -Wcast-qual -Wno-unused-function)
  54. list(APPEND C_FLAGS -Wshadow -Wstrict-prototypes -Wpointer-arith -Wmissing-prototypes
  55. -Werror=implicit-int -Werror=implicit-function-declaration)
  56. list(APPEND CXX_FLAGS -Wmissing-declarations -Wmissing-noreturn)
  57. list(APPEND C_FLAGS ${WARNING_FLAGS})
  58. list(APPEND CXX_FLAGS ${WARNING_FLAGS})
  59. ggml_get_flags(${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION})
  60. add_compile_options("$<$<COMPILE_LANGUAGE:C>:${C_FLAGS};${GF_C_FLAGS}>"
  61. "$<$<COMPILE_LANGUAGE:CXX>:${CXX_FLAGS};${GF_CXX_FLAGS}>")
  62. else()
  63. # todo : msvc
  64. set(C_FLAGS "")
  65. set(CXX_FLAGS "")
  66. endif()
  67. endif()
  68. if (GGML_LTO)
  69. include(CheckIPOSupported)
  70. check_ipo_supported(RESULT result OUTPUT output)
  71. if (result)
  72. set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
  73. else()
  74. message(WARNING "IPO is not supported: ${output}")
  75. endif()
  76. endif()
  77. if (GGML_CCACHE)
  78. find_program(GGML_CCACHE_FOUND ccache)
  79. find_program(GGML_SCCACHE_FOUND sccache)
  80. if (GGML_CCACHE_FOUND OR GGML_SCCACHE_FOUND)
  81. if(GGML_CCACHE_FOUND)
  82. set(GGML_CCACHE_VARIANT ccache)
  83. else()
  84. set(GGML_CCACHE_VARIANT sccache)
  85. endif()
  86. # TODO: should not be set globally
  87. set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${GGML_CCACHE_VARIANT}")
  88. set(ENV{CCACHE_SLOPPINESS} time_macros)
  89. message(STATUS "${GGML_CCACHE_VARIANT} found, compilation results will be cached. Disable with GGML_CCACHE=OFF.")
  90. else()
  91. message(STATUS "Warning: ccache not found - consider installing it for faster compilation or disable this warning with GGML_CCACHE=OFF")
  92. endif ()
  93. endif()
  94. # this version of Apple ld64 is buggy
  95. execute_process(
  96. COMMAND ${CMAKE_C_COMPILER} ${CMAKE_EXE_LINKER_FLAGS} -Wl,-v
  97. ERROR_VARIABLE output
  98. OUTPUT_QUIET
  99. )
  100. if (output MATCHES "dyld-1015\.7")
  101. add_compile_definitions(HAVE_BUGGY_APPLE_LINKER)
  102. endif()
  103. # architecture specific
  104. # TODO: probably these flags need to be tweaked on some architectures
  105. # feel free to update the Makefile for your architecture and send a pull request or issue
  106. message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
  107. if (MSVC)
  108. string(TOLOWER "${CMAKE_GENERATOR_PLATFORM}" CMAKE_GENERATOR_PLATFORM_LWR)
  109. message(STATUS "CMAKE_GENERATOR_PLATFORM: ${CMAKE_GENERATOR_PLATFORM}")
  110. else ()
  111. set(CMAKE_GENERATOR_PLATFORM_LWR "")
  112. endif ()
  113. if (NOT MSVC)
  114. if (GGML_STATIC)
  115. add_link_options(-static)
  116. if (MINGW)
  117. add_link_options(-static-libgcc -static-libstdc++)
  118. endif()
  119. endif()
  120. if (GGML_GPROF)
  121. add_compile_options(-pg)
  122. endif()
  123. endif()
  124. if (MINGW)
  125. # Target Windows 8 for PrefetchVirtualMemory
  126. add_compile_definitions(_WIN32_WINNT=${GGML_WIN_VER})
  127. endif()
  128. #
  129. # POSIX conformance
  130. #
  131. # clock_gettime came in POSIX.1b (1993)
  132. # CLOCK_MONOTONIC came in POSIX.1-2001 / SUSv3 as optional
  133. # posix_memalign came in POSIX.1-2001 / SUSv3
  134. # M_PI is an XSI extension since POSIX.1-2001 / SUSv3, came in XPG1 (1985)
  135. # Somehow in OpenBSD whenever POSIX conformance is specified
  136. # some string functions rely on locale_t availability,
  137. # which was introduced in POSIX.1-2008, forcing us to go higher
  138. if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
  139. add_compile_definitions(_XOPEN_SOURCE=700)
  140. else()
  141. add_compile_definitions(_XOPEN_SOURCE=600)
  142. endif()
  143. # Data types, macros and functions related to controlling CPU affinity and
  144. # some memory allocation are available on Linux through GNU extensions in libc
  145. if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android")
  146. add_compile_definitions(_GNU_SOURCE)
  147. endif()
  148. # RLIMIT_MEMLOCK came in BSD, is not specified in POSIX.1,
  149. # and on macOS its availability depends on enabling Darwin extensions
  150. # similarly on DragonFly, enabling BSD extensions is necessary
  151. if (
  152. CMAKE_SYSTEM_NAME MATCHES "Darwin" OR
  153. CMAKE_SYSTEM_NAME MATCHES "iOS" OR
  154. CMAKE_SYSTEM_NAME MATCHES "tvOS" OR
  155. CMAKE_SYSTEM_NAME MATCHES "DragonFly"
  156. )
  157. add_compile_definitions(_DARWIN_C_SOURCE)
  158. endif()
  159. # alloca is a non-standard interface that is not visible on BSDs when
  160. # POSIX conformance is specified, but not all of them provide a clean way
  161. # to enable it in such cases
  162. if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
  163. add_compile_definitions(__BSD_VISIBLE)
  164. endif()
  165. if (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
  166. add_compile_definitions(_NETBSD_SOURCE)
  167. endif()
  168. if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
  169. add_compile_definitions(_BSD_SOURCE)
  170. endif()
  171. if (WIN32)
  172. add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
  173. endif()
  174. # ggml
  175. if (GGML_BACKEND_DL AND NOT BUILD_SHARED_LIBS)
  176. message(FATAL_ERROR "GGML_BACKEND_DL requires BUILD_SHARED_LIBS")
  177. endif()
  178. add_library(ggml-base
  179. ../include/ggml.h
  180. ../include/ggml-alloc.h
  181. ../include/ggml-backend.h
  182. ../include/ggml-cpp.h
  183. ../include/ggml-opt.h
  184. ../include/gguf.h
  185. ggml.c
  186. ggml-alloc.c
  187. ggml-backend.cpp
  188. ggml-opt.cpp
  189. ggml-threading.cpp
  190. ggml-threading.h
  191. ggml-quants.c
  192. ggml-quants.h
  193. gguf.cpp)
  194. target_include_directories(ggml-base PRIVATE .)
  195. add_library(ggml
  196. ggml-backend-reg.cpp)
  197. target_link_libraries(ggml PUBLIC ggml-base)
  198. if (CMAKE_SYSTEM_NAME MATCHES "Linux")
  199. target_link_libraries(ggml PRIVATE dl)
  200. endif()
  201. function(ggml_add_backend_library backend)
  202. if (GGML_BACKEND_DL)
  203. add_library(${backend} MODULE ${ARGN})
  204. # write the shared library to the output directory
  205. set_target_properties(${backend} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
  206. target_compile_definitions(${backend} PRIVATE GGML_BACKEND_DL)
  207. add_dependencies(ggml ${backend})
  208. else()
  209. add_library(${backend} ${ARGN})
  210. target_link_libraries(ggml PUBLIC ${backend})
  211. install(TARGETS ${backend} LIBRARY)
  212. endif()
  213. target_link_libraries(${backend} PRIVATE ggml-base)
  214. target_include_directories(${backend} PRIVATE ..)
  215. if (${BUILD_SHARED_LIBS})
  216. target_compile_definitions(${backend} PRIVATE GGML_BACKEND_BUILD)
  217. target_compile_definitions(${backend} PUBLIC GGML_BACKEND_SHARED)
  218. endif()
  219. if(NOT GGML_AVAILABLE_BACKENDS)
  220. set(GGML_AVAILABLE_BACKENDS "${backend}"
  221. CACHE INTERNAL "List of backends for cmake package")
  222. else()
  223. list(FIND GGML_AVAILABLE_BACKENDS "${backend}" has_backend)
  224. if(has_backend EQUAL -1)
  225. set(GGML_AVAILABLE_BACKENDS "${GGML_AVAILABLE_BACKENDS};${backend}"
  226. CACHE INTERNAL "List of backends for cmake package")
  227. endif()
  228. endif()
  229. endfunction()
  230. function(ggml_add_backend backend)
  231. string(TOUPPER "GGML_${backend}" backend_id)
  232. if (${backend_id})
  233. string(TOLOWER "ggml-${backend}" backend_target)
  234. add_subdirectory(${backend_target})
  235. message(STATUS "Including ${backend} backend")
  236. if (NOT GGML_BACKEND_DL)
  237. string(TOUPPER "GGML_USE_${backend}" backend_use)
  238. target_compile_definitions(ggml PUBLIC ${backend_use})
  239. endif()
  240. endif()
  241. endfunction()
  242. function(ggml_add_cpu_backend_variant tag_name)
  243. set(GGML_CPU_TAG_NAME ${tag_name})
  244. # other: OPENMP LLAMAFILE CPU_HBM
  245. foreach (feat NATIVE
  246. AVX AVX2 AVX_VNNI FMA F16C
  247. AVX512 AVX512_VBMI AVX512_VNNI AVX512_BF16
  248. AMX_TILE AMX_INT8 AMX_BF16)
  249. set(GGML_${feat} OFF)
  250. endforeach()
  251. foreach (feat ${ARGN})
  252. set(GGML_${feat} ON)
  253. endforeach()
  254. ggml_add_cpu_backend_variant_impl(${tag_name})
  255. endfunction()
  256. ggml_add_backend(CPU)
  257. if (GGML_CPU_ALL_VARIANTS)
  258. if (NOT GGML_BACKEND_DL)
  259. message(FATAL_ERROR "GGML_CPU_ALL_VARIANTS requires GGML_BACKEND_DL")
  260. endif()
  261. ggml_add_cpu_backend_variant(sandybridge AVX)
  262. ggml_add_cpu_backend_variant(haswell AVX F16C AVX2 FMA)
  263. ggml_add_cpu_backend_variant(skylakex AVX F16C AVX2 FMA AVX512)
  264. ggml_add_cpu_backend_variant(icelake AVX F16C AVX2 FMA AVX512 AVX512_VBMI AVX512_VNNI)
  265. ggml_add_cpu_backend_variant(alderlake AVX F16C AVX2 FMA AVX_VNNI)
  266. if (NOT MSVC)
  267. # MSVC doesn't support AMX
  268. ggml_add_cpu_backend_variant(sapphirerapids AVX F16C AVX2 FMA AVX512 AVX512_VBMI AVX512_VNNI AVX512_BF16 AMX_TILE AMX_INT8)
  269. endif()
  270. elseif (GGML_CPU)
  271. ggml_add_cpu_backend_variant_impl("")
  272. endif()
  273. ggml_add_backend(BLAS)
  274. ggml_add_backend(CANN)
  275. ggml_add_backend(CUDA)
  276. ggml_add_backend(HIP)
  277. ggml_add_backend(Kompute)
  278. ggml_add_backend(METAL)
  279. ggml_add_backend(MUSA)
  280. ggml_add_backend(RPC)
  281. ggml_add_backend(SYCL)
  282. ggml_add_backend(Vulkan)
  283. ggml_add_backend(OpenCL)
  284. foreach (target ggml-base ggml)
  285. target_include_directories(${target} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include> $<INSTALL_INTERFACE:include>)
  286. target_compile_features (${target} PRIVATE c_std_11 cxx_std_17) # don't bump
  287. endforeach()
  288. target_link_libraries(ggml-base PRIVATE Threads::Threads)
  289. find_library(MATH_LIBRARY m)
  290. if (MATH_LIBRARY)
  291. if (NOT WIN32 OR NOT DEFINED ENV{ONEAPI_ROOT})
  292. target_link_libraries(ggml-base PRIVATE m)
  293. endif()
  294. endif()
  295. if (CMAKE_SYSTEM_NAME MATCHES "Android")
  296. target_link_libraries(ggml-base PRIVATE dl)
  297. endif()
  298. if (BUILD_SHARED_LIBS)
  299. foreach (target ggml-base ggml)
  300. set_target_properties(${target} PROPERTIES POSITION_INDEPENDENT_CODE ON)
  301. target_compile_definitions(${target} PRIVATE GGML_BUILD)
  302. target_compile_definitions(${target} PUBLIC GGML_SHARED)
  303. endforeach()
  304. endif()