diff --git a/ggml/src/ggml-vulkan/CMakeLists.txt b/ggml/src/ggml-vulkan/CMakeLists.txt index d970f7e20b4..cb61f976d37 100644 --- a/ggml/src/ggml-vulkan/CMakeLists.txt +++ b/ggml/src/ggml-vulkan/CMakeLists.txt @@ -1,7 +1,15 @@ cmake_minimum_required(VERSION 3.19) cmake_policy(SET CMP0114 NEW) -find_package(Vulkan COMPONENTS glslc REQUIRED) +# First find glslc on the host system (not target) to ensure we have control over which one is used +find_program(Vulkan_GLSLC_EXECUTABLE glslc NO_CMAKE_FIND_ROOT_PATH) +if(NOT Vulkan_GLSLC_EXECUTABLE) + message(WARNING "glslc not found on host system. Will attempt to find via Vulkan package") +endif() + +# Find Vulkan package with required components +find_package(Vulkan REQUIRED) +message(STATUS "Using glslc: ${Vulkan_GLSLC_EXECUTABLE}") function(detect_host_compiler) if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") @@ -22,33 +30,97 @@ if (Vulkan_FOUND) ggml-vulkan.cpp ../../include/ggml-vulkan.h ) + if (CMAKE_CROSSCOMPILING) + # Check if user has explicitly set these options + if(NOT DEFINED GGML_VULKAN_COOPMAT_GLSLC_SUPPORT OR NOT DEFINED GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT) + # Try to detect target capabilities based on architecture/platform + message(STATUS "Cross-compiling: attempting to auto-detect target shader capabilities") + + # Set defaults based on known platforms + if(ANDROID) + # Most modern Android devices support cooperative matrices + message(STATUS "Android target detected: enabling COOPMAT support by default") + set(DETECTED_COOPMAT_SUPPORT ON) + + # Check Android API level or NDK version for COOPMAT2 support + # Android NDK r25+ and modern devices generally support this + if(ANDROID_PLATFORM_LEVEL GREATER_EQUAL 29 OR (DEFINED ANDROID_NDK_REVISION AND ANDROID_NDK_REVISION GREATER_EQUAL 25)) + message(STATUS "Modern Android target detected: enabling COOPMAT2 support by default") + set(DETECTED_COOPMAT2_SUPPORT ON) + else() + set(DETECTED_COOPMAT2_SUPPORT OFF) + endif() + elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|ARM64") + # ARM64 generally supports cooperative matrices on newer GPUs + message(STATUS "ARM64 target detected: enabling COOPMAT support by default") + set(DETECTED_COOPMAT_SUPPORT ON) + set(DETECTED_COOPMAT2_SUPPORT OFF) # Be conservative with COOPMAT2 + else() + # For other platforms, default to OFF to be safe + set(DETECTED_COOPMAT_SUPPORT OFF) + set(DETECTED_COOPMAT2_SUPPORT OFF) + endif() + + # Set the options based on detection if not already set + if(NOT DEFINED GGML_VULKAN_COOPMAT_GLSLC_SUPPORT) + option(GGML_VULKAN_COOPMAT_GLSLC_SUPPORT "Enable coopmat shaders" ${DETECTED_COOPMAT_SUPPORT}) + endif() + + if(NOT DEFINED GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT) + option(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT "Enable coopmat2 shaders" ${DETECTED_COOPMAT2_SUPPORT}) + endif() + else() + # Options already set, use those values + option(GGML_VULKAN_COOPMAT_GLSLC_SUPPORT "Enable coopmat shaders" ${GGML_VULKAN_COOPMAT_GLSLC_SUPPORT}) + option(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT "Enable coopmat2 shaders" ${GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT}) + endif() + + message(STATUS "Cross-compile COOPMAT support: ${GGML_VULKAN_COOPMAT_GLSLC_SUPPORT}") + message(STATUS "Cross-compile COOPMAT2 support: ${GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT}") + else() + # Compile a test shader to determine whether GL_KHR_cooperative_matrix is supported. + # If it's not, there will be an error to stderr. + # If it's supported, set a define to indicate that we should compile those shaders + execute_process(COMMAND ${Vulkan_GLSLC_EXECUTABLE} -o - -fshader-stage=compute --target-env=vulkan1.3 "${CMAKE_CURRENT_SOURCE_DIR}/vulkan-shaders/test_coopmat_support.comp" + OUTPUT_VARIABLE glslc_output + ERROR_VARIABLE glslc_error) + + if (${glslc_error} MATCHES ".*extension not supported: GL_KHR_cooperative_matrix.*") + message(STATUS "GL_KHR_cooperative_matrix not supported by glslc") + set(GGML_VULKAN_COOPMAT_GLSLC_SUPPORT OFF CACHE INTERNAL "Not enable coopmat shaders") + else() + message(STATUS "GL_KHR_cooperative_matrix supported by glslc") + set(GGML_VULKAN_COOPMAT_GLSLC_SUPPORT ON CACHE INTERNAL "Enable coopmat shaders") + endif() - # Compile a test shader to determine whether GL_KHR_cooperative_matrix is supported. - # If it's not, there will be an error to stderr. - # If it's supported, set a define to indicate that we should compile those shaders - execute_process(COMMAND ${Vulkan_GLSLC_EXECUTABLE} -o - -fshader-stage=compute --target-env=vulkan1.3 "${CMAKE_CURRENT_SOURCE_DIR}/vulkan-shaders/test_coopmat_support.comp" - OUTPUT_VARIABLE glslc_output - ERROR_VARIABLE glslc_error) + # Compile a test shader to determine whether GL_NV_cooperative_matrix2 is supported. + # If it's not, there will be an error to stderr. + # If it's supported, set a define to indicate that we should compile those shaders + execute_process(COMMAND ${Vulkan_GLSLC_EXECUTABLE} -o - -fshader-stage=compute --target-env=vulkan1.3 "${CMAKE_CURRENT_SOURCE_DIR}/vulkan-shaders/test_coopmat2_support.comp" + OUTPUT_VARIABLE glslc_output + ERROR_VARIABLE glslc_error) - if (${glslc_error} MATCHES ".*extension not supported: GL_KHR_cooperative_matrix.*") - message(STATUS "GL_KHR_cooperative_matrix not supported by glslc") - else() - message(STATUS "GL_KHR_cooperative_matrix supported by glslc") - add_compile_definitions(GGML_VULKAN_COOPMAT_GLSLC_SUPPORT) + if (${glslc_error} MATCHES ".*extension not supported: GL_NV_cooperative_matrix2.*") + message(STATUS "GL_NV_cooperative_matrix2 not supported by glslc") + set(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT OFF CACHE INTERNAL "Not enable coopmat2 shaders") + else() + message(STATUS "GL_NV_cooperative_matrix2 supported by glslc") + set(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT ON CACHE INTERNAL "Enable coopmat2 shaders") + endif() endif() - # Compile a test shader to determine whether GL_NV_cooperative_matrix2 is supported. - # If it's not, there will be an error to stderr. - # If it's supported, set a define to indicate that we should compile those shaders - execute_process(COMMAND ${Vulkan_GLSLC_EXECUTABLE} -o - -fshader-stage=compute --target-env=vulkan1.3 "${CMAKE_CURRENT_SOURCE_DIR}/vulkan-shaders/test_coopmat2_support.comp" - OUTPUT_VARIABLE glslc_output - ERROR_VARIABLE glslc_error) - - if (${glslc_error} MATCHES ".*extension not supported: GL_NV_cooperative_matrix2.*") - message(STATUS "GL_NV_cooperative_matrix2 not supported by glslc") + if (GGML_VULKAN_COOPMAT_GLSLC_SUPPORT) + message(STATUS "GGML_VULKAN_COOPMAT_GLSLC_SUPPORT enabled") + add_compile_definitions(GGML_VULKAN_COOPMAT_GLSLC_SUPPORT) else() - message(STATUS "GL_NV_cooperative_matrix2 supported by glslc") + message(STATUS "GGML_VULKAN_COOPMAT_GLSLC_SUPPORT disabled") + endif() + + if (GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT) + message(STATUS "GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT enabled") add_compile_definitions(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT) + else() + message(STATUS "GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT disabled") endif() target_link_libraries(ggml-vulkan PRIVATE Vulkan::Vulkan) @@ -119,6 +191,9 @@ if (Vulkan_FOUND) SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vulkan-shaders CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${HOST_CMAKE_TOOLCHAIN_FILE} -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} + -DGGML_VULKAN_COOPMAT_GLSLC_SUPPORT=${GGML_VULKAN_COOPMAT_GLSLC_SUPPORT} + -DGGML_VULKAN_COOPMAT2_GLSLC_SUPPORT=${GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT} + -DGGML_VULKAN_GLSLC_EXECUTABLE=${Vulkan_GLSLC_EXECUTABLE} BUILD_COMMAND ${CMAKE_COMMAND} --build . INSTALL_COMMAND ${CMAKE_COMMAND} --install . INSTALL_DIR ${CMAKE_BINARY_DIR} @@ -159,4 +234,4 @@ if (Vulkan_FOUND) else() message(WARNING "Vulkan not found") -endif() +endif() \ No newline at end of file diff --git a/ggml/src/ggml-vulkan/ggml-vulkan.cpp b/ggml/src/ggml-vulkan/ggml-vulkan.cpp index ff53bdfbe17..f66e0d3d748 100644 --- a/ggml/src/ggml-vulkan/ggml-vulkan.cpp +++ b/ggml/src/ggml-vulkan/ggml-vulkan.cpp @@ -1394,7 +1394,7 @@ static std::array fa_rows_cols(uint32_t D, uint32_t clamp, ggml_typ return {64, 32}; } return {64, 64}; -}; +} static bool ggml_vk_matmul_shmem_support(const vk_device& device, const std::vector& warptile, bool mul_mat_id, ggml_type src0_type) { diff --git a/ggml/src/ggml-vulkan/vulkan-shaders/CMakeLists.txt b/ggml/src/ggml-vulkan/vulkan-shaders/CMakeLists.txt index 074031087f4..7d2fcaf28d2 100644 --- a/ggml/src/ggml-vulkan/vulkan-shaders/CMakeLists.txt +++ b/ggml/src/ggml-vulkan/vulkan-shaders/CMakeLists.txt @@ -1,11 +1,36 @@ find_package (Threads REQUIRED) -find_program(GLSLC_EXECUTABLE glslc) -if(NOT GLSLC_EXECUTABLE) - message(FATAL_ERROR "glslc not found.") + +# Use glslc from the parent CMake context or find it on the host system +if(DEFINED Vulkan_GLSLC_EXECUTABLE) + set(GLSLC_EXECUTABLE ${Vulkan_GLSLC_EXECUTABLE}) + message(STATUS "Using glslc from parent CMake: ${GLSLC_EXECUTABLE}") + # Also define this at compile time to set the default value in the shader generator + add_compile_definitions(VULKAN_GLSLC_EXECUTABLE="${GLSLC_EXECUTABLE}") +else() + # Find glslc on the host system, not the target + find_program(GLSLC_EXECUTABLE glslc NO_CMAKE_FIND_ROOT_PATH) + if(NOT GLSLC_EXECUTABLE) + message(FATAL_ERROR "glslc not found. Please set Vulkan_GLSLC_EXECUTABLE in parent CMake.") + endif() + message(STATUS "Found host glslc: ${GLSLC_EXECUTABLE}") endif() +option(GGML_VULKAN_COOPMAT_GLSLC_SUPPORT "Enable coopmat shaders" OFF) +option(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT "Enable coopmat2 shaders" OFF) + +message(STATUS "GGML_VULKAN_COOPMAT_GLSLC_SUPPORT: ${GGML_VULKAN_COOPMAT_GLSLC_SUPPORT}") +message(STATUS "GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT: ${GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT}") + set(TARGET vulkan-shaders-gen) add_executable(${TARGET} vulkan-shaders-gen.cpp) +if (GGML_VULKAN_COOPMAT_GLSLC_SUPPORT) + target_compile_definitions(vulkan-shaders-gen PRIVATE GGML_VULKAN_COOPMAT_GLSLC_SUPPORT) +endif() + +if (GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT) + target_compile_definitions(vulkan-shaders-gen PRIVATE GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT) +endif() + install(TARGETS ${TARGET} RUNTIME) target_compile_features(${TARGET} PRIVATE cxx_std_17) target_link_libraries(vulkan-shaders-gen PUBLIC Threads::Threads) diff --git a/ggml/src/ggml-vulkan/vulkan-shaders/vulkan-shaders-gen.cpp b/ggml/src/ggml-vulkan/vulkan-shaders/vulkan-shaders-gen.cpp index ee1fec4e114..9221532b85c 100644 --- a/ggml/src/ggml-vulkan/vulkan-shaders/vulkan-shaders-gen.cpp +++ b/ggml/src/ggml-vulkan/vulkan-shaders/vulkan-shaders-gen.cpp @@ -1,5 +1,6 @@ + #include #include #include @@ -35,7 +36,16 @@ std::mutex lock; std::vector> shader_fnames; -std::string GLSLC = "glslc"; +// Default glslc path, can be overridden at compile time or runtime +#ifdef VULKAN_GLSLC_EXECUTABLE + // If VULKAN_GLSLC_EXECUTABLE is defined at compile time, use it + #define DEFAULT_GLSLC_EXECUTABLE VULKAN_GLSLC_EXECUTABLE +#else + // Otherwise default to "glslc" + #define DEFAULT_GLSLC_EXECUTABLE "glslc" +#endif + +std::string GLSLC = DEFAULT_GLSLC_EXECUTABLE; std::string input_dir = "vulkan-shaders"; std::string output_dir = "/tmp"; std::string target_hpp = "ggml-vulkan-shaders.hpp";