Skip to content

Commit c69d44c

Browse files
committed
updates for free-threading
1 parent 60ad4a5 commit c69d44c

File tree

5 files changed

+65
-59
lines changed

5 files changed

+65
-59
lines changed

.github/workflows/python-package-conda.yml

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,41 +22,51 @@ jobs:
2222
strategy:
2323
fail-fast: False
2424
matrix:
25-
os: [ubuntu-latest, macos-12, windows-latest]
26-
python-version: ["3.10", "3.11", "3.12", "3.13"]
27-
mkl-version: ['2023', '2024']
25+
os: [ubuntu-latest, windows-latest]
26+
python-version: ["3.11", "3.12", "3.13", "3.14"]
27+
mkl-version: ['2024', '2025']
28+
free-threaded: [true, false]
2829
include:
2930
- os: ubuntu-latest
3031
python-version: "3.12"
3132
coverage: ${{ true }}
33+
- os: macos-15-intel
34+
python-version: "3.12"
35+
mkl-version: "2023"
36+
free-threaded: false
3237
exclude:
33-
- os: macos-12
34-
mkl-version: "2024"
38+
- python-version: "3.11"
39+
free-threaded: true
40+
- python-version: "3.12"
41+
free-threaded: true
3542

3643
steps:
37-
- uses: actions/checkout@v4
44+
- uses: actions/checkout@v5
45+
with:
46+
fetch-depth: 0
47+
3848
- name: Setup Conda
3949
uses: conda-incubator/setup-miniconda@v3
4050
with:
41-
python-version: ${{ matrix.python-version }}
4251
channels: conda-forge, defaults
4352
channel-priority: true
4453
activate-environment: dev
4554

46-
- name: Conda information
47-
run: |
48-
conda info
49-
conda list
50-
conda config --show
51-
5255
- name: Create environment
5356
run: |
5457
conda install --quiet --yes -c conda-forge \
58+
${{ matrix.free-threaded && "python-freethreaded" || "python" }}=${{ matrix.python-version }} \
5559
pip numpy scipy cython mkl=${{ matrix.mkl-version }} pytest \
5660
mkl-devel pkg-config meson-python meson ninja setuptools_scm \
5761
${{ matrix.coverage && 'coverage' || ''}} \
5862
${{ matrix.os == 'windows-latest' && '"libblas=*=*mkl"' || ''}}
5963
64+
- name: Conda information
65+
run: |
66+
conda info
67+
conda list
68+
conda config --show
69+
6070
- name: Install Our Package
6171
run: |
6272
python -m pip install --no-build-isolation --verbose --editable . \

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ mkl_solver.c.dep
1010
coverage.xml
1111

1212
.idea/
13+
14+
.vscode/

pydiso/_mkl_solver.pyx.in renamed to pydiso/_mkl_solver.in.pyx

Lines changed: 27 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
#cython: language_level=3
1+
# cython: language_level=3
2+
# cython: embedsignature=True, language_level=3
3+
# cython: freethreading_compatible=True
24
cimport numpy as np
35
import cython
4-
from cpython.pythread cimport (
5-
PyThread_type_lock,
6-
PyThread_allocate_lock,
7-
PyThread_acquire_lock,
8-
PyThread_release_lock,
9-
PyThread_free_lock
10-
)
116

127
import numpy as np
138
import os
@@ -79,7 +74,6 @@ class PardisoError(Exception):
7974
class PardisoWarning(UserWarning):
8075
pass
8176

82-
8377
#call pardiso (pt, maxfct, mnum, mtype, phase, n, a, ia, ja, perm, nrhs, iparm, msglvl, b, x, error)
8478
cdef int mkl_progress(int *thread, int* step, char* stage, int stage_len) nogil:
8579
# must be a nogil process to pass to mkl pardiso progress reporting
@@ -175,7 +169,7 @@ ctypedef fused real_or_complex:
175169
{{for int_type in ["int_t", "long_t"]}}
176170
cdef class _PardisoHandle_{{int_type}}:
177171
cdef _MKL_DSS_HANDLE_t handle[64]
178-
cdef PyThread_type_lock lock
172+
cdef cython.pymutex lock
179173

180174
cdef {{int_type}} n, maxfct, mnum, msglvl
181175
cdef public {{int_type}} matrix_type
@@ -184,7 +178,6 @@ cdef class _PardisoHandle_{{int_type}}:
184178

185179
@cython.boundscheck(False)
186180
def __cinit__(self, A_dat_dtype, n, matrix_type, maxfct, mnum, msglvl):
187-
self.lock = PyThread_allocate_lock()
188181

189182
np_int_dtype = np.dtype(f"i{sizeof({{int_type}})}")
190183

@@ -197,11 +190,13 @@ cdef class _PardisoHandle_{{int_type}}:
197190
self.mnum = mnum
198191
self.msglvl = msglvl
199192

200-
if self.msglvl:
201-
#for reporting factorization progress via python's `print`
202-
mkl_set_progress(mkl_progress)
203-
else:
204-
mkl_set_progress(mkl_no_progress)
193+
194+
with self.lock:
195+
if self.msglvl:
196+
#for reporting factorization progress via python's `print`
197+
mkl_set_progress(mkl_progress)
198+
else:
199+
mkl_set_progress(mkl_no_progress)
205200

206201
is_single_precision = np.issubdtype(A_dat_dtype, np.single) or np.issubdtype(A_dat_dtype, np.csingle)
207202

@@ -264,14 +259,13 @@ cdef class _PardisoHandle_{{int_type}}:
264259
cdef {{int_type}} error, nrhs
265260
with nogil:
266261
nrhs = rhs.shape[1]
267-
PyThread_acquire_lock(self.lock, mode=1)
268-
pardiso{{if int_type == "long_t"}}_64{{endif}}(
269-
self.handle, &self.maxfct, &self.mnum, &self.matrix_type, &phase, &self.n,
270-
&a_data[0], &a_indptr[0], &a_indices[0], &self.perm[0],
271-
&nrhs, self.iparm, &self.msglvl,
272-
&rhs[0, 0], &out[0, 0], &error
273-
)
274-
PyThread_release_lock(self.lock)
262+
with self.lock:
263+
pardiso{{if int_type == "long_t"}}_64{{endif}}(
264+
self.handle, &self.maxfct, &self.mnum, &self.matrix_type, &phase, &self.n,
265+
&a_data[0], &a_indptr[0], &a_indices[0], &self.perm[0],
266+
&nrhs, self.iparm, &self.msglvl,
267+
&rhs[0, 0], &out[0, 0], &error
268+
)
275269
return error
276270

277271
@cython.boundscheck(False)
@@ -280,20 +274,15 @@ cdef class _PardisoHandle_{{int_type}}:
280274
cdef {{int_type}} phase = -1, nrhs = 0, error = 0
281275

282276
with nogil:
283-
PyThread_acquire_lock(self.lock, mode=1)
284-
if self._initialized():
285-
pardiso{{if int_type == "long_t"}}_64{{endif}}(
286-
self.handle, &self.maxfct, &self.mnum, &self.matrix_type,
287-
&phase, &self.n, NULL, NULL, NULL, NULL, &nrhs, self.iparm,
288-
&self.msglvl, NULL, NULL, &error)
289-
if error == 0:
290-
for i in range(64):
291-
self.handle[i] = NULL
292-
PyThread_release_lock(self.lock)
277+
with self.lock:
278+
if self._initialized():
279+
pardiso{{if int_type == "long_t"}}_64{{endif}}(
280+
self.handle, &self.maxfct, &self.mnum, &self.matrix_type,
281+
&phase, &self.n, NULL, NULL, NULL, NULL, &nrhs, self.iparm,
282+
&self.msglvl, NULL, NULL, &error)
283+
if error == 0:
284+
for i in range(64):
285+
self.handle[i] = NULL
293286
if error != 0:
294287
raise MemoryError("Pardiso Memory release error: " + _err_messages[error])
295-
if self.lock:
296-
#deallocate the lock
297-
PyThread_free_lock(self.lock)
298-
self.lock = NULL
299288
{{endfor}}

pydiso/meson.build

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
cython_file = custom_target(
2-
input: '_mkl_solver.pyx.in',
2+
input: '_mkl_solver.in.pyx',
33
output: '_mkl_solver.pyx',
44
command: [py,
55
'-c',
@@ -60,6 +60,11 @@ else
6060

6161
endif
6262

63+
cython_args = []
64+
if cy.version().version_compare('>=3.1.0')
65+
cython_args += ['-Xfreethreading_compatible=True']
66+
endif
67+
6368
c_undefined_ok = ['-Wno-maybe-uninitialized']
6469
cython_c_args = [numpy_nodepr_api, '-DCYTHON_CCOMPLEX=0']
6570

@@ -68,6 +73,7 @@ module_path = 'pydiso'
6873
py.extension_module(
6974
'_mkl_solver',
7075
cython_file,
76+
cython_args: cython_args,
7177
c_args: cython_c_args,
7278
install: true,
7379
subdir: module_path,

pyproject.toml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
build-backend = 'mesonpy'
44
requires = [
55
"meson-python>=0.15.0",
6-
"Cython>=3.0.8",
6+
"Cython>=3.1.0",
77
"setuptools_scm[toml]>=6.2",
88
"numpy>=2.0.0rc1",
99
]
@@ -13,7 +13,7 @@ name = 'pydiso'
1313
dynamic = ["version"]
1414
description = "Wrapper for intel's pardiso implementation in the MKL"
1515
readme = 'README.md'
16-
requires-python = '>=3.10'
16+
requires-python = '>=3.11'
1717
authors = [
1818
{name = 'SimPEG developers', email = '[email protected]'},
1919
]
@@ -28,7 +28,7 @@ dependencies = [
2828
# TODO: update to "pin-compatible" once possible, see
2929
# https://github.com/mesonbuild/meson-python/issues/29
3030
"numpy>=1.22.4",
31-
"scipy>=1.8",
31+
"scipy>=1.12",
3232
]
3333
classifiers = [
3434
"Development Status :: 4 - Beta",
@@ -57,11 +57,11 @@ test = [
5757
]
5858

5959
build = [
60-
"meson-python>=0.14.0",
60+
"meson-python>=0.15.0",
6161
"meson",
6262
"ninja",
63-
"numpy>=1.22.4",
64-
"cython>=0.29.35",
63+
"numpy>=2.0.0rc1",
64+
"cython>=3.1.0",
6565
"setuptools_scm",
6666
]
6767

@@ -74,7 +74,6 @@ Repository = 'https://github.com/simpeg/pydiso.git'
7474

7575
[tool.coverage.run]
7676
branch = true
77-
plugins = ["Cython.Coverage"]
7877
source = ["pydiso", "tests"]
7978

8079
[tool.coverage.report]

0 commit comments

Comments
 (0)