-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Fixed cooperative matrix shaders on Vulkan builds when CROSS_COMPILE ON #2914
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
04ab3d3
e6ab39f
62e5be8
eaa2808
3275375
3519d2d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,14 @@ cmake_policy(SET CMP0114 NEW) | |
|
|
||
| find_package(Vulkan COMPONENTS glslc REQUIRED) | ||
|
|
||
| # Allow explicitly specifying glslc executable for cross-compilation scenarios | ||
| if(DEFINED GGML_VULKAN_GLSLC_EXECUTABLE) | ||
| set(VULKAN_GLSLC_EXECUTABLE_OVERRIDE ${GGML_VULKAN_GLSLC_EXECUTABLE}) | ||
| message(STATUS "Using explicitly provided glslc: ${VULKAN_GLSLC_EXECUTABLE_OVERRIDE}") | ||
| else() | ||
| set(VULKAN_GLSLC_EXECUTABLE_OVERRIDE ${Vulkan_GLSLC_EXECUTABLE}) | ||
| endif() | ||
|
|
||
| function(detect_host_compiler) | ||
| if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") | ||
| find_program(HOST_C_COMPILER NAMES cl gcc clang NO_CMAKE_FIND_ROOT_PATH) | ||
|
|
@@ -26,28 +34,32 @@ if (Vulkan_FOUND) | |
| # 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" | ||
| execute_process(COMMAND ${VULKAN_GLSLC_EXECUTABLE_OVERRIDE} -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") | ||
| add_compile_definitions(GGML_VULKAN_COOPMAT_GLSLC_SUPPORT) | ||
| set(GGML_VULKAN_COOPMAT_GLSLC_SUPPORT ON CACHE INTERNAL "Enable coopmat shaders") | ||
| 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" | ||
| execute_process(COMMAND ${VULKAN_GLSLC_EXECUTABLE_OVERRIDE} -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") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should there be an "OFF" here like there is for coopmat1 above?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch! It would not be consistent otherwise => won't cause issues as default will be OFF anyway, but I think it is better to have it explicit. |
||
| 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") | ||
| add_compile_definitions(GGML_VULKAN_COOPMAT2_GLSLC_SUPPORT) | ||
| endif() | ||
|
|
||
|
|
@@ -119,6 +131,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_OVERRIDE} | ||
| BUILD_COMMAND ${CMAKE_COMMAND} --build . | ||
| INSTALL_COMMAND ${CMAKE_COMMAND} --install . | ||
| INSTALL_DIR ${CMAKE_BINARY_DIR} | ||
|
|
@@ -144,7 +159,7 @@ if (Vulkan_FOUND) | |
| ${_ggml_vk_source} | ||
|
|
||
| COMMAND ${_ggml_vk_genshaders_cmd} | ||
| --glslc ${Vulkan_GLSLC_EXECUTABLE} | ||
| --glslc ${VULKAN_GLSLC_EXECUTABLE_OVERRIDE} | ||
| --input-dir ${_ggml_vk_input_dir} | ||
| --output-dir ${_ggml_vk_output_dir} | ||
| --target-hpp ${_ggml_vk_header} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,32 @@ | ||
| find_package (Threads REQUIRED) | ||
| find_program(GLSLC_EXECUTABLE glslc) | ||
| if(NOT GLSLC_EXECUTABLE) | ||
| message(FATAL_ERROR "glslc not found.") | ||
|
|
||
| # Allow explicitly specifying glslc executable path from parent CMake | ||
| if(DEFINED GGML_VULKAN_GLSLC_EXECUTABLE) | ||
| set(GLSLC_EXECUTABLE ${GGML_VULKAN_GLSLC_EXECUTABLE}) | ||
| message(STATUS "Using explicitly provided glslc: ${GLSLC_EXECUTABLE}") | ||
| else() | ||
| find_program(GLSLC_EXECUTABLE glslc) | ||
| if(NOT GLSLC_EXECUTABLE) | ||
| message(FATAL_ERROR "glslc not found.") | ||
| endif() | ||
| 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) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In ggml-org/llama.cpp#11695 (comment) I had guessed that we may need to pass through a cmake variable telling this makefile which version of glslc to use? Is that not necessary? It's just the #defines that weren't making it through?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not 100% sure if we need additional version to be used (and in my case it was working as same version as the host system was used). I can confirm that only providing the compile definitions is working for my build => https://github.com/sandrohanea/whisper.net/actions/runs/13977409227/job/39134498314 |
||
| 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) | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not convinced that providing a command-line override is the right solution here. When cross-compiling the standard behavior is to separate build/target utilities via the find-root path. For example, the line above is stating that it requires glslc, but it seems this should not in fact be required but found separately using a appropriate paths.
For example, what we are basically saying is:
As such, it would be more consistent with general cross-compiling to instead use
find_program(VULKAN_GLSLC_EXECUTABLE glslc REQUIRED NO_CMAKE_FIND_ROOT_PATH)and change the Vulkan find command tofind_package(Vulkan)(not specifying the glslc component there).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about the Android case though, where there are multiple NDKs, and each might have its own glslc might be worthwhile to support both modes. So, the default behavior could be to use find_program, but also allow the command-line option to ensure we have our bases covered. There have been a couple issues surrounding this so probably best to play it safe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, so I just took a quick look in the
FindVulkan.cmakefile on my system and quickly checked the docs. Based on the docs, the search for glslc will not be repeated if it is cached first:One possibility is to set the cache variable
Vulkan_GLSLC_EXECUTABLEbefore callingfind_package(Vulkan COMPONENTS glslc REQUIRED). So, first runningfind_program(Vulkan_GLSLC_EXECUTABLE glslc REQUIRED NO_CMAKE_FIND_ROOT_PATH)would override the search. Similarly, the command-line approach overriding the Vulkan_GLSLC_EXECUTABLE cache variable would override that, and then we don't need a separate variable for the same thing. Something to consider. 🙂There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO we should just always use the glslc installed on the build system. The NDK glslc is egregiously out of date, it's really not what we want to be using.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the description of the PR, let me know what do you think