cmake_minimum_required(VERSION 3.22)
project(hannk)
# We need to set this for some of the subprojects pulled in by TFLite (eg flatbuffers)
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
enable_testing()
# ----------------------------
option(HANNK_AOT_HOST_ONLY "Only build AOT host tools for cross-compiling" OFF)
option(HANNK_BUILD_TFLITE "Build TFLite+Delegate for HANNK" ON)
if (HANNK_BUILD_TFLITE AND (Halide_TARGET MATCHES "wasm"))
message(FATAL_ERROR "HANNK_BUILD_TFLITE must be OFF when targeting wasm")
endif ()
message(STATUS "HANNK_BUILD_TFLITE is ${HANNK_BUILD_TFLITE}")
# -fPIC is necessary for .so builds (at least on Linux); not necessary for the non-delegate
# builds but easier to enable it for everything.
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# Set up language settings
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS NO)
# Set up the version of TFLite we expect
# (We need to do this even if HANNK_BUILD_TFLITE is off,
# so that the .tflite file parser can get the right schema)
set(TFLITE_VERSION_MAJOR "2" CACHE STRING "Major version of TFLite to assume")
set(TFLITE_VERSION_MINOR "8" CACHE STRING "Minor version of TFLite to assume")
set(TFLITE_VERSION_PATCH "3" CACHE STRING "Patch version of TFLite to assume")
set(TFLITE_VERSION "${TFLITE_VERSION_MAJOR}.${TFLITE_VERSION_MINOR}.${TFLITE_VERSION_PATCH}")
# ----------------------------
add_compile_definitions(TFLITE_VERSION_MAJOR=${TFLITE_VERSION_MAJOR})
add_compile_definitions(TFLITE_VERSION_MINOR=${TFLITE_VERSION_MINOR})
add_compile_definitions(TFLITE_VERSION_PATCH=${TFLITE_VERSION_PATCH})
add_compile_definitions(HANNK_BUILD_TFLITE=$<BOOL:${HANNK_BUILD_TFLITE}>)
# ----------------------------
# Find HalideHelpers -- this is just the Runtime headers and CMake functions, but no libraries
find_package(HalideHelpers REQUIRED)
# ----------------------------
add_subdirectory(halide)
if (HANNK_AOT_HOST_ONLY)
# Don't add anything else to the build... everything for AOT is in the halide subdirectory
return()
endif ()
add_subdirectory(interpreter)
add_subdirectory(tflite)
add_subdirectory(util)
if (HANNK_BUILD_TFLITE)
add_subdirectory(delegate)
endif ()
# ----------------------------
# Benchmarking executable
add_executable(benchmark benchmark.cpp)
target_link_libraries(benchmark PRIVATE
tflite_parser
interpreter
error_util
file_util
hannk_log_stderr
Halide::Tools # for halide_benchmark.h
Halide::Runtime)
add_executable(compare_vs_tflite compare_vs_tflite.cpp)
target_link_libraries(compare_vs_tflite PRIVATE
hannk_log_stderr
model_runner
Halide::Runtime)
target_include_directories(compare_vs_tflite
PUBLIC $<BUILD_INTERFACE:${hannk_SOURCE_DIR}>)
# TODO: Surely there's a better way to set Emscripten flags.
if (Halide_TARGET MATCHES "wasm")
foreach (t IN ITEMS benchmark compare_vs_tflite)
# Note: "SHELL:" prevents de-duplication of the -s flag.
target_link_options(
${t} PRIVATE
"SHELL:-s ALLOW_MEMORY_GROWTH=1"
"SHELL:-s ENVIRONMENT=node"
"SHELL:-s NODERAWFS"
"SHELL:$<$<CONFIG:Debug>:-s ASSERTIONS=1>"
)
endforeach ()
endif ()
if (Halide_TARGET MATCHES "wasm" AND NODE_JS_EXECUTABLE)
execute_process(COMMAND "${NODE_JS_EXECUTABLE}" --version
OUTPUT_VARIABLE NODE_JS_VERSION_RAW
OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REPLACE "v" "" NODE_JS_VERSION ${NODE_JS_VERSION_RAW})
if (NODE_JS_VERSION VERSION_LESS "16.13")
message(FATAL_ERROR "Halide requires Node v16.13 or later, but found ${NODE_JS_VERSION_RAW} at ${NODE_JS_EXECUTABLE}. Please set NODE_JS_EXECUTABLE on the CMake command line.")
endif ()
endif ()
# Tests
file(GLOB TEST_FILES CONFIGURE_DEPENDS "test/*/*.tflite")
foreach (t IN LISTS TEST_FILES)
file(RELATIVE_PATH test_name ${hannk_SOURCE_DIR} ${t})
# Emscripten sets CMAKE_CROSSCOMPILING_TOOLCHAIN to NODE_JS_EXECUTABLE,
# which ensures these tests will run in Node.
add_test(NAME ${test_name}
COMMAND compare_vs_tflite ${t} --benchmark 0)
set_tests_properties(${test_name} PROPERTIES
LABELS hannk_tests)
endforeach ()