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

Add helper for cross-compiling Halide generators. #6366

Merged
merged 2 commits into from
Nov 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
127 changes: 36 additions & 91 deletions apps/hannk/halide/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,45 +1,3 @@
add_custom_target(hannk-halide_generators)

# This function adds the target ${TARGET} to the hannk-halide_generators
# CMake package that exists in the build-tree of a host build. It also adds
# it to the target of the same name that can be used as a convenience for
# just building the host targets.
function(_export_host_target TARGET)
add_dependencies(hannk-halide_generators ${TARGET})
export(TARGETS ${TARGET}
NAMESPACE hannk::halide_generators::
APPEND FILE "${hannk_BINARY_DIR}/hannk-halide_generators-config.cmake")
endfunction()

# Emscripten tries to disable finding packages outside its sysroot,
# but we need our native generators. Setting CMAKE_FIND_ROOT_PATH_BOTH
# here overrides Emscripten's search preference.
find_package(hannk-halide_generators QUIET CMAKE_FIND_ROOT_PATH_BOTH)

if (hannk-halide_generators_FOUND)
message(STATUS "Using hannk-halide_generators from ${hannk-halide_generators_DIR}")
else ()
if (CMAKE_CROSSCOMPILING)
message(WARNING
"hannk-halide_generators were not found and it looks like you are cross-compiling. "
"This is likely to fail. Please set -Dhannk-halide_generators_ROOT=... at the CMake "
"command line to the build directory of a host-built hannk.")
endif ()
find_package(Halide REQUIRED)
endif ()

if (NOT TARGET hannk::halide_generators::common_halide)
add_library(common_halide STATIC common_halide.cpp)
add_library(hannk::halide_generators::common_halide ALIAS common_halide)

target_link_libraries(common_halide PRIVATE Halide::Halide)
target_include_directories(common_halide PUBLIC $<BUILD_INTERFACE:${hannk_SOURCE_DIR}>)

_export_host_target(common_halide)
endif ()

# ----------------------------

function(_begin_halide_library_set LIBRARY_SET)
add_library(${LIBRARY_SET} INTERFACE)
target_include_directories(${LIBRARY_SET} INTERFACE "$<BUILD_INTERFACE:${hannk_BINARY_DIR}>")
Expand All @@ -50,22 +8,16 @@ endfunction()
function(_add_halide_library_set LIBRARY_SET)
set(options)
set(oneValueArgs TARGET GENERATOR_NAME)
set(multiValueArgs SRCS GENERATOR_ARGS GENERATOR_DEPS FEATURES)
set(multiValueArgs SRCS GENERATOR_ARGS FEATURES)
cmake_parse_arguments(args "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

set(gen hannk::halide_generators::${args_TARGET}.generator)

if (NOT TARGET ${gen})
add_executable(${args_TARGET}.generator ${args_SRCS})
add_executable(${gen} ALIAS ${args_TARGET}.generator)

target_link_libraries(${args_TARGET}.generator PRIVATE ${args_GENERATOR_DEPS} common_halide Halide::Generator)
target_include_directories(${args_TARGET}.generator PUBLIC $<BUILD_INTERFACE:${hannk_SOURCE_DIR}>)

_export_host_target(${args_TARGET}.generator)
add_halide_generator(${args_TARGET}.generator ${args_SRCS})
if (TARGET ${args_TARGET}.generator)
target_link_libraries(${args_TARGET}.generator PRIVATE common_halide)
target_include_directories(${args_TARGET}.generator PRIVATE $<BUILD_INTERFACE:${hannk_SOURCE_DIR}>)
endif ()

add_halide_library(${args_TARGET} FROM ${gen}
add_halide_library(${args_TARGET} FROM hannk::halide_generators::${args_TARGET}.generator
NAMESPACE hannk
GENERATOR ${args_GENERATOR_NAME}
FEATURES c_plus_plus_name_mangling ${args_FEATURES}
Expand All @@ -76,7 +28,18 @@ function(_add_halide_library_set LIBRARY_SET)
endfunction()

function(_finish_halide_library_set LIBRARY_SET)
# Nothing to do for now.
# Create common sources target if it wasn't imported by add_halide_generator above.
if (NOT TARGET hannk::halide_generators::common_halide)
add_library(common_halide STATIC common_halide.cpp)
add_library(hannk::halide_generators::common_halide ALIAS common_halide)

target_link_libraries(common_halide PRIVATE Halide::Halide)
target_include_directories(common_halide PUBLIC $<BUILD_INTERFACE:${hannk_SOURCE_DIR}>)

export(TARGETS common_halide
NAMESPACE hannk::halide_generators::
APPEND FILE "${hannk_BINARY_DIR}/cmake/hannk-halide_generators-config.cmake")
endif ()
endfunction()

# ---------------------------
Expand All @@ -88,134 +51,116 @@ _add_halide_library_set(halide_op_implementations
SRCS elementwise_generator.cpp
FEATURES no_bounds_query
GENERATOR_NAME Add
GENERATOR_ARGS
GENERATOR_DEPS)
GENERATOR_ARGS)

_add_halide_library_set(halide_op_implementations
TARGET average_pool_uint8
SRCS pool_generator.cpp
GENERATOR_NAME AveragePool
GENERATOR_ARGS
GENERATOR_DEPS)
GENERATOR_ARGS)

_add_halide_library_set(halide_op_implementations
TARGET conv_u8_u8_u8
SRCS conv_generator.cpp
GENERATOR_NAME Conv
GENERATOR_ARGS output.type=uint8
GENERATOR_DEPS)
GENERATOR_ARGS output.type=uint8)

_add_halide_library_set(halide_op_implementations
TARGET conv_u8_u8_i16
SRCS conv_generator.cpp
GENERATOR_NAME Conv
GENERATOR_ARGS output.type=int16
GENERATOR_DEPS)
GENERATOR_ARGS output.type=int16)

_add_halide_library_set(halide_op_implementations
TARGET copy_uint8_uint8
SRCS copy_generator.cpp
FEATURES no_bounds_query
GENERATOR_NAME Copy
GENERATOR_ARGS input.type=uint8 output.type=uint8
GENERATOR_DEPS)
GENERATOR_ARGS input.type=uint8 output.type=uint8)

_add_halide_library_set(halide_op_implementations
TARGET depthwise_conv_uint8
SRCS depthwise_conv_generator.cpp
GENERATOR_NAME DepthwiseConv
GENERATOR_ARGS inv_depth_multiplier=1
GENERATOR_DEPS)
GENERATOR_ARGS inv_depth_multiplier=1)

_add_halide_library_set(halide_op_implementations
TARGET depthwise_conv_broadcast_uint8
SRCS depthwise_conv_generator.cpp
GENERATOR_NAME DepthwiseConv
GENERATOR_ARGS inv_depth_multiplier=0
GENERATOR_DEPS)
GENERATOR_ARGS inv_depth_multiplier=0)

_add_halide_library_set(halide_op_implementations
TARGET depthwise_conv_shallow_uint8
SRCS depthwise_conv_generator.cpp
GENERATOR_NAME DepthwiseConv
GENERATOR_ARGS inv_depth_multiplier=1 shallow=true
GENERATOR_DEPS)
GENERATOR_ARGS inv_depth_multiplier=1 shallow=true)

_add_halide_library_set(halide_op_implementations
TARGET fill_uint8
SRCS fill_generator.cpp
FEATURES no_bounds_query no_asserts
GENERATOR_NAME Fill
GENERATOR_ARGS
GENERATOR_DEPS)
GENERATOR_ARGS)

_add_halide_library_set(halide_op_implementations
TARGET elementwise_5xuint8_1xuint8
SRCS elementwise_generator.cpp
FEATURES no_bounds_query
GENERATOR_NAME Elementwise
GENERATOR_ARGS inputs.size=5 inputs.type=uint8 output1_type=uint8
GENERATOR_DEPS)
GENERATOR_ARGS inputs.size=5 inputs.type=uint8 output1_type=uint8)

_add_halide_library_set(halide_op_implementations
TARGET elementwise_5xint16_1xuint8int16
SRCS elementwise_generator.cpp
FEATURES no_bounds_query
GENERATOR_NAME Elementwise
GENERATOR_ARGS inputs.size=5 inputs.type=int16 output1_type=uint8 output2_type=int16
GENERATOR_DEPS)
GENERATOR_ARGS inputs.size=5 inputs.type=int16 output1_type=uint8 output2_type=int16)

_add_halide_library_set(halide_op_implementations
TARGET l2_normalization_uint8
SRCS normalizations_generator.cpp
FEATURES no_bounds_query
GENERATOR_NAME L2Normalization
GENERATOR_ARGS
GENERATOR_DEPS)
GENERATOR_ARGS)

_add_halide_library_set(halide_op_implementations
TARGET max_pool_uint8
SRCS pool_generator.cpp
GENERATOR_NAME MaxPool
GENERATOR_ARGS
GENERATOR_DEPS)
GENERATOR_ARGS)

_add_halide_library_set(halide_op_implementations
TARGET mean_uint8
SRCS reductions_generator.cpp
GENERATOR_NAME Mean
GENERATOR_ARGS
GENERATOR_DEPS)
GENERATOR_ARGS)

_add_halide_library_set(halide_op_implementations
TARGET mul_uint8_uint8_uint8
SRCS elementwise_generator.cpp
FEATURES no_bounds_query
GENERATOR_NAME Mul
GENERATOR_ARGS
GENERATOR_DEPS)
GENERATOR_ARGS)

_add_halide_library_set(halide_op_implementations
TARGET softmax_uint8
SRCS normalizations_generator.cpp
FEATURES no_bounds_query
GENERATOR_NAME Softmax
GENERATOR_ARGS
GENERATOR_DEPS)
GENERATOR_ARGS)

_add_halide_library_set(halide_op_implementations
TARGET tile_conv_filter_uint8
SRCS conv_generator.cpp
GENERATOR_NAME TileConvFilter
GENERATOR_ARGS
GENERATOR_DEPS)
GENERATOR_ARGS)

_add_halide_library_set(halide_op_implementations
TARGET upsample_channels_uint8
SRCS depthwise_conv_generator.cpp
GENERATOR_NAME UpsampleChannels
GENERATOR_ARGS
GENERATOR_DEPS)
GENERATOR_ARGS)

_finish_halide_library_set(halide_op_implementations)

84 changes: 84 additions & 0 deletions cmake/HalideGeneratorHelpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,90 @@ define_property(TARGET PROPERTY Halide_GENERATOR_HAS_POST_BUILD
BRIEF_DOCS "On a Halide generator target, true if Halide.dll copy command has already been added."
FULL_DOCS "On a Halide generator target, true if Halide.dll copy command has already been added.")

##
# Function to simplify writing the CMake rules for creating a generator executable
# that follows our recommended cross-compiling workflow.
##

function(add_halide_generator TARGET)
set(options "")
set(oneValueArgs PACKAGE_NAME PACKAGE_NAMESPACE EXPORT_FILE)
set(multiValueArgs SOURCES)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

if (NOT ARG_PACKAGE_NAME)
set(ARG_PACKAGE_NAME "${PROJECT_NAME}-halide_generators")
endif ()

if (NOT ARG_PACKAGE_NAMESPACE)
set(ARG_PACKAGE_NAMESPACE "${PROJECT_NAME}::halide_generators::")
endif ()

if (NOT ARG_EXPORT_FILE)
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/cmake")
set(ARG_EXPORT_FILE "${PROJECT_BINARY_DIR}/cmake/${ARG_PACKAGE_NAME}-config.cmake")
endif ()

if (NOT ARG_SOURCES)
set(ARG_SOURCES "${ARG_UNPARSED_ARGUMENTS}")
endif ()

_Halide_try_load_generators()

# Communicate found information to the caller
set(${ARG_PACKAGE_NAME}_FOUND "${${ARG_PACKAGE_NAME}_FOUND}" PARENT_SCOPE)

set(gen "${ARG_PACKAGE_NAMESPACE}${TARGET}")
if (NOT TARGET "${gen}")
if (NOT TARGET "${ARG_PACKAGE_NAME}")
add_custom_target("${ARG_PACKAGE_NAME}")
endif ()

if (NOT Halide_FOUND)
find_package(Halide REQUIRED)
endif ()

add_executable(${TARGET} ${ARG_SOURCES})
add_executable(${gen} ALIAS ${TARGET})
target_link_libraries(${TARGET} PRIVATE Halide::Generator)

add_dependencies("${ARG_PACKAGE_NAME}" ${TARGET})
export(TARGETS ${TARGET}
NAMESPACE ${ARG_PACKAGE_NAMESPACE}
APPEND FILE "${ARG_EXPORT_FILE}")
endif ()
endfunction()

# NOTE: this function must only be called by add_halide_generator
# since it reads from its scope.
function(_Halide_try_load_generators)
# Don't repeatedly run the search for the tools package.
if (NOT DEFINED ${ARG_PACKAGE_NAME}_FOUND)
# Some toolchains, like Emscripten, try to disable finding packages
# outside their sysroots, but we always want to find the native
# generators. Setting CMAKE_FIND_ROOT_PATH_BOTH here overrides
# the toolchain search preference. This is okay since a user can
# always override this call by setting ${ARG_PACKAGE_NAME}_ROOT.
find_package(${ARG_PACKAGE_NAME} QUIET
CMAKE_FIND_ROOT_PATH_BOTH)

# Communicate found information to the caller
set(${ARG_PACKAGE_NAME}_FOUND "${${ARG_PACKAGE_NAME}_FOUND}" PARENT_SCOPE)

if (NOT ${ARG_PACKAGE_NAME}_FOUND AND CMAKE_CROSSCOMPILING)
message(WARNING
"${ARG_PACKAGE_NAME} were not found and it looks like you are cross-compiling. "
"This is likely to fail. Please set -D${ARG_PACKAGE_NAME}_ROOT=... at the CMake "
"command line to the build directory of a host-built ${PROJECT_NAME}.")
endif ()
endif ()
endfunction()

##
# Function to simplify writing the CMake rules for invoking a generator executable
# and getting a usable CMake library out of it.
##

function(add_halide_library TARGET)
##
# Set up argument parsing for extra outputs.
Expand Down
2 changes: 1 addition & 1 deletion test/integration/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ if (CMAKE_HOST_SYSTEM_NAME MATCHES "Linux")
--build-options
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_CURRENT_LIST_DIR}/../../cmake/toolchain.linux-aarch64.cmake
-DCMAKE_BUILD_TYPE=Release
"-Dxc-generators_ROOT=${CMAKE_CURRENT_BINARY_DIR}/xc-host"
"-Dxc-halide_generators_ROOT=${CMAKE_CURRENT_BINARY_DIR}/xc-host"
--test-command ${CMAKE_CTEST_COMMAND} --output-on-failure)

set_tests_properties(cross_compile_host PROPERTIES FIXTURES_SETUP xc-host)
Expand Down
17 changes: 11 additions & 6 deletions test/integration/xc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ project(xc)

enable_testing()

if (CMAKE_CROSSCOMPILING)
find_package(xc-generators REQUIRED)
else ()
add_subdirectory(generators)
endif ()
# Only need the platform-independent / source-only helpers.
find_package(HalideHelpers REQUIRED)

add_subdirectory(add)
add_halide_generator(add_gen add.cpp)
add_halide_library(add FROM xc::halide_generators::add_gen
REGISTRATION add_reg_cpp)

add_executable(run_add ${add_reg_cpp})
target_link_libraries(run_add PRIVATE add Halide::RunGenMain)

add_test(NAME run_add
COMMAND run_add --output_extents=[10,10] --benchmarks=all)
File renamed without changes.
13 changes: 0 additions & 13 deletions test/integration/xc/add/CMakeLists.txt

This file was deleted.

Loading