RustaCUDA
RustaCUDA copied to clipboard
Panic during CUDA types' Drop implementations inside thread-local storage
Hi, I'm writing a Python module that uses RustaCUDA and I am running into an issue where the library panics when Python is exiting.
I store some RustaCUDA state in a thread-local storage key, like this:
struct CUDAInstance {
module: Module,
_context: Context
}
impl CUDAInstance {
fn init() -> CudaResult<CUDAInstance> {
rustacuda::init(CudaFlags::empty())?;
let device = Device::get_device(0)?;
let context = Context::create_and_push(ContextFlags::MAP_HOST | ContextFlags::SCHED_AUTO, device)?;
Ok(CUDAInstance {
_context: context,
module: {
const PTX: &str = concat!(include_str!(concat!("../cuda/cuda.ptx")), "\0");
Module::load_from_string(unsafe { std::ffi::CStr::from_ptr(PTX.as_ptr() as *const i8) })?
}
})
}
}
thread_local! {
static CUDA: Result<CUDAInstance, CudaError> = CUDAInstance::init();
}
Everything works as expected, except that when Python has finished executing the script, Windows runs the thread-local storage destructor functions and RustaCUDA panics.
I would guess that CUDA has already been informed that the program is exiting and deinitializes itself, therefore the drop implementations panic, as they don't check if the types have already been deinitialized.
thread '<unnamed>' panicked at 'Failed to unload CUDA module: Deinitialized', C:\Users\William\.cargo\registry\src\github.com-1ecc6299db9ec823\rustacuda-0.1.3\src\module.rs:223:18
stack backtrace:
0: std::panicking::begin_panic_handler
at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c\/library\std\src\panicking.rs:584
1: core::panicking::panic_fmt
at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c\/library\core\src\panicking.rs:143
2: core::result::unwrap_failed
at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c\/library\core\src\result.rs:1749
3: enum$<core::result::Result<tuple$<>,enum$<rustacuda::error::CudaError> >, 1, 100101, Err>::expect
at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c\library\core\src\result.rs:1022
4: rustacuda::module::impl$1::drop
at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c\library\core\src\ptr\mod.rs:188
5: core::ptr::drop_in_place
at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c\library\core\src\ptr\mod.rs:188
6: core::ptr::drop_in_place
at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c\library\core\src\ptr\mod.rs:188
7: core::ptr::drop_in_place
at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c\library\core\src\ptr\mod.rs:188
8: core::ptr::drop_in_place
at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c\library\core\src\ptr\mod.rs:188
9: core::mem::drop
at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c\library\core\src\mem\mod.rs:909
10: std::thread::local::fast::destroy_value<enum$<core::result::Result<smh_vision_gpu::cuda::CUDAInstance,enum$<rustacuda::error::CudaError> > > >
at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c\library\std\src\thread\local.rs:669
11: std::sys::windows::thread_local_dtor::run_keyless_dtors
at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c\/library\std\src\sys\windows\thread_local_dtor.rs:24
12: std::sys::windows::thread_local_key::on_tls_callback
at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c\/library\std\src\sys\windows\thread_local_key.rs:200
13: RtlInitializeConditionVariable
14: RtlActivateActivationContextUnsafeFast
15: LdrLoadAlternateResourceModuleEx
16: LdrShutdownProcess
17: RtlExitUserProcess
18: ExitProcess
19: exit
20: exit
21: <unknown>
22: BaseThreadInitThunk
23: RtlUserThreadStart
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.