1message(STATUS  "GGML_SYCL_TARGET=${GGML_SYCL_TARGET}")
  2
  3if (NOT GGML_SYCL_TARGET MATCHES "^(INTEL)$")
  4    message(FATAL_ERROR "GGML_SYCL_TARGET: Invalid target, the supported options are [INTEL]")
  5endif()
  6
  7check_cxx_compiler_flag("-fsycl" SUPPORTS_SYCL)
  8
  9if (DEFINED ENV{ONEAPI_ROOT})
 10    message(STATUS "Using oneAPI Release SYCL compiler (icpx).")
 11elseif(SUPPORTS_SYCL)
 12    message(WARNING "Using open-source SYCL compiler (clang++). Didn't detect ENV {ONEAPI_ROOT}.
 13        If you expected the oneAPI Release compiler, please install oneAPI & source it, like:
 14        source /opt/intel/oneapi/setvars.sh")
 15else()
 16    message(FATAL_ERROR "C++ compiler lacks SYCL support.")
 17endif()
 18message(STATUS "SYCL found")
 19#todo: AOT
 20
 21ggml_add_backend_library(ggml-sycl
 22                         ggml-sycl.cpp
 23                         ../../include/ggml-sycl.h
 24                        )
 25
 26file(GLOB   GGML_HEADERS_SYCL "*.hpp")
 27file(GLOB   GGML_SOURCES_SYCL "*.cpp")
 28target_sources(ggml-sycl PRIVATE ${GGML_HEADERS_SYCL} ${GGML_SOURCES_SYCL})
 29
 30if (WIN32)
 31    # To generate a Visual Studio solution, using Intel C++ Compiler for ggml-sycl is mandatory
 32    if( ${CMAKE_GENERATOR} MATCHES "Visual Studio" AND NOT (${CMAKE_GENERATOR_TOOLSET} MATCHES "Intel C"))
 33        set_target_properties(ggml-sycl PROPERTIES VS_PLATFORM_TOOLSET "Intel C++ Compiler 2025")
 34        set(CMAKE_CXX_COMPILER "icx")
 35        set(CMAKE_CXX_COMPILER_ID "IntelLLVM")
 36    endif()
 37endif()
 38
 39macro(detect_and_find_package package_name)
 40    set(test_source "
 41    cmake_minimum_required(VERSION ${CMAKE_VERSION})
 42    project(check_package LANGUAGES CXX)
 43    find_package(${package_name} QUIET)
 44    ")
 45
 46    set(test_dir "${CMAKE_CURRENT_BINARY_DIR}/check_package_${package_name}")
 47    file(WRITE "${test_dir}/CMakeLists.txt" "${test_source}")
 48
 49    set(cmake_args "")
 50    if(CMAKE_GENERATOR)
 51        list(APPEND cmake_args "-G" "${CMAKE_GENERATOR}")
 52    endif()
 53    if(CMAKE_GENERATOR_PLATFORM)
 54        list(APPEND cmake_args "-A" "${CMAKE_GENERATOR_PLATFORM}")
 55    endif()
 56    if(CMAKE_GENERATOR_TOOLSET)
 57        list(APPEND cmake_args "-T" "${CMAKE_GENERATOR_TOOLSET}")
 58    endif()
 59    if(CMAKE_CXX_COMPILER)
 60        list(APPEND cmake_args "-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}")
 61    endif()
 62
 63    execute_process(
 64        COMMAND ${CMAKE_COMMAND} ${cmake_args} .
 65        WORKING_DIRECTORY "${test_dir}"
 66        RESULT_VARIABLE result
 67        OUTPUT_QUIET
 68        ERROR_QUIET
 69    )
 70
 71    if(result EQUAL 0)
 72        find_package(${package_name} ${ARGN})
 73    else()
 74        message(WARNING "Detection of ${package_name} failed. The package might be broken or incompatible.")
 75        set(${package_name}_FOUND FALSE)
 76    endif()
 77endmacro()
 78
 79detect_and_find_package(IntelSYCL)
 80if (IntelSYCL_FOUND)
 81    # Use oneAPI CMake when possible
 82    target_link_libraries(ggml-sycl PRIVATE IntelSYCL::SYCL_CXX)
 83else()
 84    # Fallback to the simplest way of enabling SYCL when using intel/llvm nightly for instance
 85    target_compile_options(ggml-sycl PRIVATE "-fsycl")
 86    target_link_options(ggml-sycl PRIVATE "-fsycl")
 87endif()
 88
 89target_compile_options(ggml-sycl PRIVATE "-Wno-narrowing")
 90
 91# Link against oneDNN
 92set(GGML_SYCL_DNNL 0)
 93if(GGML_SYCL_DNN)
 94    find_package(DNNL)
 95    if(DNNL_FOUND)
 96        if (NOT DEFINED DNNL_GPU_VENDOR)
 97            # default to intel target
 98            set(DNNL_GPU_VENDOR "INTEL")
 99            if(NOT "${GGML_SYCL_TARGET}" STREQUAL "INTEL")
100                message(WARNING "oneDNN builds bundled with oneapi release only support INTEL target")
101            endif()
102        endif()
103
104        # Verify oneDNN was compiled for the same target as llama
105        if("${GGML_SYCL_TARGET}" STREQUAL "${DNNL_GPU_VENDOR}")
106            target_link_libraries(ggml-sycl PRIVATE DNNL::dnnl)
107            set(GGML_SYCL_DNNL 1)
108            get_target_property(CONFIGS DNNL::dnnl IMPORTED_CONFIGURATIONS)
109            foreach(CONFIG ${CONFIGS})
110                get_target_property(DNNL_LIB DNNL::dnnl IMPORTED_LOCATION_${CONFIG})
111                message(STATUS "Found oneDNN: ${DNNL_LIB}")
112            endforeach()
113        else()
114            message(WARNING
115                "oneDNN must be compiled for the same target as llama.cpp.
116                 llama.cpp: ${GGML_SYCL_TARGET}, oneDNN: ${DNNL_GPU_VENDOR}.
117                 Disabling oneDNN support.")
118        endif()
119    else()
120        message(STATUS "oneDNN not found, disabling oneDNN support")
121    endif()
122else()
123    message(STATUS "oneDNN support disabled by the user")
124endif()
125target_compile_definitions(ggml-sycl PRIVATE GGML_SYCL_DNNL=${GGML_SYCL_DNNL})
126
127if (GGML_SYCL_F16)
128    add_compile_definitions(GGML_SYCL_F16)
129endif()
130
131if (GGML_SYCL_TARGET STREQUAL "INTEL")
132    add_compile_definitions(GGML_SYCL_WARP_SIZE=16)
133    target_link_options(ggml-sycl PRIVATE  -Xs   -ze-intel-greater-than-4GB-buffer-required)
134
135    # Link against Intel oneMKL
136    if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
137        set(SYCL_COMPILER ON)
138    endif()
139    find_package(MKL REQUIRED)
140    target_link_libraries(ggml-sycl PRIVATE MKL::MKL_SYCL::BLAS)
141else()
142    # default for other target
143    message(FATAL_ERROR "GGML_SYCL_TARGET is not supported")
144    add_compile_definitions(GGML_SYCL_WARP_SIZE=32)
145endif()
146
147if (GGML_SYCL_GRAPH)
148    target_compile_definitions(ggml-sycl PRIVATE GGML_SYCL_GRAPH)
149endif()
150
151if (GGML_SYCL_DEVICE_ARCH)
152    target_compile_options(ggml-sycl PRIVATE -Xsycl-target-backend --offload-arch=${GGML_SYCL_DEVICE_ARCH})
153    target_link_options(ggml-sycl PRIVATE -Xsycl-target-backend --offload-arch=${GGML_SYCL_DEVICE_ARCH})
154endif()
155