find_package(OpenMP) configure_file(images/gray.png images/gray.png COPYONLY) configure_file(images/rgb.png images/rgb.png COPYONLY) function(add_tutorial source_file) set(options WITH_IMAGE_IO WITH_OPENMP) set(oneValueArgs) set(multiValueArgs SRCS GROUPS) cmake_parse_arguments(args "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) cmake_path(GET source_file STEM name) add_executable("${name}" "${source_file}") target_link_libraries("${name}" PRIVATE Halide::Halide Halide::Tools) target_compile_options(${name} PRIVATE "$<$:-Wno-unused-but-set-variable>") add_test(NAME tutorial_${name} COMMAND ${name}) set_tests_properties(tutorial_${name} PROPERTIES ENVIRONMENT "HL_TARGET=${Halide_TARGET};HL_JIT_TARGET=${Halide_TARGET}" LABELS "tutorial;${args_GROUPS}") if (args_WITH_IMAGE_IO) target_link_libraries(${name} PRIVATE Halide::ImageIO) endif () if (args_WITH_OPENMP) if (TARGET OpenMP::OpenMP_CXX) target_link_libraries(${name} PRIVATE OpenMP::OpenMP_CXX) else () # Compile anyway but suppress warnings about unrecognised pragmas target_compile_options("${name}" PRIVATE $<$:/Wd4068> $<$>:-Wno-unknown-pragmas>) endif () endif () endfunction() # Declare tutorials add_tutorial(lesson_01_basics.cpp) add_tutorial(lesson_02_input_image.cpp WITH_IMAGE_IO) add_tutorial(lesson_03_debugging_1.cpp) add_tutorial(lesson_04_debugging_2.cpp GROUPS multithreaded) add_tutorial(lesson_05_scheduling_1.cpp GROUPS multithreaded) add_tutorial(lesson_06_realizing_over_shifted_domains.cpp) add_tutorial(lesson_07_multi_stage_pipelines.cpp WITH_IMAGE_IO) add_tutorial(lesson_08_scheduling_2.cpp WITH_IMAGE_IO WITH_OPENMP GROUPS multithreaded) add_tutorial(lesson_09_update_definitions.cpp WITH_IMAGE_IO WITH_OPENMP GROUPS multithreaded) if ("NVPTX" IN_LIST Halide_LLVM_COMPONENTS) if (Halide_TARGET MATCHES "wasm") # TODO: Requires custom build rules to work under wasm. message(WARNING "Not all tutorials build under WASM.") else () # Tutorial 10 requires that we build generation code, then run it, # so we can build the final executable. add_tutorial(lesson_10_aot_compilation_generate.cpp) set(FILTER_LIB "lesson_10_halide${CMAKE_STATIC_LIBRARY_SUFFIX}") add_custom_command(OUTPUT lesson_10_halide.h "${FILTER_LIB}" DEPENDS lesson_10_aot_compilation_generate COMMAND lesson_10_aot_compilation_generate VERBATIM) add_custom_target(exec_lesson_10_aot_compilation_generate DEPENDS lesson_10_halide.h "${FILTER_LIB}") # This will be linked with the code generated by # the generator (lesson_10_aot_compilation_generate) add_executable(lesson_10_aot_compilation_run lesson_10_aot_compilation_run.cpp) add_dependencies(lesson_10_aot_compilation_run exec_lesson_10_aot_compilation_generate) target_link_libraries(lesson_10_aot_compilation_run PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/${FILTER_LIB}" Halide::Runtime Threads::Threads ${CMAKE_DL_LIBS}) # Undocumented function in HalideGeneratorHelpers. Do not call in external code. # Users of the AOT functions (as opposed to Generators) should link to the relevant # GPU libraries manually. _Halide_target_link_gpu_libs(lesson_10_aot_compilation_run PRIVATE ${Halide_TARGET}) target_include_directories(lesson_10_aot_compilation_run PRIVATE "${CMAKE_CURRENT_BINARY_DIR}") add_test(NAME tutorial_lesson_10_aot_compilation_run COMMAND lesson_10_aot_compilation_run) set_tests_properties(tutorial_lesson_10_aot_compilation_run PROPERTIES LABELS "tutorial;multithreaded") endif () endif () add_tutorial(lesson_11_cross_compilation.cpp) add_tutorial(lesson_12_using_the_gpu.cpp WITH_IMAGE_IO GROUPS multithreaded) add_tutorial(lesson_13_tuples.cpp) add_tutorial(lesson_14_types.cpp) # Lesson 15 add_executable(lesson_15_generate lesson_15_generators.cpp) target_link_libraries(lesson_15_generate PRIVATE Halide::Generator) ## Hack to build the libraries add_custom_target(lesson_15_targets) set(LESSON_15_EXPECTED_FILES "") ## add_halide_library(my_first_generator_win32 FROM lesson_15_generate GENERATOR my_first_generator TARGETS x86-32-windows) list(APPEND LESSON_15_EXPECTED_FILES $ my_first_generator_win32.h) add_dependencies(lesson_15_targets my_first_generator_win32) ## add_halide_library(my_first_generator FROM lesson_15_generate STMT my_first_generator_STMT) list(APPEND LESSON_15_EXPECTED_FILES ${my_first_generator_STMT}) add_dependencies(lesson_15_targets my_first_generator) ## add_halide_library(my_second_generator_1 FROM lesson_15_generate GENERATOR my_second_generator PARAMS parallel=false scale=3.0 rotation=ccw output.type=uint16) add_halide_library(my_second_generator_2 FROM lesson_15_generate GENERATOR my_second_generator PARAMS scale=9.0 rotation=ccw output.type=float32) add_halide_library(my_second_generator_3 FROM lesson_15_generate GENERATOR my_second_generator PARAMS parallel=false output.type=float64) list(APPEND LESSON_15_EXPECTED_FILES $ my_second_generator_1.h $ my_second_generator_2.h $ my_second_generator_3.h) add_dependencies(lesson_15_targets my_second_generator_1 my_second_generator_2 my_second_generator_3) ## add_test(NAME tutorial_lesson_15_build_gens COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target lesson_15_targets --config $) set_tests_properties(tutorial_lesson_15_build_gens PROPERTIES LABELS tutorial FIXTURES_SETUP tutorial_lesson_15) add_test(NAME tutorial_lesson_15_check_files COMMAND ${CMAKE_COMMAND} "-DFILES_TO_CHECK=$>" -P "${Halide_SOURCE_DIR}/cmake/CheckFilesExist.cmake") set_tests_properties(tutorial_lesson_15_check_files PROPERTIES LABELS tutorial FIXTURES_REQUIRED tutorial_lesson_15) # Lesson 16 if (Halide_TARGET MATCHES "wasm") # TODO: Requires custom build rules to work under wasm message(WARNING "Not all tutorials build under WASM.") else () add_executable(lesson_16_rgb_generate lesson_16_rgb_generate.cpp) target_link_libraries(lesson_16_rgb_generate PRIVATE Halide::Generator) add_halide_library(brighten_planar FROM lesson_16_rgb_generate TARGETS cmake GENERATOR brighten PARAMS layout=planar) add_halide_library(brighten_interleaved FROM lesson_16_rgb_generate TARGETS cmake GENERATOR brighten PARAMS layout=interleaved) add_halide_library(brighten_either FROM lesson_16_rgb_generate TARGETS cmake GENERATOR brighten PARAMS layout=either) add_halide_library(brighten_specialized FROM lesson_16_rgb_generate TARGETS cmake GENERATOR brighten PARAMS layout=specialized) add_executable(lesson_16_rgb_run lesson_16_rgb_run.cpp) target_link_libraries(lesson_16_rgb_run PRIVATE brighten_planar brighten_interleaved brighten_either brighten_specialized Halide::ImageIO Halide::Tools) add_test(NAME tutorial_lesson_16_rgb_run COMMAND lesson_16_rgb_run) set_tests_properties(tutorial_lesson_16_rgb_run PROPERTIES LABELS tutorial) endif () # Lessons 17 - 20 add_tutorial(lesson_17_predicated_rdom.cpp) add_tutorial(lesson_18_parallel_associative_reductions.cpp GROUPS multithreaded) add_tutorial(lesson_19_wrapper_funcs.cpp) add_tutorial(lesson_20_cloning_funcs.cpp) # Lesson 21 if (TARGET Halide::Mullapudi2016) add_executable(lesson_21_auto_scheduler_generate lesson_21_auto_scheduler_generate.cpp) target_link_libraries(lesson_21_auto_scheduler_generate PRIVATE Halide::Generator) add_halide_library(auto_schedule_false FROM lesson_21_auto_scheduler_generate TARGETS cmake GENERATOR auto_schedule_gen) add_halide_library(auto_schedule_true FROM lesson_21_auto_scheduler_generate TARGETS cmake AUTOSCHEDULER Halide::Mullapudi2016 GENERATOR auto_schedule_gen PARAMS autoscheduler.parallelism=32 autoscheduler.last_level_cache_size=16777216 autoscheduler.balance=40) add_executable(lesson_21_auto_scheduler_run lesson_21_auto_scheduler_run.cpp) target_link_libraries(lesson_21_auto_scheduler_run PRIVATE auto_schedule_false auto_schedule_true Halide::Tools) add_test(NAME tutorial_lesson_21_auto_scheduler_run COMMAND lesson_21_auto_scheduler_run) set_tests_properties(tutorial_lesson_21_auto_scheduler_run PROPERTIES LABELS "tutorial;multithreaded") endif () # Lessons 22-24 add_tutorial(lesson_22_jit_performance.cpp) add_tutorial(lesson_23_serialization.cpp WITH_IMAGE_IO) add_tutorial(lesson_24_async.cpp)