Skip to content

Commit 06676d4

Browse files
committed
BUG: fix nogil LinearNDInterpolator
* Fixes scipygh-21885 * A `nogil` block in `LinearNDInterpolator` is reliably segfaulting on x86_64 Ubuntu Linux with Python 3.10 and Python 3.11. I see the same error locally as reported in CI, and it is present in both `v1.14.1` and on latest `main` branch of SciPy. Diffing the last succeeding version of the CI job with the current failing CI job only shows `tomli` and `hypothesis` changing versions. So, this is pretty weird, but the test is behind a `slow` marker so maybe we're just discovering the instability now for some reason. * Removing the `nogil` directive fixes the issue on Python `3.10` and `3.11` locally. * Note that GNU compiler toolchains 9.x and 11.x both reproduce the segfault locally as well, so the "minimum version" CI label may be a red herring. It is also worth noting that the CI job name contains "fast," and the `pytest` incantation isn't using slow, so there may be yet another issue about i.e., respecting markers when running `pytest` outside the root folder in that job or something like that. Nonetheless, the test fails consistently before this fix locally, which should probably supersede performance concerns for now. [skip circle] [skip cirrus]
1 parent d821271 commit 06676d4

File tree

1 file changed

+20
-18
lines changed

1 file changed

+20
-18
lines changed

scipy/interpolate/_interpnd.pyx

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -336,30 +336,32 @@ class LinearNDInterpolator(NDInterpolatorBase):
336336
eps = 100 * DBL_EPSILON
337337
eps_broad = sqrt(DBL_EPSILON)
338338

339-
with nogil:
340-
for i in range(xi.shape[0]):
339+
# NOTE: a nogil block segfaults here with Python 3.10
340+
# and 3.11 on x86_64 Ubuntu Linux with gcc 9.x and 11.x
341+
# and therefore nogil was disabled to fix gh-21885
342+
for i in range(xi.shape[0]):
341343

342-
# 1) Find the simplex
344+
# 1) Find the simplex
343345

344-
isimplex = qhull._find_simplex(&info, c,
345-
&xi[0,0] + i*ndim,
346-
&start, eps, eps_broad)
346+
isimplex = qhull._find_simplex(&info, c,
347+
&xi[0,0] + i*ndim,
348+
&start, eps, eps_broad)
347349

348-
# 2) Linear barycentric interpolation
349-
350-
if isimplex == -1:
351-
# don't extrapolate
352-
for k in range(nvalues):
353-
out[i,k] = fill_value
354-
continue
350+
# 2) Linear barycentric interpolation
355351

352+
if isimplex == -1:
353+
# don't extrapolate
356354
for k in range(nvalues):
357-
out[i,k] = 0
355+
out[i,k] = fill_value
356+
continue
358357

359-
for j in range(ndim+1):
360-
for k in range(nvalues):
361-
m = simplices[isimplex,j]
362-
out[i,k] = out[i,k] + c[j] * values[m,k]
358+
for k in range(nvalues):
359+
out[i,k] = 0
360+
361+
for j in range(ndim+1):
362+
for k in range(nvalues):
363+
m = simplices[isimplex,j]
364+
out[i,k] = out[i,k] + c[j] * values[m,k]
363365

364366
return out
365367

0 commit comments

Comments
 (0)