Skip to content
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

vulkan : cmake integration #8119

Merged
merged 40 commits into from
Jul 13, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
4eadfb1
Add Vulkan to CMake pkg
bandoti Jun 24, 2024
c46a789
Add Sycl to CMake pkg
bandoti Jun 24, 2024
36b081a
Add OpenMP to CMake pkg
bandoti Jun 24, 2024
29ba5a8
Split generated shader file into separate translation unit
bandoti Jun 25, 2024
1b4759f
Add CMake target for Vulkan shaders
bandoti Jun 25, 2024
cb3ec88
Merge branch 'ggerganov:master' into vulkan-build-integration
bandoti Jun 25, 2024
37bcad7
Update README.md
bandoti Jun 25, 2024
b1a70fc
Merge branch 'ggerganov:master' into vulkan-build-integration
bandoti Jun 25, 2024
dd198ce
Merge branch 'ggerganov:master' into vulkan-build-integration
bandoti Jun 25, 2024
491a967
Add make target for Vulkan shaders
bandoti Jun 25, 2024
99c3027
Use pkg-config to locate vulkan library
bandoti Jun 26, 2024
8859546
Add vulkan SDK dep to ubuntu-22-cmake-vulkan workflow
bandoti Jun 26, 2024
c61cd05
Clean up tabs
bandoti Jun 26, 2024
2318cad
Move sudo to apt-key invocation
bandoti Jun 26, 2024
a1495e7
Merge branch 'master' into vulkan-build-integration
bandoti Jun 26, 2024
6571046
Forward GGML_EXTRA_LIBS to CMake config pkg
bandoti Jun 26, 2024
d053004
Update vulkan obj file paths
bandoti Jun 27, 2024
d0d825f
Add shaderc to nix pkg
bandoti Jun 27, 2024
eec17a6
Add python3 to Vulkan nix build
bandoti Jun 27, 2024
8590508
Link against ggml in cmake pkg
bandoti Jun 27, 2024
ac9a065
Remove Python dependency from Vulkan build
bandoti Jun 30, 2024
4eab311
Merge branch 'ggerganov:master' into vulkan-build-integration
bandoti Jun 30, 2024
9bca872
code review changes
bandoti Jul 1, 2024
422bfb3
Merge branch 'master' into vulkan-build-integration
bandoti Jul 1, 2024
22323d5
Merge branch 'master' into vulkan-build-integration
bandoti Jul 2, 2024
2f5a0e8
Remove trailing newline
bandoti Jul 2, 2024
a85b5d8
Merge branch 'master' into vulkan-build-integration
bandoti Jul 2, 2024
019e4a3
Add cflags from pkg-config to fix w64devkit build
bandoti Jul 2, 2024
3a554ae
Update README.md
bandoti Jul 2, 2024
dafcaf1
Remove trailing whitespace
bandoti Jul 2, 2024
4226103
Update README.md
bandoti Jul 3, 2024
613a3c6
Remove trailing whitespace
bandoti Jul 3, 2024
f638ade
Merge branch 'master' into vulkan-build-integration
bandoti Jul 5, 2024
02e65ad
Fix doc heading
bandoti Jul 5, 2024
6b5c5af
Merge branch 'ggerganov:master' into vulkan-build-integration
bandoti Jul 7, 2024
50da329
Merge branch 'master' into vulkan-build-integration
bandoti Jul 8, 2024
f47829a
Merge branch 'master' into vulkan-build-integration
bandoti Jul 10, 2024
9501f66
Make glslc required Vulkan component
bandoti Jul 10, 2024
88fd99b
remove clblast from nix pkg
bandoti Jul 12, 2024
24fd7d3
Merge branch 'master' into vulkan-build-integration
bandoti Jul 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .devops/nix/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
rocmPackages,
vulkan-headers,
vulkan-loader,
shaderc,
clblast,
0cc4m marked this conversation as resolved.
Show resolved Hide resolved
useBlas ? builtins.all (x: !x) [
useCuda
Expand Down Expand Up @@ -132,6 +133,8 @@ let
vulkanBuildInputs = [
vulkan-headers
vulkan-loader
shaderc
python3
];
in

Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -355,8 +355,10 @@ jobs:
- name: Dependencies
id: depends
run: |
sudo apt-get update
sudo apt-get install build-essential libvulkan-dev
wget -qO - https://packages.lunarg.com/lunarg-signing-key-pub.asc | sudo apt-key add -
sudo wget -qO /etc/apt/sources.list.d/lunarg-vulkan-jammy.list https://packages.lunarg.com/vulkan/lunarg-vulkan-jammy.list
sudo apt-get update -y
sudo apt-get install -y build-essential vulkan-sdk

- name: Build
id: cmake_build
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ llama-batched-swift
/rpc-server
out/
tmp/
ggml-vulkan-shaders.hpp
ggml-vulkan-shaders.cpp
bandoti marked this conversation as resolved.
Show resolved Hide resolved

# CI

Expand Down
11 changes: 10 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,16 @@ set(LLAMA_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Location o
set(LLAMA_LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Location of library files")
set(LLAMA_BIN_INSTALL_DIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Location of binary files")

get_directory_property(LLAMA_TRANSIENT_DEFINES COMPILE_DEFINITIONS)

# At the moment some compile definitions are placed within the ggml/src
# directory but not exported on the `ggml` target. This could be improved by
# determining _precisely_ which defines are necessary for the llama-config
# package.
#
get_directory_property(GGML_DIR_DEFINES DIRECTORY ggml/src COMPILE_DEFINITIONS)
get_target_property(GGML_TARGET_DEFINES ggml COMPILE_DEFINITIONS)
set(GGML_TRANSIENT_DEFINES ${GGML_TARGET_DEFINES} ${GGML_DIR_DEFINES})
get_target_property(GGML_LINK_LIBRARIES ggml LINK_LIBRARIES)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why this is needed - an example with a specific flag that is not exported would help. It's OK to merge as it is though

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ggerganov I will take a closer look at this. The flags which should be exported should be all interface defines (public interface only) on the ggml/llama libraries. I will follow up with a new pull request.


set_target_properties(llama PROPERTIES PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/include/llama.h)
install(TARGETS llama LIBRARY PUBLIC_HEADER)
Expand Down
27 changes: 22 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -688,8 +688,8 @@ endif # GGML_CUDA

ifdef GGML_VULKAN
MK_CPPFLAGS += -DGGML_USE_VULKAN
MK_LDFLAGS += -lvulkan
OBJ_GGML += ggml/src/ggml-vulkan.o
MK_LDFLAGS += $(shell pkg-config --libs vulkan)
OBJ_GGML += ggml/src/ggml-vulkan.o ggml/src/ggml-vulkan-shaders.o

ifdef GGML_VULKAN_CHECK_RESULTS
MK_CPPFLAGS += -DGGML_VULKAN_CHECK_RESULTS
Expand All @@ -711,10 +711,26 @@ ifdef GGML_VULKAN_RUN_TESTS
MK_CPPFLAGS += -DGGML_VULKAN_RUN_TESTS
endif

ggml/src/ggml-vulkan.o: \
ggml/src/ggml-vulkan.cpp \
ggml/include/ggml-vulkan.h
PYTHON_CMD = python
GLSLC_CMD = glslc
_llama_vk_genshaders_cmd = $(PYTHON_CMD) ggml/ggml_vk_generate_shaders.py
_llama_vk_header = ggml/src/ggml-vulkan-shaders.hpp
_llama_vk_source = ggml/src/ggml-vulkan-shaders.cpp
_llama_vk_input_dir = ggml/src/vulkan-shaders
_llama_vk_shader_deps = $(echo $(_llama_vk_input_dir)/*.comp)

ggml/src/ggml-vulkan.o: ggml/src/ggml-vulkan.cpp ggml/include/ggml-vulkan.h $(_llama_vk_header) $(_llama_vk_source)
$(CXX) $(CXXFLAGS) -c $< -o $@

$(_llama_vk_header): $(_llama_vk_source)

$(_llama_vk_source): $(_llama_vk_shader_deps)
$(_llama_vk_genshaders_cmd) \
--glslc $(GLSLC_CMD) \
--input-dir $(_llama_vk_input_dir) \
--target-hpp $(_llama_vk_header) \
--target-cpp $(_llama_vk_source)

endif # GGML_VULKAN

ifdef GGML_HIPBLAS
Expand Down Expand Up @@ -1084,6 +1100,7 @@ clean:
rm -vrf ggml/src/ggml-cuda/template-instances/*.o
rm -rvf $(BUILD_TARGETS)
rm -rvf $(TEST_TARGETS)
rm -f ggml/src/ggml-vulkan-shaders.hpp ggml/src/ggml-vulkan-shaders.cpp
find examples pocs -type f -name "*.o" -delete

#
Expand Down
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,21 @@ Building the program with BLAS support may lead to some performance improvements
| GGML_CUDA_KQUANTS_ITER | 1 or 2 | 2 | Number of values processed per iteration and per HIP thread for Q2_K and Q6_K quantization formats. Setting this value to 1 can improve performance for slow GPUs. |

- #### Vulkan
##### Windows (MSYS2)
Install [MSYS2](https://www.msys2.org/) and then run the following commands in a UCRT terminal to install dependencies.
```sh
pacman -S git \
mingw-w64-ucrt-x86_64-gcc \
mingw-w64-ucrt-x86_64-cmake \
mingw-w64-ucrt-x86_64-vulkan-devel \
mingw-w64-ucrt-x86_64-shaderc \
mingw-w64-ucrt-x86_64-python3
```
Switch into `llama.cpp` directory and build using CMake.
```sh
cmake -B build -DLLAMA_VULKAN=ON
cmake --build build --config Release
```

**With docker**:

Expand Down
29 changes: 27 additions & 2 deletions cmake/llama-config.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ set(GGML_CUDA @GGML_CUDA@)
set(GGML_METAL @GGML_METAL@)
set(GGML_HIPBLAS @GGML_HIPBLAS@)
set(GGML_ACCELERATE @GGML_ACCELERATE@)
set(GGML_VULKAN @GGML_VULKAN@)
set(GGML_VULKAN_CHECK_RESULTS @GGML_VULKAN_CHECK_RESULTS@)
set(GGML_VULKAN_DEBUG @GGML_VULKAN_DEBUG@)
set(GGML_VULKAN_MEMORY_DEBUG @GGML_VULKAN_MEMORY_DEBUG@)
set(GGML_VULKAN_VALIDATE @GGML_VULKAN_VALIDATE@)
set(GGML_SYCL @GGML_SYCL@)
set(GGML_OPENMP @GGML_OPENMP@)

@PACKAGE_INIT@

Expand Down Expand Up @@ -37,18 +44,36 @@ if (GGML_METAL)
find_library(METALKIT_FRAMEWORK MetalKit REQUIRED)
endif()

if (GGML_VULKAN)
find_package(Vulkan REQUIRED)
endif()

if (GGML_HIPBLAS)
find_package(hip REQUIRED)
find_package(hipblas REQUIRED)
find_package(rocblas REQUIRED)
endif()

if (GGML_SYCL)
find_package(IntelSYCL REQUIRED)
find_package(MKL REQUIRED)
endif()

if (GGML_OPENMP)
find_package(OpenMP REQUIRED)
endif()


find_library(ggml_LIBRARY ggml
REQUIRED
HINTS ${LLAMA_LIB_DIR})

find_library(llama_LIBRARY llama
REQUIRED
HINTS ${LLAMA_LIB_DIR})

set(_llama_link_deps "Threads::Threads" "@LLAMA_EXTRA_LIBS@")
set(_llama_transient_defines "@LLAMA_TRANSIENT_DEFINES@")
set(_llama_link_deps "${ggml_LIBRARY}" "@GGML_LINK_LIBRARIES@")
set(_llama_transient_defines "@GGML_TRANSIENT_DEFINES@")

add_library(llama UNKNOWN IMPORTED)

Expand Down
41 changes: 29 additions & 12 deletions ggml/ggml_vk_generate_shaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import asyncio
import os
from tempfile import gettempdir
import sys

logger = logging.getLogger("ggml-vk-generate-shaders")

Expand All @@ -27,9 +28,6 @@

ASYNCIO_CONCURRENCY = 64

input_dir = "vulkan-shaders"
output_dir = gettempdir()

lock = asyncio.Lock()
shader_fnames = []

Expand Down Expand Up @@ -184,30 +182,37 @@ async def withSemaphore(sem, task):
sem = asyncio.Semaphore(ASYNCIO_CONCURRENCY)
await asyncio.gather(*(withSemaphore(sem, task) for task in tasks))

with open("ggml-vulkan-shaders.hpp", "w") as f:
f.write("#include <cstdint>\n\n")
with open(target_hpp, "w") as hdr, open(target_cpp, "w") as src:
hdr.write("#include <cstdint>\n\n")
src.write(f"#include \"{os.path.basename(target_hpp)}\"\n\n")
for name, path in sorted(shader_fnames):

with open(path, "rb") as spv:
counter = 0
newline_counter = 0
f.write(f"unsigned char {name}_data[] = {{\n")
data = ""
for val in spv.read():
f.write(f"0x{val:02x},")
data += f"0x{val:02x},"
newline_counter += 1
counter += 1
if newline_counter >= 12:
newline_counter = 0
f.write("\n")
f.write("\n};\n")
f.write(f"const uint64_t {name}_len = {counter};\n\n")
os.remove(path)
data += "\n"
hdr.write(f"extern unsigned char {name}_data[{counter}];\n")
hdr.write(f"const uint64_t {name}_len = {counter};\n\n")
src.write(f"unsigned char {name}_data[{counter}] = {{\n{data}\n}};\n\n")
if not no_clean:
os.remove(path)


if __name__ == "__main__":
parser = argparse.ArgumentParser(description="GGML Vulkan Shader Generator")

parser.add_argument("--glslc", help="Path to glslc")
parser.add_argument("--input-dir", default="vulkan-shaders", help="Directory containing shader sources")
parser.add_argument("--output-dir", default=gettempdir(), help="Directory for containing SPIR-V output")
parser.add_argument("--target-hpp", default="ggml-vulkan-shaders.hpp", help="Path to generated header file")
parser.add_argument("--target-cpp", default="ggml-vulkan-shaders.cpp", help="Path to generated cpp file")
parser.add_argument("--no-clean", action="store_true", help="Keep temporary SPIR-V files in output-dir after build")
parser.add_argument("--verbose", action="store_true", help="increase output verbosity")

args = parser.parse_args()
Expand All @@ -217,4 +222,16 @@ async def withSemaphore(sem, task):
if args.glslc:
GLSLC = args.glslc

input_dir = args.input_dir
if not os.path.isdir(input_dir):
sys.exit(f"\"{input_dir}\" must be a valid directory containing shader sources")

output_dir = args.output_dir
if not os.path.isdir(output_dir):
os.makedirs(output_dir)

target_hpp = args.target_hpp
target_cpp = args.target_cpp
no_clean = args.no_clean

asyncio.run(main())
38 changes: 34 additions & 4 deletions ggml/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -525,14 +525,16 @@ if (GGML_RPC)
endif()

if (GGML_VULKAN)
find_package(Python COMPONENTS Interpreter)
if (NOT Python_FOUND)
message(FATAL_ERROR "python is required to compile Vulkan shaders")
bandoti marked this conversation as resolved.
Show resolved Hide resolved
endif()

find_package(Vulkan)

if (Vulkan_FOUND)
message(STATUS "Vulkan found")

set(GGML_HEADERS_VULKAN ../include/ggml-vulkan.h)
set(GGML_SOURCES_VULKAN ggml-vulkan.cpp)

list(APPEND GGML_CDEF_PUBLIC GGML_USE_VULKAN)

# Workaround to the "can't dereference invalidated vector iterator" bug in clang-cl debug build
Expand Down Expand Up @@ -561,7 +563,35 @@ if (GGML_VULKAN)
add_compile_definitions(GGML_VULKAN_RUN_TESTS)
endif()

set(GGML_EXTRA_LIBS ${GGML_EXTRA_LIBS} Vulkan::Vulkan)
set (_llama_vk_genshaders_cmd ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../ggml_vk_generate_shaders.py)
bandoti marked this conversation as resolved.
Show resolved Hide resolved
set (_llama_vk_header ${CMAKE_CURRENT_BINARY_DIR}/ggml-vulkan-shaders.hpp)
set (_llama_vk_source ${CMAKE_CURRENT_BINARY_DIR}/ggml-vulkan-shaders.cpp)
set (_llama_vk_input_dir ${CMAKE_CURRENT_SOURCE_DIR}/vulkan-shaders)
set (_llama_vk_output_dir ${CMAKE_CURRENT_BINARY_DIR}/vulkan-shaders.spv)
bandoti marked this conversation as resolved.
Show resolved Hide resolved

file(GLOB _llama_vk_shader_deps "${_llama_vk_input_dir}/*.comp")

add_custom_command(
OUTPUT ${_llama_vk_header}
${_llama_vk_source}

COMMAND ${_llama_vk_genshaders_cmd}
--glslc ${Vulkan_GLSLC_EXECUTABLE}
--input-dir ${_llama_vk_input_dir}
--output-dir ${_llama_vk_output_dir}
--target-hpp ${_llama_vk_header}
--target-cpp ${_llama_vk_source}
--no-clean

DEPENDS ${_llama_vk_shader_deps}
COMMENT "Generate vulkan shaders"
bandoti marked this conversation as resolved.
Show resolved Hide resolved
)

set(GGML_HEADERS_VULKAN ${CMAKE_CURRENT_SOURCE_DIR}/../include/ggml-vulkan.h ${_llama_vk_header})
set(GGML_SOURCES_VULKAN ggml-vulkan.cpp ${_llama_vk_source})

set(GGML_EXTRA_LIBS ${GGML_EXTRA_LIBS} Vulkan::Vulkan)
set(GGML_EXTRA_INCLUDES ${GGML_EXTRA_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR})
else()
message(WARNING "Vulkan not found")
endif()
Expand Down
Loading
Loading