Skip to content

Commit fe5af6b

Browse files
[shortfin] Fix issues with free threaded Python builds. (#226)
* Fixes a method signature issue that manifested on 3.13 generally (not FT related). * Bumps nanobind to a recent HEAD commit to pick up free threaded support. * Adds nanobind option to enable free threading if building for a CPython with it enabled. * Adds a README stanza advising on how to acquire a free threaded CPython. * Makes fastapi tests skip if deps not met (not yet available / hard to install). * Adds an LSAN exclusion for something unrelated that has snuck in. * Sets FT CMAKE_BUILD_TYPE=Debug in the CI. Note that on the large NUMA system I was testing on, the CPU test which creates an executor on each NUMA node for all processes exceeded the default file handle ulimit, requiring it to be increased. I assume that the FT CPython internally uses more synchronization handles and it just happened to go over budget. This resulted in fixing iree-org/iree#18609, which was causing an assert to be hit in this specific RESOURCE_EXHAUSTED scenario.
1 parent a9fecda commit fe5af6b

File tree

6 files changed

+33
-4
lines changed

6 files changed

+33
-4
lines changed

.github/workflows/ci_linux_x64_nogil-libshortfin.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ jobs:
7979
mkdir ${{ env.LIBSHORTFIN_DIR }}/build
8080
cd ${{ env.LIBSHORTFIN_DIR }}/build
8181
cmake -GNinja \
82+
-DCMAKE_BUILD_TYPE=Debug \
8283
-DCMAKE_C_COMPILER=clang-18 \
8384
-DCMAKE_CXX_COMPILER=clang++-18 \
8485
-DCMAKE_LINKER_TYPE=LLD \

libshortfin/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,23 @@ recommended:
101101
* Compile dependencies with `-fvisibility=hidden`
102102
* Enable LTO builds of libshortfin
103103
* Set flags to enable symbol versioning
104+
105+
# Miscellaneous Build Topics
106+
107+
## Free threaded Python
108+
109+
Support for free threaded Python builds (aka. "nogil") is in progress. It
110+
is currently being tested via dev builds of CPython 3.13 with the
111+
`--disable-gil` option set. There are multiple ways to acquire such an
112+
environment. If using `pyenv`, here is a way:
113+
114+
```
115+
# Build a 3.13-dev-nogil version.
116+
PYTHON_CONFIGURE_OPTS='--disable-gil' \
117+
$(pyenv root)/plugins/python-build/bin/python-build 3.13-dev \
118+
$(pyenv root)/versions/3.13-dev-nogil
119+
120+
# Test (should print "1").
121+
pyenv shell 3.13-dev-nogil
122+
python -c 'import sysconfig; print(sysconfig.get_config_var("Py_GIL_DISABLED"))'
123+
```

libshortfin/build_tools/python_lsan_suppressions.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ leak:google/_upb
77
leak:import_find_and_load
88
leak:pyo3::pyclass::create_type_object
99
leak:ufunc
10+
leak:pydantic_core

libshortfin/python/CMakeLists.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,17 @@
1111
# Others.
1212

1313
# nanobind
14+
# Pinned to a pre 2.2.0 commit hash which includes free threaded support.
15+
# TODO: Bump to 2.2.0 when available.
1416
FetchContent_Declare(
1517
nanobind
1618
GIT_REPOSITORY https://github.com/wjakob/nanobind.git
17-
GIT_TAG 9641bb7151f04120013b812789b3ebdfa7e7324f # 2.1.0
19+
GIT_TAG 8ce0dee7f62add575f85c0de386a9c819e4d50af # HEAD > 2.1.0
1820
)
1921
FetchContent_MakeAvailable(nanobind)
2022

21-
nanobind_add_module(shortfin_python_extension NB_STATIC LTO
23+
nanobind_add_module(shortfin_python_extension
24+
NB_STATIC LTO FREE_THREADED
2225
array_binding.cc
2326
array_host_ops.cc
2427
lib_ext.cc

libshortfin/python/_shortfin/asyncio_bridge.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ def get_debug(self):
1717
# Requirement of asyncio.
1818
return False
1919

20-
def create_task(self, coro):
21-
return asyncio.Task(coro, loop=self)
20+
def create_task(self, coro, *, name=None, context=None):
21+
return asyncio.Task(coro, loop=self, name=name, context=context)
2222

2323
def create_future(self):
2424
return asyncio.Future(loop=self)

libshortfin/tests/examples/fastapi_test.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020

2121
@pytest.fixture(scope="session")
2222
def server():
23+
try:
24+
import fastapi
25+
except ModuleNotFoundError as e:
26+
pytest.skip(f"Required dep not available: {e}")
2327
runner = ServerRunner([])
2428
yield runner
2529
print("Sending kill signal")

0 commit comments

Comments
 (0)