char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Daniel Beveniusggml : replace compile definitions with version.h.in (#28364)86b351fd6

char/aliceai-t5-moe
26.4 KiB634 linesraw
1include(CheckCXXCompilerFlag)
2include("../cmake/common.cmake")
3
4add_compile_definitions(GGML_SCHED_MAX_COPIES=${GGML_SCHED_MAX_COPIES})
5
6# enable libstdc++ assertions for debug builds
7if (CMAKE_SYSTEM_NAME MATCHES "Linux")
8    add_compile_definitions($<$<CONFIG:Debug>:_GLIBCXX_ASSERTIONS>)
9endif()
10
11if (NOT MSVC)
12    if (GGML_SANITIZE_THREAD)
13        add_compile_options(-fsanitize=thread)
14        link_libraries     (-fsanitize=thread)
15    endif()
16
17    if (GGML_SANITIZE_ADDRESS)
18        add_compile_options(-fsanitize=address -fno-omit-frame-pointer)
19        link_libraries     (-fsanitize=address)
20    endif()
21
22    if (GGML_SANITIZE_UNDEFINED)
23        add_compile_options(-fsanitize=undefined)
24        link_libraries     (-fsanitize=undefined)
25    endif()
26endif()
27
28if (GGML_FATAL_WARNINGS)
29    if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
30        list(APPEND C_FLAGS   -Werror)
31        list(APPEND CXX_FLAGS -Werror)
32    elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
33        add_compile_options(/WX)
34    endif()
35endif()
36
37if (GGML_ALL_WARNINGS)
38    if (NOT MSVC)
39        list(APPEND WARNING_FLAGS -Wall -Wextra -Wpedantic -Wcast-qual -Wno-unused-function)
40        list(APPEND C_FLAGS       -Wshadow -Wstrict-prototypes -Wpointer-arith -Wmissing-prototypes
41                                  -Werror=implicit-int -Werror=implicit-function-declaration)
42        list(APPEND CXX_FLAGS     -Wmissing-declarations -Wmissing-noreturn)
43
44        list(APPEND C_FLAGS   ${WARNING_FLAGS})
45        list(APPEND CXX_FLAGS ${WARNING_FLAGS})
46
47        ggml_get_flags(${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION})
48
49        add_compile_options("$<$<COMPILE_LANGUAGE:C>:${C_FLAGS};${GF_C_FLAGS}>"
50                            "$<$<COMPILE_LANGUAGE:CXX>:${CXX_FLAGS};${GF_CXX_FLAGS}>")
51    else()
52        # todo : msvc
53        set(C_FLAGS   "")
54        set(CXX_FLAGS "")
55    endif()
56endif()
57
58if (GGML_LTO)
59    include(CheckIPOSupported)
60    check_ipo_supported(RESULT result OUTPUT output)
61    if (result)
62        set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
63    else()
64        message(WARNING "IPO is not supported: ${output}")
65    endif()
66endif()
67
68if (GGML_CCACHE AND NOT CMAKE_C_COMPILER_LAUNCHER AND NOT CMAKE_CXX_COMPILER_LAUNCHER)
69    find_program(GGML_CCACHE_FOUND ccache)
70    find_program(GGML_SCCACHE_FOUND sccache)
71
72    if (GGML_CCACHE_FOUND OR GGML_SCCACHE_FOUND)
73        if(GGML_CCACHE_FOUND)
74            set(GGML_CCACHE_VARIANT ccache)
75        else()
76            set(GGML_CCACHE_VARIANT sccache)
77        endif()
78        # TODO: should not be set globally
79        if (GGML_SYCL AND GGML_CCACHE_FOUND AND WIN32)
80            set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "ccache compiler_type=icl")
81        else ()
82            set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${GGML_CCACHE_VARIANT}")
83        endif ()
84        set(ENV{CCACHE_SLOPPINESS} time_macros)
85        message(STATUS "${GGML_CCACHE_VARIANT} found, compilation results will be cached. Disable with GGML_CCACHE=OFF.")
86    else()
87        message(STATUS "Warning: ccache not found - consider installing it for faster compilation or disable this warning with GGML_CCACHE=OFF")
88    endif ()
89endif()
90
91# this version of Apple ld64 is buggy
92execute_process(
93    COMMAND ${CMAKE_C_COMPILER} ${CMAKE_EXE_LINKER_FLAGS} -Wl,-v
94    ERROR_VARIABLE output
95    OUTPUT_QUIET
96)
97
98if (output MATCHES "dyld-1015\.7")
99    add_compile_definitions(HAVE_BUGGY_APPLE_LINKER)
100endif()
101
102# architecture specific
103# TODO: probably these flags need to be tweaked on some architectures
104#       feel free to update the Makefile for your architecture and send a pull request or issue
105message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
106if (MSVC)
107    string(TOLOWER "${CMAKE_GENERATOR_PLATFORM}" CMAKE_GENERATOR_PLATFORM_LWR)
108    message(STATUS "CMAKE_GENERATOR_PLATFORM: ${CMAKE_GENERATOR_PLATFORM}")
109else ()
110    set(CMAKE_GENERATOR_PLATFORM_LWR "")
111endif ()
112ggml_get_system_arch()
113message(STATUS "GGML_SYSTEM_ARCH: ${GGML_SYSTEM_ARCH}")
114
115if (NOT MSVC)
116    if (GGML_STATIC)
117        if (UNIX AND NOT APPLE)
118            set(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.so")
119        endif()
120        add_link_options(-static)
121        if (MINGW)
122            add_link_options(-static-libgcc -static-libstdc++)
123        endif()
124    endif()
125    if (GGML_GPROF)
126        add_compile_options(-pg)
127    endif()
128endif()
129
130#
131# POSIX conformance
132#
133
134# clock_gettime came in POSIX.1b (1993)
135# CLOCK_MONOTONIC came in POSIX.1-2001 / SUSv3 as optional
136# posix_memalign came in POSIX.1-2001 / SUSv3
137# M_PI is an XSI extension since POSIX.1-2001 / SUSv3, came in XPG1 (1985)
138
139# Somehow in OpenBSD whenever POSIX conformance is specified
140# some string functions rely on locale_t availability,
141# which was introduced in POSIX.1-2008, forcing us to go higher
142if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
143    add_compile_definitions(_XOPEN_SOURCE=700)
144elseif (CMAKE_SYSTEM_NAME MATCHES "AIX")
145    # Don't define _XOPEN_SOURCE.  We need _ALL_SOURCE, which is the default,
146    # in order to define _SC_PHYS_PAGES.
147else()
148    add_compile_definitions(_XOPEN_SOURCE=600)
149endif()
150
151# Data types, macros and functions related to controlling CPU affinity and
152# some memory allocation are available on Linux through GNU extensions in libc
153if (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android")
154    add_compile_definitions(_GNU_SOURCE)
155endif()
156
157# RLIMIT_MEMLOCK came in BSD, is not specified in POSIX.1,
158# and on macOS its availability depends on enabling Darwin extensions
159# similarly on DragonFly, enabling BSD extensions is necessary
160if (
161    CMAKE_SYSTEM_NAME MATCHES "Darwin" OR
162    CMAKE_SYSTEM_NAME MATCHES "iOS"    OR
163    CMAKE_SYSTEM_NAME MATCHES "tvOS"   OR
164    CMAKE_SYSTEM_NAME MATCHES "DragonFly"
165)
166    add_compile_definitions(_DARWIN_C_SOURCE)
167endif()
168
169# alloca is a non-standard interface that is not visible on BSDs when
170# POSIX conformance is specified, but not all of them provide a clean way
171# to enable it in such cases
172if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
173    add_compile_definitions(__BSD_VISIBLE)
174endif()
175if (CMAKE_SYSTEM_NAME MATCHES "NetBSD")
176    add_compile_definitions(_NETBSD_SOURCE)
177endif()
178if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
179    add_compile_definitions(_BSD_SOURCE)
180endif()
181
182if (WIN32)
183    add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
184endif()
185
186# ggml
187
188if (GGML_BACKEND_DL AND NOT BUILD_SHARED_LIBS)
189    message(FATAL_ERROR "GGML_BACKEND_DL requires BUILD_SHARED_LIBS")
190endif()
191
192add_library(ggml-base
193            ../include/ggml.h
194            ../include/ggml-alloc.h
195            ../include/ggml-backend.h
196            ../include/ggml-cpp.h
197            ../include/ggml-opt.h
198            ../include/gguf.h
199            ggml.c
200            ggml.cpp
201            ggml-alloc.c
202            ggml-backend.cpp
203            ggml-backend-meta.cpp
204            ggml-opt.cpp
205            ggml-threading.cpp
206            ggml-threading.h
207            ggml-quants.c
208            ggml-quants.h
209            gguf.cpp)
210
211set_target_properties(ggml-base PROPERTIES
212    VERSION ${GGML_VERSION}
213    SOVERSION ${GGML_VERSION_MAJOR}
214)
215
216configure_file(ggml-version.h.in ${CMAKE_CURRENT_BINARY_DIR}/ggml-version.h @ONLY)
217
218target_include_directories(ggml-base PRIVATE . ${CMAKE_CURRENT_BINARY_DIR})
219if (GGML_BACKEND_DL)
220    target_compile_definitions(ggml-base PUBLIC GGML_BACKEND_DL)
221endif()
222
223if (GGML_SCHED_NO_REALLOC)
224    target_compile_definitions(ggml-base PUBLIC GGML_SCHED_NO_REALLOC)
225endif()
226
227if (GGML_OPENMP_FETCH)
228    if (NOT GGML_OPENMP)
229        message(FATAL_ERROR "GGML_OPENMP_FETCH requires GGML_OPENMP")
230    elseif (NOT WIN32 OR NOT (CMAKE_C_COMPILER_ID MATCHES "Clang"))
231        message(FATAL_ERROR "GGML_OPENMP_FETCH currently requires Clang on Windows")
232    endif()
233
234    set(GGML_OPENMP_LLVM_VERSION "20.1.8")
235    string(REGEX MATCH "^[0-9]+" GGML_OPENMP_LLVM_VERSION_MAJOR "${GGML_OPENMP_LLVM_VERSION}")
236    string(REGEX MATCH "^[0-9]+" GGML_OPENMP_COMPILER_VERSION_MAJOR "${CMAKE_C_COMPILER_VERSION}")
237    if (NOT GGML_OPENMP_COMPILER_VERSION_MAJOR STREQUAL GGML_OPENMP_LLVM_VERSION_MAJOR)
238        message(FATAL_ERROR "LLVM OpenMP ${GGML_OPENMP_LLVM_VERSION} requires Clang ${GGML_OPENMP_LLVM_VERSION_MAJOR}.x")
239    endif()
240
241    string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" GGML_OPENMP_SYSTEM_PROCESSOR)
242    if (GGML_OPENMP_SYSTEM_PROCESSOR MATCHES "^(amd64|x86_64)$")
243        set(GGML_OPENMP_ARCH "x64")
244        set(GGML_OPENMP_INSTALLER_SUFFIX "win64")
245        set(GGML_OPENMP_INSTALLER_SHA256 "3197846a2b19063687dd56e93e34cd941e3548d907f23a6131571321bdf9fe7b")
246    elseif (GGML_OPENMP_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)$")
247        set(GGML_OPENMP_ARCH "arm64")
248        set(GGML_OPENMP_INSTALLER_SUFFIX "woa64")
249        set(GGML_OPENMP_INSTALLER_SHA256 "7c4ac97eb2ae6b960ca5f9caf3ff6124c8d2a18cc07a7840a4d2ea15537bad8e")
250    else()
251        message(FATAL_ERROR "GGML_OPENMP_FETCH does not support ${CMAKE_SYSTEM_PROCESSOR}")
252    endif()
253
254    set(GGML_OPENMP_CACHE_DIR "${CMAKE_BINARY_DIR}/_deps")
255    set(GGML_OPENMP_ROOT "${GGML_OPENMP_CACHE_DIR}/llvm-openmp-${GGML_OPENMP_LLVM_VERSION}-${GGML_OPENMP_ARCH}")
256    set(GGML_OPENMP_LIBRARY "${GGML_OPENMP_ROOT}/lib/libomp.lib")
257    set(GGML_OPENMP_RUNTIME "${GGML_OPENMP_ROOT}/bin/libomp.dll")
258    set(GGML_OPENMP_HEADER "${GGML_OPENMP_ROOT}/include/omp.h")
259    set(GGML_OPENMP_LICENSE "${GGML_OPENMP_ROOT}/LICENSE.TXT")
260    set(GGML_OPENMP_LICENSE_SHA256 "fdad1758a9e1f9d5a81e18879b3406772115edc92c24bfa36b70c654f325e8e4")
261
262    if (NOT EXISTS "${GGML_OPENMP_LIBRARY}" OR NOT EXISTS "${GGML_OPENMP_RUNTIME}" OR NOT EXISTS "${GGML_OPENMP_HEADER}")
263        find_program(GGML_OPENMP_7Z NAMES 7z 7zz 7za)
264        if (NOT GGML_OPENMP_7Z)
265            message(FATAL_ERROR "GGML_OPENMP_FETCH requires 7-Zip to extract the LLVM installer")
266        endif()
267
268        set(GGML_OPENMP_INSTALLER "${GGML_OPENMP_ROOT}/LLVM-${GGML_OPENMP_LLVM_VERSION}-${GGML_OPENMP_INSTALLER_SUFFIX}.exe")
269        set(GGML_OPENMP_EXTRACT_DIR "${GGML_OPENMP_ROOT}/extract")
270        set(GGML_OPENMP_INSTALLER_URL "https://github.com/llvm/llvm-project/releases/download/llvmorg-${GGML_OPENMP_LLVM_VERSION}/LLVM-${GGML_OPENMP_LLVM_VERSION}-${GGML_OPENMP_INSTALLER_SUFFIX}.exe")
271
272        file(MAKE_DIRECTORY "${GGML_OPENMP_EXTRACT_DIR}")
273        file(DOWNLOAD "${GGML_OPENMP_INSTALLER_URL}" "${GGML_OPENMP_INSTALLER}"
274            EXPECTED_HASH "SHA256=${GGML_OPENMP_INSTALLER_SHA256}"
275            SHOW_PROGRESS
276            STATUS GGML_OPENMP_DOWNLOAD_STATUS)
277        list(GET GGML_OPENMP_DOWNLOAD_STATUS 0 GGML_OPENMP_DOWNLOAD_RESULT)
278        if (NOT GGML_OPENMP_DOWNLOAD_RESULT EQUAL 0)
279            list(GET GGML_OPENMP_DOWNLOAD_STATUS 1 GGML_OPENMP_DOWNLOAD_ERROR)
280            message(FATAL_ERROR "Failed to download LLVM OpenMP: ${GGML_OPENMP_DOWNLOAD_ERROR}")
281        endif()
282
283        execute_process(
284            COMMAND "${GGML_OPENMP_7Z}" e -y "-o${GGML_OPENMP_EXTRACT_DIR}" "${GGML_OPENMP_INSTALLER}" -r libomp.lib libomp.dll omp.h
285            RESULT_VARIABLE GGML_OPENMP_EXTRACT_RESULT
286            OUTPUT_QUIET)
287        if (NOT GGML_OPENMP_EXTRACT_RESULT EQUAL 0 OR
288            NOT EXISTS "${GGML_OPENMP_EXTRACT_DIR}/libomp.lib" OR
289            NOT EXISTS "${GGML_OPENMP_EXTRACT_DIR}/libomp.dll" OR
290            NOT EXISTS "${GGML_OPENMP_EXTRACT_DIR}/omp.h")
291            message(FATAL_ERROR "Failed to extract libomp from ${GGML_OPENMP_INSTALLER}")
292        endif()
293
294        file(MAKE_DIRECTORY "${GGML_OPENMP_ROOT}/lib" "${GGML_OPENMP_ROOT}/bin" "${GGML_OPENMP_ROOT}/include")
295        file(COPY "${GGML_OPENMP_EXTRACT_DIR}/libomp.lib" DESTINATION "${GGML_OPENMP_ROOT}/lib")
296        file(COPY "${GGML_OPENMP_EXTRACT_DIR}/libomp.dll" DESTINATION "${GGML_OPENMP_ROOT}/bin")
297        file(COPY "${GGML_OPENMP_EXTRACT_DIR}/omp.h" DESTINATION "${GGML_OPENMP_ROOT}/include")
298        file(REMOVE_RECURSE "${GGML_OPENMP_INSTALLER}" "${GGML_OPENMP_EXTRACT_DIR}")
299    endif()
300
301    # The NSIS installer embeds LLVM's general license in its UI but does not install it as a file; use OpenMP's license to include its additional notices.
302    if (EXISTS "${GGML_OPENMP_LICENSE}")
303        file(SHA256 "${GGML_OPENMP_LICENSE}" GGML_OPENMP_LICENSE_ACTUAL_SHA256)
304    endif()
305    if (NOT GGML_OPENMP_LICENSE_ACTUAL_SHA256 STREQUAL GGML_OPENMP_LICENSE_SHA256)
306        file(DOWNLOAD "https://raw.githubusercontent.com/llvm/llvm-project/llvmorg-${GGML_OPENMP_LLVM_VERSION}/openmp/LICENSE.TXT" "${GGML_OPENMP_LICENSE}"
307            EXPECTED_HASH "SHA256=${GGML_OPENMP_LICENSE_SHA256}")
308    endif()
309
310    if (COMMAND license_add_file)
311        license_add_file("LLVM OpenMP" "${GGML_OPENMP_LICENSE}")
312    endif()
313
314    add_library(ggml-openmp-c INTERFACE)
315    target_compile_options(ggml-openmp-c INTERFACE "$<$<COMPILE_LANGUAGE:C>:-fopenmp=libomp>")
316    target_include_directories(ggml-openmp-c SYSTEM INTERFACE "${GGML_OPENMP_ROOT}/include")
317    target_link_libraries(ggml-openmp-c INTERFACE "${GGML_OPENMP_LIBRARY}")
318
319    add_library(ggml-openmp-cxx INTERFACE)
320    target_compile_options(ggml-openmp-cxx INTERFACE "$<$<COMPILE_LANGUAGE:CXX>:-fopenmp=libomp>")
321    target_include_directories(ggml-openmp-cxx SYSTEM INTERFACE "${GGML_OPENMP_ROOT}/include")
322    target_link_libraries(ggml-openmp-cxx INTERFACE "${GGML_OPENMP_LIBRARY}")
323
324    set(GGML_OPENMP_RUNTIME_OUTPUT_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
325    if (CMAKE_CONFIGURATION_TYPES)
326        string(APPEND GGML_OPENMP_RUNTIME_OUTPUT_DIR "/$<CONFIG>")
327    endif()
328    add_custom_target(ggml-openmp-runtime ALL
329        COMMAND ${CMAKE_COMMAND} -E make_directory "${GGML_OPENMP_RUNTIME_OUTPUT_DIR}"
330        COMMAND ${CMAKE_COMMAND} -E copy_if_different "${GGML_OPENMP_RUNTIME}" "${GGML_OPENMP_RUNTIME_OUTPUT_DIR}/libomp.dll"
331        COMMAND ${CMAKE_COMMAND} -E copy_if_different "${GGML_OPENMP_LICENSE}" "${GGML_OPENMP_RUNTIME_OUTPUT_DIR}/LICENSE-LLVM-OpenMP")
332    add_dependencies(ggml-base ggml-openmp-runtime)
333    install(FILES "${GGML_OPENMP_RUNTIME}" DESTINATION ${CMAKE_INSTALL_BINDIR})
334    install(FILES "${GGML_OPENMP_LICENSE}" DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME LICENSE-LLVM-OpenMP)
335
336    set(GGML_OPENMP_TARGET_C ggml-openmp-c)
337    set(GGML_OPENMP_TARGET_CXX ggml-openmp-cxx)
338    set(GGML_OPENMP_ENABLED "ON" CACHE INTERNAL "")
339elseif (GGML_OPENMP)
340    find_package(OpenMP)
341    if (OpenMP_FOUND)
342        set(GGML_OPENMP_TARGET_C OpenMP::OpenMP_C)
343        set(GGML_OPENMP_TARGET_CXX OpenMP::OpenMP_CXX)
344        set(GGML_OPENMP_ENABLED "ON" CACHE INTERNAL "")
345    else()
346        set(GGML_OPENMP_ENABLED "OFF" CACHE INTERNAL "")
347        message(WARNING "OpenMP not found")
348    endif()
349else()
350    set(GGML_OPENMP_ENABLED "OFF" CACHE INTERNAL "")
351endif()
352
353if (GGML_OPENMP_ENABLED)
354    target_compile_definitions(ggml-base PRIVATE GGML_USE_OPENMP)
355    target_link_libraries(ggml-base PRIVATE ${GGML_OPENMP_TARGET_C} ${GGML_OPENMP_TARGET_CXX})
356endif()
357
358add_library(ggml
359            ggml-backend-dl.cpp
360            ggml-backend-reg.cpp)
361add_library(ggml::ggml ALIAS ggml)
362
363set_target_properties(ggml PROPERTIES
364    VERSION ${GGML_VERSION}
365    SOVERSION ${GGML_VERSION_MAJOR}
366)
367
368if (GGML_BACKEND_DIR)
369    if (NOT GGML_BACKEND_DL)
370        message(FATAL_ERROR "GGML_BACKEND_DIR requires GGML_BACKEND_DL")
371    endif()
372    target_compile_definitions(ggml PUBLIC GGML_BACKEND_DIR="${GGML_BACKEND_DIR}")
373endif()
374
375target_link_libraries(ggml PUBLIC ggml-base)
376
377if (CMAKE_SYSTEM_NAME MATCHES "Linux")
378    target_link_libraries(ggml PRIVATE dl)
379endif()
380
381function(ggml_add_backend_library backend)
382    if (GGML_BACKEND_DL)
383        add_library(${backend} MODULE ${ARGN})
384        # write the shared library to the output directory
385        set_target_properties(${backend} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
386        target_compile_definitions(${backend} PRIVATE GGML_BACKEND_DL)
387        add_dependencies(ggml ${backend})
388        if (GGML_BACKEND_DIR)
389            install(TARGETS ${backend} LIBRARY DESTINATION ${GGML_BACKEND_DIR})
390        else()
391            install(TARGETS ${backend} LIBRARY DESTINATION ${CMAKE_INSTALL_BINDIR})
392        endif()
393    else()
394        add_library(${backend} ${ARGN})
395        target_link_libraries(ggml PUBLIC ${backend})
396        install(TARGETS ${backend} LIBRARY)
397    endif()
398
399    target_link_libraries(${backend} PRIVATE ggml-base)
400    target_include_directories(${backend} PRIVATE ..)
401
402    if (${BUILD_SHARED_LIBS})
403        target_compile_definitions(${backend} PRIVATE GGML_BACKEND_BUILD)
404        target_compile_definitions(${backend} PUBLIC  GGML_BACKEND_SHARED)
405    endif()
406
407    # Set versioning properties for all backend libraries
408    # Building a MODULE library with a version is not supported on macOS (https://gitlab.kitware.com/cmake/cmake/-/issues/20782)
409    if (NOT (APPLE AND GGML_BACKEND_DL))
410        set_target_properties(${backend} PROPERTIES
411            VERSION ${GGML_VERSION}
412            SOVERSION ${GGML_VERSION_MAJOR}
413        )
414    endif()
415
416    if(NOT GGML_AVAILABLE_BACKENDS)
417        set(GGML_AVAILABLE_BACKENDS "${backend}"
418            CACHE INTERNAL "List of backends for cmake package")
419    else()
420        list(FIND GGML_AVAILABLE_BACKENDS "${backend}" has_backend)
421        if(has_backend EQUAL -1)
422            set(GGML_AVAILABLE_BACKENDS "${GGML_AVAILABLE_BACKENDS};${backend}"
423                CACHE INTERNAL "List of backends for cmake package")
424        endif()
425    endif()
426endfunction()
427
428function(ggml_add_backend backend)
429    string(TOUPPER "GGML_${backend}" backend_id)
430    if (${backend_id})
431        string(TOLOWER "ggml-${backend}" backend_target)
432        add_subdirectory(${backend_target})
433        message(STATUS "Including ${backend} backend")
434        if (NOT GGML_BACKEND_DL)
435            string(TOUPPER "GGML_USE_${backend}" backend_use)
436            target_compile_definitions(ggml PUBLIC ${backend_use})
437        endif()
438    endif()
439endfunction()
440
441function(ggml_add_cpu_backend_variant tag_name)
442    set(GGML_CPU_TAG_NAME ${tag_name})
443    # other: OPENMP LLAMAFILE CPU_HBM
444    if (GGML_SYSTEM_ARCH STREQUAL "x86")
445        foreach (feat NATIVE
446                      SSE42
447                      AVX AVX2 BMI2 AVX_VNNI FMA F16C
448                      AVX512 AVX512_VBMI AVX512_VNNI AVX512_BF16
449                      AMX_TILE AMX_INT8 AMX_BF16)
450            set(GGML_${feat} OFF)
451        endforeach()
452
453        foreach (feat ${ARGN})
454            set(GGML_${feat} ON)
455        endforeach()
456    elseif (GGML_SYSTEM_ARCH STREQUAL "ARM")
457        foreach (feat ${ARGN})
458            set(GGML_INTERNAL_${feat} ON)
459        endforeach()
460    elseif (GGML_SYSTEM_ARCH STREQUAL "PowerPC")
461        foreach (feat ${ARGN})
462            set(GGML_INTERNAL_${feat} ON)
463        endforeach()
464    elseif (GGML_SYSTEM_ARCH STREQUAL "s390x")
465        foreach (feat VXE2 NNPA)
466            set(GGML_INTERNAL_${feat} OFF)
467        endforeach()
468
469        foreach (feat ${ARGN})
470            set(GGML_INTERNAL_${feat} ON)
471        endforeach()
472    elseif (GGML_SYSTEM_ARCH STREQUAL "riscv64")
473        foreach (feat RVV)
474            set(GGML_INTERNAL_${feat} OFF)
475        endforeach()
476
477        foreach (feat ${ARGN})
478            set(GGML_INTERNAL_${feat} ON)
479        endforeach()
480    endif()
481
482    ggml_add_cpu_backend_variant_impl(${tag_name})
483endfunction()
484
485ggml_add_backend(CPU)
486
487if (GGML_CPU_ALL_VARIANTS)
488    if (NOT GGML_BACKEND_DL)
489        message(FATAL_ERROR "GGML_CPU_ALL_VARIANTS requires GGML_BACKEND_DL")
490    elseif (GGML_CPU_ARM_ARCH)
491        message(FATAL_ERROR "Cannot use both GGML_CPU_ARM_ARCH and GGML_CPU_ALL_VARIANTS")
492    endif()
493    if (GGML_SYSTEM_ARCH STREQUAL "x86")
494        ggml_add_cpu_backend_variant(x64)
495        ggml_add_cpu_backend_variant(sse42              SSE42)
496        ggml_add_cpu_backend_variant(sandybridge        SSE42 AVX)
497        if (NOT MSVC)
498            # __FMA__ and __F16C__ are not defined in MSVC, however they are implied with AVX2/AVX512
499            ggml_add_cpu_backend_variant(ivybridge      SSE42 AVX F16C)
500            ggml_add_cpu_backend_variant(piledriver     SSE42 AVX F16C FMA)
501        endif()
502        ggml_add_cpu_backend_variant(haswell            SSE42 AVX F16C FMA AVX2 BMI2)
503        ggml_add_cpu_backend_variant(skylakex           SSE42 AVX F16C FMA AVX2 BMI2 AVX512)
504        ggml_add_cpu_backend_variant(cannonlake         SSE42 AVX F16C FMA AVX2 BMI2 AVX512 AVX512_VBMI)
505        ggml_add_cpu_backend_variant(cascadelake        SSE42 AVX F16C FMA AVX2 BMI2 AVX512 AVX512_VNNI)
506        ggml_add_cpu_backend_variant(icelake            SSE42 AVX F16C FMA AVX2 BMI2 AVX512 AVX512_VBMI AVX512_VNNI)
507        if (NOT MSVC)
508            # MSVC 2022 doesn't support BF16 intrinsics without `/arch:AVX10.1` ?!
509            # https://learn.microsoft.com/en-us/cpp/intrinsics/x64-amd64-intrinsics-list?view=msvc-170
510            # https://learn.microsoft.com/en-us/cpp/build/reference/arch-x64?view=msvc-170
511            ggml_add_cpu_backend_variant(cooperlake     SSE42 AVX F16C FMA AVX2 BMI2 AVX512 AVX512_VNNI AVX512_BF16)
512            ggml_add_cpu_backend_variant(zen4           SSE42 AVX F16C FMA AVX2 BMI2 AVX512 AVX512_VBMI AVX512_VNNI AVX512_BF16)
513        endif()
514        ggml_add_cpu_backend_variant(alderlake          SSE42 AVX F16C FMA AVX2 BMI2 AVX_VNNI)
515        if (NOT MSVC)
516            # MSVC doesn't support AMX
517            ggml_add_cpu_backend_variant(sapphirerapids SSE42 AVX F16C FMA AVX2 BMI2 AVX512 AVX512_VBMI AVX512_VNNI AVX512_BF16 AMX_TILE AMX_INT8)
518        endif()
519    elseif(GGML_SYSTEM_ARCH STREQUAL "ARM")
520        if (CMAKE_SYSTEM_NAME MATCHES "Linux")
521            # Many of these features are optional so we build versions with popular
522            # combinations and name the backends based on the version they were
523            # first released with
524            ggml_add_cpu_backend_variant(armv8.0_1)
525            ggml_add_cpu_backend_variant(armv8.2_1    DOTPROD)
526            ggml_add_cpu_backend_variant(armv8.2_2    DOTPROD FP16_VECTOR_ARITHMETIC)
527            ggml_add_cpu_backend_variant(armv8.2_3    DOTPROD FP16_VECTOR_ARITHMETIC SVE)
528            ggml_add_cpu_backend_variant(armv8.6_1    DOTPROD FP16_VECTOR_ARITHMETIC SVE MATMUL_INT8)
529            ggml_add_cpu_backend_variant(armv8.6_2    DOTPROD FP16_VECTOR_ARITHMETIC SVE MATMUL_INT8 SVE2)
530            ggml_add_cpu_backend_variant(armv9.2_1    DOTPROD FP16_VECTOR_ARITHMETIC SVE MATMUL_INT8 SME)
531            ggml_add_cpu_backend_variant(armv9.2_2    DOTPROD FP16_VECTOR_ARITHMETIC SVE MATMUL_INT8 SVE2 SME)
532        elseif (CMAKE_SYSTEM_NAME MATCHES "Android")
533            # Android-specific backends with SoC-compatible feature sets
534            ggml_add_cpu_backend_variant(android_armv8.0_1)
535            ggml_add_cpu_backend_variant(android_armv8.2_1    DOTPROD)
536            ggml_add_cpu_backend_variant(android_armv8.2_2    DOTPROD FP16_VECTOR_ARITHMETIC)
537            ggml_add_cpu_backend_variant(android_armv8.6_1    DOTPROD FP16_VECTOR_ARITHMETIC MATMUL_INT8)
538            ggml_add_cpu_backend_variant(android_armv9.0_1    DOTPROD MATMUL_INT8 FP16_VECTOR_ARITHMETIC SVE2)
539            ggml_add_cpu_backend_variant(android_armv9.2_1    DOTPROD MATMUL_INT8 FP16_VECTOR_ARITHMETIC SVE SME)
540            ggml_add_cpu_backend_variant(android_armv9.2_2    DOTPROD MATMUL_INT8 FP16_VECTOR_ARITHMETIC SVE SVE2 SME)
541        elseif (APPLE)
542            ggml_add_cpu_backend_variant(apple_m1             DOTPROD)
543            ggml_add_cpu_backend_variant(apple_m2_m3          DOTPROD MATMUL_INT8)
544            ggml_add_cpu_backend_variant(apple_m4             DOTPROD MATMUL_INT8 NOSVE SME)
545        else()
546            message(FATAL_ERROR "Unsupported ARM target OS: ${CMAKE_SYSTEM_NAME}")
547        endif()
548    elseif (GGML_SYSTEM_ARCH STREQUAL "PowerPC")
549        if (CMAKE_SYSTEM_NAME MATCHES "Linux|AIX")
550            ggml_add_cpu_backend_variant(power0)
551            ggml_add_cpu_backend_variant(power7_1       POWER7)
552            ggml_add_cpu_backend_variant(power7_2       POWER7  VSX)
553            ggml_add_cpu_backend_variant(power8_1       POWER8)
554            ggml_add_cpu_backend_variant(power8_2       POWER8  VSX)
555            ggml_add_cpu_backend_variant(power9         POWER9  VSX)
556            ggml_add_cpu_backend_variant(power10        POWER10 VSX)
557            # POWER11 backend: only if compiler supports -mcpu=power11
558            check_cxx_compiler_flag("-mcpu=power11" GGML_CXX_SUPPORTS_POWER11)
559            if (GGML_CXX_SUPPORTS_POWER11)
560                message(STATUS "Compiler supports -mcpu=power11, enabling POWER11 backend")
561                ggml_add_cpu_backend_variant(power11 POWER11 VSX)
562            else()
563                message(STATUS "Skipping POWER11 backend: compiler does not support -mcpu=power11")
564            endif()
565        else()
566            message(FATAL_ERROR "Unsupported PowerPC target OS: ${CMAKE_SYSTEM_NAME}")
567        endif()
568    elseif (GGML_SYSTEM_ARCH STREQUAL "s390x")
569        if (CMAKE_SYSTEM_NAME MATCHES "Linux")
570            ggml_add_cpu_backend_variant(z15    Z15 VXE2)
571            ggml_add_cpu_backend_variant(z16    Z16 VXE2 NNPA)
572        else()
573            message(FATAL_ERROR "Unsupported s390x target OS: ${CMAKE_SYSTEM_NAME}")
574        endif()
575    elseif (GGML_SYSTEM_ARCH STREQUAL "riscv64")
576        if (CMAKE_SYSTEM_NAME MATCHES "Linux")
577            ggml_add_cpu_backend_variant(riscv64_0)
578            ggml_add_cpu_backend_variant(riscv64_v   RVV)
579        else()
580            message(FATAL_ERROR "Unsupported RISC-V target OS: ${CMAKE_SYSTEM_NAME}")
581        endif()
582    else()
583        message(FATAL_ERROR "GGML_CPU_ALL_VARIANTS not yet supported with ${GGML_SYSTEM_ARCH} on ${CMAKE_SYSTEM_NAME}")
584    endif()
585elseif (GGML_CPU)
586    ggml_add_cpu_backend_variant_impl("")
587endif()
588
589ggml_add_backend(BLAS)
590ggml_add_backend(CANN)
591ggml_add_backend(CUDA)
592ggml_add_backend(ET)
593ggml_add_backend(HIP)
594ggml_add_backend(METAL)
595ggml_add_backend(MUSA)
596ggml_add_backend(RPC)
597ggml_add_backend(VirtGPU)
598ggml_add_backend(SYCL)
599ggml_add_backend(Vulkan)
600ggml_add_backend(WebGPU)
601ggml_add_backend(zDNN)
602ggml_add_backend(OpenCL)
603ggml_add_backend(Hexagon)
604ggml_add_backend(ZenDNN)
605ggml_add_backend(OPENVINO)
606
607foreach (target ggml-base ggml)
608    target_include_directories(${target} PUBLIC    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include> $<INSTALL_INTERFACE:include>)
609    target_compile_features   (${target} PRIVATE c_std_11 cxx_std_17) # don't bump
610endforeach()
611
612target_link_libraries(ggml-base PRIVATE Threads::Threads)
613
614if (DEFINED MATH_LIBRARY)
615    target_link_libraries(ggml-base PRIVATE ${MATH_LIBRARY})
616elseif (NOT WIN32 AND NOT DEFINED ENV{ONEAPI_ROOT})
617    target_link_libraries(ggml-base PRIVATE m)
618endif()
619
620if (CMAKE_SYSTEM_NAME MATCHES "Android")
621    target_link_libraries(ggml-base PRIVATE dl)
622endif()
623
624if(CMAKE_SYSTEM_NAME MATCHES "visionOS")
625    target_compile_definitions(ggml-base PUBLIC _DARWIN_C_SOURCE)
626endif()
627
628if (BUILD_SHARED_LIBS)
629    foreach (target ggml-base ggml)
630        set_target_properties(${target} PROPERTIES POSITION_INDEPENDENT_CODE ON)
631        target_compile_definitions(${target} PRIVATE GGML_BUILD)
632        target_compile_definitions(${target} PUBLIC  GGML_SHARED)
633    endforeach()
634endif()