Skip to content

[MRG] Load triton before TensorFlow in ot.backend (closes #816) - #839

Open
deeb01 wants to merge 1 commit into
PythonOT:masterfrom
deeb01:fix-816-triton-import-order
Open

[MRG] Load triton before TensorFlow in ot.backend (closes #816)#839
deeb01 wants to merge 1 commit into
PythonOT:masterfrom
deeb01:fix-816-triton-import-order

Conversation

@deeb01

@deeb01 deeb01 commented Aug 25, 2026

Copy link
Copy Markdown

Types of changes

Bug fix (non-breaking change which fixes an issue).

Motivation and context / Related issue

Closes #816.

triton and TensorFlow both ship a statically linked LLVM; loading libtriton.so after TensorFlow segfaults inside dlopen. torch imports triton lazily, on the first torch.optim constructor — which in a POT process is after TensorFlow is resident. TensorFlow is the trigger, not JAX.

ot/backend.py imports torch ~60 lines before TensorFlow, so the probe goes there, guarded on TensorFlow being importable. Not in conftest.py: the doc build never loads it. Both torch<2.12 pins removed.

Upstream reproducer: import tensorflow; import triton.

How has this been tested (if it applies)

On Linux with torch 2.13.0+cu130, triton 3.7.1, TensorFlow 2.21.0, test/conftest.py untouched:

with fix without
test_free_support_barycenter_generic_costs_auto_ground_bary passes rc=139 SIGSEGV
new test passes fails, returncode=-11
test_ot.py + test_backend.py 91 passed, 8 skipped

The new test runs in a subprocess so the segfault is reported as a failure rather than killing the runner.

PR checklist

  • I have read the CONTRIBUTING document.
  • The documentation is up-to-date with the changes I made (check build artifacts).
  • All tests passed, and additional code has been covered with new tests.
  • I have added the PR and Issue fix to the RELEASES.md file.

triton and TensorFlow both ship a statically linked LLVM. Loading triton's
libtriton.so into a process that has already imported TensorFlow segfaults
inside dlopen, during the static initializers of a 461 MB shared object.

torch imports triton lazily rather than at import time: torch.optim's
Optimizer.__init__ calls add_param_group, which is decorated with
@torch._disable_dynamo, whose wrapper imports torch._dynamo on first call,
which calls torch.utils._triton.has_triton_package(), which imports triton.
So the first construction of any torch optimizer loads libtriton, and in a
process that imported ot.backend that happens after TensorFlow is resident.

This is why the crash only appeared in the jobs that install every backend
into one process, and why the individual tests all passed on their own.
It is not specific to torch 2.12; that was simply when torch started
shipping a triton version that collides.

ot.backend already imports torch before TensorFlow, so probing for triton
at the torch import site loads it while the process is still clean. The
probe is guarded on TensorFlow actually being importable, so installations
without TensorFlow do not pay the cost of loading libtriton.

Reproduced on Linux with torch 2.13.0, triton 3.7.1 and TensorFlow 2.21.0:
the crash is a SIGSEGV at triton/knobs.py:15 inside create_module, matching
the traceback in the issue. Verified that importing triton after TensorFlow
still crashes, so it is the ordering and not the import itself that matters.

Adds a non-regression test that builds a torch optimizer after importing
ot.backend in a subprocess, so the segfault is reported as a test failure
instead of killing the test runner. Removes the torch<2.12 pin from
.github/requirements_doctests.txt and docs/requirements.txt.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug on linux tests and doc build with Pytorch 2.12

1 participant