Skip to content

Commit

Permalink
Make apps testable from pip package.
Browse files Browse the repository at this point in the history
  • Loading branch information
alexreinking committed Sep 3, 2024
1 parent c522887 commit f6e093f
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 44 deletions.
16 changes: 9 additions & 7 deletions cmake/HalideGeneratorHelpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ function(add_halide_generator TARGET)
set(stub_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.${GEN_NAME}.${MODULE_NAME}.py_stub_generated.cpp")
file(CONFIGURE OUTPUT "${stub_file}" CONTENT "${stub_text}" @ONLY)

Python3_add_library(${TARGET}_pystub MODULE WITH_SOABI "${stub_file}" ${ARG_SOURCES})
Python_add_library(${TARGET}_pystub MODULE WITH_SOABI "${stub_file}" ${ARG_SOURCES})
set_target_properties(${TARGET}_pystub PROPERTIES
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON
Expand Down Expand Up @@ -398,16 +398,17 @@ function(_Halide_compute_generator_cmd)

# 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.")
message(FATAL_ERROR "Missing Halide::Python. Load the Python component "
"in find_package() or set WITH_PYTHON_BINDINGS=ON if in tree.")
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.")
if (NOT TARGET Python::Interpreter)
message(FATAL_ERROR "Missing Python::Interpreter. Missing call to find_package(Python 3)?")
endif ()

set("${ARG_OUT_COMMAND}"
${CMAKE_COMMAND} -E env "PYTHONPATH=$<PATH:GET_PARENT_PATH,$<TARGET_FILE_DIR:Halide::Python>>" --
${Halide_PYTHON_LAUNCHER} "$<TARGET_FILE:Python3::Interpreter>" $<SHELL_PATH:${py_src}>
${CMAKE_COMMAND} -E env "PYTHONPATH=$<PATH:NORMAL_PATH,$<TARGET_FILE_DIR:Halide::Python>/..>" --
${Halide_PYTHON_LAUNCHER} "$<TARGET_FILE:Python::Interpreter>" $<SHELL_PATH:${py_src}>
PARENT_SCOPE)
set("${ARG_OUT_DEPENDS}" ${ARG_FROM} Halide::Python ${py_src} PARENT_SCOPE)
endfunction()
Expand Down Expand Up @@ -794,14 +795,15 @@ function(add_halide_python_extension_library TARGET)
DEPENDS Halide::GenRT
VERBATIM)

Python3_add_library(${TARGET} MODULE WITH_SOABI ${pycpps} ${pyext_module_definition_src})
Python_add_library(${TARGET} MODULE WITH_SOABI ${pycpps} ${pyext_module_definition_src})
target_link_libraries(${TARGET} PRIVATE ${ARG_HALIDE_LIBRARIES})
target_compile_definitions(${TARGET} PRIVATE
# Skip the default module-definition code in each file
HALIDE_PYTHON_EXTENSION_OMIT_MODULE_DEFINITION
# Gotta explicitly specify the module name and function(s) for this mode
HALIDE_PYTHON_EXTENSION_MODULE_NAME=${ARG_MODULE_NAME}
"HALIDE_PYTHON_EXTENSION_FUNCTIONS=${function_names}")
target_compile_features(${TARGET} PRIVATE cxx_std_17)
set_target_properties(${TARGET} PROPERTIES OUTPUT_NAME ${ARG_MODULE_NAME})
_Halide_target_export_single_symbol(${TARGET} "PyInit_${ARG_MODULE_NAME}")
endfunction()
Expand Down
32 changes: 3 additions & 29 deletions python_bindings/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ cmake_dependent_option(
# Development.Module and Development.Embed. We don't need the Embed
# part, so only requesting Module avoids failures when Embed is not
# available, as is the case in the manylinux Docker images.
find_package(Python3 3.8 REQUIRED Interpreter Development.Module)
find_package(Python 3.8 REQUIRED Interpreter Development.Module)

if (WITH_PYTHON_BINDINGS)
find_package(pybind11 2.10.4 REQUIRED)
Expand All @@ -56,34 +56,8 @@ if (NOT Halide_ENABLE_RTTI OR NOT Halide_ENABLE_EXCEPTIONS)
message(FATAL_ERROR "Python bindings require RTTI and exceptions to be enabled.")
endif ()

##
# A helper for creating tests with correct PYTHONPATH and sanitizer preloading
##

function(add_python_test)
cmake_parse_arguments(ARG "" "FILE;LABEL" "PYTHONPATH;ENVIRONMENT;TEST_ARGS" ${ARGN})

list(PREPEND ARG_PYTHONPATH "$<PATH:GET_PARENT_PATH,$<TARGET_FILE_DIR:Halide::Python>>")
list(TRANSFORM ARG_PYTHONPATH PREPEND "PYTHONPATH=path_list_prepend:")

list(PREPEND ARG_ENVIRONMENT "HL_TARGET=${Halide_TARGET};HL_JIT_TARGET=${Halide_TARGET}")

cmake_path(GET ARG_FILE STEM test_name)
set(test_name "${ARG_LABEL}_${test_name}")

add_test(
NAME "${test_name}"
COMMAND ${Halide_PYTHON_LAUNCHER} "$<TARGET_FILE:Python3::Interpreter>" "$<SHELL_PATH:${CMAKE_CURRENT_SOURCE_DIR}/${ARG_FILE}>" ${ARG_TEST_ARGS}
)
set_tests_properties(
"${test_name}"
PROPERTIES
LABELS "python"
ENVIRONMENT "${ARG_ENVIRONMENT}"
ENVIRONMENT_MODIFICATION "${ARG_PYTHONPATH}"
)
endfunction()

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(AddPythonTest)

##
# Add our sources to this sub-tree.
Expand Down
14 changes: 13 additions & 1 deletion python_bindings/apps/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
cmake_minimum_required(VERSION 3.28)
project(Halide_Python_apps)

if (PROJECT_IS_TOP_LEVEL)
enable_testing()
endif ()

find_package(Halide REQUIRED COMPONENTS Python)

if (Halide_TARGET MATCHES "wasm")
message(WARNING "Python apps are skipped under WASM.")
return()
Expand All @@ -13,6 +22,9 @@ if (NOT WITH_AUTOSCHEDULERS)
return()
endif ()

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
include(AddPythonTest)

set(TEST_TMPDIR "$<SHELL_PATH:${CMAKE_CURRENT_BINARY_DIR}>")
set(TEST_IMAGES_DIR "$<SHELL_PATH:${CMAKE_CURRENT_SOURCE_DIR}/../../apps/images>")

Expand Down Expand Up @@ -53,7 +65,7 @@ foreach (app IN LISTS APPS)
MODULE_NAME ${G}
HALIDE_LIBRARIES app_aot_${G})
list(APPEND DEPS app_ext_${G})
endforeach()
endforeach ()

set(app_src "${app}_app.py")
add_python_test(
Expand Down
27 changes: 27 additions & 0 deletions python_bindings/cmake/AddPythonTest.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
##
# A helper for creating tests with correct PYTHONPATH and sanitizer preloading
##

function(add_python_test)
cmake_parse_arguments(ARG "" "FILE;LABEL" "PYTHONPATH;ENVIRONMENT;TEST_ARGS" ${ARGN})

list(PREPEND ARG_PYTHONPATH "$<PATH:NORMAL_PATH,$<TARGET_FILE_DIR:Halide::Python>/..>")
list(TRANSFORM ARG_PYTHONPATH PREPEND "PYTHONPATH=path_list_prepend:")

list(PREPEND ARG_ENVIRONMENT "HL_TARGET=${Halide_TARGET};HL_JIT_TARGET=${Halide_TARGET}")

cmake_path(GET ARG_FILE STEM test_name)
set(test_name "${ARG_LABEL}_${test_name}")

add_test(
NAME "${test_name}"
COMMAND ${Halide_PYTHON_LAUNCHER} "$<TARGET_FILE:Python::Interpreter>" "$<SHELL_PATH:${CMAKE_CURRENT_SOURCE_DIR}/${ARG_FILE}>" ${ARG_TEST_ARGS}
)
set_tests_properties(
"${test_name}"
PROPERTIES
LABELS "python"
ENVIRONMENT "${ARG_ENVIRONMENT}"
ENVIRONMENT_MODIFICATION "${ARG_PYTHONPATH}"
)
endfunction()
3 changes: 3 additions & 0 deletions python_bindings/packaging/Halide_PythonConfig.cmake.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
cmake_minimum_required(VERSION 3.28)
@PACKAGE_INIT@

include(CMakeFindDependencyMacro)
find_dependency(Python 3 COMPONENTS Interpreter Development.Module)

include("${CMAKE_CURRENT_LIST_DIR}/Halide_Python-targets.cmake")

check_required_components(${CMAKE_FIND_PACKAGE_NAME})
8 changes: 4 additions & 4 deletions python_bindings/tutorial/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ set(tests
lesson_12_using_the_gpu.py
lesson_13_tuples.py
lesson_14_types.py
)
)

set(PYPATH_lesson_10_aot_compilation_run "$<TARGET_FILE_DIR:lesson_10_halide>")

Expand Down Expand Up @@ -64,9 +64,9 @@ else ()

# This target allows CMake to build lesson_10_halide.so (or whatever the correct extension is) as part of the tests
# later. It is excluded from ALL since it isn't valid to build outside of this context.
Python3_add_library(lesson_10_halide MODULE EXCLUDE_FROM_ALL
lesson_10_halide.py.cpp
lesson_10_halide.o)
Python_add_library(lesson_10_halide MODULE EXCLUDE_FROM_ALL
lesson_10_halide.py.cpp
lesson_10_halide.o)

target_link_libraries(lesson_10_halide PRIVATE Halide::Runtime)

Expand Down
6 changes: 3 additions & 3 deletions test/autoschedulers/li2018/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ if (WITH_PYTHON_BINDINGS)
if (Halide_TARGET MATCHES "webgpu")
message(WARNING "li2018_gradient_autoscheduler_test_py is not supported with WebGPU.")
else()
find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module)
find_package(Python 3.8 REQUIRED COMPONENTS Interpreter Development.Module)

add_test(
NAME li2018_gradient_autoscheduler_test_py
COMMAND ${Halide_PYTHON_LAUNCHER} "$<TARGET_FILE:Python3::Interpreter>" "${CMAKE_CURRENT_SOURCE_DIR}/test.py" $<TARGET_FILE:Halide::Li2018>
COMMAND ${Halide_PYTHON_LAUNCHER} "$<TARGET_FILE:Python::Interpreter>" "${CMAKE_CURRENT_SOURCE_DIR}/test.py" $<TARGET_FILE:Halide::Li2018>
)

set(PYTHONPATH "$<PATH:GET_PARENT_PATH,$<TARGET_FILE_DIR:Halide::Python>>")
set(PYTHONPATH "$<PATH:NORMAL_PATH,$<TARGET_FILE_DIR:Halide::Python>/..>")
list(TRANSFORM PYTHONPATH PREPEND "PYTHONPATH=path_list_prepend:")

set_tests_properties(li2018_gradient_autoscheduler_test_py PROPERTIES
Expand Down

0 comments on commit f6e093f

Please sign in to comment.