1cmake_minimum_required(VERSION 3.13)
 2
 3find_package(Python3 REQUIRED)
 4
 5# Shader locations
 6set(SHADER_DIR "${CMAKE_CURRENT_SOURCE_DIR}/wgsl-shaders")
 7set(SHADER_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated")
 8set(SHADER_HEADER "${SHADER_OUTPUT_DIR}/ggml-wgsl-shaders.hpp")
 9file(MAKE_DIRECTORY ${SHADER_OUTPUT_DIR})
10
11message(STATUS "Shader output dir: ${SHADER_OUTPUT_DIR}")
12
13# Find all WGSL files
14file(GLOB WGSL_SHADER_FILES "${SHADER_DIR}/*.wgsl")
15
16# Generate the header using a Python script
17add_custom_command(
18    OUTPUT ${SHADER_HEADER}
19    COMMAND ${CMAKE_COMMAND} -E echo "Embedding WGSL shaders to ggml-wgsl-shaders.hpp"
20    COMMAND ${CMAKE_COMMAND} -E make_directory ${SHADER_OUTPUT_DIR}
21    COMMAND ${CMAKE_COMMAND} -E env PYTHONIOENCODING=utf-8
22        ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/wgsl-shaders/embed_wgsl.py
23            --input_dir "${SHADER_DIR}"
24            --output_file "${SHADER_HEADER}"
25    DEPENDS ${WGSL_SHADER_FILES} ${CMAKE_CURRENT_SOURCE_DIR}/wgsl-shaders/embed_wgsl.py
26    VERBATIM
27)
28
29add_custom_target(generate_shaders DEPENDS ${SHADER_HEADER})
30
31ggml_add_backend_library(ggml-webgpu
32    ggml-webgpu.cpp
33    ${SHADER_HEADER}
34    ../../include/ggml-webgpu.h
35)
36
37add_dependencies(ggml-webgpu generate_shaders)
38
39if(EMSCRIPTEN)
40    set(EMDAWNWEBGPU_DIR "" CACHE PATH "Path to emdawnwebgpu_pkg")
41
42    if(NOT EMDAWNWEBGPU_DIR)
43        # default built-in port
44        target_compile_options(ggml-webgpu PRIVATE "--use-port=emdawnwebgpu")
45        target_link_options(ggml-webgpu INTERFACE "--use-port=emdawnwebgpu")
46    else()
47        # custom port
48        target_compile_options(ggml-webgpu PRIVATE "--use-port=${EMDAWNWEBGPU_DIR}/emdawnwebgpu.port.py")
49        target_link_options(ggml-webgpu INTERFACE "--use-port=${EMDAWNWEBGPU_DIR}/emdawnwebgpu.port.py")
50    endif()
51
52    if (GGML_WEBGPU_JSPI)
53        target_compile_options(ggml-webgpu PRIVATE "-fwasm-exceptions")
54        target_link_options(ggml-webgpu INTERFACE "-sJSPI" "-fwasm-exceptions")
55    else()
56        target_compile_options(ggml-webgpu PRIVATE "-fexceptions")
57        target_link_options(ggml-webgpu INTERFACE "-sASYNCIFY" "-exceptions")
58    endif()
59else()
60    find_package(Dawn REQUIRED)
61    set(DawnWebGPU_TARGET dawn::webgpu_dawn)
62endif()
63
64if (GGML_WEBGPU_DEBUG)
65    target_compile_definitions(ggml-webgpu PRIVATE GGML_WEBGPU_DEBUG=1)
66    if(EMSCRIPTEN)
67        target_link_options(ggml-webgpu INTERFACE "-sASSERTIONS=2")
68    endif()
69endif()
70
71if (GGML_WEBGPU_CPU_PROFILE)
72    target_compile_definitions(ggml-webgpu PRIVATE GGML_WEBGPU_CPU_PROFILE=1)
73endif()
74
75if (GGML_WEBGPU_GPU_PROFILE)
76    target_compile_definitions(ggml-webgpu PRIVATE GGML_WEBGPU_GPU_PROFILE=1)
77endif()
78
79target_include_directories(ggml-webgpu PRIVATE ${SHADER_OUTPUT_DIR})
80target_link_libraries(ggml-webgpu PRIVATE ${DawnWebGPU_TARGET})