File size: 9,633 Bytes
9422383
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# Build the model-independent YOLO26n runtime for its one supported native
# target. This project owns dependency acquisition, native compilation, ABI
# verification, and installation. Model conversion remains a separate operation
# and does not rebuild this target.
cmake_minimum_required(VERSION 3.24)
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/../../VERSION" yolo26n_version LIMIT_COUNT 1)
if(NOT yolo26n_version MATCHES "^[0-9]+\\.[0-9]+\\.[0-9]+$")
  message(FATAL_ERROR "VERSION must contain one semantic version")
endif()
project(yolo26n_runtime VERSION "${yolo26n_version}" LANGUAGES C CXX ASM)

include(CTest)
include(FetchContent)
include(GNUInstallDirs)

option(YOLO26N_ENABLE_COVERAGE "Instrument the runtime for source coverage" OFF)

if(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux"
    OR NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)$")
  message(FATAL_ERROR "The YOLO26n runtime builds on Linux AArch64")
endif()
if(NOT CMAKE_C_COMPILER_ID STREQUAL "GNU"
    OR NOT CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
    OR NOT CMAKE_ASM_COMPILER_ID STREQUAL "GNU")
  message(FATAL_ERROR
    "The YOLO26n runtime requires the GNU C, C++, and assembler toolchain")
endif()
if(YOLO26N_ENABLE_COVERAGE AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
  message(FATAL_ERROR "YOLO26N_ENABLE_COVERAGE requires CMAKE_BUILD_TYPE=Debug")
endif()
find_program(PATCH_EXECUTABLE patch REQUIRED)
set(FETCHCONTENT_QUIET OFF)

# Pinned native dependencies
# Fetch and patch each archive without configuring its top-level project.
# XNNPACK is added once below, after its build options and source dependencies
# have been set.
FetchContent_Declare(cpuinfo
  URL https://codeload.github.com/pytorch/cpuinfo/tar.gz/f9a03241f8c3d4ed0c9728f5d70bff873d43d4e0
  URL_HASH SHA256=90e3f1a6c3671a0f94259a1e35ad0524ec9d6a8e9275aeb1e3af502341b9eb0e
  SOURCE_DIR "${CMAKE_BINARY_DIR}/sources/cpuinfo"
  SOURCE_SUBDIR _populate_only)
# The pinned XNNPACK revision selects this same revision from FXdiv's canonical
# upstream repository.
FetchContent_Declare(fxdiv
  URL https://codeload.github.com/Maratyszcza/FXdiv/tar.gz/b408327ac2a15ec3e43352421954f5b1967701d1
  URL_HASH SHA256=9ccf554541666b5c089ad5dd465141d671c99971f36d72f313652f5c49ffce14
  SOURCE_DIR "${CMAKE_BINARY_DIR}/sources/fxdiv"
  SOURCE_SUBDIR _populate_only)
FetchContent_Declare(pthreadpool
  URL https://codeload.github.com/google/pthreadpool/tar.gz/a56dcd79c699366e7ac6466792c3025883ff7704
  URL_HASH SHA256=0663f88fbfc3e7e2c3e2522e18a460af94367aade7a5caf20b037b2eb7940173
  SOURCE_DIR "${CMAKE_BINARY_DIR}/sources/pthreadpool"
  SOURCE_SUBDIR _populate_only
  PATCH_COMMAND "${PATCH_EXECUTABLE}" --strip=3 --batch --forward
    --input=${CMAKE_CURRENT_SOURCE_DIR}/patches/pthreadpool-spin-wait.patch)
FetchContent_Declare(xnnpack
  URL https://codeload.github.com/google/XNNPACK/tar.gz/1adaa7c709d4839d29e1f219cb962b01c9e6a905
  URL_HASH SHA256=a101582c57d3d45f9fdb4d89b7aad7b9dbe4b488b429ccde483e199d564a9c41
  SOURCE_DIR "${CMAKE_BINARY_DIR}/sources/xnnpack"
  SOURCE_SUBDIR _populate_only
  PATCH_COMMAND "${PATCH_EXECUTABLE}" --strip=3 --batch --forward
    --input=${CMAKE_CURRENT_SOURCE_DIR}/patches/xnnpack-graph-api-pruning.patch
  COMMAND "${PATCH_EXECUTABLE}" --strip=3 --batch --forward
    --input=${CMAKE_CURRENT_SOURCE_DIR}/patches/xnnpack-yolo26-graph-extensions.patch
  COMMAND "${PATCH_EXECUTABLE}" --strip=3 --batch --forward
    --input=${CMAKE_CURRENT_SOURCE_DIR}/patches/xnnpack-operator-pruning.patch
  COMMAND "${PATCH_EXECUTABLE}" --strip=3 --batch --forward
    --input=${CMAKE_CURRENT_SOURCE_DIR}/patches/xnnpack-yolo26-operator-extensions.patch
  COMMAND "${PATCH_EXECUTABLE}" --strip=3 --batch --forward
    --input=${CMAKE_CURRENT_SOURCE_DIR}/patches/xnnpack-yolo26-kernels.patch
  COMMAND "${PATCH_EXECUTABLE}" --strip=3 --batch --forward
    --input=${CMAKE_CURRENT_SOURCE_DIR}/patches/xnnpack-rpi5-bti-diagnostic.patch)
FetchContent_MakeAvailable(cpuinfo fxdiv pthreadpool xnnpack)

# Raspberry Pi 5 XNNPACK configuration
#
# Point XNNPACK at the already-fetched supporting sources, exclude kernels for
# CPU features outside the fixed target, then add XNNPACK exactly once.
set(CPUINFO_SOURCE_DIR "${cpuinfo_SOURCE_DIR}" CACHE PATH "" FORCE)
set(FXDIV_SOURCE_DIR "${fxdiv_SOURCE_DIR}" CACHE PATH "" FORCE)
set(PTHREADPOOL_SOURCE_DIR "${pthreadpool_SOURCE_DIR}" CACHE PATH "" FORCE)
set(XNNPACK_BUILD_BENCHMARKS OFF CACHE BOOL "" FORCE)
set(XNNPACK_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(XNNPACK_BUILD_ALL_MICROKERNELS OFF CACHE BOOL "" FORCE)
# The fixed Raspberry Pi 5 target uses AArch64 NEON FP16 kernels. Do not build
# dispatch families for CPU features outside that target.
set(XNNPACK_ENABLE_ARM_BF16 OFF CACHE BOOL "" FORCE)
set(XNNPACK_ENABLE_ARM_DOTPROD OFF CACHE BOOL "" FORCE)
set(XNNPACK_ENABLE_ARM_FP16_SCALAR OFF CACHE BOOL "" FORCE)
set(XNNPACK_ENABLE_ARM_I8MM OFF CACHE BOOL "" FORCE)
set(XNNPACK_ENABLE_ARM_SME OFF CACHE BOOL "" FORCE)
set(XNNPACK_ENABLE_ARM_SME2 OFF CACHE BOOL "" FORCE)
set(XNNPACK_ENABLE_KLEIDIAI OFF CACHE BOOL "" FORCE)
set(XNNPACK_LIBRARY_TYPE static CACHE STRING "" FORCE)
add_subdirectory("${xnnpack_SOURCE_DIR}" xnnpack EXCLUDE_FROM_ALL)

# These four project-owned kernels enter XNNPACK through the kernel patch but
# are deliberately absent from XNNPACK's upstream source lists. Register them
# with the production microkernel target explicitly because the fixed runtime
# disables XNNPACK_BUILD_ALL_MICROKERNELS. The assembly kernels require the
# same Armv8.2-A FP16 ISA as the runtime.
set(yolo26n_xnnpack_microkernels
  "${xnnpack_SOURCE_DIR}/src/f16-igemm/f16-igemm-1x16-yolo26-silu-asm-aarch64-neonfp16arith-ld64.S"
  "${xnnpack_SOURCE_DIR}/src/f16-igemm/f16-igemm-6x16-yolo26-silu-asm-aarch64-neonfp16arith-cortex-a75.S"
  "${xnnpack_SOURCE_DIR}/src/f16-vsilu/f16-vsilu-neonfp16arith-rr2-p2-nr1fma-u32.c"
  "${xnnpack_SOURCE_DIR}/src/f32-vsilu/f32-vsilu-neonfma-rr1-lut64-p2-nr2recps-u16.c")
target_sources(xnnpack-microkernels-prod PRIVATE ${yolo26n_xnnpack_microkernels})
set_source_files_properties(${yolo26n_xnnpack_microkernels}
  TARGET_DIRECTORY xnnpack-microkernels-prod
  PROPERTIES
  COMPILE_OPTIONS "-march=armv8.2-a+fp16")

# Runtime targets
#
# The shared-library export map keeps every C++ and dependency symbol private.
add_library(arm_yolo26n SHARED
  fixed_graph.cpp
  fixed_memory_plan.cpp
  fixed_schedule.cpp
  model_store.cpp
  arm_yolo26n.cpp
  preprocess.cpp
  projection_optimization.cpp)
set_target_properties(arm_yolo26n PROPERTIES
  OUTPUT_NAME "arm-yolo26n"
  VERSION "${PROJECT_VERSION}"
  SOVERSION 0)
target_compile_features(arm_yolo26n PRIVATE cxx_std_17)
target_compile_options(arm_yolo26n PRIVATE
  -march=armv8.2-a+fp16
  -mno-fix-cortex-a53-843419 -ffunction-sections -fdata-sections
  -Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Werror)
target_include_directories(arm_yolo26n SYSTEM PRIVATE
  "${xnnpack_SOURCE_DIR}"
  "${xnnpack_SOURCE_DIR}/include"
  "${pthreadpool_SOURCE_DIR}/include")
target_link_libraries(arm_yolo26n PRIVATE XNNPACK pthreadpool m)
target_link_options(arm_yolo26n PRIVATE
  "LINKER:--version-script=${CMAKE_CURRENT_SOURCE_DIR}/native_runtime.map"
  "LINKER:--gc-sections"
  "LINKER:--sort-section=alignment"
  "LINKER:-Bsymbolic"
  "LINKER:-Map,${CMAKE_BINARY_DIR}/libarm-yolo26n.map"
  "LINKER:--cref")
if(YOLO26N_ENABLE_COVERAGE)
  # Debug supplies unoptimized code and symbols; this option adds only the GNU
  # coverage instrumentation. Coverage builds are diagnostic and are never
  # used for performance measurement or release.
  target_compile_options(arm_yolo26n PRIVATE --coverage)
  target_link_options(arm_yolo26n PRIVATE --coverage)
endif()

# Native verification
if(BUILD_TESTING)
  # Inspect the built library's dynamic dependencies and exported symbols
  # without loading it. The C API test below exercises function behavior.
  add_test(NAME yolo26n_runtime_binary
    COMMAND "${CMAKE_COMMAND}"
      -DNATIVE_RUNTIME=$<TARGET_FILE:arm_yolo26n>
      -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/verify_runtime_binary.cmake")

  # Compile the repository's only C API behavior test against the public
  # header. It covers invalid calls that the higher-level Python API prevents
  # from reaching the native boundary.
  add_executable(yolo26n_runtime_api_test tests/runtime_api_test.c)
  target_compile_features(yolo26n_runtime_api_test PRIVATE c_std_11)
  target_compile_options(yolo26n_runtime_api_test PRIVATE
    -Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion -Werror)
  target_include_directories(yolo26n_runtime_api_test PRIVATE
    "${CMAKE_CURRENT_SOURCE_DIR}")
  target_link_libraries(yolo26n_runtime_api_test PRIVATE arm_yolo26n)

  # The behavior test returns 77 when no converted model was supplied. CTest
  # reports that result as skipped, allowing an ordinary native build to run
  # every available check without making CMake own model conversion. The
  # end-to-end and coverage workflows supply the model and exercise the test.
  add_test(NAME yolo26n_runtime_api_behavior COMMAND yolo26n_runtime_api_test)
  set_tests_properties(yolo26n_runtime_api_behavior PROPERTIES SKIP_RETURN_CODE 77)
endif()

# Installation
install(TARGETS arm_yolo26n
  LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
  COMPONENT runtime
  NAMELINK_COMPONENT development)
install(FILES arm_yolo26n.h
  DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
  COMPONENT development)
install(DIRECTORY licenses/
  DESTINATION "${CMAKE_INSTALL_DATADIR}/doc/arm-yolo26n/licenses"
  COMPONENT runtime)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/../../../LICENSE"
  DESTINATION "${CMAKE_INSTALL_DATADIR}/doc/arm-yolo26n"
  COMPONENT runtime)