Skip to content

Commit 40f7f75

Browse files
committed
Added an experimental support of free-threading/no-GIL.
1 parent e492fa8 commit 40f7f75

File tree

5 files changed

+34
-0
lines changed

5 files changed

+34
-0
lines changed

python/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,12 @@ with urllib.request.urlopen(
209209
sp = spm.SentencePieceProcessor(model_proto=model.getvalue())
210210
print(sp.encode('this is test'))
211211
```
212+
213+
### Free Threading support
214+
Experimental support for no-GIL/Free-Threading has been introduced since v0.2.1. For more details, please refer to [this page](https://py-free-threading.github.io.).
215+
This operates similarly to how [NumPy](https://numpy.org/devdocs/reference/thread_safety.html#free-threaded-python) handles it.
216+
217+
The C++ library's const and static methods, e.g., encode(), decode() and train(), are designed to work in a non-GIL environment.
218+
However, non-const methods, e.g., load(), may have potential data race issues, so please ensure you implement appropriate locks beforehand.
219+
220+
While this limitation might be removed in the future, please note that it's not a simple fix, as it would require additional shared locks in C++.

python/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ classifiers = [
2828
"Programming Language :: Python :: 3.12",
2929
"Programming Language :: Python :: 3.13",
3030
"Programming Language :: Python :: 3.14",
31+
"Programming Language :: Python :: Free Threading :: 2 - Beta",
3132
"Topic :: Text Processing :: Linguistic",
3233
"Topic :: Software Development :: Libraries :: Python Modules",
3334
]

python/setup.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import shutil
2222
import subprocess
2323
import sys
24+
import sysconfig
2425
from setuptools import Extension, setup
2526
from setuptools.command.build_ext import build_ext as _build_ext
2627

@@ -60,6 +61,10 @@ def is_sentencepiece_installed():
6061
return False
6162

6263

64+
def is_gil_disabled():
65+
return sysconfig.get_config_var('Py_GIL_DISABLED')
66+
67+
6368
def get_cflags_and_libs(root):
6469
cflags = ['-std=c++17', '-I' + os.path.join(root, 'include')]
6570
libs = []
@@ -103,6 +108,8 @@ def build_extension(self, ext):
103108
libs.append('-Wl,-strip-all')
104109
if sys.platform == 'linux':
105110
libs.append('-Wl,-Bsymbolic')
111+
if is_gil_disabled():
112+
cflags.append('-DPy_GIL_DISABLED')
106113
print('## cflags={}'.format(' '.join(cflags)))
107114
print('## libs={}'.format(' '.join(libs)))
108115
ext.extra_compile_args = cflags
@@ -198,11 +205,17 @@ def get_win_arch():
198205
'8',
199206
])
200207
cflags = ['/std:c++17', '/I.\\build\\root\\include']
208+
201209
libs = [
202210
'.\\build\\root\\lib\\sentencepiece.lib',
203211
'.\\build\\root\\lib\\sentencepiece_train.lib',
204212
]
205213

214+
# on Windows, GIL flag is not set automatically.
215+
# https://docs.python.org/3/howto/free-threading-python.html
216+
if is_gil_disabled():
217+
cflags.append('/DPy_GIL_DISABLED')
218+
206219
SENTENCEPIECE_EXT = Extension(
207220
'sentencepiece._sentencepiece',
208221
sources=['src/sentencepiece/sentencepiece_wrap.cxx'],

python/src/sentencepiece/sentencepiece.i

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,12 @@ inline void InitNumThreads(const std::vector<T> &ins, int *num_threads) {
292292
} // namespace
293293
%}
294294

295+
%init %{
296+
#ifdef Py_GIL_DISABLED
297+
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
298+
#endif
299+
%}
300+
295301
%exception {
296302
try {
297303
$action

python/src/sentencepiece/sentencepiece_wrap.cxx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10614,6 +10614,11 @@ SWIG_init(void) {
1061410614

1061510615
SWIG_InstallConstants(d,swig_const_table);
1061610616

10617+
10618+
#ifdef Py_GIL_DISABLED
10619+
PyUnstable_Module_SetGIL(m, Py_MOD_GIL_NOT_USED);
10620+
#endif
10621+
1061710622
#if PY_VERSION_HEX >= 0x03000000
1061810623
return m;
1061910624
#else

0 commit comments

Comments
 (0)