From 4d31ad002d6bab2ec3701fc3535a39fc341299ea Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Tue, 16 Jul 2024 16:05:02 -0400 Subject: [PATCH 1/4] Move dependencies/wasm to use sites Some code was used only by test/generator, other code by src/. This prepares the repository for decoupling our build from FetchContent. --- CMakeLists.txt | 2 +- dependencies/CMakeLists.txt | 8 -- dependencies/wasm/CMakeLists.txt | 152 ------------------------------- src/CMakeLists.txt | 62 +++++++++++-- test/generator/CMakeLists.txt | 94 +++++++++++++++++++ 5 files changed, 150 insertions(+), 168 deletions(-) delete mode 100644 dependencies/CMakeLists.txt delete mode 100644 dependencies/wasm/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 2364f58ee4f1..5af14c0080ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -188,7 +188,7 @@ option(THREADS_PREFER_PTHREAD_FLAG "When enabled, prefer to use the -pthread fla find_package(Threads REQUIRED) ## Complex dependencies -add_subdirectory(dependencies) +add_subdirectory(dependencies/llvm) ## Image formats diff --git a/dependencies/CMakeLists.txt b/dependencies/CMakeLists.txt deleted file mode 100644 index 56078b20d4e0..000000000000 --- a/dependencies/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -## -# Third-party dependencies in their own subdirectories -## - -add_subdirectory(llvm) - -# Needs cache vars set by llvm, do not reorder. -add_subdirectory(wasm) diff --git a/dependencies/wasm/CMakeLists.txt b/dependencies/wasm/CMakeLists.txt deleted file mode 100644 index 38ad1f79198f..000000000000 --- a/dependencies/wasm/CMakeLists.txt +++ /dev/null @@ -1,152 +0,0 @@ -include(FetchContent) -include(CMakeDependentOption) - -cmake_dependent_option(WITH_WABT "Include WABT Interpreter for WASM testing" ON "TARGET_WEBASSEMBLY" OFF) -cmake_dependent_option(WITH_V8 "Include V8 for WASM testing" OFF "TARGET_WEBASSEMBLY" OFF) - -if (WITH_WABT AND WITH_V8) - message(FATAL_ERROR "Cannot use both WABT and V8 at the same time, disable one of them.") -endif () - -if ("${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows") - if (WITH_WABT) - message(STATUS "WITH_WABT is not yet supported on Windows") - set(WITH_WABT OFF CACHE BOOL "WITH_WABT is not yet supported on Windows" FORCE) - endif () -endif () - -if (WITH_WABT) - set(WABT_VER 1.0.33) - - message(STATUS "Fetching WABT ${WABT_VER}...") - FetchContent_Declare(wabt - GIT_REPOSITORY https://github.com/WebAssembly/wabt.git - GIT_TAG ${WABT_VER} - GIT_SHALLOW TRUE) - - # configuration for wabt - set(WITH_EXCEPTIONS ${Halide_ENABLE_EXCEPTIONS}) - set(BUILD_TESTS OFF) - set(BUILD_TOOLS OFF) - set(BUILD_LIBWASM OFF) - set(USE_INTERNAL_SHA256 ON) - FetchContent_MakeAvailable(wabt) - - set_target_properties(wabt PROPERTIES POSITION_INDEPENDENT_CODE ON) - - # Disable this very-noisy warning in GCC - target_compile_options(wabt - PRIVATE - $<$:-Wno-alloca-larger-than>) - - # TODO: we want to require unique prefixes to include these files, to avoid ambiguity; - # this means we have to prefix with "wabt-src/...", which is less bad than other alternatives, - # but perhaps we could do better (esp. if wabt was smarter about what it exposed?) - add_library(Halide_wabt INTERFACE) - target_sources(Halide_wabt INTERFACE $>) - target_include_directories(Halide_wabt - SYSTEM # Use -isystem instead of -I; this is a trick so that clang-tidy won't analyze these includes - INTERFACE - $/include - $/include) - set_target_properties(Halide_wabt PROPERTIES EXPORT_NAME wabt) -endif () - -if (WITH_V8) - find_package(V8 REQUIRED) - set_target_properties(V8::V8 PROPERTIES IMPORTED_GLOBAL TRUE) -endif () - -function(add_wasm_executable TARGET) - set(options) - set(oneValueArgs) - set(multiValueArgs SRCS DEPS INCLUDES OPTIONS ENABLE_IF) - cmake_parse_arguments(args "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - if (args_ENABLE_IF AND NOT (${args_ENABLE_IF})) - return() - endif () - - # Conceptually, we want something like this: - # add_executable(${TARGET} ${args_SRCS}) - # if (args_INCLUDES) - # target_include_directories("${TARGET}" PRIVATE ${args_INCLUDES}) - # endif() - # if (args_DEPS) - # target_link_libraries(${TARGET} PRIVATE ${args_DEPS}) - # endif () - - find_program(EMCC emcc REQUIRED HINTS "$ENV{EMSDK}/upstream/emscripten") - - # TODO: this is currently hardcoded to settings that are sensible for most of Halide's - # internal purposes. Consider adding ways to customize this as appropriate. - set(EMCC_FLAGS - -O3 - -std=c++17 - -Wall - -Wcast-qual - -Werror - -Wignored-qualifiers - -Wno-comment - -Wno-psabi - -Wno-unknown-warning-option - -Wno-unused-function - -Wsign-compare - -Wsuggest-override - -s ASSERTIONS=1 - -s ALLOW_MEMORY_GROWTH=1 - -s ENVIRONMENT=node - -s STACK_SIZE=98304 - ${args_OPTIONS} - ) - - if ("${Halide_TARGET}" MATCHES "webgpu") - set(EMCC_FLAGS - ${EMCC_FLAGS} - -s USE_WEBGPU=1 - -s ASYNCIFY - ) - endif () - - set(SRCS) - foreach (S IN LISTS args_SRCS) - list(APPEND SRCS "${CMAKE_CURRENT_SOURCE_DIR}/${S}") - endforeach () - - set(INCLUDES) - foreach (I IN LISTS args_INCLUDES) - list(APPEND INCLUDES "-I${I}") - endforeach () - - set(DEPS) - foreach (D IN LISTS args_DEPS) - list(APPEND DEPS $) - endforeach () - - add_custom_command(OUTPUT "${TARGET}.wasm" "${TARGET}.js" - COMMAND ${EMCC} ${EMCC_FLAGS} ${INCLUDES} ${SRCS} ${DEPS} -o "${TARGET}.js" - DEPENDS ${SRCS} ${DEPS} - VERBATIM) - - add_custom_target("${TARGET}" ALL - DEPENDS "${TARGET}.wasm" "${TARGET}.js") - -endfunction() - -function(add_wasm_halide_test TARGET) - set(options) - set(oneValueArgs) - set(multiValueArgs GROUPS ENABLE_IF) - cmake_parse_arguments(args "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - if (args_ENABLE_IF AND NOT (${args_ENABLE_IF})) - return() - endif () - - find_package(NodeJS 16.13 REQUIRED) - add_halide_test( - "${TARGET}" - GROUPS ${args_GROUPS} - COMMAND "${NodeJS_EXECUTABLE}" "${Halide_SOURCE_DIR}/tools/launch_wasm_test.js" "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.js" "${Halide_TARGET}" - ) -endfunction() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a5ee7ecb39dd..874c16b4f8a4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -562,14 +562,62 @@ target_compile_definitions(Halide PUBLIC HALIDE_VERSION_MINOR=${Halide_VERSION_MINOR} HALIDE_VERSION_PATCH=${Halide_VERSION_PATCH}) -if (TARGET Halide_wabt) - target_link_libraries(Halide PRIVATE Halide_wabt) - target_compile_definitions(Halide PRIVATE WITH_WABT) -endif () +## +# WasmExecutor backend selection +## -if (TARGET V8::V8) - target_link_libraries(Halide PRIVATE V8::V8) - target_compile_definitions(Halide PRIVATE WITH_V8) +if (TARGET_WEBASSEMBLY) + include(FetchContent) + + set(Halide_WASM_BACKEND "wabt" + CACHE STRING "Which backend to use for Halide's WASM testing.") + set_property(CACHE Halide_WASM_BACKEND PROPERTY STRINGS "wabt;V8;OFF") + + if (Halide_WASM_BACKEND STREQUAL "wabt") + set(WABT_VER 1.0.33) + + message(STATUS "Fetching WABT ${WABT_VER}...") + FetchContent_Declare(wabt + GIT_REPOSITORY https://github.com/WebAssembly/wabt.git + GIT_TAG ${WABT_VER} + GIT_SHALLOW TRUE) + + # configuration for wabt + set(WITH_EXCEPTIONS ${Halide_ENABLE_EXCEPTIONS}) + set(BUILD_TESTS OFF) + set(BUILD_TOOLS OFF) + set(BUILD_LIBWASM OFF) + set(USE_INTERNAL_SHA256 ON) + FetchContent_MakeAvailable(wabt) + + set_target_properties(wabt PROPERTIES POSITION_INDEPENDENT_CODE ON) + + # Disable this very-noisy warning in GCC + target_compile_options(wabt + PRIVATE + $<$:-Wno-alloca-larger-than>) + + # TODO: we want to require unique prefixes to include these files, to avoid ambiguity; + # this means we have to prefix with "wabt-src/...", which is less bad than other alternatives, + # but perhaps we could do better (esp. if wabt was smarter about what it exposed?) + add_library(Halide_wabt INTERFACE) + target_sources(Halide_wabt INTERFACE $>) + target_include_directories(Halide_wabt + SYSTEM # Use -isystem instead of -I; this is a trick so that clang-tidy won't analyze these includes + INTERFACE + $/include + $/include) + set_target_properties(Halide_wabt PROPERTIES EXPORT_NAME wabt) + + target_link_libraries(Halide PRIVATE Halide_wabt) + target_compile_definitions(Halide PRIVATE WITH_WABT) + elseif (Halide_WASM_BACKEND STREQUAL "V8") + find_package(V8 REQUIRED) + target_link_libraries(Halide PRIVATE V8::V8) + target_compile_definitions(Halide PRIVATE WITH_V8) + elseif (Halide_WASM_BACKEND) + message(FATAL_ERROR "Unknown Halide_WASM_BACKEND `${Halide_WASM_BACKEND}`") + endif () endif () ## diff --git a/test/generator/CMakeLists.txt b/test/generator/CMakeLists.txt index 866ca2589e6c..3e1a656cefcf 100644 --- a/test/generator/CMakeLists.txt +++ b/test/generator/CMakeLists.txt @@ -12,6 +12,100 @@ else() set(_USING_WASM 0) endif() +function(add_wasm_executable TARGET) + set(options) + set(oneValueArgs) + set(multiValueArgs SRCS DEPS INCLUDES OPTIONS ENABLE_IF) + cmake_parse_arguments(args "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if (args_ENABLE_IF AND NOT (${args_ENABLE_IF})) + return() + endif () + + # Conceptually, we want something like this: + # add_executable(${TARGET} ${args_SRCS}) + # if (args_INCLUDES) + # target_include_directories("${TARGET}" PRIVATE ${args_INCLUDES}) + # endif() + # if (args_DEPS) + # target_link_libraries(${TARGET} PRIVATE ${args_DEPS}) + # endif () + + find_program(EMCC emcc REQUIRED HINTS "$ENV{EMSDK}/upstream/emscripten") + + # TODO: this is currently hardcoded to settings that are sensible for most of Halide's + # internal purposes. Consider adding ways to customize this as appropriate. + set(EMCC_FLAGS + -O3 + -std=c++17 + -Wall + -Wcast-qual + -Werror + -Wignored-qualifiers + -Wno-comment + -Wno-psabi + -Wno-unknown-warning-option + -Wno-unused-function + -Wsign-compare + -Wsuggest-override + -s ASSERTIONS=1 + -s ALLOW_MEMORY_GROWTH=1 + -s ENVIRONMENT=node + -s STACK_SIZE=98304 + ${args_OPTIONS} + ) + + if ("${Halide_TARGET}" MATCHES "webgpu") + set(EMCC_FLAGS + ${EMCC_FLAGS} + -s USE_WEBGPU=1 + -s ASYNCIFY + ) + endif () + + set(SRCS) + foreach (S IN LISTS args_SRCS) + list(APPEND SRCS "${CMAKE_CURRENT_SOURCE_DIR}/${S}") + endforeach () + + set(INCLUDES) + foreach (I IN LISTS args_INCLUDES) + list(APPEND INCLUDES "-I${I}") + endforeach () + + set(DEPS) + foreach (D IN LISTS args_DEPS) + list(APPEND DEPS $) + endforeach () + + add_custom_command(OUTPUT "${TARGET}.wasm" "${TARGET}.js" + COMMAND ${EMCC} ${EMCC_FLAGS} ${INCLUDES} ${SRCS} ${DEPS} -o "${TARGET}.js" + DEPENDS ${SRCS} ${DEPS} + VERBATIM) + + add_custom_target("${TARGET}" ALL + DEPENDS "${TARGET}.wasm" "${TARGET}.js") + +endfunction() + +function(add_wasm_halide_test TARGET) + set(options) + set(oneValueArgs) + set(multiValueArgs GROUPS ENABLE_IF) + cmake_parse_arguments(args "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if (args_ENABLE_IF AND NOT (${args_ENABLE_IF})) + return() + endif () + + find_package(NodeJS 16.13 REQUIRED) + add_halide_test( + "${TARGET}" + GROUPS ${args_GROUPS} + COMMAND "${NodeJS_EXECUTABLE}" "${Halide_SOURCE_DIR}/tools/launch_wasm_test.js" "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.js" "${Halide_TARGET}" + ) +endfunction() + # Emit two halide_library targets, one with the default backend with the given name, # and (optionally) one with the C++ backend with the name NAME_cpp. (The CPP one defaults to being # emitted, but can be skipped if OMIT_C_BACKEND is specified.) From a90bb76612be79681f7f1b088f13e0029e3ad623 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Thu, 8 Aug 2024 00:20:11 -0400 Subject: [PATCH 2/4] Add deprecation notices to WITH_WABT/V8 --- src/CMakeLists.txt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 874c16b4f8a4..76447231f2f7 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -573,6 +573,19 @@ if (TARGET_WEBASSEMBLY) CACHE STRING "Which backend to use for Halide's WASM testing.") set_property(CACHE Halide_WASM_BACKEND PROPERTY STRINGS "wabt;V8;OFF") + if (WITH_WABT AND NOT WITH_V8) + message(DEPRECATION "WITH_WABT has been replaced by Halide_WASM_BACKEND=\"wabt\"") + set(Halide_WASM_BACKEND "wabt") + elseif (NOT WITH_WABT AND WITH_V8) + message(DEPRECATION "WITH_V8 has been replaced by Halide_WASM_BACKEND=\"V8\"") + set(Halide_WASM_BACKEND "V8") + elseif (WITH_WABT AND WITH_V8) + message(FATAL_ERROR "Cannot enable both wabt and V8 simultaneously.") + elseif (DEFINED WITH_WABT AND DEFINED WITH_V8 AND NOT WITH_WABT AND NOT WITH_V8) + message(DEPRECATION "Disabling both WITH_WABT and WITH_V8 has been replaced by Halide_WASM_BACKEND=\"OFF\"") + set(Halide_WASM_BACKEND "OFF") + endif () + if (Halide_WASM_BACKEND STREQUAL "wabt") set(WABT_VER 1.0.33) From dea6b5beec3b811088fd263749f447137c9dda12 Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Thu, 8 Aug 2024 08:17:38 -0400 Subject: [PATCH 3/4] Disable wabt on Windows --- src/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 76447231f2f7..ce22fbf65990 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -580,12 +580,17 @@ if (TARGET_WEBASSEMBLY) message(DEPRECATION "WITH_V8 has been replaced by Halide_WASM_BACKEND=\"V8\"") set(Halide_WASM_BACKEND "V8") elseif (WITH_WABT AND WITH_V8) - message(FATAL_ERROR "Cannot enable both wabt and V8 simultaneously.") + message(FATAL_ERROR "Cannot use both WABT and V8 at the same time, disable one of them.") elseif (DEFINED WITH_WABT AND DEFINED WITH_V8 AND NOT WITH_WABT AND NOT WITH_V8) message(DEPRECATION "Disabling both WITH_WABT and WITH_V8 has been replaced by Halide_WASM_BACKEND=\"OFF\"") set(Halide_WASM_BACKEND "OFF") endif () + if (MSVC AND Halide_WASM_BACKEND STREQUAL "wabt") + message(WARNING "wabt is not yet supported on Windows") + set(Halide_WASM_BACKEND "OFF") + endif () + if (Halide_WASM_BACKEND STREQUAL "wabt") set(WABT_VER 1.0.33) From e29944d857b20080f835dfd4b255cfc82176aeab Mon Sep 17 00:00:00 2001 From: Alex Reinking Date: Thu, 8 Aug 2024 00:26:27 -0400 Subject: [PATCH 4/4] Update README_cmake.md --- README_cmake.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README_cmake.md b/README_cmake.md index 6b075646da7f..60adfc76d61d 100644 --- a/README_cmake.md +++ b/README_cmake.md @@ -458,9 +458,9 @@ The following options enable/disable various Halide-specific backends: The following options are WebAssembly-specific. They only apply when `TARGET_WEBASSEMBLY=ON`: -| Option | Default | Description | -|-------------|---------|-------------------------------------------| -| `WITH_WABT` | `ON` | Include WABT Interpreter for WASM testing | +| Option | Default | Description | +|-----------------------|---------|------------------------------------------------------------------------------------------| +| `Halide_WASM_BACKEND` | `wabt` | Select the backend for WASM testing. Can be `wabt`, `V8` or a false value such as `OFF`. | ### Find module options