CMakeLists.txt 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. cmake_minimum_required(VERSION 3.21)
  2. project(aphrodite_extensions LANGUAGES CXX)
  3. message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
  4. include(${CMAKE_CURRENT_LIST_DIR}/cmake/utils.cmake)
  5. #[=======================================================================[
  6. Supported python versions. These versions will be searched in order, the
  7. first match will be selected. These should be kept in sync with setup.py.
  8. #]=======================================================================]
  9. set(PYTHON_SUPPORTED_VERSIONS "3.8" "3.9" "3.10" "3.11")
  10. # Supported NVIDIA architectures.
  11. set(CUDA_SUPPORTED_ARCHS "6.1;7.0;7.5;8.0;8.6;8.9;9.0")
  12. # Supported AMD GPU architectures.
  13. set(HIP_SUPPORTED_ARCHS "gfx908;gfx90a;gfx942;gfx1100")
  14. #[=====================================================================[
  15. Supported/expected torch versions for CUDA/ROCm.
  16. Currently, having an incorrect pytorch version results in a warning
  17. rather than an error.
  18. NOTE: the CUDA torch version is derived from pyproject.toml and various
  19. requirements.txt files and should be kept consistent. The ROCm torch
  20. versions are derived from Dockerfile.rocm
  21. #]=====================================================================]
  22. set(TORCH_SUPPORTED_VERSION_CUDA "2.2.0")
  23. set(TORCH_SUPPORTED_VERSION_ROCM_5X "2.0.1")
  24. set(TORCH_SUPPORTED_VERSION_ROCM_6X "2.1.1")
  25. #[=====================================================================[
  26. Try to find python package with an executable that exactly matches
  27. `APHRODITE_PYTHON_EXECUTABLE` and is one of the supported versions.
  28. #]=====================================================================]
  29. if (APHRODITE_PYTHON_EXECUTABLE)
  30. find_python_from_executable(${APHRODITE_PYTHON_EXECUTABLE} "${PYTHON_SUPPORTED_VERSIONS}")
  31. else()
  32. message(FATAL_ERROR
  33. "Please set APHRODITE_PYTHON_EXECUTABLE to the path of the desired python version"
  34. " before running cmake configure.")
  35. endif()
  36. # Update cmake's `CMAKE_PREFIX_PATH` with torch location.
  37. append_cmake_prefix_path("torch" "torch.utils.cmake_prefix_path")
  38. #[==============================================================================[
  39. Import torch cmake configuration.
  40. Torch also imports CUDA (and partially HIP) languages with some customizations,
  41. so there is no need to do this explicitly with check_language/enable_language,
  42. etc.
  43. #]==============================================================================]
  44. find_package(Torch REQUIRED)
  45. #[==============================================================================[
  46. Normally `torch.utils.cpp_extension.CUDAExtension` would add
  47. `libtorch_python.so` for linking against an extension. Torch's cmake
  48. configuration does not include this library (presumably since the cmake
  49. config is used for standalone C++ binaries that link against torch).
  50. The `libtorch_python.so` library defines some of the glue code between
  51. torch/python via pybind and is required by Aphrodite extensions for this
  52. reason. So, add it by manually using `append_torchlib_if_found` from
  53. torch's cmake setup.
  54. #]==============================================================================]
  55. append_torchlib_if_found(torch_python)
  56. #[====================================================================[
  57. # Set up GPU language and check the torch version and warn if it isn't
  58. # what is expected.
  59. #]====================================================================]
  60. if (NOT HIP_FOUND AND CUDA_FOUND)
  61. set(APHRODITE_GPU_LANG "CUDA")
  62. if (NOT Torch_VERSION VERSION_EQUAL ${TORCH_SUPPORTED_VERSION_CUDA})
  63. message(WARNING "Pytorch version ${TORCH_SUPPORTED_VERSION_CUDA} "
  64. "expected for CUDA build, saw ${Torch_VERSION} instead.")
  65. endif()
  66. elseif(HIP_FOUND)
  67. set(APHRODITE_GPU_LANG "HIP")
  68. #[===========================================================================[
  69. Importing torch recognizes and sets up some HIP/ROCm configuration but does
  70. not let cmake recognize .hip files. In order to get cmake to understand the
  71. .hip extension automatically, HIP must be enabled explicitly.
  72. #]===========================================================================]
  73. enable_language(HIP)
  74. # ROCm 5.x
  75. if (ROCM_VERSION_DEV_MAJOR EQUAL 5 AND
  76. NOT Torch_VERSION VERSION_EQUAL ${TORCH_SUPPORTED_VERSION_ROCM_5X})
  77. message(WARNING "Pytorch version ${TORCH_SUPPORTED_VERSION_ROCM_5X} "
  78. "expected for ROCMm 5.x build, saw ${Torch_VERSION} instead.")
  79. endif()
  80. # ROCm 6.x
  81. if (ROCM_VERSION_DEV_MAJOR EQUAL 6 AND
  82. NOT Torch_VERSION VERSION_EQUAL ${TORCH_SUPPORTED_VERSION_ROCM_6X})
  83. message(WARNING "Pytorch version ${TORCH_SUPPORTED_VERSION_ROCM_6X} "
  84. "expected for ROCMm 6.x build, saw ${Torch_VERSION} instead.")
  85. endif()
  86. else()
  87. message(FATAL_ERROR "Can't find CUDA or HIP installation.")
  88. endif()
  89. #[=========================================================================[
  90. Override the GPU architectures detected by cmake/torch and filter them by
  91. the supported versions for the current language.
  92. The final set of arches is stored in `APHRODITE_GPU_ARCHES`.
  93. #]=========================================================================]
  94. override_gpu_arches(APHRODITE_GPU_ARCHES
  95. ${APHRODITE_GPU_LANG}
  96. "${${APHRODITE_GPU_LANG}_SUPPORTED_ARCHS}")
  97. #[=========================================================================[
  98. Query torch for additional GPU compilation flags for the given
  99. `APHRODITE_GPU_LANG`.
  100. The final set of arches is stored in `APHRODITE_GPU_FLAGS`.
  101. #]=========================================================================]
  102. get_torch_gpu_compiler_flags(APHRODITE_GPU_FLAGS ${APHRODITE_GPU_LANG})
  103. # Set nvcc parallelism.
  104. if(NVCC_THREADS AND APHRODITE_GPU_LANG STREQUAL "CUDA")
  105. list(APPEND APHRODITE_GPU_FLAGS "--threads=${NVCC_THREADS}")
  106. endif()
  107. # Define extension targets
  108. # _C extension
  109. set(APHRODITE_EXT_SRC
  110. "kernels/cache_kernels.cu"
  111. "kernels/attention/attention_kernels.cu"
  112. "kernels/pos_encoding_kernels.cu"
  113. "kernels/activation_kernels.cu"
  114. "kernels/layernorm_kernels.cu"
  115. "kernels/quantization/squeezellm/quant_cuda_kernel.cu"
  116. "kernels/quantization/gguf/gguf_kernel.cu"
  117. "kernels/quantization/gptq/q_gemm.cu"
  118. "kernels/quantization/exl2/q_matrix.cu"
  119. "kernels/quantization/exl2/q_gemm_exl2.cu"
  120. "kernels/cuda_utils_kernels.cu"
  121. "kernels/moe/align_block_size_kernel.cu"
  122. "kernels/pybind.cpp")
  123. if(APHRODITE_GPU_LANG STREQUAL "CUDA")
  124. list(APPEND APHRODITE_EXT_SRC
  125. "kernels/quantization/awq/gemm_kernels.cu"
  126. "kernels/quantization/quip/origin_order.cu"
  127. "kernels/quantization/marlin/marlin_cuda_kernel.cu"
  128. "kernels/all_reduce/custom_all_reduce.cu"
  129. "kernels/quantization/aqlm/aqlm_cuda_entry.cpp"
  130. "kernels/quantization/aqlm/aqlm_cuda_kernel.cu"
  131. "kernels/quantization/bitsandbytes/int4_fp16_gemm_kernels.cu"
  132. "kernels/quantization/bitsandbytes/format.cu"
  133. "kernels/quantization/bitsandbytes/gemm_s4_f16.cu")
  134. endif()
  135. define_gpu_extension_target(
  136. _C
  137. DESTINATION aphrodite
  138. LANGUAGE ${APHRODITE_GPU_LANG}
  139. SOURCES ${APHRODITE_EXT_SRC}
  140. COMPILE_FLAGS ${APHRODITE_GPU_FLAGS}
  141. ARCHITECTURES ${APHRODITE_GPU_ARCHES}
  142. WITH_SOABI)
  143. # _moe_C extension
  144. set(APHRODITE_MOE_EXT_SRC
  145. "kernels/moe/moe_ops.cpp"
  146. "kernels/moe/softmax.cu")
  147. define_gpu_extension_target(
  148. _moe_C
  149. DESTINATION aphrodite
  150. LANGUAGE ${APHRODITE_GPU_LANG}
  151. SOURCES ${APHRODITE_MOE_EXT_SRC}
  152. COMPILE_FLAGS ${APHRODITE_GPU_FLAGS}
  153. ARCHITECTURES ${APHRODITE_GPU_ARCHES}
  154. WITH_SOABI)
  155. # _punica_C extension
  156. set(APHRODITE_PUNICA_EXT_SRC
  157. "kernels/punica/bgmv/bgmv_bf16_bf16_bf16.cu"
  158. "kernels/punica/bgmv/bgmv_bf16_bf16_fp16.cu"
  159. "kernels/punica/bgmv/bgmv_bf16_fp16_bf16.cu"
  160. "kernels/punica/bgmv/bgmv_bf16_fp16_fp16.cu"
  161. "kernels/punica/bgmv/bgmv_bf16_fp32_bf16.cu"
  162. "kernels/punica/bgmv/bgmv_bf16_fp32_fp16.cu"
  163. "kernels/punica/bgmv/bgmv_fp16_bf16_bf16.cu"
  164. "kernels/punica/bgmv/bgmv_fp16_bf16_fp16.cu"
  165. "kernels/punica/bgmv/bgmv_fp16_fp16_bf16.cu"
  166. "kernels/punica/bgmv/bgmv_fp16_fp16_fp16.cu"
  167. "kernels/punica/bgmv/bgmv_fp16_fp32_bf16.cu"
  168. "kernels/punica/bgmv/bgmv_fp16_fp32_fp16.cu"
  169. "kernels/punica/bgmv/bgmv_fp32_bf16_bf16.cu"
  170. "kernels/punica/bgmv/bgmv_fp32_bf16_fp16.cu"
  171. "kernels/punica/bgmv/bgmv_fp32_fp16_bf16.cu"
  172. "kernels/punica/bgmv/bgmv_fp32_fp16_fp16.cu"
  173. "kernels/punica/bgmv/bgmv_fp32_fp32_bf16.cu"
  174. "kernels/punica/bgmv/bgmv_fp32_fp32_fp16.cu"
  175. "kernels/punica/punica_ops.cc")
  176. # Copy GPU compilation flags+update for punica
  177. set(APHRODITE_PUNICA_GPU_FLAGS ${APHRODITE_GPU_FLAGS})
  178. list(REMOVE_ITEM APHRODITE_PUNICA_GPU_FLAGS
  179. "-D__CUDA_NO_HALF_OPERATORS__"
  180. "-D__CUDA_NO_HALF_CONVERSIONS__"
  181. "-D__CUDA_NO_BFLOAT16_CONVERSIONS__"
  182. "-D__CUDA_NO_HALF2_OPERATORS__")
  183. # Filter out CUDA architectures < 8.0 for punica.
  184. if (${APHRODITE_GPU_LANG} STREQUAL "CUDA")
  185. set(APHRODITE_PUNICA_GPU_ARCHES)
  186. foreach(ARCH ${APHRODITE_GPU_ARCHES})
  187. string_to_ver(CODE_VER ${ARCH})
  188. if (CODE_VER GREATER_EQUAL 8.0)
  189. list(APPEND APHRODITE_PUNICA_GPU_ARCHES ${ARCH})
  190. endif()
  191. endforeach()
  192. message(STATUS "Punica target arches: ${APHRODITE_PUNICA_GPU_ARCHES}")
  193. endif()
  194. if (APHRODITE_PUNICA_GPU_ARCHES)
  195. define_gpu_extension_target(
  196. _punica_C
  197. DESTINATION aphrodite
  198. LANGUAGE ${APHRODITE_GPU_LANG}
  199. SOURCES ${APHRODITE_PUNICA_EXT_SRC}
  200. COMPILE_FLAGS ${APHRODITE_PUNICA_GPU_FLAGS}
  201. ARCHITECTURES ${APHRODITE_PUNICA_GPU_ARCHES}
  202. WITH_SOABI)
  203. else()
  204. message(WARNING "Unable to create _punica_C target because none of the "
  205. "requested architectures (${APHRODITE_GPU_ARCHES}) are supported, i.e. >= 8.0")
  206. endif()
  207. # _hadamard_C extension
  208. set(APHRODITE_HADAMARD_EXT_SRC
  209. "kernels/hadamard/fast_hadamard_transform.cpp"
  210. "kernels/hadamard/fast_hadamard_transform_cuda.cu")
  211. # Copy GPU compilation flags+update for hadamard
  212. set(APHRODITE_HADAMARD_GPU_FLAGS ${APHRODITE_GPU_FLAGS})
  213. list(APPEND APHRODITE_HADAMARD_GPU_FLAGS
  214. "-U__CUDA_NO_HALF_OPERATORS__"
  215. "-U__CUDA_NO_HALF_CONVERSIONS__"
  216. "-U__CUDA_NO_BFLOAT16_OPERATORS__"
  217. "-U__CUDA_NO_BFLOAT16_CONVERSIONS__"
  218. "-U__CUDA_NO_BFLOAT162__OPERATORS"
  219. "-U__CUDA_NO_BFLOAT162_CONVERSIONS__"
  220. "--expt-relaxed-constexpr"
  221. "--expt-extended-lambda"
  222. "--use_fast_math"
  223. "--ptxas-options=-v"
  224. "-lineinfo"
  225. )
  226. # Filter out CUDA architectures < 7.0 for hadamard.
  227. if (${APHRODITE_GPU_LANG} STREQUAL "CUDA")
  228. set(APHRODITE_HADAMARD_GPU_ARCHES)
  229. foreach(ARCH ${APHRODITE_GPU_ARCHES})
  230. string_to_ver(CODE_VER ${ARCH})
  231. if (CODE_VER GREATER_EQUAL 7.0)
  232. list(APPEND APHRODITE_HADAMARD_GPU_ARCHES ${ARCH})
  233. endif()
  234. endforeach()
  235. message(STATUS "Hadamard target arches: ${APHRODITE_HADAMARD_GPU_ARCHES}")
  236. if (APHRODITE_HADAMARD_GPU_ARCHES)
  237. define_gpu_extension_target(
  238. _hadamard_C
  239. DESTINATION aphrodite
  240. LANGUAGE ${APHRODITE_GPU_LANG}
  241. SOURCES ${APHRODITE_HADAMARD_EXT_SRC}
  242. COMPILE_FLAGS ${APHRODITE_HADAMARD_GPU_FLAGS}
  243. ARCHITECTURES ${APHRODITE_HADAMARD_GPU_ARCHES}
  244. WITH_SOABI)
  245. else()
  246. message(WARNING "Unable to create _hadamard_C target because none of the "
  247. "requested architectures (${APHRODITE_GPU_ARCHES}) are supported, i.e. >= 7.0")
  248. endif()
  249. endif()
  250. #[=====================================================================[
  251. # Add the `default` target which detects which extensions should be
  252. # built based on platform/architecture. This is the same logic that
  253. # setup.py uses to select which extensions should be built and should
  254. # be kept in sync.
  255. #
  256. # The `default` target makes direct use of cmake easier since knowledge
  257. # of which extensions are supported has been factored in, e.g.
  258. #
  259. # mkdir build && cd build
  260. # cmake -G Ninja -DAPHRODITE_PYTHON_EXECUTABLE=`which python3` -DCMAKE_LIBRARY_OUTPUT_DIRECTORY=../aphrodite ..
  261. # cmake --build . --target default
  262. #]=====================================================================]
  263. add_custom_target(default)
  264. if(APHRODITE_GPU_LANG STREQUAL "CUDA" OR APHRODITE_GPU_LANG STREQUAL "HIP")
  265. message(STATUS "Enabling C extension.")
  266. add_dependencies(default _C)
  267. endif()
  268. if(APHRODITE_GPU_LANG STREQUAL "CUDA")
  269. message(STATUS "Enabling moe extension.")
  270. add_dependencies(default _moe_C)
  271. #[=====================================================================[
  272. # Enable punica if -DAPHRODITE_INSTALL_PUNICA_KERNELS=ON or
  273. # APHRODITE_INSTALL_PUNICA_KERNELS is set in the environment and
  274. # there are supported target arches.
  275. #]=====================================================================]
  276. if (APHRODITE_PUNICA_GPU_ARCHES AND
  277. (ENV{APHRODITE_INSTALL_PUNICA_KERNELS} OR APHRODITE_INSTALL_PUNICA_KERNELS))
  278. message(STATUS "Enabling punica extension.")
  279. add_dependencies(default _punica_C)
  280. endif()
  281. endif()
  282. if (APHRODITE_HADAMARD_GPU_ARCHES)
  283. message(STATUS "Enabling hadamard extension.")
  284. add_dependencies(default _hadamard_C)
  285. #[=====================================================================[
  286. # Enable hadamard if -DAPHRODITE_INSTALL_HADAMARD_KERNELS=ON or
  287. # APHRODITE_INSTALL_HADAMARD_KERNELS is set in the environment and
  288. # there are supported target arches.
  289. #]=====================================================================]
  290. if (APHRODITE_HADAMARD_GPU_ARCHES AND
  291. (ENV{APHRODITE_INSTALL_HADAMARD_KERNELS} OR APHRODITE_INSTALL_HADAMARD_KERNELS))
  292. message(STATUS "Enabling hadamard extension.")
  293. add_dependencies(default _hadamard_C)
  294. endif()
  295. endif()