CMakeLists.txt 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. if (GGML_ALL_WARNINGS)
  2. if (NOT MSVC)
  3. add_compile_options(-Wunused -Wextra -Wcast-qual -Wdouble-promotion)
  4. add_compile_options("$<$<COMPILE_LANGUAGE:C>:-Wshadow;-Wno-unused-function;-Wmissing-prototypes>")
  5. else()
  6. # todo : windows
  7. endif()
  8. endif()
  9. # compiler flags
  10. if (NOT MSVC)
  11. #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-math-errno -ffinite-math-only -funsafe-math-optimizations")
  12. endif()
  13. message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
  14. if (NOT UNAME_S)
  15. execute_process(COMMAND uname -s OUTPUT_VARIABLE UNAME_S)
  16. endif()
  17. if (NOT UNAME_P)
  18. execute_process(COMMAND uname -p OUTPUT_VARIABLE UNAME_P)
  19. endif()
  20. if (NOT UNAME_M)
  21. execute_process(COMMAND uname -m OUTPUT_VARIABLE UNAME_M)
  22. endif()
  23. #message(STATUS "UNAME_S: ${UNAME_S} UNAME_P: ${UNAME_P} UNAME_M: ${UNAME_M}")
  24. # Mac OS + Arm can report x86_64
  25. # ref: https://github.com/ggerganov/whisper.cpp/issues/66#issuecomment-1282546789
  26. if (UNAME_S MATCHES "Darwin")
  27. if (NOT UNAME_P MATCHES "arm")
  28. execute_process(COMMAND sysctl -n hw.optional.arm64 OUTPUT_VARIABLE SYSCTL_M)
  29. if (SYSCTL_M MATCHES "1")
  30. #set(UNAME_P "arm")
  31. #set(UNAME_M "arm64")
  32. message(WARNING "Your arch is announced as x86_64, but it seems to actually be ARM64. Not fixing that can lead to bad performance. For more info see: https://github.com/ggerganov/whisper.cpp/issues/66\#issuecomment-#1282546789")
  33. endif()
  34. endif()
  35. endif()
  36. if (${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
  37. message(STATUS "Emscripten detected")
  38. elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64")
  39. message(STATUS "ARM detected")
  40. #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcpu=apple-m1")
  41. elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc64le" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc64")
  42. message(STATUS "PPC64 detected")
  43. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mpower9-vector")
  44. else()
  45. message(STATUS "x86 detected")
  46. #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx -mavx2 -mfma -mf16c")
  47. if (UNAME_S MATCHES "Darwin")
  48. execute_process(COMMAND sysctl machdep.cpu.features OUTPUT_VARIABLE AVX1_M)
  49. if (AVX1_M MATCHES "AVX1.0")
  50. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx")
  51. endif()
  52. execute_process(COMMAND sysctl machdep.cpu.leaf7_features OUTPUT_VARIABLE AVX2_M)
  53. if (AVX2_M MATCHES "AVX2")
  54. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx2")
  55. endif()
  56. if (AVX1_M MATCHES "FMA")
  57. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfma")
  58. endif()
  59. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mf16c")
  60. elseif (UNAME_S MATCHES "Linux")
  61. message(STATUS "Linux detected")
  62. execute_process(COMMAND grep "avx " /proc/cpuinfo OUTPUT_VARIABLE AVX1_M)
  63. if (AVX1_M MATCHES "avx")
  64. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx")
  65. endif()
  66. execute_process(COMMAND grep "avx2 " /proc/cpuinfo OUTPUT_VARIABLE AVX2_M)
  67. if (AVX2_M MATCHES "avx2")
  68. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx2")
  69. endif()
  70. execute_process(COMMAND grep "fma " /proc/cpuinfo OUTPUT_VARIABLE FMA_M)
  71. if (FMA_M MATCHES "fma")
  72. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfma")
  73. endif()
  74. execute_process(COMMAND grep "f16c " /proc/cpuinfo OUTPUT_VARIABLE F16C_M)
  75. if (F16C_M MATCHES "f16c")
  76. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mf16c")
  77. endif()
  78. execute_process(COMMAND grep "sse3 " /proc/cpuinfo OUTPUT_VARIABLE SSE3_M)
  79. if (SSE3_M MATCHES "sse3")
  80. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse3")
  81. endif()
  82. elseif (UNAME_S MATCHES "Haiku")
  83. message(STATUS "Haiku detected")
  84. execute_process(COMMAND sysinfo -cpu COMMAND grep "AVX " OUTPUT_VARIABLE AVX1_M)
  85. if (AVX1_M MATCHES "avx")
  86. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx")
  87. endif()
  88. execute_process(COMMAND sysinfo -cpu COMMAND grep "AVX2 " OUTPUT_VARIABLE AVX2_M)
  89. if (AVX2_M MATCHES "avx2")
  90. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx2")
  91. endif()
  92. execute_process(COMMAND sysinfo -cpu COMMAND grep "FMA " OUTPUT_VARIABLE FMA_M)
  93. if (FMA_M MATCHES "fma")
  94. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfma")
  95. endif()
  96. execute_process(COMMAND sysinfo -cpu COMMAND grep "F16C " OUTPUT_VARIABLE F16C_M)
  97. if (F16C_M MATCHES "f16c")
  98. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mf16c")
  99. endif()
  100. elseif (MSVC)
  101. if (GGML_AVX512)
  102. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:AVX512")
  103. # MSVC has no compile-time flags enabling specific
  104. # AVX512 extensions, neither it defines the
  105. # macros corresponding to the extensions.
  106. # Do it manually.
  107. if (GGML_AVX512_VBMI)
  108. add_compile_definitions(__AVX512VBMI__)
  109. endif()
  110. if (GGML_AVX512_VNNI)
  111. add_compile_definitions(__AVX512VNNI__)
  112. endif()
  113. elseif (GGML_AVX2)
  114. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:AVX2")
  115. elseif (GGML_AVX)
  116. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:AVX")
  117. endif()
  118. else()
  119. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfma -mf16c -mavx -mavx2")
  120. endif()
  121. endif()
  122. # ggml
  123. set(TARGET ggml)
  124. # on APPLE - include Accelerate framework
  125. if (APPLE AND NOT GGML_NO_ACCELERATE)
  126. find_library(ACCELERATE_FRAMEWORK Accelerate)
  127. if (ACCELERATE_FRAMEWORK)
  128. message(STATUS "Accelerate framework found")
  129. set(GGML_EXTRA_LIBS ${GGML_EXTRA_LIBS} ${ACCELERATE_FRAMEWORK})
  130. set(GGML_EXTRA_FLAGS ${GGML_EXTRA_FLAGS} -DGGML_USE_ACCELERATE)
  131. else()
  132. message(WARNING "Accelerate framework not found")
  133. endif()
  134. endif()
  135. if (GGML_OPENBLAS)
  136. set(OPENBLAS_INCLUDE_SEARCH_PATHS
  137. /usr/include
  138. /usr/include/openblas
  139. /usr/include/openblas-base
  140. /usr/local/include
  141. /usr/local/include/openblas
  142. /usr/local/include/openblas-base
  143. /opt/OpenBLAS/include
  144. $ENV{OpenBLAS_HOME}
  145. $ENV{OpenBLAS_HOME}/include
  146. )
  147. find_path(OPENBLAS_INC NAMES cblas.h PATHS ${OPENBLAS_INCLUDE_SEARCH_PATHS})
  148. find_library(OPENBLAS_LIB NAMES openblas libopenblas)
  149. if (OPENBLAS_LIB)
  150. message(STATUS "OpenBLAS found")
  151. set(GGML_EXTRA_LIBS ${GGML_EXTRA_LIBS} ${OPENBLAS_LIB})
  152. set(GGML_EXTRA_INCS ${GGML_EXTRA_INCS} ${OPENBLAS_INC})
  153. set(GGML_EXTRA_FLAGS ${GGML_EXTRA_FLAGS} -DGGML_USE_OPENBLAS)
  154. else()
  155. message(WARNING "OpenBLAS not found")
  156. endif()
  157. endif()
  158. if (GGML_CLBLAST)
  159. set(CLBLAST_INCLUDE_SEARCH_PATHS
  160. /usr/include
  161. /usr/local/include
  162. $ENV{CLBLAST_HOME}
  163. $ENV{CLBLAST_HOME}/include
  164. )
  165. find_path(CLBLAST_INC NAMES clblast.h PATHS ${CLBLAST_INCLUDE_SEARCH_PATHS})
  166. find_library(CLBLAST_LIB NAMES clblast)
  167. if (CLBLAST_LIB AND CLBLAST_INC)
  168. message(STATUS "clBLAST found")
  169. set(GGML_EXTRA_INCS ${GGML_EXTRA_INCS} ${CLBLAST_INC})
  170. set(GGML_EXTRA_LIBS ${GGML_EXTRA_LIBS} ${CLBLAST_LIB})
  171. set(GGML_EXTRA_FLAGS ${GGML_EXTRA_FLAGS} -DGGML_USE_CLBLAST)
  172. set(GGML_OPENCL_SOURCES ggml-opencl.cpp ggml-opencl.h)
  173. link_libraries("-Wl,--copy-dt-needed-entries")
  174. else()
  175. message(WARNING "clBLAST not found")
  176. endif()
  177. endif()
  178. if (GGML_CUBLAS)
  179. cmake_minimum_required(VERSION 3.17)
  180. find_package(CUDAToolkit)
  181. if (CUDAToolkit_FOUND)
  182. message(STATUS "cuBLAS found")
  183. enable_language(CUDA)
  184. set(GGML_CUDA_SOURCES ggml-cuda.cu ggml-cuda.h)
  185. add_compile_definitions(GGML_USE_CUBLAS)
  186. if (GGML_STATIC)
  187. set(GGML_EXTRA_LIBS ${GGML_EXTRA_LIBS} CUDA::cudart_static CUDA::cublas_static CUDA::cublasLt_static)
  188. else()
  189. set(GGML_EXTRA_LIBS ${GGML_EXTRA_LIBS} CUDA::cudart CUDA::cublas CUDA::cublasLt)
  190. endif()
  191. else()
  192. message(WARNING "cuBLAS not found")
  193. endif()
  194. endif()
  195. if (GGML_METAL)
  196. find_library(FOUNDATION_LIBRARY Foundation REQUIRED)
  197. find_library(METAL_FRAMEWORK Metal REQUIRED)
  198. find_library(METALKIT_FRAMEWORK MetalKit REQUIRED)
  199. find_library(METALPERFORMANCE_FRAMEWORK MetalPerformanceShaders REQUIRED)
  200. set(GGML_METAL_SOURCES ggml-metal.m ggml-metal.h)
  201. add_compile_definitions(GGML_USE_METAL)
  202. add_compile_definitions(GGML_METAL_NDEBUG)
  203. # get full path to the file
  204. #add_compile_definitions(GGML_METAL_DIR_KERNELS="${CMAKE_CURRENT_SOURCE_DIR}/")
  205. # copy ggml-metal.metal to bin directory
  206. configure_file(ggml-metal.metal ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ggml-metal.metal COPYONLY)
  207. set(GGML_EXTRA_LIBS ${GGML_EXTRA_LIBS}
  208. ${FOUNDATION_LIBRARY}
  209. ${METAL_FRAMEWORK}
  210. ${METALKIT_FRAMEWORK}
  211. ${METALPERFORMANCE_FRAMEWORK}
  212. )
  213. endif()
  214. if (GGML_PERF)
  215. set(GGML_EXTRA_FLAGS ${GGML_EXTRA_FLAGS} -DGGML_PERF)
  216. endif()
  217. add_library(${TARGET}
  218. ggml.c
  219. ggml-alloc.c
  220. ../include/ggml/ggml.h
  221. ../include/ggml/ggml-alloc.h
  222. ${GGML_CUDA_SOURCES}
  223. ${GGML_OPENCL_SOURCES}
  224. ${GGML_METAL_SOURCES}
  225. )
  226. target_include_directories(${TARGET} PUBLIC
  227. .
  228. ../include
  229. ../include/ggml
  230. ../examples/
  231. ../tracy/public/
  232. ${GGML_EXTRA_INCS}
  233. )
  234. if (TRACY_ENABLE)
  235. target_link_libraries (${TARGET} PUBLIC Tracy::TracyClient )
  236. endif()
  237. if (MSVC)
  238. target_link_libraries(${TARGET} PUBLIC ${GGML_EXTRA_LIBS} ${CMAKE_THREAD_LIBS_INIT} kaldi-native-fbank)
  239. else()
  240. target_link_libraries(${TARGET} PUBLIC m ${GGML_EXTRA_LIBS} ${CMAKE_THREAD_LIBS_INIT} kaldi-native-fbank)
  241. endif()
  242. if (BUILD_SHARED_LIBS)
  243. set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
  244. target_link_libraries(${TARGET} PUBLIC
  245. ${CMAKE_DL_LIBS}
  246. )
  247. target_compile_definitions(${TARGET} PUBLIC
  248. GGML_SHARED
  249. )
  250. target_compile_definitions(${TARGET} PRIVATE
  251. GGML_BUILD
  252. )
  253. if (GGML_METAL)
  254. set_target_properties(${TARGET} PROPERTIES RESOURCE "${CMAKE_CURRENT_SOURCE_DIR}/ggml-metal.metal")
  255. endif()
  256. endif()
  257. target_compile_definitions(${TARGET} PUBLIC
  258. ${GGML_EXTRA_FLAGS}
  259. )
  260. if (MINGW)
  261. target_link_libraries(${TARGET} PUBLIC
  262. stdc++
  263. )
  264. endif()
  265. if (GGML_CUDA_SOURCES)
  266. message(STATUS "GGML CUDA sources found, configuring CUDA architecture")
  267. set_property(TARGET ggml PROPERTY CUDA_ARCHITECTURES "52;61")
  268. set_property(TARGET ggml PROPERTY CUDA_SELECT_NVCC_ARCH_FLAGS "Auto")
  269. if (NOT MSVC)
  270. target_link_libraries(ggml PUBLIC stdc++)
  271. endif()
  272. endif()
  273. set (GGML_PUBLIC_HEADERS
  274. ${CMAKE_CURRENT_SOURCE_DIR}/../include/ggml/ggml.h
  275. ${CMAKE_CURRENT_SOURCE_DIR}/../include/ggml/ggml-alloc.h)
  276. set_target_properties(${TARGET} PROPERTIES
  277. PUBLIC_HEADER "${GGML_PUBLIC_HEADERS}")
  278. install(TARGETS ${TARGET}
  279. LIBRARY DESTINATION lib
  280. ARCHIVE DESTINATION lib/static
  281. PUBLIC_HEADER DESTINATION include/ggml
  282. )