Skip to content

Commit 59553d7

Browse files
authored
Add add_halide_stub helper and build for linear_blur app. (#9093)
Fixes #8735
1 parent 4a1869f commit 59553d7

3 files changed

Lines changed: 146 additions & 3 deletions

File tree

apps/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ add_app(iir_blur)
5656
add_app(interpolate)
5757
add_app(lens_blur)
5858
add_app(linear_algebra)
59-
# add_app(linear_blur) # TODO(#5374): missing CMake build
59+
add_app(linear_blur)
6060
add_app(local_laplacian)
6161
add_app(max_filter)
6262
add_app(nl_means)

apps/linear_blur/CMakeLists.txt

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
cmake_minimum_required(VERSION 3.28)
2+
project(linear_blur)
3+
4+
enable_testing()
5+
6+
# Set up language settings
7+
set(CMAKE_CXX_STANDARD 17)
8+
set(CMAKE_CXX_STANDARD_REQUIRED YES)
9+
set(CMAKE_CXX_EXTENSIONS NO)
10+
11+
# Find Halide
12+
find_package(Halide REQUIRED)
13+
14+
# Component generators (standalone executables that also produce stubs)
15+
add_halide_generator(srgb_to_linear.generator SOURCES srgb_to_linear_generator.cpp)
16+
add_halide_generator(simple_blur.generator SOURCES simple_blur_generator.cpp)
17+
add_halide_generator(linear_to_srgb.generator SOURCES linear_to_srgb_generator.cpp)
18+
19+
# Generate stub headers for pipeline composition
20+
add_halide_stub(srgb_to_linear.stub FROM srgb_to_linear.generator GENERATOR srgb_to_linear)
21+
add_halide_stub(simple_blur.stub FROM simple_blur.generator GENERATOR simple_blur)
22+
add_halide_stub(linear_to_srgb.stub FROM linear_to_srgb.generator GENERATOR linear_to_srgb)
23+
24+
# Composite generator: includes all component sources (for HALIDE_REGISTER_GENERATOR
25+
# factory functions) and links stub headers (for compile-time composition).
26+
add_halide_generator(
27+
linear_blur.generator
28+
SOURCES
29+
linear_blur_generator.cpp
30+
srgb_to_linear_generator.cpp
31+
simple_blur_generator.cpp
32+
linear_to_srgb_generator.cpp
33+
34+
LINK_LIBRARIES
35+
srgb_to_linear.stub
36+
simple_blur.stub
37+
linear_to_srgb.stub
38+
)
39+
40+
# AOT-compiled filter libraries
41+
add_halide_library(simple_blur FROM simple_blur.generator
42+
PARAMS
43+
input.type=float32 input.dim=3
44+
output.type=float32 output.dim=3)
45+
add_halide_library(linear_blur FROM linear_blur.generator
46+
AUTOSCHEDULER Halide::Mullapudi2016)
47+
48+
# Main executable
49+
add_executable(linear_blur_process run_linear_blur.cpp)
50+
target_link_libraries(linear_blur_process
51+
PRIVATE
52+
Halide::ImageIO
53+
linear_blur
54+
simple_blur)
55+
56+
# Test that the app actually works!
57+
set(IMAGE ${CMAKE_CURRENT_LIST_DIR}/../images/rgb.png)
58+
if (EXISTS ${IMAGE})
59+
configure_file(${IMAGE} rgb.png COPYONLY)
60+
add_test(NAME linear_blur_test
61+
COMMAND linear_blur_process 1 rgb.png out.png)
62+
set_tests_properties(linear_blur_test PROPERTIES
63+
LABELS linear_blur
64+
PASS_REGULAR_EXPRESSION "Using linear blur"
65+
SKIP_REGULAR_EXPRESSION "\\[SKIP\\]")
66+
endif ()

cmake/HalideGeneratorHelpers.cmake

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ function(_Halide_library_from_generator TARGET)
208208
set(compiler_log_extension ".halide_compiler_log")
209209
set(conceptual_stmt_extension ".conceptual.stmt")
210210
set(conceptual_stmt_html_extension ".conceptual.stmt.html")
211-
# set(cpp_stub_extension ".stub.h") # not implemented
211+
# set(cpp_stub_extension ".stub.h") # handled by add_halide_stub()
212212
set(device_code_extension ".device_code")
213213
set(featurization_extension ".featurization")
214214
set(function_info_header_extension ".function_info.h")
@@ -465,6 +465,83 @@ function(_Halide_set_osx_arch TARGET TRIPLE)
465465
endif ()
466466
endfunction()
467467

468+
##
469+
# Function to generate a C++ stub header from a Halide generator.
470+
#
471+
# Stubs allow one Generator to compose another at Halide compile time by
472+
# inlining the sub-generator's pipeline definition. The stub header provides
473+
# a type-safe C++ interface (Inputs, Outputs, GeneratorParams structs and a
474+
# static generate() method) for the sub-generator.
475+
#
476+
# The generated <name>.stub.h must be available when compiling the composite
477+
# generator, and the composite generator executable must link the component
478+
# generators' sources so that their HALIDE_REGISTER_GENERATOR factory
479+
# functions are present at link time.
480+
#
481+
# Usage:
482+
# add_halide_stub(<target> FROM <generator_target>
483+
# [GENERATOR <name>]
484+
# [OUTPUT_DIR <dir>])
485+
#
486+
# The GENERATOR name defaults to TARGET and controls both the -g flag and the
487+
# output filename (<GENERATOR>.stub.h).
488+
##
489+
490+
function(add_halide_stub TARGET)
491+
set(options "")
492+
set(oneValueArgs FROM GENERATOR OUTPUT_DIR)
493+
set(multiValueArgs "")
494+
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
495+
496+
if (NOT ARG_FROM)
497+
message(FATAL_ERROR "add_halide_stub requires FROM specifying a generator target")
498+
endif ()
499+
500+
if (NOT ARG_GENERATOR)
501+
set(ARG_GENERATOR "${TARGET}")
502+
endif ()
503+
504+
if (NOT ARG_OUTPUT_DIR)
505+
set(ARG_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
506+
endif ()
507+
508+
cmake_path(SET ARG_OUTPUT_DIR "${ARG_OUTPUT_DIR}")
509+
cmake_path(ABSOLUTE_PATH ARG_OUTPUT_DIR BASE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" NORMALIZE)
510+
511+
_Halide_compute_generator_cmd(
512+
FROM "${ARG_FROM}"
513+
OUT_COMMAND generator_cmd
514+
OUT_DEPENDS generator_cmd_deps
515+
)
516+
517+
# Absolute path to the generated stub header.
518+
cmake_path(SET stub_file NORMALIZE "${ARG_OUTPUT_DIR}/${ARG_GENERATOR}.stub.h")
519+
520+
# Relative path for add_custom_command OUTPUT (avoids Xcode .rule file collisions).
521+
cmake_path(RELATIVE_PATH stub_file BASE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
522+
OUTPUT_VARIABLE stub_file_rel)
523+
524+
add_custom_command(
525+
OUTPUT "${stub_file_rel}"
526+
COMMAND ${generator_cmd}
527+
-g "${ARG_GENERATOR}"
528+
-n "${ARG_GENERATOR}"
529+
-o "${ARG_OUTPUT_DIR}"
530+
-e cpp_stub
531+
DEPENDS ${generator_cmd_deps}
532+
VERBATIM
533+
)
534+
535+
add_library("${TARGET}" INTERFACE)
536+
add_custom_target("${TARGET}.update" DEPENDS "${stub_file}")
537+
set_property(TARGET "${TARGET}.update" PROPERTY FOLDER "Halide Internal")
538+
add_dependencies("${TARGET}" "${TARGET}.update")
539+
target_sources("${TARGET}" INTERFACE
540+
FILE_SET HEADERS
541+
BASE_DIRS "${ARG_OUTPUT_DIR}"
542+
FILES "${stub_file}")
543+
endfunction()
544+
468545
##
469546
# Function to simplify writing the CMake rules for invoking a generator executable
470547
# and getting a usable CMake library out of it.
@@ -477,7 +554,7 @@ function(add_halide_library TARGET)
477554

478555
# See Module.cpp for list of extra outputs. The following outputs intentionally do not appear:
479556
# - `c_header` is always generated
480-
# - `cpp_stub` is not available
557+
# - `cpp_stub` is handled by add_halide_stub()
481558
# - `object` is selected for CMake-target-compile
482559
# - `static_library` is selected for cross-compile
483560
set(extra_output_names

0 commit comments

Comments
 (0)