2023-03-21 17:29:41 +02:00
cmake_minimum_required ( VERSION 3.12 ) # Don't bump this version for no reason
2023-03-21 09:37:16 +09:00
project ( "llama.cpp" C CXX )
2023-03-13 14:12:33 -03:00
2023-03-21 17:29:41 +02:00
set ( CMAKE_EXPORT_COMPILE_COMMANDS ON )
2023-03-13 21:22:15 +02:00
if ( NOT XCODE AND NOT MSVC AND NOT CMAKE_BUILD_TYPE )
set ( CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE )
set_property ( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo" )
endif ()
2023-03-21 17:29:41 +02:00
set ( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ CMAKE_BINARY_DIR } /bin )
if ( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
set ( LLAMA_STANDALONE ON )
# configure project version
# TODO
else ()
set ( LLAMA_STANDALONE OFF )
endif ()
if ( EMSCRIPTEN )
set ( BUILD_SHARED_LIBS_DEFAULT OFF )
option ( LLAMA_WASM_SINGLE_FILE "llama: embed WASM inside the generated llama.js" ON )
else ()
if ( MINGW )
set ( BUILD_SHARED_LIBS_DEFAULT OFF )
else ()
set ( BUILD_SHARED_LIBS_DEFAULT ON )
endif ()
endif ()
2023-03-21 09:37:16 +09:00
#
# Option list
#
2023-03-13 14:12:33 -03:00
2023-03-21 09:37:16 +09:00
# general
2023-05-25 23:07:29 +02:00
option ( LLAMA_STATIC "llama: static link libraries" OFF )
option ( LLAMA_NATIVE "llama: enable -march=native flag" OFF )
option ( LLAMA_LTO "llama: enable link time optimization" OFF )
2023-03-13 14:12:33 -03:00
2023-03-21 09:37:16 +09:00
# debug
2023-05-25 23:07:29 +02:00
option ( LLAMA_ALL_WARNINGS "llama: enable all compiler warnings" ON )
option ( LLAMA_ALL_WARNINGS_3RD_PARTY "llama: enable all compiler warnings in 3rd party libs" OFF )
option ( LLAMA_GPROF "llama: enable gprof" OFF )
2023-03-21 09:37:16 +09:00
# sanitizers
2023-05-25 23:07:29 +02:00
option ( LLAMA_SANITIZE_THREAD "llama: enable thread sanitizer" OFF )
option ( LLAMA_SANITIZE_ADDRESS "llama: enable address sanitizer" OFF )
option ( LLAMA_SANITIZE_UNDEFINED "llama: enable undefined sanitizer" OFF )
2023-03-21 09:37:16 +09:00
# instruction set specific
2023-05-25 23:07:29 +02:00
option ( LLAMA_AVX "llama: enable AVX" ON )
option ( LLAMA_AVX2 "llama: enable AVX2" ON )
option ( LLAMA_AVX512 "llama: enable AVX512" OFF )
option ( LLAMA_AVX512_VBMI "llama: enable AVX512-VBMI" OFF )
option ( LLAMA_AVX512_VNNI "llama: enable AVX512-VNNI" OFF )
option ( LLAMA_FMA "llama: enable FMA" ON )
2023-04-13 15:48:21 +03:00
# in MSVC F16C is implied with AVX2/AVX512
if ( NOT MSVC )
2023-05-25 23:07:29 +02:00
option ( LLAMA_F16C "llama: enable F16C" ON )
2023-04-13 15:48:21 +03:00
endif ()
2023-03-21 09:37:16 +09:00
# 3rd party libs
2023-05-25 23:07:29 +02:00
option ( LLAMA_ACCELERATE "llama: enable Accelerate framework" ON )
option ( LLAMA_BLAS "llama: use BLAS" OFF )
2023-05-27 17:24:06 +03:00
set ( LLAMA_BLAS_VENDOR "Generic" CACHE STRING "llama: BLAS library vendor" )
2023-05-25 23:07:29 +02:00
option ( LLAMA_CUBLAS "llama: use cuBLAS" OFF )
set ( LLAMA_CUDA_DMMV_X "32" CACHE STRING "llama: x stride for dmmv CUDA kernels" )
set ( LLAMA_CUDA_DMMV_Y "1" CACHE STRING "llama: y block size for dmmv CUDA kernels" )
option ( LLAMA_CLBLAST "llama: use CLBlast" OFF )
2023-03-21 09:37:16 +09:00
2023-05-25 23:07:29 +02:00
option ( LLAMA_BUILD_TESTS "llama: build tests" ${ LLAMA_STANDALONE } )
option ( LLAMA_BUILD_EXAMPLES "llama: build examples" ${ LLAMA_STANDALONE } )
option ( LLAMA_BUILD_SERVER "llama: build server example" OFF )
2023-03-21 17:29:41 +02:00
2023-05-01 09:23:47 -07:00
#
# Build info header
#
# Generate initial build-info.h
include ( ${ CMAKE_CURRENT_SOURCE_DIR } /scripts/build-info.cmake )
if ( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git" )
2023-05-03 03:43:43 +03:00
set ( GIT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.git" )
# Is git submodule
if ( NOT IS_DIRECTORY "${GIT_DIR}" )
file ( READ ${ GIT_DIR } REAL_GIT_DIR_LINK )
string ( REGEX REPLACE "gitdir: (.*)\n$" "\\1" REAL_GIT_DIR ${ REAL_GIT_DIR_LINK } )
set ( GIT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${REAL_GIT_DIR}" )
endif ()
2023-05-01 09:23:47 -07:00
# Add a custom target for build-info.h
add_custom_target ( BUILD_INFO ALL DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/build-info.h" )
# Add a custom command to rebuild build-info.h when .git/index changes
add_custom_command (
OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/build-info.h"
COMMENT "Generating build details from Git"
COMMAND ${ CMAKE_COMMAND } -P "${CMAKE_CURRENT_SOURCE_DIR}/scripts/build-info.cmake"
WORKING_DIRECTORY ${ CMAKE_CURRENT_SOURCE_DIR }
2023-05-03 03:43:43 +03:00
DEPENDS "${GIT_DIR}/index"
2023-05-01 09:23:47 -07:00
VERBATIM
)
else ()
message ( WARNING "Git repository not found; to enable automatic generation of build info, make sure Git is installed and the project is a Git repository." )
endif ()
2023-03-21 09:37:16 +09:00
#
# Compile flags
#
2023-03-31 19:19:16 +00:00
set ( CMAKE_CXX_STANDARD 11 )
2023-03-21 09:37:16 +09:00
set ( CMAKE_CXX_STANDARD_REQUIRED true )
2023-03-31 19:19:16 +00:00
set ( CMAKE_C_STANDARD 11 )
2023-03-21 09:37:16 +09:00
set ( CMAKE_C_STANDARD_REQUIRED true )
set ( THREADS_PREFER_PTHREAD_FLAG ON )
find_package ( Threads REQUIRED )
2023-03-13 14:12:33 -03:00
if ( NOT MSVC )
if ( LLAMA_SANITIZE_THREAD )
2023-03-21 09:37:16 +09:00
add_compile_options ( -fsanitize=thread )
2023-03-25 23:38:11 +02:00
link_libraries ( -fsanitize=thread )
2023-03-13 14:12:33 -03:00
endif ()
if ( LLAMA_SANITIZE_ADDRESS )
2023-03-21 09:37:16 +09:00
add_compile_options ( -fsanitize=address -fno-omit-frame-pointer )
2023-03-25 23:38:11 +02:00
link_libraries ( -fsanitize=address )
2023-03-13 14:12:33 -03:00
endif ()
if ( LLAMA_SANITIZE_UNDEFINED )
2023-03-21 09:37:16 +09:00
add_compile_options ( -fsanitize=undefined )
2023-03-25 23:38:11 +02:00
link_libraries ( -fsanitize=undefined )
2023-03-13 14:12:33 -03:00
endif ()
endif ()
2023-03-21 09:37:16 +09:00
if ( APPLE AND LLAMA_ACCELERATE )
2023-03-13 14:12:33 -03:00
find_library ( ACCELERATE_FRAMEWORK Accelerate )
if ( ACCELERATE_FRAMEWORK )
message ( STATUS "Accelerate framework found" )
2023-03-21 09:37:16 +09:00
add_compile_definitions ( GGML_USE_ACCELERATE )
set ( LLAMA_EXTRA_LIBS ${ LLAMA_EXTRA_LIBS } ${ ACCELERATE_FRAMEWORK } )
2023-03-13 14:12:33 -03:00
else ()
message ( WARNING "Accelerate framework not found" )
endif ()
endif ()
2023-04-20 03:14:14 +02:00
2023-05-20 23:58:31 +09:00
if ( LLAMA_BLAS )
2023-03-21 09:37:16 +09:00
if ( LLAMA_STATIC )
set ( BLA_STATIC ON )
endif ()
2023-05-20 23:58:31 +09:00
if ( $ ( CMAKE_VERSION ) VERSION_GREATER_EQUAL 3.22 )
set ( BLA_SIZEOF_INTEGER 8 )
endif ()
set ( BLA_VENDOR ${ LLAMA_BLAS_VENDOR } )
2023-03-21 09:37:16 +09:00
find_package ( BLAS )
if ( BLAS_FOUND )
2023-05-20 23:58:31 +09:00
message ( STATUS "BLAS found, Libraries: ${BLAS_LIBRARIES}" )
2023-03-21 09:37:16 +09:00
2023-05-20 23:58:31 +09:00
add_compile_options ( ${ BLAS_LINKER_FLAGS } )
2023-03-21 09:37:16 +09:00
add_compile_definitions ( GGML_USE_OPENBLAS )
2023-05-20 23:58:31 +09:00
set ( LLAMA_EXTRA_LIBS ${ LLAMA_EXTRA_LIBS } ${ BLAS_LIBRARIES } )
2023-04-15 14:51:11 +09:00
2023-05-20 23:58:31 +09:00
message ( "${BLAS_LIBRARIES} ${BLAS_INCLUDE_DIRS}" )
include_directories ( ${ BLAS_INCLUDE_DIRS } )
2023-03-21 09:37:16 +09:00
else ()
2023-05-20 23:58:31 +09:00
message ( WARNING "BLAS not found, please refer to "
"https://cmake.org/cmake/help/latest/module/FindBLAS.html#blas-lapack-vendors"
" to set correct LLAMA_BLAS_VENDOR" )
2023-03-21 09:37:16 +09:00
endif ()
endif ()
2023-03-13 14:12:33 -03:00
2023-04-19 11:22:45 +02:00
if ( LLAMA_CUBLAS )
cmake_minimum_required ( VERSION 3.17 )
find_package ( CUDAToolkit )
if ( CUDAToolkit_FOUND )
message ( STATUS "cuBLAS found" )
2023-04-20 03:14:14 +02:00
enable_language ( CUDA )
set ( GGML_CUDA_SOURCES ggml-cuda.cu ggml-cuda.h )
2023-04-19 11:22:45 +02:00
add_compile_definitions ( GGML_USE_CUBLAS )
2023-05-25 23:07:29 +02:00
add_compile_definitions ( GGML_CUDA_DMMV_X= ${ LLAMA_CUDA_DMMV_X } )
add_compile_definitions ( GGML_CUDA_DMMV_Y= ${ LLAMA_CUDA_DMMV_Y } )
2023-04-19 11:22:45 +02:00
if ( LLAMA_STATIC )
set ( LLAMA_EXTRA_LIBS ${ LLAMA_EXTRA_LIBS } CUDA::cudart_static CUDA::cublas_static CUDA::cublasLt_static )
else ()
set ( LLAMA_EXTRA_LIBS ${ LLAMA_EXTRA_LIBS } CUDA::cudart CUDA::cublas CUDA::cublasLt )
endif ()
else ()
message ( WARNING "cuBLAS not found" )
endif ()
endif ()
2023-04-28 16:57:16 +02:00
if ( LLAMA_CLBLAST )
find_package ( CLBlast )
if ( CLBlast_FOUND )
message ( STATUS "CLBlast found" )
2023-05-22 23:33:24 +02:00
set ( GGML_OPENCL_SOURCES ggml-opencl.cpp ggml-opencl.h )
2023-04-28 16:57:16 +02:00
add_compile_definitions ( GGML_USE_CLBLAST )
set ( LLAMA_EXTRA_LIBS ${ LLAMA_EXTRA_LIBS } clblast )
else ()
message ( WARNING "CLBlast not found" )
endif ()
endif ()
2023-03-13 14:12:33 -03:00
if ( LLAMA_ALL_WARNINGS )
if ( NOT MSVC )
2023-03-21 09:37:16 +09:00
set ( c_flags
-Wall
-Wextra
-Wpedantic
-Wcast-qual
2023-03-28 16:48:20 +00:00
-Wdouble-promotion
-Wshadow
2023-03-21 09:37:16 +09:00
-Wstrict-prototypes
-Wpointer-arith
)
set ( cxx_flags
-Wall
-Wextra
-Wpedantic
-Wcast-qual
2023-03-28 19:51:55 +03:00
-Wno-unused-function
2023-04-08 12:24:37 -07:00
-Wno-multichar
2023-03-21 09:37:16 +09:00
)
2023-03-13 14:12:33 -03:00
else ()
# todo : msvc
endif ()
2023-03-21 09:37:16 +09:00
add_compile_options (
"$<$<COMPILE_LANGUAGE:C>:${c_flags}>"
"$<$<COMPILE_LANGUAGE:CXX>:${cxx_flags}>"
)
2023-03-13 14:12:33 -03:00
endif ()
2023-04-08 12:24:37 -07:00
if ( MSVC )
add_compile_definitions ( _CRT_SECURE_NO_WARNINGS )
2023-04-22 16:18:20 +08:00
if ( BUILD_SHARED_LIBS )
set ( CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON )
endif ()
2023-04-08 12:24:37 -07:00
endif ()
2023-03-21 09:37:16 +09:00
if ( LLAMA_LTO )
include ( CheckIPOSupported )
check_ipo_supported ( RESULT result OUTPUT output )
if ( result )
set ( CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE )
2023-03-13 14:12:33 -03:00
else ()
2023-03-21 09:37:16 +09:00
message ( WARNING "IPO is not supported: ${output}" )
2023-03-13 14:12:33 -03:00
endif ()
endif ()
2023-03-21 09:37:16 +09:00
# Architecture specific
# TODO: probably these flags need to be tweaked on some architectures
# feel free to update the Makefile for your architecture and send a pull request or issue
message ( STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}" )
if ( NOT MSVC )
if ( LLAMA_STATIC )
add_link_options ( -static )
if ( MINGW )
add_link_options ( -static-libgcc -static-libstdc++ )
endif ()
endif ()
if ( LLAMA_GPROF )
add_compile_options ( -pg )
endif ()
if ( LLAMA_NATIVE )
add_compile_options ( -march=native )
endif ()
endif ()
2023-03-13 14:12:33 -03:00
2023-03-21 09:37:16 +09:00
if ( ${ CMAKE_SYSTEM_PROCESSOR } MATCHES "arm" OR ${ CMAKE_SYSTEM_PROCESSOR } MATCHES "aarch64" )
message ( STATUS "ARM detected" )
if ( MSVC )
# TODO: arm msvc?
else ()
if ( ${ CMAKE_SYSTEM_PROCESSOR } MATCHES "aarch64" )
2023-04-30 20:48:38 +02:00
# Apple M1, M2, etc.
# Raspberry Pi 3, 4, Zero 2 (64-bit)
2023-03-21 09:37:16 +09:00
add_compile_options ( -mcpu=native )
endif ()
2023-04-30 20:48:38 +02:00
if ( ${ CMAKE_SYSTEM_PROCESSOR } MATCHES "armv6" )
# Raspberry Pi 1, Zero
add_compile_options ( -mfpu=neon-fp-armv8 -mfp16-format=ieee -mno-unaligned-access )
endif ()
if ( ${ CMAKE_SYSTEM_PROCESSOR } MATCHES "armv7" )
# Raspberry Pi 2
add_compile_options ( -mfpu=neon-fp-armv8 -mfp16-format=ieee -mno-unaligned-access -funsafe-math-optimizations )
endif ()
if ( ${ CMAKE_SYSTEM_PROCESSOR } MATCHES "armv8" )
# Raspberry Pi 3, 4, Zero 2 (32-bit)
add_compile_options ( -mfp16-format=ieee -mno-unaligned-access )
endif ()
2023-03-21 09:37:16 +09:00
endif ()
elseif ( ${ CMAKE_SYSTEM_PROCESSOR } MATCHES "^(x86_64|i686|AMD64)$" )
message ( STATUS "x86 detected" )
if ( MSVC )
2023-03-25 23:38:11 +02:00
if ( LLAMA_AVX512 )
2023-04-20 03:14:14 +02:00
add_compile_options ( $< $<COMPILE_LANGUAGE:C > :/arch:AVX512> )
add_compile_options ( $< $<COMPILE_LANGUAGE:CXX > :/arch:AVX512> )
2023-04-17 15:10:57 +02:00
# MSVC has no compile-time flags enabling specific
# AVX512 extensions, neither it defines the
# macros corresponding to the extensions.
# Do it manually.
if ( LLAMA_AVX512_VBMI )
2023-04-20 03:14:14 +02:00
add_compile_definitions ( $< $<COMPILE_LANGUAGE:C > :__AVX512VBMI__> )
add_compile_definitions ( $< $<COMPILE_LANGUAGE:CXX > :__AVX512VBMI__> )
2023-04-17 15:10:57 +02:00
endif ()
if ( LLAMA_AVX512_VNNI )
2023-04-20 03:14:14 +02:00
add_compile_definitions ( $< $<COMPILE_LANGUAGE:C > :__AVX512VNNI__> )
add_compile_definitions ( $< $<COMPILE_LANGUAGE:CXX > :__AVX512VNNI__> )
2023-04-17 15:10:57 +02:00
endif ()
2023-03-25 23:38:11 +02:00
elseif ( LLAMA_AVX2 )
2023-04-20 03:14:14 +02:00
add_compile_options ( $< $<COMPILE_LANGUAGE:C > :/arch:AVX2> )
add_compile_options ( $< $<COMPILE_LANGUAGE:CXX > :/arch:AVX2> )
2023-03-21 09:37:16 +09:00
elseif ( LLAMA_AVX )
2023-04-20 03:14:14 +02:00
add_compile_options ( $< $<COMPILE_LANGUAGE:C > :/arch:AVX> )
add_compile_options ( $< $<COMPILE_LANGUAGE:CXX > :/arch:AVX> )
2023-03-21 09:37:16 +09:00
endif ()
else ()
2023-04-13 15:48:21 +03:00
if ( LLAMA_F16C )
add_compile_options ( -mf16c )
endif ()
2023-03-21 09:37:16 +09:00
if ( LLAMA_FMA )
add_compile_options ( -mfma )
endif ()
if ( LLAMA_AVX )
add_compile_options ( -mavx )
endif ()
if ( LLAMA_AVX2 )
add_compile_options ( -mavx2 )
endif ()
2023-03-25 23:38:11 +02:00
if ( LLAMA_AVX512 )
add_compile_options ( -mavx512f )
2023-04-17 15:10:57 +02:00
add_compile_options ( -mavx512bw )
endif ()
if ( LLAMA_AVX512_VBMI )
add_compile_options ( -mavx512vbmi )
endif ()
if ( LLAMA_AVX512_VNNI )
add_compile_options ( -mavx512vnni )
2023-03-25 23:38:11 +02:00
endif ()
2023-03-21 09:37:16 +09:00
endif ()
2023-05-02 18:42:16 +02:00
elseif ( ${ CMAKE_SYSTEM_PROCESSOR } MATCHES "ppc64" )
message ( STATUS "PowerPC detected" )
add_compile_options ( -mcpu=native -mtune=native )
#TODO: Add targets for Power8/Power9 (Altivec/VSX) and Power10(MMA) and query for big endian systems (ppc64/le/be)
2023-03-21 09:37:16 +09:00
else ()
message ( STATUS "Unknown architecture" )
endif ()
2023-03-13 14:12:33 -03:00
2023-03-21 09:37:16 +09:00
#
2023-03-22 07:32:36 +02:00
# Build libraries
2023-03-21 09:37:16 +09:00
#
2023-03-13 14:12:33 -03:00
2023-03-21 17:29:41 +02:00
add_library ( ggml OBJECT
ggml.c
2023-04-20 03:14:14 +02:00
ggml.h
2023-04-28 16:57:16 +02:00
${ GGML_CUDA_SOURCES }
${ GGML_OPENCL_SOURCES } )
2023-03-21 17:29:41 +02:00
2023-03-13 14:12:33 -03:00
target_include_directories ( ggml PUBLIC . )
2023-03-21 17:29:41 +02:00
target_compile_features ( ggml PUBLIC c_std_11 ) # don't bump
2023-04-22 02:27:06 +08:00
target_link_libraries ( ggml PUBLIC Threads::Threads ${ LLAMA_EXTRA_LIBS } )
2023-04-22 16:31:56 +03:00
2023-03-24 05:16:48 +09:00
if ( BUILD_SHARED_LIBS )
set_target_properties ( ggml PROPERTIES POSITION_INDEPENDENT_CODE ON )
endif ()
2023-03-22 07:32:36 +02:00
2023-03-22 17:37:10 +01:00
add_library ( llama
2023-03-22 07:32:36 +02:00
llama.cpp
2023-04-08 12:24:37 -07:00
llama.h
2023-04-29 13:53:12 +03:00
llama-util.h )
2023-03-22 07:32:36 +02:00
target_include_directories ( llama PUBLIC . )
target_compile_features ( llama PUBLIC cxx_std_11 ) # don't bump
2023-03-25 20:26:40 +02:00
target_link_libraries ( llama PRIVATE ggml ${ LLAMA_EXTRA_LIBS } )
2023-04-22 16:31:56 +03:00
2023-03-24 05:16:48 +09:00
if ( BUILD_SHARED_LIBS )
set_target_properties ( llama PROPERTIES POSITION_INDEPENDENT_CODE ON )
target_compile_definitions ( llama PRIVATE LLAMA_SHARED LLAMA_BUILD )
endif ()
2023-03-22 07:32:36 +02:00
2023-04-20 03:14:14 +02:00
if ( GGML_CUDA_SOURCES )
message ( STATUS "GGML CUDA sources found, configuring CUDA architecture" )
set_property ( TARGET ggml PROPERTY CUDA_ARCHITECTURES OFF )
set_property ( TARGET ggml PROPERTY CUDA_SELECT_NVCC_ARCH_FLAGS "Auto" )
set_property ( TARGET llama PROPERTY CUDA_ARCHITECTURES OFF )
endif ()
2023-03-21 17:29:41 +02:00
#
# programs, examples and tests
#
if ( LLAMA_BUILD_TESTS AND NOT CMAKE_JS_VERSION )
2023-03-30 17:56:59 +00:00
include ( CTest )
2023-03-21 17:29:41 +02:00
add_subdirectory ( tests )
endif ()
2023-03-25 20:26:40 +02:00
if ( LLAMA_BUILD_EXAMPLES )
add_subdirectory ( examples )
2023-04-18 21:00:14 +02:00
add_subdirectory ( pocs )
2023-03-25 20:26:40 +02:00
endif ()