"Fork from non-main thread" warning

Hi there. I am developing a GUI Application for high-energy x-ray diffraction.

When we start a long-running computation, we typically start it in a non-main thread, since the main thread is the GUI thread and we keep the GUI thread free to show things like a progress bar with updates. The long-running computations typically use numba.

In the past few months, we started seeing this message when running these:

Numba: Attempted to fork from a non-main thread, the TBB library may be in an invalid state in the child process.

I guess there is some TBB backend that is forking, and since it is running in a non-main thread, it produces this warning? I have a couple of questions:

  1. Why did this message only start appearing recently for us? Is it due to something new?
  2. Is there any way we can continue to call numba functions from non-main threads? This is preferable for us since, as I mentioned, the main thread is the GUI thread.

Thank you,
Patrick

Some system details:

OS: Ubuntu-22.04 (although I believe the warning is occurring on Mac as well)
python==3.10.6
numba==0.56.4
llvmlite==0.39.1
numpy==1.22.4

Hi @psavery,

I don’t think it will be TBB itself forking (or at least it wouldn’t be to my knowledge). That message appears because a fork(2) call has been made from a thread which is not the thread on which the TBB backend/library was initialised.

Not sure. Have you tried some different versions of Numba? I think that PR #6324 added both the detection code for this problem and the error message, it would have first appeared in Numba 0.52 to fix issue #5973.

Providing an answer to this will depend on what is causing the fork(2) call in the first place and whether the child processes need to use TBB. Maybe try and trace the cause of the fork(2) call, once it’s found it might be possible to suggest workarounds. Standard linux tooling such as strace and gdb should help with finding where the call is made.

Hope this helps?

Hi @stuartarchibald. Thank you for your reply.

I went back and tested a few different numba versions, and it looks like the message starts occurring at numba==0.54.0.

I also ran my python program with gdb and created a breakpoint via break fork. When the relevant functions get called, here is the backtrace at break fork. I’m not sure if it is helpful (let me know if I should try something else):

#0  __libc_fork () at ./posix/fork.c:41
#1  0x00005555557e193e in  ()
#2  0x00005555556ad64e in  ()
#3  0x000055555569ea72 in _PyEval_EvalFrameDefault ()
#4  0x00005555556b03ac in _PyFunction_Vectorcall ()
#5  0x000055555569914a in _PyEval_EvalFrameDefault ()
#6  0x00005555556a5964 in _PyObject_FastCallDictTstate ()
#7  0x00005555556ba594 in  ()
#8  0x00005555556a677c in _PyObject_MakeTpCall ()
#9  0x000055555569ee39 in _PyEval_EvalFrameDefault ()
#10 0x00005555556b03ac in _PyFunction_Vectorcall ()
#11 0x000055555569ea72 in _PyEval_EvalFrameDefault ()
#12 0x00005555556b03ac in _PyFunction_Vectorcall ()
#13 0x000055555569914a in _PyEval_EvalFrameDefault ()
#14 0x00005555556b03ac in _PyFunction_Vectorcall ()
#15 0x000055555569914a in _PyEval_EvalFrameDefault ()
#16 0x00005555556b03ac in _PyFunction_Vectorcall ()
#17 0x000055555569914a in _PyEval_EvalFrameDefault ()
#18 0x00005555556b03ac in _PyFunction_Vectorcall ()
#19 0x000055555569914a in _PyEval_EvalFrameDefault ()
#20 0x00005555556be4de in  ()
#21 0x000055555569b3b0 in _PyEval_EvalFrameDefault ()
#22 0x00005555556b03ac in _PyFunction_Vectorcall ()
#23 0x0000555555699005 in _PyEval_EvalFrameDefault ()
#24 0x00005555556be391 in  ()
#25 0x000055555569a2fc in _PyEval_EvalFrameDefault ()
#26 0x00005555556b03ac in _PyFunction_Vectorcall ()
#27 0x000055555569914a in _PyEval_EvalFrameDefault ()
#28 0x00005555556be391 in  ()
#29 0x00005555556bf032 in PyObject_Call ()
#30 0x000055555569b3b0 in _PyEval_EvalFrameDefault ()
#31 0x00005555556be391 in  ()
#32 0x000055555569a2fc in _PyEval_EvalFrameDefault ()
#33 0x00005555556be391 in  ()
#34 0x00005555556bf032 in PyObject_Call ()
#35 0x000055555569b3b0 in _PyEval_EvalFrameDefault ()
#36 0x00005555556be5f1 in  ()
#37 0x000055555569b3b0 in _PyEval_EvalFrameDefault ()
#38 0x00005555556be5f1 in  ()
#39 0x00007fff7ca1f117 in QRunnableWrapper::run() ()
    at /home/patrick/virtualenvs/hexrd/lib/python3.10/site-packages/PySide2/QtCore.abi3.so
#40 0x00007fff7bcb766a in QThreadPoolThread::run() ()
    at /home/patrick/virtualenvs/hexrd/lib/python3.10/site-packages/PySide2/Qt/lib/libQt5Core.so.5
#41 0x00007fff7bcb3b35 in QThreadPrivate::start(void*) ()
    at /home/patrick/virtualenvs/hexrd/lib/python3.10/site-packages/PySide2/Qt/lib/libQt5Core.so.5
#42 0x00007ffff7cdbb43 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#43 0x00007ffff7d6da00 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

By the way, we are using a ProcessPoolExecutor for this. That may be the cause of the fork() call. But I believe it is important for us to use the ProcessPoolExecutor on a non-main thread, since the main thread is the GUI thread and we don’t want to block the application.

The numba functions are called within the separate processes of the ProcessPoolExecutor.

Thanks for looking into this some more @psavery.

RE the Numba version. I think the reporting of this condition was added in #6324 which is part of Numba 0.52.

RE the use of fork(2). This note is made in the above PR:

maybe it might help assess whether the occurrence of this message is “safe”? From what I can recall, the “main” thread in this case is that which launched the TBB pool, this launch typically occurs through calling a @njit(parallel=True) function.

I’ve also taken a look at the CPython source for concurrent.futures.ProcessPoolExecutor. It takes a mp_context kwarg for supplying a multiprocessing context and looking at the use, the implementation calls that to start workers (processes) and also e.g. adjust the process count etc. I would imagine that if the default context is used on Unix (fork) that that could be the source of the fork(2) calls.

To debug this, perhaps try and find the thread that launches the TBB pool? There’s a symbol in the threading layers launch_threads, which is called to launch the threadpool, I would guess that it can be used as a breakpoint in e.g. gdb to help with this.

(I tried this locally and it seemed to work).

Hope this helps?

Hi Stuart,

Thank you very much for your reply, and for working with me to solve this!

I just went back and double-checked: I did indeed start getting this warning at numba 0.54.0. If I use numba 0.53.1, I do not receive the warning, and then if I upgrade to numba 0.54.0 (which also changes llvm-lite, but nothing else), then I do receive the warning. So, even though the warning was introduced in 0.52.0, perhaps something changed in 0.54.0 that caused the warning to start printing out for me?

Thank you for providing hints for gdb! I gave the breakpoint at launch_threads() a try, and it actually appears to be called when I initially start up the GUI application. It does not get called again when I perform the steps to make the error appear. But you can see the full callstack for that pasted below.

I also looked back in the numba source at version 0.54.0 to see which line the warning occurs on, and I put a breakpoint at that line too. You can see that callstack pasted in the next message (note that it is occurring in a thread spawned by Qt - that is a background thread being used so that the GUI thread does not get blocked).

Please let me know if you see anything insightful, or if you have other ideas for debugging!

Thank you,
Patrick

Thread 1 "python" hit Breakpoint 1, launch_threads (count=48) at numba/np/ufunc/tbbpool.cpp:283
283	numba/np/ufunc/tbbpool.cpp: No such file or directory.
(gdb) where
#0  launch_threads(int) (count=48) at numba/np/ufunc/tbbpool.cpp:283
#1  0x00007ffff633ae2e in  () at /lib/x86_64-linux-gnu/libffi.so.8
#2  0x00007ffff6337493 in  () at /lib/x86_64-linux-gnu/libffi.so.8
#3  0x00007ffff666cebc in _call_function_pointer
    (argtypecount=<optimized out>, argcount=1, resmem=<optimized out>, restype=<optimized out>, atypes=<optimized out>, avalues=<optimized out>, pProc=0x7ffefae4dc20 <launch_threads(int)>, flags=4353) at /home/patrick/src/python/Python-3.8.15/Modules/_ctypes/callproc.c:921
#4  _ctypes_callproc
    (pProc=<optimized out>, argtuple=argtuple@entry=0x7ffed3254310, flags=<optimized out>, argtypes=argtypes@entry=0x7ffed3273730, restype=<optimized out>, checker=<optimized out>)
    at /home/patrick/src/python/Python-3.8.15/Modules/_ctypes/callproc.c:1264
#5  0x00007ffff666bd64 in PyCFuncPtr_call
    (self=<optimized out>, inargs=<optimized out>, kwds=0x0)
    at /home/patrick/src/python/Python-3.8.15/Modules/_ctypes/_ctypes.c:4201
#6  0x000055555565a568 in _PyObject_MakeTpCall
    (callable=0x7ffed326d280, args=args@entry=0x555558cd6910, nargs=<optimized out>, keywords=<optimized out>, keywords@entry=0x0) at Objects/call.c:159
#7  0x00005555556b47a7 in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x555558cd6910, callable=<optimized out>)
    at ./Include/cpython/abstract.h:125
#8  _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x555558cd6910, callable=<optimized out>)
    at ./Include/cpython/abstract.h:115
#9  call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x5555558c1b80)
    at Python/ceval.c:4963
#10 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
--Type <RET> for more, q to quit, c to continue without paging--
    at Python/ceval.c:3500
#11 0x00005555556aefb3 in PyEval_EvalFrameEx (throwflag=0, f=0x555558cd6730)
    at Python/ceval.c:741
#12 _PyEval_EvalCodeWithName
    (_co=<optimized out>, globals=<optimized out>, locals=locals@entry=0x0, args=args@entry=0x7ffed32689d8, argcount=argcount@entry=0, kwnames=<optimized out>, kwargs=0x7ffed32689d8, kwcount=0, kwstep=1, defs=0x0, defcount=0, kwdefs=0x0, closure=0x0, name=0x7fff755e8bf0, qualname=0x7fff755e8bf0) at Python/ceval.c:4298
#13 0x000055555565aed4 in _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffed32689d8, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:436
#14 0x00005555556aff32 in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7ffed32689d8, callable=0x7fff736fed30)
    at ./Include/cpython/abstract.h:127
#15 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x5555558c1b80)
    at Python/ceval.c:4963
#16 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3500
#17 0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=0, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
#18 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x555557fec340, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#19 0x00005555556aff32 in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x555557fec340, callable=0x7fff7370be50)
--Type <RET> for more, q to quit, c to continue without paging--
    at ./Include/cpython/abstract.h:127
#20 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x5555558c1b80)
    at Python/ceval.c:4963
#21 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3500
#22 0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=11, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
#23 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffed3288390, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#24 0x00005555556ed99a in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=11, args=0x7ffed3288390, callable=0x7fff7372b040)
    at ./Include/cpython/abstract.h:127
#25 method_vectorcall
    (method=method@entry=0x7ffed32ce4c0, args=args@entry=0x7ffed32758d8, nargsf=nargsf@entry=10, kwnames=kwnames@entry=0x0) at Objects/classobject.c:89
#26 0x000055555565c5df in PyVectorcall_Call
    (kwargs=0x0, tuple=0x7ffed32758c0, callable=0x7ffed32ce4c0) at Objects/call.c:200
#27 PyObject_Call (callable=0x7ffed32ce4c0, args=0x7ffed32758c0, kwargs=0x0)
    at Objects/call.c:228
#28 0x00005555556b1de5 in do_call_core
    (kwdict=0x0, callargs=0x7ffed32758c0, func=0x7ffed32ce4c0, tstate=<optimized out>)
    at Python/ceval.c:5010
#29 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3559
--Type <RET> for more, q to quit, c to continue without paging--
#30 0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=3, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
#31 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffed3370ae8, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#32 0x00005555556b02bd in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7ffed3370ae8, callable=0x7fff736c3e50)
    at ./Include/cpython/abstract.h:127
#33 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x5555558c1b80)
    at Python/ceval.c:4963
#34 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3486
#35 0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=3, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
#36 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7fff0376ad70, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#37 0x00005555556b02bd in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7fff0376ad70, callable=0x7fff736c7d30)
    at ./Include/cpython/abstract.h:127
#38 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x5555558c1b80)
    at Python/ceval.c:4963
#39 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
--Type <RET> for more, q to quit, c to continue without paging--
    at Python/ceval.c:3486
#40 0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=3, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
#41 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x555557fe03a0, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#42 0x00005555556b02bd in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x555557fe03a0, callable=0x7fff736c7ca0)
    at ./Include/cpython/abstract.h:127
#43 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x5555558c1b80)
    at Python/ceval.c:4963
#44 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3486
#45 0x00005555556aefb3 in PyEval_EvalFrameEx (throwflag=0, f=0x555557fe01b0)
    at Python/ceval.c:741
#46 _PyEval_EvalCodeWithName
    (_co=<optimized out>, globals=<optimized out>, locals=locals@entry=0x0, args=args@entry=0x555557f95748, argcount=argcount@entry=2, kwnames=<optimized out>, kwargs=0x555557f95758, kwcount=0, kwstep=1, defs=0x0, defcount=0, kwdefs=0x0, closure=0x0, name=0x7ffff7e44fb0, qualname=0x7fff779600d0) at Python/ceval.c:4298
#47 0x000055555565aed4 in _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x555557f95748, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:436
#48 0x00005555556b02bd in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x555557f95748, callable=0x7fff736cdf70)
--Type <RET> for more, q to quit, c to continue without paging--
    at ./Include/cpython/abstract.h:127
#49 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x5555558c1b80)
    at Python/ceval.c:4963
#50 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3486
#51 0x00005555556aefb3 in PyEval_EvalFrameEx (throwflag=0, f=0x555557f95530)
    at Python/ceval.c:741
#52 _PyEval_EvalCodeWithName
    (_co=<optimized out>, globals=<optimized out>, locals=locals@entry=0x0, args=args@entry=0x7ffefa244030, argcount=argcount@entry=18, kwnames=<optimized out>, kwargs=0x7ffefa2440c0, kwcount=0, kwstep=1, defs=0x0, defcount=0, kwdefs=0x0, closure=0x0, name=0x7fff7795c0d0, qualname=0x7fff7795a1b0) at Python/ceval.c:4298
#53 0x000055555565aed4 in _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffefa244030, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:436
#54 0x00005555556ed99a in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=18, args=0x7ffefa244030, callable=0x7fff736cd160)
    at ./Include/cpython/abstract.h:127
#55 method_vectorcall
    (method=method@entry=0x7fff04f89fc0, args=args@entry=0x7ffed326c898, nargsf=nargsf@entry=17, kwnames=kwnames@entry=0x0) at Objects/classobject.c:89
#56 0x000055555565c5df in PyVectorcall_Call
    (kwargs=0x0, tuple=0x7ffed326c880, callable=0x7fff04f89fc0) at Objects/call.c:200
#57 PyObject_Call (callable=0x7fff04f89fc0, args=0x7ffed326c880, kwargs=0x0)
    at Objects/call.c:228
#58 0x00007fff7b648350 in compile_and_invoke(Dispatcher*, PyObject*, PyObject*, PyObject*)
--Type <RET> for more, q to quit, c to continue without paging--
    (self=self@entry=0x7fff073cbf40, args=0x7ffed326c880, kws=0x0, locals=locals@entry=0x0)
    at numba/_dispatcher.cpp:453
#59 0x00007fff7b6486f5 in Dispatcher_call(Dispatcher*, PyObject*, PyObject*)
    (self=0x7fff073cbf40, args=<optimized out>, kws=<optimized out>)
    at numba/_dispatcher.cpp:739
#60 0x000055555565a568 in _PyObject_MakeTpCall
    (callable=0x7fff073cbf40, args=args@entry=0x555558d28760, nargs=<optimized out>, keywords=<optimized out>, keywords@entry=0x0) at Objects/call.c:159
#61 0x00005555556b47a7 in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x555558d28760, callable=<optimized out>)
    at ./Include/cpython/abstract.h:125
#62 _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x555558d28760, callable=<optimized out>)
    at ./Include/cpython/abstract.h:115
#63 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x5555558c1b80)
    at Python/ceval.c:4963
#64 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3500
#65 0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=2, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
#66 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffed3279a38, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#67 0x00005555556b02bd in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7ffed3279a38, callable=0x7fff0757e700)
--Type <RET> for more, q to quit, c to continue without paging--
    at ./Include/cpython/abstract.h:127
#68 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x5555558c1b80)
    at Python/ceval.c:4963
#69 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3486
#70 0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=1, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
#71 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7fff0471dba0, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#72 0x00005555556b02bd in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7fff0471dba0, callable=0x7fff07419280)
    at ./Include/cpython/abstract.h:127
#73 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x5555558c1b80)
    at Python/ceval.c:4963
#74 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3486
#75 0x00005555556aefb3 in PyEval_EvalFrameEx (throwflag=0, f=0x7fff0471d9f0)
    at Python/ceval.c:741
#76 _PyEval_EvalCodeWithName
    (_co=<optimized out>, globals=<optimized out>, locals=locals@entry=0x0, args=args@entry=0x7fffffffca50, argcount=argcount@entry=3, kwnames=kwnames@entry=0x0, kwargs=0x7fffffffca68, kwcount=0, kwstep=1, defs=0x7fff075ef918, defcount=5, kwdefs=0x0, closure=0x0, name=0x7ffff7e78530, qualname=0x7fff075e09e0) at Python/ceval.c:4298
--Type <RET> for more, q to quit, c to continue without paging--
#77 0x000055555565a21c in _PyFunction_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, stack=0x7fffffffca50, func=0x7fff07416ca0)
    at Objects/call.c:436
#78 _PyObject_FastCallDict
    (callable=0x7fff07416ca0, args=0x7fffffffca50, nargsf=<optimized out>, kwargs=<optimized out>) at Objects/call.c:96
#79 0x000055555565bb16 in _PyObject_Call_Prepend
    (callable=callable@entry=0x7fff07416ca0, obj=obj@entry=0x7ffff6c6dee0, args=args@entry=0x7fff0700f500, kwargs=kwargs@entry=0x0) at Objects/call.c:888
#80 0x000055555568f27b in slot_tp_init (self=0x7ffff6c6dee0, args=0x7fff0700f500, kwds=0x0)
    at Objects/typeobject.c:6790
#81 0x000055555568c5b3 in type_call (type=<optimized out>, args=0x7fff0700f500, kwds=0x0)
    at Objects/typeobject.c:994
#82 0x000055555565a568 in _PyObject_MakeTpCall
    (callable=0x555557538340, args=args@entry=0x7fff0471df70, nargs=<optimized out>, keywords=<optimized out>, keywords@entry=0x0) at Objects/call.c:159
#83 0x00005555556b47a7 in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7fff0471df70, callable=<optimized out>)
    at ./Include/cpython/abstract.h:125
#84 _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7fff0471df70, callable=<optimized out>)
    at ./Include/cpython/abstract.h:115
#85 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x5555558c1b80)
    at Python/ceval.c:4963
#86 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3500
--Type <RET> for more, q to quit, c to continue without paging--
#87 0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=2, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
#88 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7fff04719710, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#89 0x00005555556ed822 in _PyObject_Vectorcall
    (kwnames=<optimized out>, nargsf=2, args=0x7fff04719710, callable=0x7fff05ebdc10)
    at ./Include/cpython/abstract.h:127
#90 method_vectorcall
    (method=<optimized out>, args=0x7fff04719718, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/classobject.c:60
#91 0x00005555556b4809 in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7fff04719718, callable=0x7fff0479d9c0)
    at ./Include/cpython/abstract.h:127
#92 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x5555558c1b80)
    at Python/ceval.c:4963
#93 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3469
#94 0x00005555556aefb3 in PyEval_EvalFrameEx (throwflag=0, f=0x7fff04719580)
    at Python/ceval.c:741
#95 _PyEval_EvalCodeWithName
    (_co=<optimized out>, globals=<optimized out>, locals=locals@entry=0x0, args=args@entry=0x7fffffffd060, argcount=argcount@entry=1, kwnames=<optimized out>, kwargs=0x7fffffffd068, kwcount=0, kwstep=1, defs=0x0, defcount=0, kwdefs=0x0, closure=0x7fff736bf7f0, name=0x7ffff7e78530, qualname=0x7fff7c6575d0) at Python/ceval.c:4298
--Type <RET> for more, q to quit, c to continue without paging--
#96 0x000055555565aed4 in _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7fffffffd060, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:436
#97 0x000055555565a289 in _PyObject_FastCallDict
    (callable=0x7fff05ebb040, args=0x7fffffffd060, nargsf=<optimized out>, kwargs=<optimized out>) at Objects/call.c:104
#98 0x000055555565bb16 in _PyObject_Call_Prepend
    (callable=callable@entry=0x7fff05ebb040, obj=obj@entry=0x7fff0cfed380, args=args@entry=0x7ffff7e77040, kwargs=kwargs@entry=0x7fff03740b00) at Objects/call.c:888
#99 0x000055555568f27b in slot_tp_init
    (self=0x7fff0cfed380, args=0x7ffff7e77040, kwds=0x7fff03740b00)
    at Objects/typeobject.c:6790
#100 0x000055555568c5b3 in type_call
    (type=<optimized out>, args=0x7ffff7e77040, kwds=0x7fff03740b00)
    at Objects/typeobject.c:994
#101 0x000055555565c757 in PyObject_Call
    (callable=0x7fff037bc6d0, args=0x7ffff7e77040, kwargs=0x7fff03740b00)
    at Objects/call.c:246
#102 0x00005555556b1de5 in do_call_core
    (kwdict=0x7fff03740b00, callargs=0x7ffff7e77040, func=0x7fff037bc6d0, tstate=<optimized out>) at Python/ceval.c:5010
#103 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3559
#104 0x00005555556aefb3 in PyEval_EvalFrameEx (throwflag=0, f=0x7fff04719040)
    at Python/ceval.c:741
#105 _PyEval_EvalCodeWithName
    (_co=<optimized out>, globals=<optimized out>, locals=locals@entry=0x0, args=args@entry=0x7--Type <RET> for more, q to quit, c to continue without paging--
fffffffd480, argcount=argcount@entry=1, kwnames=kwnames@entry=0x0, kwargs=0x7fffffffd488, kwcount=0, kwstep=1, defs=0x0, defcount=0, kwdefs=0x0, closure=0x7ffff2bad910, name=0x7ffff7e781f0, qualname=0x7fff05eb7530) at Python/ceval.c:4298
#106 0x000055555565a21c in _PyFunction_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, stack=0x7fffffffd480, func=0x7fff05eb9dc0)
    at Objects/call.c:436
#107 _PyObject_FastCallDict
    (callable=0x7fff05eb9dc0, args=0x7fffffffd480, nargsf=<optimized out>, kwargs=<optimized out>) at Objects/call.c:96
#108 0x000055555565bb16 in _PyObject_Call_Prepend
    (callable=callable@entry=0x7fff05eb9dc0, obj=obj@entry=0x5555579541d0, args=args@entry=0x7ffff7e77040, kwargs=kwargs@entry=0x0) at Objects/call.c:888
#109 0x00005555557149e2 in slot_tp_call (self=0x5555579541d0, args=0x7ffff7e77040, kwds=0x0)
    at Objects/typeobject.c:6556
#110 0x000055555565a568 in _PyObject_MakeTpCall
    (callable=0x5555579541d0, args=args@entry=0x7fff037433b8, nargs=<optimized out>, keywords=<optimized out>, keywords@entry=0x0) at Objects/call.c:159
#111 0x00005555556b47a7 in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7fff037433b8, callable=<optimized out>)
    at ./Include/cpython/abstract.h:125
#112 _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7fff037433b8, callable=<optimized out>)
    at ./Include/cpython/abstract.h:115
#113 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x5555558c1b80)
    at Python/ceval.c:4963
#114 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
--Type <RET> for more, q to quit, c to continue without paging--
    at Python/ceval.c:3500
#115 0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=1, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
#116 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7fff7a45f9a8, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#117 0x00005555556aff32 in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7fff7a45f9a8, callable=0x7fff05ecb670)
    at ./Include/cpython/abstract.h:127
#118 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x5555558c1b80)
    at Python/ceval.c:4963
#119 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3500
#120 0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=0, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
#121 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffff6d8e5b0, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#122 0x00005555556aff32 in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7ffff6d8e5b0, callable=0x7ffff6df21f0)
    at ./Include/cpython/abstract.h:127
#123 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x5555558c1b80)
    at Python/ceval.c:4963
--Type <RET> for more, q to quit, c to continue without paging--
#124 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3500
#125 0x00005555556aefb3 in PyEval_EvalFrameEx (throwflag=0, f=0x7ffff6d8e440)
    at Python/ceval.c:741
#126 _PyEval_EvalCodeWithName
    (_co=<optimized out>, globals=<optimized out>, locals=<optimized out>, args=<optimized out>, argcount=<optimized out>, kwnames=<optimized out>, kwargs=0x0, kwcount=0, kwstep=2, defs=0x0, defcount=0, kwdefs=0x0, closure=0x0, name=0x0, qualname=0x0) at Python/ceval.c:4298
#127 0x0000555555723497 in PyEval_EvalCodeEx
    (closure=0x0, kwdefs=0x0, defcount=0, defs=0x0, kwcount=0, kws=0x0, argcount=0, args=0x0, locals=0x7ffff6dccf80, globals=0x7ffff6dccf80, _co=0x7ffff6d489d0) at Python/ceval.c:4327
#128 PyEval_EvalCode
    (co=co@entry=0x7ffff6d489d0, globals=globals@entry=0x7ffff6dccf80, locals=locals@entry=0x7ffff6dccf80) at Python/ceval.c:718
#129 0x00005555557335e9 in run_eval_code_obj
    (co=0x7ffff6d489d0, globals=0x7ffff6dccf80, locals=0x7ffff6dccf80)
    at Python/pythonrun.c:1166
#130 0x0000555555733583 in run_mod
    (mod=<optimized out>, filename=<optimized out>, globals=0x7ffff6dccf80, locals=0x7ffff6dccf80, flags=<optimized out>, arena=<optimized out>) at Python/pythonrun.c:1188
#131 0x00005555555fe240 in pyrun_file
    (fp=fp@entry=0x5555558c0650, filename=filename@entry=0x7ffff6bf43b0, start=start@entry=257, globals=globals@entry=0x7ffff6dccf80, locals=locals@entry=0x7ffff6dccf80, closeit=closeit@entry=1, flags=0x7fffffffdbd8) at Python/pythonrun.c:1085
#132 0x00005555555fd6f9 in pyrun_simple_file
    (flags=0x7fffffffdbd8, closeit=1, filename=0x7ffff6bf43b0, fp=0x5555558c0650)
    at Python/pythonrun.c:439
--Type <RET> for more, q to quit, c to continue without paging--
#133 PyRun_SimpleFileExFlags
    (fp=fp@entry=0x5555558c0650, filename=<optimized out>, closeit=closeit@entry=1, flags=flags@entry=0x7fffffffdbd8) at Python/pythonrun.c:472
#134 0x00005555555fe4a6 in PyRun_AnyFileExFlags
    (fp=fp@entry=0x5555558c0650, filename=<optimized out>, closeit=closeit@entry=1, flags=flags@entry=0x7fffffffdbd8) at Python/pythonrun.c:90
#135 0x00005555556fec4d in pymain_run_file (cf=0x7fffffffdbd8, config=0x5555558c0f00)
    at Modules/main.c:385
#136 pymain_run_python (exitcode=0x7fffffffdbd0) at Modules/main.c:610
#137 Py_RunMain () at Modules/main.c:689
#138 0x00005555556fe5cd in Py_BytesMain (argc=<optimized out>, argv=<optimized out>)
    at Modules/main.c:743
#139 0x00007ffff7c29d90 in __libc_start_call_main
     (main=main@entry=0x555555656f40 <main>, argc=argc@entry=2, argv=argv@entry=0x7fffffffde08)
    at ../sysdeps/nptl/libc_start_call_main.h:58
#140 0x00007ffff7c29e40 in __libc_start_main_impl
     (main=0x555555656f40 <main>, argc=2, argv=0x7fffffffde08, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffddf8) at ../csu/libc-start.c:392
#141 0x00005555556fe4c5 in _start ()

Here is the callstack for a breakpoint at the warning message:

Thread 215 "Thread (pooled)" hit Breakpoint 2, prepare_fork () at numba/np/ufunc/tbbpool.cpp:238
238	in numba/np/ufunc/tbbpool.cpp
(gdb) where
#0  prepare_fork() () at numba/np/ufunc/tbbpool.cpp:238
#1  0x00007ffff7ceafb8 in __run_fork_handlers (who=<optimized out>,
    who@entry=atfork_run_prepare, do_locking=do_locking@entry=true)
    at ./posix/register-atfork.c:120
#2  0x00007ffff7cea781 in __libc_fork () at ./posix/fork.c:50
#3  0x000055555573e9ad in os_fork_impl (module=<optimized out>)
    at ./Modules/posixmodule.c:6250
#4  os_fork (module=<optimized out>, _unused_ignored=<optimized out>)
    at ./Modules/clinic/posixmodule.c.h:2750
#5  0x000055555567d93a in cfunction_vectorcall_NOARGS
    (func=0x7ffff6dda040, args=<optimized out>, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/methodobject.c:463
#6  0x00005555556b4809 in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7ffe6b69adf0, callable=0x7ffff6dda040)
    at ./Include/cpython/abstract.h:127
#7  call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x7ffe58003800)
    at Python/ceval.c:4963
#8  _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3469
#9  0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=2, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
#10 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffed122c790, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#11 0x00005555556b02bd in _PyObject_Vectorcall
--Type <RET> for more, q to quit, c to continue without paging--
    (kwnames=0x0, nargsf=<optimized out>, args=0x7ffed122c790, callable=0x7ffe695178b0)
    at ./Include/cpython/abstract.h:127
#12 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x7ffe58003800)
    at Python/ceval.c:4963
#13 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3486
#14 0x000055555565a15a in function_code_fastcall
    (globals=<optimized out>, nargs=2, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
#15 _PyFunction_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, stack=0x7ffe5da7dbc0, func=0x7ffe695174c0)
    at Objects/call.c:411
#16 _PyObject_FastCallDict
    (callable=0x7ffe695174c0, args=0x7ffe5da7dbc0, nargsf=<optimized out>, kwargs=<optimized out>) at Objects/call.c:96
#17 0x000055555565bb16 in _PyObject_Call_Prepend
    (callable=callable@entry=0x7ffe695174c0, obj=obj@entry=0x7ffe6b39d8b0, args=args@entry=0x7ffe6b392ee0, kwargs=kwargs@entry=0x0) at Objects/call.c:888
#18 0x000055555568f27b in slot_tp_init (self=0x7ffe6b39d8b0, args=0x7ffe6b392ee0, kwds=0x0)
    at Objects/typeobject.c:6790
#19 0x000055555568c5b3 in type_call (type=<optimized out>, args=0x7ffe6b392ee0, kwds=0x0)
    at Objects/typeobject.c:994
#20 0x000055555565a568 in _PyObject_MakeTpCall
    (callable=0x7ffe5826cc40, args=args@entry=0x7ffe69518ec0, nargs=<optimized out>, keywords=<optimized out>, keywords@entry=0x0) at Objects/call.c:159
#21 0x00005555556b47a7 in _PyObject_Vectorcall
--Type <RET> for more, q to quit, c to continue without paging--
    (kwnames=0x0, nargsf=<optimized out>, args=0x7ffe69518ec0, callable=<optimized out>)
    at ./Include/cpython/abstract.h:125
#22 _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7ffe69518ec0, callable=<optimized out>)
    at ./Include/cpython/abstract.h:115
#23 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x7ffe58003800)
    at Python/ceval.c:4963
#24 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3500
#25 0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=1, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
#26 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffe69518b80, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#27 0x00005555556b4809 in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7ffe69518b80, callable=0x7fff7a432b80)
    at ./Include/cpython/abstract.h:127
#28 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x7ffe58003800)
    at Python/ceval.c:4963
#29 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3469
#30 0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=1, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
--Type <RET> for more, q to quit, c to continue without paging--
#31 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffe69514910, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#32 0x00005555556b02bd in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7ffe69514910, callable=0x7fff7a48a280)
    at ./Include/cpython/abstract.h:127
#33 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x7ffe58003800)
    at Python/ceval.c:4963
#34 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3486
#35 0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=1, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
#36 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffe6951b3a0, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#37 0x00005555556b02bd in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7ffe6951b3a0, callable=0x7fff72cd6c10)
    at ./Include/cpython/abstract.h:127
#38 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x7ffe58003800)
    at Python/ceval.c:4963
#39 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3486
#40 0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=1, args=<optimized out>, co=<optimized out>)
--Type <RET> for more, q to quit, c to continue without paging--
    at Objects/call.c:284
#41 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffe58001350, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#42 0x00005555556b02bd in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7ffe58001350, callable=0x7fff72cd6b80)
    at ./Include/cpython/abstract.h:127
#43 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x7ffe58003800)
    at Python/ceval.c:4963
#44 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3486
#45 0x00005555556aefb3 in PyEval_EvalFrameEx (throwflag=0, f=0x7ffe580011a0)
    at Python/ceval.c:741
#46 _PyEval_EvalCodeWithName
    (_co=<optimized out>, globals=<optimized out>, locals=locals@entry=0x0, args=args@entry=0x7ffe5da7e550, argcount=argcount@entry=3, kwnames=<optimized out>, kwargs=0x7ffe5da7e568, kwcount=0, kwstep=1, defs=0x0, defcount=0, kwdefs=0x0, closure=0x0, name=0x7fff7d2f0cb0, qualname=0x7fff72d2c4e0) at Python/ceval.c:4298
#47 0x000055555565aed4 in _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffe5da7e550, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:436
#48 0x00005555556ed8c2 in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=3, args=0x7ffe5da7e550, callable=0x7fff72cd6ca0)
    at ./Include/cpython/abstract.h:127
#49 method_vectorcall
    (method=method@entry=0x7ffe69516080, args=args@entry=0x7ffe6b3b64d8, nargsf=nargsf@entry=2,--Type <RET> for more, q to quit, c to continue without paging--
 kwnames=kwnames@entry=0x0) at Objects/classobject.c:89
#50 0x000055555565c5df in PyVectorcall_Call
    (kwargs=0x0, tuple=0x7ffe6b3b64c0, callable=0x7ffe69516080) at Objects/call.c:200
#51 PyObject_Call (callable=0x7ffe69516080, args=0x7ffe6b3b64c0, kwargs=0x0)
    at Objects/call.c:228
#52 0x00005555556b1de5 in do_call_core
    (kwdict=0x0, callargs=0x7ffe6b3b64c0, func=0x7ffe69516080, tstate=<optimized out>)
    at Python/ceval.c:5010
#53 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3559
#54 0x00005555556aefb3 in PyEval_EvalFrameEx (throwflag=0, f=0x7ffe695143e0)
    at Python/ceval.c:741
#55 _PyEval_EvalCodeWithName
    (_co=<optimized out>, globals=<optimized out>, locals=locals@entry=0x0, args=args@entry=0x7ffe6950dbb8, argcount=argcount@entry=1, kwnames=<optimized out>, kwargs=0x7ffe6950dbc0, kwcount=0, kwstep=1, defs=0x0, defcount=0, kwdefs=0x0, closure=0x7ffe695106c0, name=0x7ffff7e68fb0, qualname=0x7fff7a4dcbd0) at Python/ceval.c:4298
#56 0x000055555565aed4 in _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffe6950dbb8, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:436
#57 0x00005555556aff32 in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7ffe6950dbb8, callable=0x7ffe69517160)
    at ./Include/cpython/abstract.h:127
#58 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x7ffe58003800)
    at Python/ceval.c:4963
#59 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
--Type <RET> for more, q to quit, c to continue without paging--
    at Python/ceval.c:3500
#60 0x00005555556aefb3 in PyEval_EvalFrameEx (throwflag=0, f=0x7ffe6950d9f0)
    at Python/ceval.c:741
#61 _PyEval_EvalCodeWithName
    (_co=<optimized out>, globals=<optimized out>, locals=locals@entry=0x0, args=args@entry=0x7ffe6950d1e0, argcount=argcount@entry=3, kwnames=<optimized out>, kwargs=0x7ffe6950d1f8, kwcount=1, kwstep=1, defs=0x0, defcount=0, kwdefs=0x7fff7a469ec0, closure=0x0, name=0x7ffff7e47bb0, qualname=0x7fff7a4690f0) at Python/ceval.c:4298
#62 0x000055555565aed4 in _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffe6950d1e0, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:436
#63 0x00005555556ed822 in _PyObject_Vectorcall
    (kwnames=<optimized out>, nargsf=3, args=0x7ffe6950d1e0, callable=0x7fff7a466c10)
    at ./Include/cpython/abstract.h:127
#64 method_vectorcall
    (method=<optimized out>, args=0x7ffe6950d1e8, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/classobject.c:60
#65 0x00005555556b0cdf in _PyObject_Vectorcall
    (kwnames=0x7fff72d2b160, nargsf=<optimized out>, args=<optimized out>, callable=0x7ffe6b6a9500) at ./Include/cpython/abstract.h:127
#66 call_function
    (kwnames=0x7fff72d2b160, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=<optimized out>) at Python/ceval.c:4963
#67 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3515
#68 0x00005555556aefb3 in PyEval_EvalFrameEx (throwflag=0, f=0x7ffe6950d040)
    at Python/ceval.c:741
--Type <RET> for more, q to quit, c to continue without paging--
#69 _PyEval_EvalCodeWithName
    (_co=<optimized out>, globals=<optimized out>, locals=locals@entry=0x0, args=args@entry=0x7ffe58002a90, argcount=argcount@entry=3, kwnames=<optimized out>, kwargs=0x7ffe58002aa8, kwcount=0, kwstep=1, defs=0x0, defcount=0, kwdefs=0x7fff72cd4a00, closure=0x7fff72cc9c40, name=0x7ffff7e47bb0, qualname=0x7fff72d2c5d0) at Python/ceval.c:4298
#70 0x000055555565aed4 in _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffe58002a90, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:436
#71 0x00005555556b02bd in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=<optimized out>, args=0x7ffe58002a90, callable=0x7fff72cd6d30)
    at ./Include/cpython/abstract.h:127
#72 call_function
    (kwnames=0x0, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=0x7ffe58003800)
    at Python/ceval.c:4963
#73 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3486
#74 0x00005555556aefb3 in PyEval_EvalFrameEx (throwflag=0, f=0x7ffe58002810)
    at Python/ceval.c:741
#75 _PyEval_EvalCodeWithName
    (_co=<optimized out>, globals=<optimized out>, locals=locals@entry=0x0, args=args@entry=0x7ffe6950e6f0, argcount=argcount@entry=1, kwnames=<optimized out>, kwargs=0x7ffe6950e6f8, kwcount=11, kwstep=1, defs=0x7fff72d1d058, defcount=10, kwdefs=0x0, closure=0x0, name=0x7fff72d17350, qualname=0x7fff72d0ec90) at Python/ceval.c:4298
#76 0x000055555565aed4 in _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffe6950e6f0, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:436
#77 0x00005555556ed99a in _PyObject_Vectorcall
--Type <RET> for more, q to quit, c to continue without paging--
    (kwnames=0x7fff037ab7c0, nargsf=1, args=0x7ffe6950e6f0, callable=0x7fff073b04c0)
    at ./Include/cpython/abstract.h:127
#78 method_vectorcall
    (method=method@entry=0x7ffe6b6647c0, args=args@entry=0x7ffe6950e5d0, nargsf=nargsf@entry=0, kwnames=kwnames@entry=0x7fff037ab7c0) at Objects/classobject.c:89
#79 0x000055555565c634 in PyVectorcall_Call
    (kwargs=<optimized out>, tuple=<optimized out>, callable=0x7ffe6b6647c0)
    at Objects/call.c:200
#80 PyObject_Call (callable=0x7ffe6b6647c0, args=<optimized out>, kwargs=<optimized out>)
    at Objects/call.c:228
#81 0x00005555556b1de5 in do_call_core
    (kwdict=0x7ffe69500ec0, callargs=0x7ffff7e77040, func=0x7ffe6b6647c0, tstate=<optimized out>) at Python/ceval.c:5010
#82 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3559
#83 0x00005555556aefb3 in PyEval_EvalFrameEx (throwflag=0, f=0x7ffe58005810)
    at Python/ceval.c:741
#84 _PyEval_EvalCodeWithName
    (_co=<optimized out>, globals=<optimized out>, locals=locals@entry=0x0, args=args@entry=0x7ffe69511578, argcount=argcount@entry=1, kwnames=<optimized out>, kwargs=0x7ffe69511580, kwcount=2, kwstep=1, defs=0x7fff04bfd118, defcount=2, kwdefs=0x0, closure=0x0, name=0x7fff04bfc030, qualname=0x7fff04bf3690) at Python/ceval.c:4298
#85 0x000055555565aed4 in _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffe69511578, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:436
#86 0x00005555556ed822 in _PyObject_Vectorcall
    (kwnames=<optimized out>, nargsf=1, args=0x7ffe69511578, callable=0x7fff04b8a820)
--Type <RET> for more, q to quit, c to continue without paging--
    at ./Include/cpython/abstract.h:127
#87 method_vectorcall
    (method=<optimized out>, args=0x7ffe69511580, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/classobject.c:60
#88 0x00005555556b0cdf in _PyObject_Vectorcall
    (kwnames=0x7fff04bfd440, nargsf=<optimized out>, args=<optimized out>, callable=0x7ffe6b655b00) at ./Include/cpython/abstract.h:127
#89 call_function
    (kwnames=0x7fff04bfd440, oparg=<optimized out>, pp_stack=<synthetic pointer>, tstate=<optimized out>) at Python/ceval.c:4963
#90 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3515
#91 0x00005555556aefb3 in PyEval_EvalFrameEx (throwflag=0, f=0x7ffe695113e0)
    at Python/ceval.c:741
#92 _PyEval_EvalCodeWithName
    (_co=<optimized out>, globals=<optimized out>, locals=locals@entry=0x0, args=args@entry=0x7ffe5da7f710, argcount=argcount@entry=1, kwnames=<optimized out>, kwargs=0x7ffe5da7f718, kwcount=2, kwstep=1, defs=0x7fff04bfb6b8, defcount=1, kwdefs=0x0, closure=0x0, name=0x7fff04bebe70, qualname=0x7fff04bf3b10) at Python/ceval.c:4298
#93 0x000055555565aed4 in _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffe5da7f710, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:436
#94 0x00005555556ed8c2 in _PyObject_Vectorcall
    (kwnames=0x7ffea4023a40, nargsf=1, args=0x7ffe5da7f710, callable=0x7fff04b8af70)
    at ./Include/cpython/abstract.h:127
#95 method_vectorcall
    (method=method@entry=0x7ffe6b6c6f80, args=args@entry=0x7ffe6b3de530, nargsf=nargsf@entry=0,--Type <RET> for more, q to quit, c to continue without paging--
 kwnames=kwnames@entry=0x7ffea4023a40) at Objects/classobject.c:89
#96 0x000055555565c634 in PyVectorcall_Call
    (kwargs=<optimized out>, tuple=<optimized out>, callable=0x7ffe6b6c6f80)
    at Objects/call.c:200
#97 PyObject_Call (callable=0x7ffe6b6c6f80, args=<optimized out>, kwargs=<optimized out>)
    at Objects/call.c:228
#98 0x00005555556b1de5 in do_call_core
    (kwdict=0x7ffe6950a780, callargs=0x7ffff7e77040, func=0x7ffe6b6c6f80, tstate=<optimized out>) at Python/ceval.c:5010
#99 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3559
#100 0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=1, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
#101 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffe5da7f988, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#102 0x00005555556ed915 in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=1, args=0x7ffe5da7f988, callable=0x7fff04b95280)
    at ./Include/cpython/abstract.h:127
#103 method_vectorcall
    (method=method@entry=0x7ffe6b3a0880, args=args@entry=0x7ffff7e77058, nargsf=nargsf@entry=0, kwnames=kwnames@entry=0x0) at Objects/classobject.c:67
#104 0x000055555565c5df in PyVectorcall_Call
    (kwargs=0x7ffe6950ac80, tuple=0x7ffff7e77040, callable=0x7ffe6b3a0880)
    at Objects/call.c:200
#105 PyObject_Call (callable=0x7ffe6b3a0880, args=0x7ffff7e77040, kwargs=0x7ffe6950ac80)
--Type <RET> for more, q to quit, c to continue without paging--
    at Objects/call.c:228
#106 0x00005555556b1de5 in do_call_core
    (kwdict=0x7ffe6950ac80, callargs=0x7ffff7e77040, func=0x7ffe6b3a0880, tstate=<optimized out>) at Python/ceval.c:5010
#107 _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3559
#108 0x000055555565ae3a in function_code_fastcall
    (globals=<optimized out>, nargs=1, args=<optimized out>, co=<optimized out>)
    at Objects/call.c:284
#109 _PyFunction_Vectorcall
    (func=<optimized out>, stack=0x7ffe5da7fc08, nargsf=<optimized out>, kwnames=<optimized out>) at Objects/call.c:411
#110 0x00005555556ed915 in _PyObject_Vectorcall
    (kwnames=0x0, nargsf=1, args=0x7ffe5da7fc08, callable=0x7fff05e7c940)
    at ./Include/cpython/abstract.h:127
#111 method_vectorcall
    (method=method@entry=0x7ffe6b3d5ec0, args=args@entry=0x7ffff7e77058, nargsf=nargsf@entry=0, kwnames=kwnames@entry=0x0) at Objects/classobject.c:67
#112 0x000055555565c5df in PyVectorcall_Call
    (kwargs=0x0, tuple=0x7ffff7e77040, callable=0x7ffe6b3d5ec0) at Objects/call.c:200
#113 PyObject_Call (callable=0x7ffe6b3d5ec0, args=0x7ffff7e77040, kwargs=0x0)
    at Objects/call.c:228
#114 0x00007fff7941f117 in QRunnableWrapper::run() ()
    at /home/patrick/virtualenvs/hexrd-3.8/lib/python3.8/site-packages/PySide2/QtCore.abi3.so
#115 0x00007fff786b766a in QThreadPoolThread::run() ()
    at /home/patrick/virtualenvs/hexrd-3.8/lib/python3.8/site-packages/PySide2/Qt/lib/libQt5Core.so.5
--Type <RET> for more, q to quit, c to continue without paging--
#116 0x00007fff786b3b35 in QThreadPrivate::start(void*) ()
    at /home/patrick/virtualenvs/hexrd-3.8/lib/python3.8/site-packages/PySide2/Qt/lib/libQt5Core.so.5
#117 0x00007ffff7c94b43 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:442
#118 0x00007ffff7d26a00 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81

@stuartarchibald Some of our users started noticing this warning, and I looked into it more. I think I have more insightful information now. A simplified code example is pasted at the bottom of this message. Please try it out!

Basically, what is happening is that TBB is being initialized in some thread, and then when we use multiprocessing in another thread, that warning gets printed out, even if our multiprocessing doesn’t use TBB at all (so the warning is not relevant for us).

In our application, our main (GUI) thread needs to be kept free most of the time so that the interface is responsive to the user. Most processing is done in background threads. We end up having a background thread that is creating a ProcessPoolExecutor to spawn more processes for some work. These processes do not use TBB, and thus the warning is not relevant for them, but the warning gets printed out anyways.

Is there anything we can do to change the warning, so that it is only printed out in relevant situations, or a way we can suppress it entirely?

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
import time

from numba import config, njit, prange
import numpy as np


@njit(parallel=True)
def prange_test(A):
    # This was taken from the Numba examples
    s = 0
    for i in prange(A.shape[0]):
        s += A[i]
    return s


def run_in_process():
    # This function should do something that doesn't use TBB,
    # and might not even use Numba at all.
    time.sleep(1)
    return 1


def run_in_non_main_thread():
    # Use multiprocessing to do the actual work
    process_executor = ProcessPoolExecutor()
    future = process_executor.submit(run_in_process)
    return future.result()


if __name__ == '__main__':
    # Make sure we are using TBB
    config.THREADING_LAYER = 'tbb'

    thread_executor = ThreadPoolExecutor()

    # Run this function once to initialize TBB in the main thread
    prange_test(np.arange(1e1))

    # Start the processing in a separate thread.
    # This is similar to GUI applications, because we want to relinquish
    # control of the main thread quickly so that the main (GUI) thread can
    # keep the application responsive for the user.
    future = thread_executor.submit(run_in_non_main_thread)
    result = future.result()
    print(f'{result=}')