Skip to content

Commit

Permalink
Distribute GenGen as a static library (#8367)
Browse files Browse the repository at this point in the history
Also use a mutex and timestamp checking to ensure that
multiple generators in the same directory do not race
to place Halide.dll next to them on Windows.
  • Loading branch information
alexreinking authored Aug 6, 2024
1 parent 1a7b914 commit 37ab461
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 46 deletions.
37 changes: 17 additions & 20 deletions apps/hexagon_benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,32 @@ enable_testing()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS NO)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")

# Find Halide
find_package(Halide REQUIRED)

macro(add_generator_and_library FILTER_NAME)
set(GENERATOR_EXE ${FILTER_NAME}.generator)
set(GENERATOR_SRC ${FILTER_NAME}_generator.cpp)
add_halide_generator(${GENERATOR_EXE} SOURCES ${GENERATOR_SRC})
add_halide_library(${FILTER_NAME} FROM ${GENERATOR_EXE})
endmacro()
# Add Halide libraries
add_halide_generator(dilate3x3.generator SOURCES dilate3x3_generator.cpp)
add_halide_library(dilate3x3 FROM dilate3x3.generator)

add_halide_generator(gaussian5x5.generator SOURCES gaussian5x5_generator.cpp)
add_halide_library(gaussian5x5 FROM gaussian5x5.generator)

add_generator_and_library(dilate3x3)
add_generator_and_library(gaussian5x5)
add_generator_and_library(median3x3)
add_generator_and_library(sobel)
add_halide_generator(median3x3.generator SOURCES median3x3_generator.cpp)
add_halide_library(median3x3 FROM median3x3.generator)

add_halide_generator(sobel.generator SOURCES sobel_generator.cpp)
add_halide_library(sobel FROM sobel.generator)

# Main executable
add_executable(process process.cpp)
target_compile_options(process PRIVATE $<$<CXX_COMPILER_ID:GNU,Clang,AppleClang>:-O2>)
target_compile_definitions(process PRIVATE DILATE3X3 GAUSSIAN5X5 MEDIAN3X3 SOBEL)
target_link_libraries(process PRIVATE Halide::Tools dilate3x3 gaussian5x5 median3x3 sobel)

if (Halide_TARGET MATCHES "hvx")
target_compile_definitions(process PRIVATE DILATE3X3 GAUSSIAN5X5 MEDIAN3X3 SOBEL TARGET_HAS_HVX)
else()
target_compile_definitions(process PRIVATE DILATE3X3 GAUSSIAN5X5 MEDIAN3X3 SOBEL)
endif()
target_link_libraries(process
PRIVATE
Halide::Tools
dilate3x3 gaussian5x5 median3x3 sobel)
target_compile_definitions(process PRIVATE TARGET_HAS_HVX)
endif ()

# Test that the app actually works!
add_test(NAME hexagon_benchmarks COMMAND process -n 1)
Expand Down
50 changes: 29 additions & 21 deletions cmake/HalideGeneratorHelpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ function(add_halide_generator TARGET)
list(LENGTH ARG_SOURCES len)
if (NOT len EQUAL 1)
message(FATAL_ERROR "Python Generators must specify exactly one source file.")
endif()
endif ()

# Make a fake target here that we can attach the Python source to,
# so that we can extract 'em in add_halide_library()
Expand All @@ -102,7 +102,8 @@ function(add_halide_generator TARGET)
# we *want* deprecation warnings to be propagated. So we must set
# NO_SYSTEM_FROM_IMPORTED in order for it to be seen.
set_target_properties(${TARGET} PROPERTIES NO_SYSTEM_FROM_IMPORTED YES)
target_compile_options(${TARGET} PRIVATE
target_compile_options(
${TARGET} PRIVATE
$<$<CXX_COMPILER_ID:GNU,Clang,AppleClang>:-Wdeprecated-declarations>
$<$<CXX_COMPILER_ID:MSVC>:/w14996> # 4996: compiler encountered deprecated declaration
)
Expand All @@ -128,7 +129,7 @@ function(add_halide_generator TARGET)
set(stub_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.${GEN_NAME}.${MODULE_NAME}.py_stub_generated.cpp")
if (NOT EXISTS "${stub_file}")
file(WRITE "${stub_file}" "${stub_text}")
endif()
endif ()

Python3_add_library(${TARGET}_pystub MODULE WITH_SOABI "${stub_file}" ${ARG_SOURCES})
set_target_properties(${TARGET}_pystub PROPERTIES
Expand Down Expand Up @@ -236,15 +237,15 @@ function(add_halide_library TARGET)
message(FATAL_ERROR "Unable to locate FROM as either ${ARG_FROM} or ${FQ_ARG_FROM}")
endif ()
set(ARG_FROM "${FQ_ARG_FROM}")
endif()
endif ()

get_property(py_src TARGET ${ARG_FROM} PROPERTY Halide_PYTHON_GENERATOR_SOURCE)
if (py_src)
# TODO: Python Generators need work to support crosscompiling (https://github.com/halide/Halide/issues/7014)
if (NOT TARGET Halide::Python)
message(FATAL_ERROR "This version of Halide was built without support for Python bindings; rebuild using WITH_PYTHON_BINDINGS=ON to use this rule with Python Generators.")
endif ()

if (NOT TARGET Python3::Interpreter)
message(FATAL_ERROR "You must call find_package(Python3) in your CMake code in order to use this rule with Python Generators.")
endif ()
Expand All @@ -262,11 +263,11 @@ function(add_halide_library TARGET)
"$<TARGET_FILE:Python3::Interpreter>" $<SHELL_PATH:${py_src}>
)
set(GENERATOR_CMD_DEPS ${ARG_FROM} Halide::Python ${py_src})
else()
else ()
set(GENERATOR_CMD "${ARG_FROM}")
set(GENERATOR_CMD_DEPS ${ARG_FROM})
_Halide_place_dll(${ARG_FROM})
endif()
endif ()

if (ARG_C_BACKEND)
if (ARG_USE_RUNTIME)
Expand Down Expand Up @@ -348,10 +349,10 @@ function(add_halide_library TARGET)
##

_Halide_get_platform_details(
is_crosscompiling
object_suffix
static_library_suffix
${ARG_TARGETS})
is_crosscompiling
object_suffix
static_library_suffix
${ARG_TARGETS})

# Always emit a C header
set(generator_outputs c_header)
Expand Down Expand Up @@ -428,7 +429,8 @@ function(add_halide_library TARGET)
LINKER_LANGUAGE CXX)
if (NOT Halide_NO_DEFAULT_FLAGS)
# Silence many useless warnings in generated C++ code compilation
target_compile_options("${TARGET}" PRIVATE
target_compile_options(
"${TARGET}" PRIVATE
$<$<CXX_COMPILER_ID:GNU,Clang,AppleClang>:-Wno-psabi>)
endif ()
_Halide_fix_xcode("${TARGET}")
Expand Down Expand Up @@ -571,8 +573,14 @@ function(_Halide_place_dll GEN)
return()
endif ()

add_custom_command(TARGET ${GEN} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Halide::Halide> $<TARGET_FILE_DIR:${GEN}>)
add_custom_command(
TARGET ${GEN} POST_BUILD
COMMAND powershell -NoProfile -ExecutionPolicy Bypass
-File "${CMAKE_CURRENT_FUNCTION_LIST_DIR}/MutexCopy.ps1"
-src "$<TARGET_FILE:Halide::Halide>"
-dstDir "$<TARGET_FILE_DIR:${GEN}>"
VERBATIM
)
set_property(TARGET ${GEN} PROPERTY Halide_GENERATOR_HAS_POST_BUILD 1)
endfunction()

Expand Down Expand Up @@ -605,8 +613,8 @@ function(add_halide_runtime RT)
get_target_property(aliased ${ARG_FROM} ALIASED_TARGET)
if (target_type STREQUAL "EXECUTABLE" AND NOT aliased)
add_executable(_Halide_gengen ALIAS ${ARG_FROM})
endif()
endif()
endif ()
endif ()

# The default of NO_THREADS/NO_DL_LIBS is OFF unless Halide_RUNTIME_NO_THREADS/NO_DL_LIBS is defined globally
if (NOT DEFINED ARG_NO_THREADS)
Expand All @@ -620,10 +628,10 @@ function(add_halide_runtime RT)
_Halide_gengen_ensure()

_Halide_get_platform_details(
is_crosscompiling
object_suffix
static_library_suffix
${ARG_TARGETS})
is_crosscompiling
object_suffix
static_library_suffix
${ARG_TARGETS})

if (is_crosscompiling)
set(GEN_OUTS "${RT}${static_library_suffix}")
Expand Down Expand Up @@ -746,7 +754,7 @@ function(_Halide_target_export_single_symbol TARGET SYMBOL)
file(WRITE
"${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.${SYMBOL}.ldscript.apple"
"_${SYMBOL}\n")
endif()
endif ()
if (NOT EXISTS "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.${SYMBOL}.ldscript")
file(WRITE
"${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.${SYMBOL}.ldscript"
Expand Down
31 changes: 31 additions & 0 deletions cmake/MutexCopy.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
param([string]$src, [string]$dstDir)

try {
$bytes = [System.Text.Encoding]::UTF8.GetBytes($dstDir)
$hash = [System.Security.Cryptography.SHA512]::Create().ComputeHash($bytes)
$key = "Halide-" + ([Convert]::ToBase64String($hash) -replace ('/', '-'))

$m = New-Object System.Threading.Mutex($false, $key)
if (!$m) {
throw "Failed to create mutex $key"
}

$m.WaitOne() | Out-Null

$name = Split-Path $src -leaf
$dst = Join-Path $dstDir $name
if (Test-Path $dst) {
$srcTime = (Get-Item $src).LastWriteTime
$dstTime = (Get-Item $dst).LastWriteTime
if ($dstTime -ge $srcTime) {
Return
}
}

Copy-Item $src $dstDir
} finally {
if ($m) {
$m.ReleaseMutex() | Out-Null
$m.Dispose() | Out-Null
}
}
5 changes: 2 additions & 3 deletions packaging/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ set(Halide_INSTALL_TOOLSDIR "${CMAKE_INSTALL_DATADIR}/tools"
# Main library exports
##

target_sources(Halide_Generator INTERFACE $<INSTALL_INTERFACE:${Halide_INSTALL_TOOLSDIR}/GenGen.cpp>)

install(TARGETS Halide Halide_Generator Halide_LanguageOptions
install(TARGETS Halide Halide_Generator Halide_GenGen Halide_LanguageOptions
EXPORT Halide_Targets
RUNTIME COMPONENT Halide_Runtime
LIBRARY COMPONENT Halide_Runtime
Expand Down Expand Up @@ -216,6 +214,7 @@ install(FILES
${Halide_SOURCE_DIR}/cmake/FindHalide_WebGPU.cmake
${Halide_SOURCE_DIR}/cmake/HalideTargetHelpers.cmake
${Halide_SOURCE_DIR}/cmake/TargetExportScript.cmake
${Halide_SOURCE_DIR}/cmake/MutexCopy.ps1
DESTINATION ${Halide_INSTALL_HELPERSDIR}
COMPONENT Halide_Development)

Expand Down
12 changes: 10 additions & 2 deletions tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,20 @@ target_sources(Halide_RunGenMain INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOU
target_link_libraries(Halide_RunGenMain INTERFACE Halide::Runtime Halide::ImageIO Halide::Tools)
set_target_properties(Halide_RunGenMain PROPERTIES EXPORT_NAME RunGenMain)

add_library(Halide_GenGen STATIC GenGen.cpp)
add_library(Halide::GenGen ALIAS Halide_GenGen)
set_target_properties(Halide_GenGen PROPERTIES EXPORT_NAME GenGen)

target_link_libraries(Halide_GenGen PUBLIC Halide::Halide ${CMAKE_DL_LIBS})

add_library(Halide_Generator INTERFACE)
add_library(Halide::Generator ALIAS Halide_Generator)
target_sources(Halide_Generator INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/GenGen.cpp>)
target_link_libraries(Halide_Generator INTERFACE Halide::Halide ${CMAKE_DL_LIBS})
set_target_properties(Halide_Generator PROPERTIES EXPORT_NAME Generator)

target_link_libraries(
Halide_Generator INTERFACE "$<LINK_LIBRARY:WHOLE_ARCHIVE,Halide::GenGen>"
)

add_library(Halide_Tools INTERFACE)
add_library(Halide::Tools ALIAS Halide_Tools)
target_include_directories(Halide_Tools INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>)
Expand Down

0 comments on commit 37ab461

Please sign in to comment.