Skip to content

Commit e5b7afe

Browse files
Pybind11 free threading (#3158)
* pickup latest pybind11 and support free threaded * Cleanup Some stuff wasn't actually thread safe: - Made the jitter RNG thread_local in tools/python/src/numpy_returns.cpp:97. - Serialized concurrent inference on the same face-recognition or CNN detector instance in tools/python/src/face_recognition.cpp:72 and tools/python/src/ cnn_face_detector.cpp:52. I also pulled the official pybind11 release. What was here looks like one of their alpha snapshots. We should use an official pybind11 release In particular, I replaced the mixed development pybind11 snapshot with exact upstream pybind11 v3.0.4, commit d03662f0984f652b60e7ddce53d3868002275197. Also added provenance/update instructions in dlib/external/pybind11/README.dlib. Then some other minor related cleanup * fix errors --------- Co-authored-by: Katsumi Yokomichi <yokomichikt@scft.co.jp>
1 parent e8d99e5 commit e5b7afe

73 files changed

Lines changed: 9455 additions & 2316 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/build_python.yml

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,36 @@ jobs:
6060
- name: Test
6161
run: python -m pytest --ignore docs --ignore dlib
6262

63+
Ubuntu-Free-Threaded:
64+
runs-on: 'ubuntu-latest'
65+
steps:
66+
- uses: actions/checkout@v6
67+
- uses: actions/setup-python@v6
68+
with:
69+
python-version: '3.13t'
70+
- name: Install python deps
71+
run: pip install pytest numpy
72+
- name: Build
73+
run: pip install .
74+
- name: Verify free-threading
75+
run: python -c "import sys; assert not sys._is_gil_enabled()"
76+
- name: Test
77+
run: python -m pytest --ignore docs --ignore dlib
78+
79+
Ubuntu-Python-3-8:
80+
runs-on: 'ubuntu-latest'
81+
steps:
82+
- uses: actions/checkout@v6
83+
- uses: actions/setup-python@v6
84+
with:
85+
python-version: '3.8'
86+
- name: Install python deps
87+
run: pip install pytest numpy
88+
- name: Build
89+
run: pip install .
90+
- name: Test
91+
run: python -m pytest --ignore docs --ignore dlib
92+
6393
# Disabled for now since something is going sideways with python packages on github actions
6494
# MacOS:
6595
# runs-on: 'macos-latest'
@@ -73,4 +103,3 @@ jobs:
73103
# pip install .
74104
# - name: Test
75105
# run: python3 -m pytest --ignore docs --ignore dlib
76-

dlib/external/pybind11/CMakeLists.txt

Lines changed: 114 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,15 @@ if(NOT CMAKE_VERSION VERSION_LESS "3.27")
1010
cmake_policy(GET CMP0148 _pybind11_cmp0148)
1111
endif()
1212

13-
cmake_minimum_required(VERSION 3.5)
14-
15-
# The `cmake_minimum_required(VERSION 3.5...3.27)` syntax does not work with
16-
# some versions of VS that have a patched CMake 3.11. This forces us to emulate
17-
# the behavior using the following workaround:
18-
if(${CMAKE_VERSION} VERSION_LESS 3.27)
19-
cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
20-
else()
21-
cmake_policy(VERSION 3.27)
22-
endif()
13+
cmake_minimum_required(VERSION 3.15...4.2)
2314

2415
if(_pybind11_cmp0148)
2516
cmake_policy(SET CMP0148 ${_pybind11_cmp0148})
2617
unset(_pybind11_cmp0148)
2718
endif()
2819

2920
# Avoid infinite recursion if tests include this as a subdirectory
30-
if(DEFINED PYBIND11_MASTER_PROJECT)
31-
return()
32-
endif()
21+
include_guard(GLOBAL)
3322

3423
# Extract project version from source
3524
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/pybind11/detail/common.h"
@@ -74,16 +63,15 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
7463

7564
set(PYBIND11_MASTER_PROJECT ON)
7665

77-
if(OSX AND CMAKE_VERSION VERSION_LESS 3.7)
78-
# Bug in macOS CMake < 3.7 is unable to download catch
79-
message(WARNING "CMAKE 3.7+ needed on macOS to download catch, and newer HIGHLY recommended")
80-
elseif(WINDOWS AND CMAKE_VERSION VERSION_LESS 3.8)
81-
# Only tested with 3.8+ in CI.
82-
message(WARNING "CMAKE 3.8+ tested on Windows, previous versions untested")
83-
endif()
84-
8566
message(STATUS "CMake ${CMAKE_VERSION}")
8667

68+
if(DEFINED SKBUILD AND DEFINED ENV{PYBIND11_GLOBAL_SDIST})
69+
message(
70+
FATAL_ERROR
71+
"PYBIND11_GLOBAL_SDIST is not supported, use nox -s build_global or a pybind11-global SDist instead."
72+
)
73+
endif()
74+
8775
if(CMAKE_CXX_STANDARD)
8876
set(CMAKE_CXX_EXTENSIONS OFF)
8977
set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -100,7 +88,7 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
10088
else()
10189
set(PYBIND11_MASTER_PROJECT OFF)
10290
set(pybind11_system SYSTEM)
103-
set(_pybind11_findpython_default OFF)
91+
set(_pybind11_findpython_default COMPAT)
10492
endif()
10593

10694
# Options
@@ -111,54 +99,115 @@ option(PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION
11199
"To enforce that a handle_type_name<> specialization exists" OFF)
112100
option(PYBIND11_SIMPLE_GIL_MANAGEMENT
113101
"Use simpler GIL management logic that does not support disassociation" OFF)
114-
option(PYBIND11_NUMPY_1_ONLY
115-
"Disable NumPy 2 support to avoid changes to previous pybind11 versions." OFF)
116102
set(PYBIND11_INTERNALS_VERSION
117103
""
118104
CACHE STRING "Override the ABI version, may be used to enable the unstable ABI.")
105+
option(PYBIND11_USE_CROSSCOMPILING "Respect CMAKE_CROSSCOMPILING" OFF)
119106

120107
if(PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION)
121108
add_compile_definitions(PYBIND11_DISABLE_HANDLE_TYPE_NAME_DEFAULT_IMPLEMENTATION)
122109
endif()
123110
if(PYBIND11_SIMPLE_GIL_MANAGEMENT)
124111
add_compile_definitions(PYBIND11_SIMPLE_GIL_MANAGEMENT)
125112
endif()
126-
if(PYBIND11_NUMPY_1_ONLY)
127-
add_compile_definitions(PYBIND11_NUMPY_1_ONLY)
128-
endif()
129113

130114
cmake_dependent_option(
131115
USE_PYTHON_INCLUDE_DIR
132116
"Install pybind11 headers in Python include directory instead of default installation prefix"
133117
OFF "PYBIND11_INSTALL" OFF)
134118

135-
cmake_dependent_option(PYBIND11_FINDPYTHON "Force new FindPython" ${_pybind11_findpython_default}
136-
"NOT CMAKE_VERSION VERSION_LESS 3.12" OFF)
119+
set(PYBIND11_FINDPYTHON
120+
${_pybind11_findpython_default}
121+
CACHE STRING "Force new FindPython - NEW, OLD, COMPAT")
137122

138-
# Allow PYTHON_EXECUTABLE if in FINDPYTHON mode and building pybind11's tests
139-
# (makes transition easier while we support both modes).
140-
if(PYBIND11_MASTER_PROJECT
141-
AND PYBIND11_FINDPYTHON
142-
AND DEFINED PYTHON_EXECUTABLE
143-
AND NOT DEFINED Python_EXECUTABLE)
144-
set(Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
123+
if(PYBIND11_MASTER_PROJECT)
124+
125+
# Allow PYTHON_EXECUTABLE if in FINDPYTHON mode and building pybind11's tests
126+
# (makes transition easier while we support both modes).
127+
if(PYBIND11_FINDPYTHON
128+
AND DEFINED PYTHON_EXECUTABLE
129+
AND NOT DEFINED Python_EXECUTABLE)
130+
set(Python_EXECUTABLE "${PYTHON_EXECUTABLE}")
131+
endif()
132+
133+
# This is a shortcut that is primarily for the venv cmake preset,
134+
# but can be used to quickly setup tests manually, too
135+
set(PYBIND11_CREATE_WITH_UV
136+
""
137+
CACHE STRING "Create a virtualenv if it doesn't exist")
138+
139+
if(NOT PYBIND11_CREATE_WITH_UV STREQUAL "")
140+
set(Python_ROOT_DIR "${CMAKE_CURRENT_BINARY_DIR}/.venv")
141+
if(EXISTS "${Python_ROOT_DIR}")
142+
if(EXISTS "${CMAKE_BINARY_DIR}/CMakeCache.txt")
143+
message(STATUS "Using existing venv at ${Python_ROOT_DIR}, remove or --fresh to recreate")
144+
else()
145+
# --fresh used to remove the cache
146+
file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/.venv")
147+
endif()
148+
endif()
149+
if(NOT EXISTS "${Python_ROOT_DIR}")
150+
find_program(UV uv REQUIRED)
151+
# CMake 3.19+ would be able to use COMMAND_ERROR_IS_FATAL
152+
message(
153+
STATUS "Creating venv with ${UV} venv -p ${PYBIND11_CREATE_WITH_UV} '${Python_ROOT_DIR}'")
154+
execute_process(COMMAND ${UV} venv -p ${PYBIND11_CREATE_WITH_UV} "${Python_ROOT_DIR}"
155+
RESULT_VARIABLE _venv_result)
156+
if(_venv_result AND NOT _venv_result EQUAL 0)
157+
message(FATAL_ERROR "uv venv failed with '${_venv_result}'")
158+
endif()
159+
message(
160+
STATUS
161+
"Installing deps with ${UV} pip install -p '${Python_ROOT_DIR}' -r tests/requirements.txt"
162+
)
163+
execute_process(
164+
COMMAND ${UV} pip install -p "${Python_ROOT_DIR}" -r
165+
"${CMAKE_CURRENT_SOURCE_DIR}/tests/requirements.txt" RESULT_VARIABLE _pip_result)
166+
if(_pip_result AND NOT _pip_result EQUAL 0)
167+
message(FATAL_ERROR "uv pip install failed with '${_pip_result}'")
168+
endif()
169+
endif()
170+
else()
171+
if(NOT DEFINED Python3_EXECUTABLE
172+
AND NOT DEFINED Python_EXECUTABLE
173+
AND NOT DEFINED Python_ROOT_DIR
174+
AND NOT DEFINED ENV{VIRTUALENV}
175+
AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.venv")
176+
message(STATUS "Autodetecting Python in virtual environment")
177+
set(Python_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/.venv")
178+
endif()
179+
endif()
145180
endif()
146181

147-
# NB: when adding a header don't forget to also add it to setup.py
148182
set(PYBIND11_HEADERS
183+
include/pybind11/detail/argument_vector.h
149184
include/pybind11/detail/class.h
150185
include/pybind11/detail/common.h
186+
include/pybind11/detail/cpp_conduit.h
151187
include/pybind11/detail/descr.h
188+
include/pybind11/detail/dynamic_raw_ptr_cast_if_possible.h
189+
include/pybind11/detail/exception_translation.h
190+
include/pybind11/detail/function_record_pyobject.h
191+
include/pybind11/detail/holder_caster_foreign_helpers.h
152192
include/pybind11/detail/init.h
153193
include/pybind11/detail/internals.h
194+
include/pybind11/detail/native_enum_data.h
195+
include/pybind11/detail/pybind11_namespace_macros.h
196+
include/pybind11/detail/struct_smart_holder.h
154197
include/pybind11/detail/type_caster_base.h
155198
include/pybind11/detail/typeid.h
199+
include/pybind11/detail/using_smart_holder.h
200+
include/pybind11/detail/value_and_holder.h
156201
include/pybind11/attr.h
157202
include/pybind11/buffer_info.h
158203
include/pybind11/cast.h
159204
include/pybind11/chrono.h
160205
include/pybind11/common.h
161206
include/pybind11/complex.h
207+
include/pybind11/conduit/pybind11_conduit_v1.h
208+
include/pybind11/conduit/pybind11_platform_abi_id.h
209+
include/pybind11/conduit/wrap_include_python_h.h
210+
include/pybind11/critical_section.h
162211
include/pybind11/options.h
163212
include/pybind11/eigen.h
164213
include/pybind11/eigen/common.h
@@ -168,20 +217,25 @@ set(PYBIND11_HEADERS
168217
include/pybind11/eval.h
169218
include/pybind11/gil.h
170219
include/pybind11/gil_safe_call_once.h
220+
include/pybind11/gil_simple.h
171221
include/pybind11/iostream.h
172222
include/pybind11/functional.h
223+
include/pybind11/native_enum.h
173224
include/pybind11/numpy.h
174225
include/pybind11/operators.h
175226
include/pybind11/pybind11.h
176227
include/pybind11/pytypes.h
228+
include/pybind11/subinterpreter.h
177229
include/pybind11/stl.h
178230
include/pybind11/stl_bind.h
179231
include/pybind11/stl/filesystem.h
232+
include/pybind11/trampoline_self_life_support.h
180233
include/pybind11/type_caster_pyobject_ptr.h
181-
include/pybind11/typing.h)
234+
include/pybind11/typing.h
235+
include/pybind11/warnings.h)
182236

183237
# Compare with grep and warn if mismatched
184-
if(PYBIND11_MASTER_PROJECT AND NOT CMAKE_VERSION VERSION_LESS 3.12)
238+
if(PYBIND11_MASTER_PROJECT)
185239
file(
186240
GLOB_RECURSE _pybind11_header_check
187241
LIST_DIRECTORIES false
@@ -199,10 +253,7 @@ if(PYBIND11_MASTER_PROJECT AND NOT CMAKE_VERSION VERSION_LESS 3.12)
199253
endif()
200254
endif()
201255

202-
# CMake 3.12 added list(TRANSFORM <list> PREPEND
203-
# But we can't use it yet
204-
string(REPLACE "include/" "${CMAKE_CURRENT_SOURCE_DIR}/include/" PYBIND11_HEADERS
205-
"${PYBIND11_HEADERS}")
256+
list(TRANSFORM PYBIND11_HEADERS PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/")
206257

207258
# Cache variable so this can be used in parent projects
208259
set(pybind11_INCLUDE_DIR
@@ -257,6 +308,9 @@ elseif(USE_PYTHON_INCLUDE_DIR AND DEFINED PYTHON_INCLUDE_DIR)
257308
endif()
258309

259310
if(PYBIND11_INSTALL)
311+
if(DEFINED SKBUILD_PROJECT_NAME AND SKBUILD_PROJECT_NAME STREQUAL "pybind11_global")
312+
install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION "${SKBUILD_HEADERS_DIR}")
313+
endif()
260314
install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
261315
set(PYBIND11_CMAKECONFIG_INSTALL_DIR
262316
"${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}"
@@ -272,25 +326,11 @@ if(PYBIND11_INSTALL)
272326
tools/${PROJECT_NAME}Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
273327
INSTALL_DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
274328

275-
if(CMAKE_VERSION VERSION_LESS 3.14)
276-
# Remove CMAKE_SIZEOF_VOID_P from ConfigVersion.cmake since the library does
277-
# not depend on architecture specific settings or libraries.
278-
set(_PYBIND11_CMAKE_SIZEOF_VOID_P ${CMAKE_SIZEOF_VOID_P})
279-
unset(CMAKE_SIZEOF_VOID_P)
280-
281-
write_basic_package_version_file(
282-
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
283-
VERSION ${PROJECT_VERSION}
284-
COMPATIBILITY AnyNewerVersion)
285-
286-
set(CMAKE_SIZEOF_VOID_P ${_PYBIND11_CMAKE_SIZEOF_VOID_P})
287-
else()
288-
# CMake 3.14+ natively supports header-only libraries
289-
write_basic_package_version_file(
290-
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
291-
VERSION ${PROJECT_VERSION}
292-
COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT)
293-
endif()
329+
# CMake natively supports header-only libraries
330+
write_basic_package_version_file(
331+
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
332+
VERSION ${PROJECT_VERSION}
333+
COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT)
294334

295335
install(
296336
FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
@@ -299,6 +339,7 @@ if(PYBIND11_INSTALL)
299339
tools/pybind11Common.cmake
300340
tools/pybind11Tools.cmake
301341
tools/pybind11NewTools.cmake
342+
tools/pybind11GuessPythonExtSuffix.cmake
302343
DESTINATION ${PYBIND11_CMAKECONFIG_INSTALL_DIR})
303344

304345
if(NOT PYBIND11_EXPORT_NAME)
@@ -336,6 +377,17 @@ if(PYBIND11_INSTALL)
336377
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pybind11.pc"
337378
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig/")
338379

380+
# When building a wheel, include __init__.py's for modules
381+
# (see https://github.com/pybind/pybind11/pull/5552)
382+
if(DEFINED SKBUILD_PROJECT_NAME AND SKBUILD_PROJECT_NAME STREQUAL "pybind11")
383+
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/empty")
384+
file(TOUCH "${CMAKE_CURRENT_BINARY_DIR}/empty/__init__.py")
385+
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/empty/__init__.py"
386+
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/")
387+
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/empty/__init__.py"
388+
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig/")
389+
endif()
390+
339391
# Uninstall target
340392
if(PYBIND11_MASTER_PROJECT)
341393
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake_uninstall.cmake.in"

dlib/external/pybind11/README.dlib

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
This directory vendors pybind11 v3.0.4 from commit
2+
d03662f0984f652b60e7ddce53d3868002275197.
3+
4+
The following paths are copied unchanged from the upstream release tag:
5+
6+
- CMakeLists.txt
7+
- LICENSE
8+
- README.rst
9+
- include/
10+
- tools/
11+
12+
When updating pybind11, replace all of those paths from one tagged upstream
13+
release. Do not mix headers or CMake helpers from different revisions.

0 commit comments

Comments
 (0)