Skip to content

ENH: Release Python GIL during ITK operations - #5776

Merged
thewtex merged 2 commits into
mainfrom
copilot/release-gil-itk-operations
Feb 12, 2026
Merged

thewtex merged 2 commits into
mainfrom
copilot/release-gil-itk-operations

Conversation

Copilot AI commented Feb 6, 2026 •

Copy link
Copy Markdown
Contributor

Description

ITK Python wrappers hold the Global Interpreter Lock during C++ operations, preventing concurrent execution in multi-threaded contexts (Dask, Ray, threading module) and causing server lockups.

Changes

  • CMake option: Added ITK_PYTHON_RELEASE_GIL (default ON) to control GIL release behavior
  • SWIG configuration: Pass -threads flag to generate wrappers that release/reacquire GIL around C++ calls
  • Test: test_gil_release.py verifies concurrent execution via timing overlap detection with 4 Python threads and single-threaded ITK filters for reliable testing
  • Documentation: ITK 6 migration guide section with usage examples

Implementation

Follows SimpleITK's approach (commit e9ce7283) - SWIG's -threads flag handles GIL release/reacquire automatically.

import itk
import threading

def process_image(path):
    # GIL released during ITK operations
    image = itk.imread(path)
    return itk.median_image_filter(image, radius=5)

# True concurrent execution now possible
threads = [threading.Thread(target=process_image, args=(p,)) for p in paths]
for t in threads: t.start()
for t in threads: t.join()

Disable with -DITK_PYTHON_RELEASE_GIL=OFF if callbacks/events require GIL.

Test Configuration

The GIL release test is designed for reliability and sensitivity:

  • 4 outer Python threads: Makes parallel execution effects more obvious and measurable
  • 1 ITK work unit per filter: Limits internal ITK threading to isolate GIL release behavior
  • 0.5 speedup threshold: Expects at least 2x speedup with proper GIL release
  • Failure on no concurrency: Test fails (returns 1) when concurrent execution is not detected

PR Checklist

  • No API changes were made (or the changes have been approved)
  • No major design changes were made (or the changes have been approved)
  • Added test (or behavior not changed)
  • Updated API documentation (or API not changed)
  • Added license to new files (if any)
  • Added Python wrapping to new files (if any) as described in ITK Software Guide Section 9.5
  • Added ITK examples for all new major features (if any)
Original prompt

This section details on the original issue you should resolve

<issue_title>Release the GIL in ITK operations</issue_title>
<issue_description>First, a question: Does the ITK Python library release the GIL when it calls down to lower level C/C++ code?

When I run ITK operations within Dask I notice that my servers lock up. The most common cause of this is that some low level code is holding onto the GIL and not letting go. Is it possible that ITK does this?

If ITK does not release the GIL, could it?

xref https://discourse.itk.org/t/parallelize-itk-imageseriesreader-itk-4-12/1745/15</issue_description>

Comments on the Issue (you are @copilot in this section)

@thewtex @mrocklin thanks for the report. We will dive deeper into this.

:xref: #1065 , which was not sufficient.</comment_new>
<comment_new>@blowekamp
This is how it is done in SimpleITK:
SimpleITK/SimpleITK@e9ce728</comment_new>
<comment_new>@thewtex
I am wondering if the observed behavior was related to:

cfdb502

or

#2069

@thewtex Hi @lust4life ,

Can you provide more context on ray?

itkElastixRegistrationMethod.UpdateLargestPossibleRegion, [...] it finished the registration.

It is expected that UpdateLargestPossibleRegion does not return until registration completes.</comment_new>
<comment_new>@blowekamp
This sample code appears to use asyncio, which is not multi-threading. Use the two concurrently can make things complicated, and at least make a poor example illustrated the issue. Unlocking the GIL during computation allows another thread to use the single threaded python interpreter, but does not "yield" in the async thread.

One possible work around is to wrap the computation in a async subprocess. Some ITK filters and process use callback to report progress, these could theoretically be use to yield computation but there are a lot of details here too.

Another alternative is to look at SimpleITK as it unlocks the GIL, as see if that could work better with the ray computational infrastructure.

@dzenanz @thewtex might want to comment now. @blowekamp > Plan to expose these function as an FastAPI http call, a long run case make the whole web service blocked.

There are many reasons why ITK computations should not be done in the same thread or process as a web server. I have used some type of task queue for this type of computational work, where the image processing is done in a separate process(es) shared by all api threads. As I suggested before at minimum I'd suggest running the ITK algorithm in a sub-process of the api thread, but managing resources when many ITK processes are requested would still be challanging.

I can't use it, as it has its own conventions which will generate the output image by default as the result for these calls, but what i want is just the registration output parameters.

Yes, that seams a reasonable weakness on the SimpleElastix interface, alternatives can always be proposed. </comment_new>
<comment_new>@thewtex
@lust4life thanks for the detailed report, explanation, and reproducible sample code 👏

I will:

  1. Look into the ITK GIL usage with the sample code.
  2. Look towards ITK-Wasm functionality for your use case, which inherently has better sandboxing.</comment_new>

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Investigate GIL release in ITK operations ENH: Release Python GIL during ITK operations Feb 6, 2026
Copilot AI requested a review from thewtex February 6, 2026 21:53
@hjmjohnson
hjmjohnson force-pushed the copilot/release-gil-itk-operations branch from e121d68 to df497d8 Compare February 9, 2026 14:51
@github-actions github-actions Bot added type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots type:Enhancement Improvement of existing methods or implementation area:Python wrapping Python bindings for a class type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct area:Documentation Issues affecting the Documentation module labels Feb 9, 2026
@dzenanz

dzenanz commented Feb 9, 2026

Copy link
Copy Markdown
Member

@copilot apply my review suggestions.

Copilot AI commented Feb 9, 2026

Copy link
Copy Markdown
Contributor Author

@copilot apply my review suggestions.

Applied all review suggestions in commit bae360f:

  • Limited ITK internal threads to 1 via SetNumberOfWorkUnits(1)
  • Increased outer thread count from 2 to 4
  • Adjusted speedup threshold from 0.9 to 0.5 for 4 threads
  • Test now fails (returns 1) when no concurrent execution is detected

Copilot AI requested a review from dzenanz February 9, 2026 17:32

@dzenanz dzenanz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but does it work? Can someone test this locally?

@thewtex

thewtex commented Feb 10, 2026

Copy link
Copy Markdown
Member

I tested it locally, tests pass, including the new test, and I tested the example in the Migration Guide, and it works.

It will be interesting to see how this behaves in the wild with dask, etc. after released.

@thewtex
thewtex force-pushed the copilot/release-gil-itk-operations branch from bae360f to 910410a Compare February 10, 2026 15:38
@thewtex
thewtex marked this pull request as ready for review February 10, 2026 15:38
@thewtex thewtex added this to the ITK 6.0 Beta 2 milestone Feb 10, 2026
@thewtex
thewtex force-pushed the copilot/release-gil-itk-operations branch from 910410a to 47fd5b0 Compare February 10, 2026 15:40
@thewtex
thewtex force-pushed the copilot/release-gil-itk-operations branch 2 times, most recently from 347e10a to c37ebca Compare February 10, 2026 16:09
@dzenanz

dzenanz commented Feb 10, 2026

Copy link
Copy Markdown
Member

I now see that Matt doesn't have write access? Why? He is a member of ITKLeadDevelopers team, and that team has admin access in ITK repo:
Screenshot 2026-02-10 11 08 34

- Added cmake option ITK_PYTHON_RELEASE_GIL (default ON) in WrappingOptions.cmake
- Modified Python CMakeLists.txt to add -threads flag to SWIG when option is enabled
- Created test_gil_release.py to verify GIL is released during ITK operations
- Added test to CMakeLists.txt

Co-authored-by: Matthew McCormick <matt@fideus.io>
Co-authored-by: dzenanz <1792121+dzenanz@users.noreply.github.com>
Co-authored-by: Matthew McCormick <matt@fideus.io>
@hjmjohnson
hjmjohnson force-pushed the copilot/release-gil-itk-operations branch from c37ebca to f8b120f Compare February 11, 2026 17:29
@hjmjohnson

Copy link
Copy Markdown
Member

@thewtex I think this is ready for testing in the main branch. If you are satisfied with the current codebase, would you please merge? I rebased and fixed merge conflicts, so I would prefer you to do the final merge.

@thewtex

thewtex commented Feb 12, 2026

Copy link
Copy Markdown
Member

@dzenanz I have not lost merge permissions, but thanks for checking :-).

@hjmjohnson yes, it LGTM. Let's put it out there for testing in the wild.

@thewtex
thewtex merged commit f396e52 into main Feb 12, 2026
11 checks passed
@thewtex
thewtex deleted the copilot/release-gil-itk-operations branch February 12, 2026 20:04
@dzenanz

dzenanz commented Feb 12, 2026

Copy link
Copy Markdown
Member

@thewtex your PR approval had gray check mark, instead of the usual green.

hjmjohnson pushed a commit to hjmjohnson/ITK that referenced this pull request May 6, 2026
…eConsortium/copilot/release-gil-itk-operations

ENH: Release Python GIL during ITK operations
hjmjohnson pushed a commit to hjmjohnson/ITK that referenced this pull request May 12, 2026
…eConsortium/copilot/release-gil-itk-operations

ENH: Release Python GIL during ITK operations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:Documentation Issues affecting the Documentation module area:Python wrapping Python bindings for a class type:Enhancement Improvement of existing methods or implementation type:Infrastructure Infrastructure/ecosystem related changes, such as CMake or buildbots type:Testing Ensure that the purpose of a class is met/the results on a wide set of test cases are correct

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Release the GIL in ITK operations

4 participants