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

Get the ASAN toolchain working again #7604

Merged
merged 12 commits into from
Jun 23, 2023
7 changes: 6 additions & 1 deletion cmake/HalideGeneratorHelpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,12 @@ function(add_halide_library TARGET)
message(FATAL_ERROR "You must call find_package(Python3) in your CMake code in order to use this rule with Python Generators.")
endif ()
set(PYTHONPATH "$<TARGET_FILE_DIR:Halide::Python>/..")
set(GENERATOR_CMD ${CMAKE_COMMAND} -E env PYTHONPATH=${PYTHONPATH} ${Python3_EXECUTABLE} $<SHELL_PATH:${py_src}>)
if (Halide_SHARED_ASAN_RUNTIME_LIBRARY)
# ASAN's Leak detector will report that we leaked all the PyBind11
# Module-support code, so disable it here.
set(EXTRA_ENV_VARS ASAN_OPTIONS=detect_leaks=0 ${Halide_SANITIZER_ENV_VARS})
endif ()
set(GENERATOR_CMD ${CMAKE_COMMAND} -E env PYTHONPATH=${PYTHONPATH} ${EXTRA_ENV_VARS} ${Python3_EXECUTABLE} $<SHELL_PATH:${py_src}>)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is code is part of our downstream package interface, the Halide_SHARED_ASAN_RUNTIME_LIBRARY variable would need to be documented. I think a more flexible design would be to add a Halide_PYTHON_LAUNCHER variable that works like the familiar CMAKE_CXX_COMPILER_LAUNCHER variable.

To implement that, this code would be:

Suggested change
if (Halide_SHARED_ASAN_RUNTIME_LIBRARY)
# ASAN's Leak detector will report that we leaked all the PyBind11
# Module-support code, so disable it here.
set(EXTRA_ENV_VARS ASAN_OPTIONS=detect_leaks=0 ${Halide_SANITIZER_ENV_VARS})
endif ()
set(GENERATOR_CMD ${CMAKE_COMMAND} -E env PYTHONPATH=${PYTHONPATH} ${EXTRA_ENV_VARS} ${Python3_EXECUTABLE} $<SHELL_PATH:${py_src}>)
# TODO: when upgrading to CMake 3.24+ add `--` before `${Halide_PYTHON_LAUNCHER}`
set(GENERATOR_CMD ${CMAKE_COMMAND} -E env PYTHONPATH=${PYTHONPATH} ${Halide_PYTHON_LAUNCHER} ${Python3_EXECUTABLE} $<SHELL_PATH:${py_src}>)

Then, in our toolchain file, we could set:

set(
    Halide_PYTHON_LAUNCHER
    ${CMAKE_COMMAND} -E env ASAN_OPTIONS=detect_leaks=0 LD_PRELOAD=${Halide_SHARED_ASAN_RUNTIME_LIBRARY}
)

set(GENERATOR_CMD_DEPS ${ARG_FROM} Halide::Python ${py_src})
else()
set(GENERATOR_CMD "${ARG_FROM}")
Expand Down
13 changes: 13 additions & 0 deletions cmake/toolchain.linux-x64-asan.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,16 @@ set(CMAKE_CROSSCOMPILING_EMULATOR /usr/bin/env)

# Can't mix -fsanitize=address with -fsanitize=fuzzer
set(WITH_TEST_FUZZ OFF)

if (NOT DEFINED Halide_SHARED_ASAN_RUNTIME_LIBRARY)
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} "-print-file-name=libclang_rt.asan.so"
OUTPUT_VARIABLE Halide_SHARED_ASAN_RUNTIME_LIBRARY
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif ()

set(Halide_SHARED_ASAN_RUNTIME_LIBRARY "${Halide_SHARED_ASAN_RUNTIME_LIBRARY}"
CACHE FILEPATH "Library to preload when running Python tests.")

set(Halide_SANITIZER_ENV_VARS "LD_PRELOAD=${Halide_SHARED_ASAN_RUNTIME_LIBRARY}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
set(Halide_SANITIZER_ENV_VARS "LD_PRELOAD=${Halide_SHARED_ASAN_RUNTIME_LIBRARY}")
set(
Halide_PYTHON_LAUNCHER
${CMAKE_COMMAND} -E env ASAN_OPTIONS=detect_leaks=0 LD_PRELOAD=${Halide_SHARED_ASAN_RUNTIME_LIBRARY}
)

As described above.

24 changes: 2 additions & 22 deletions python_bindings/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,35 +62,15 @@ endif ()
# A helper for creating tests with correct PYTHONPATH and sanitizer preloading
##

if (Halide_ASAN_ENABLED)
if (NOT DEFINED Halide_Python_ASAN_LIBRARY)
# TODO: this assumes clang-on-Linux, we could be smarter here and check
# CMAKE_CXX_COMPILER_ID to behave differently on GNU, AppleClang, or
# MSVC.
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} "-print-file-name=libclang_rt.asan.so"
OUTPUT_VARIABLE Halide_Python_ASAN_LIBRARY
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif ()

set(Halide_Python_ASAN_LIBRARY "${Halide_Python_ASAN_LIBRARY}"
CACHE FILEPATH "Library to preload when running Python tests.")
endif ()

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

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

list(PREPEND ARG_ENVIRONMENT "HL_TARGET=${Halide_TARGET}")
if (Halide_Python_ASAN_LIBRARY)
if (APPLE)
list(PREPEND ARG_ENVIRONMENT "DYLD_INSERT_LIBRARIES=${Halide_Python_ASAN_LIBRARY}")
else ()
list(PREPEND ARG_ENVIRONMENT "LD_PRELOAD=${Halide_Python_ASAN_LIBRARY}")
endif ()
if (Halide_SANITIZER_ENV_VARS)
list(PREPEND ARG_ENVIRONMENT ${Halide_SANITIZER_ENV_VARS})
endif ()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (Halide_SANITIZER_ENV_VARS)
list(PREPEND ARG_ENVIRONMENT ${Halide_SANITIZER_ENV_VARS})
endif ()

Then, below (GitHib won't let me comment there 😠), in the call to add_test replace

COMMAND Python3::Interpreter

with

COMMAND ${Halide_PYTHON_LAUNCHER} "${Python3_EXECUTABLE}"


cmake_path(GET ARG_FILE STEM test_name)
Expand Down
7 changes: 7 additions & 0 deletions python_bindings/src/halide/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ set_target_properties(
LIBRARY_OUTPUT_DIRECTORY "$<CONFIG>/halide"
EXPORT_NAME Python
)
if (Halide_ASAN_ENABLED)
set_target_properties(
Halide_Python
PROPERTIES
CMAKE_SHARED_LINKER_FLAGS -shared-libasan
)
endif ()
target_link_libraries(Halide_Python PRIVATE Halide::Halide)

# TODO: There's precious little information about why Python only sometimes prevents DLLs from loading from the PATH
Expand Down
45 changes: 17 additions & 28 deletions src/autoschedulers/anderson2021/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,67 +77,56 @@ endif ()
if (WITH_TESTS)
##

function(_add_test TARGET)
add_test(NAME ${TARGET} COMMAND ${TARGET})
set_tests_properties(${TARGET}
PROPERTIES
# This is a workaround for issues with the nvidia driver under ASAN
# https://forums.developer.nvidia.com/t/cuda-runtime-library-and-addresssanitizer-incompatibilty/63145
ENVIRONMENT ASAN_OPTIONS=protect_shadow_gap=0
LABELS Anderson2021)
endfunction()

add_executable(anderson2021_test_function_dag test_function_dag.cpp FunctionDAG.cpp)
target_include_directories(anderson2021_test_function_dag PRIVATE "${Halide_SOURCE_DIR}/src/autoschedulers/anderson2021")
target_link_libraries(anderson2021_test_function_dag PRIVATE ASLog Halide::Halide Halide::Tools Halide::Plugin)

add_test(NAME anderson2021_test_function_dag COMMAND anderson2021_test_function_dag)
set_tests_properties(anderson2021_test_function_dag
PROPERTIES
LABELS Anderson2021)
_add_test(anderson2021_test_function_dag)

add_executable(anderson2021_test_bounds test/bounds.cpp FunctionDAG.cpp LoopNest.cpp GPULoopInfo.cpp Tiling.cpp)
target_include_directories(anderson2021_test_bounds PRIVATE "${Halide_SOURCE_DIR}/src/autoschedulers/anderson2021")
target_link_libraries(anderson2021_test_bounds PRIVATE ASLog Halide::Halide Halide::Tools Halide::Plugin)

add_test(NAME anderson2021_test_bounds COMMAND anderson2021_test_bounds)
set_tests_properties(anderson2021_test_bounds
PROPERTIES
LABELS Anderson2021)
_add_test(anderson2021_test_bounds)

add_executable(anderson2021_test_parser test/parser.cpp)
target_include_directories(anderson2021_test_parser PRIVATE "${Halide_SOURCE_DIR}/src/autoschedulers/anderson2021")
target_link_libraries(anderson2021_test_parser PRIVATE ASLog Halide::Halide Halide::Tools Halide::Plugin)

add_test(NAME anderson2021_test_parser COMMAND anderson2021_test_parser)
set_tests_properties(anderson2021_test_parser
PROPERTIES
LABELS Anderson2021)
_add_test(anderson2021_test_parser)

add_executable(anderson2021_test_state test/state.cpp FunctionDAG.cpp LoopNest.cpp GPULoopInfo.cpp State.cpp Tiling.cpp)
target_include_directories(anderson2021_test_state PRIVATE "${Halide_SOURCE_DIR}/src/autoschedulers/anderson2021")
target_link_libraries(anderson2021_test_state PRIVATE ASLog Halide::Halide Halide::Tools Halide::Plugin)

add_test(NAME anderson2021_test_state COMMAND anderson2021_test_state)
set_tests_properties(anderson2021_test_state
PROPERTIES
LABELS Anderson2021)
_add_test(anderson2021_test_state)

add_executable(anderson2021_test_storage_strides test/storage_strides.cpp FunctionDAG.cpp LoopNest.cpp GPULoopInfo.cpp State.cpp Tiling.cpp)
target_include_directories(anderson2021_test_storage_strides PRIVATE "${Halide_SOURCE_DIR}/src/autoschedulers/anderson2021")
target_link_libraries(anderson2021_test_storage_strides PRIVATE ASLog Halide::Halide Halide::Tools Halide::Plugin)

add_test(NAME anderson2021_test_storage_strides COMMAND anderson2021_test_storage_strides)
set_tests_properties(anderson2021_test_storage_strides
PROPERTIES
LABELS Anderson2021)
_add_test(anderson2021_test_storage_strides)

add_executable(anderson2021_test_thread_info test/thread_info.cpp LoopNest.cpp
FunctionDAG.cpp GPULoopInfo.cpp Tiling.cpp)
target_include_directories(anderson2021_test_thread_info PRIVATE "${Halide_SOURCE_DIR}/src/autoschedulers/anderson2021")
target_link_libraries(anderson2021_test_thread_info PRIVATE ASLog Halide::Halide Halide::Tools Halide::Plugin)

add_test(NAME anderson2021_test_thread_info COMMAND anderson2021_test_thread_info)
set_tests_properties(anderson2021_test_thread_info
PROPERTIES
LABELS Anderson2021)
_add_test(anderson2021_test_thread_info)

add_executable(anderson2021_test_tiling test/tiling.cpp Tiling.cpp)
target_include_directories(anderson2021_test_tiling PRIVATE "${Halide_SOURCE_DIR}/src/autoschedulers/anderson2021")
target_link_libraries(anderson2021_test_tiling PRIVATE ASLog Halide::Halide Halide::Tools Halide::Plugin)

add_test(NAME anderson2021_test_tiling COMMAND anderson2021_test_tiling)
set_tests_properties(anderson2021_test_tiling
PROPERTIES
LABELS Anderson2021)
_add_test(anderson2021_test_tiling)
endif()
1 change: 1 addition & 0 deletions test/autoschedulers/li2018/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ if (WITH_PYTHON_BINDINGS)
set_tests_properties(li2018_gradient_autoscheduler_test_py PROPERTIES
DEPENDS li2018_test
LABELS "li2018;autoschedulers;auto_schedule"
ENVIRONMENT "${Halide_SANITIZER_ENV_VARS}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ENVIRONMENT "${Halide_SANITIZER_ENV_VARS}"

Same deal with add_test(... COMMAND Python3::Interpreter ...) above. Use the Halide_PYTHON_LAUNCHER variable.

ENVIRONMENT_MODIFICATION "${PYTHONPATH}")
endif()
endif ()