|
| 1 | +use crate::{ |
| 2 | + context::ContextFlags, |
| 3 | + device::Device, |
| 4 | + error::{CudaResult, ToResult}, |
| 5 | + sys as cuda, |
| 6 | +}; |
| 7 | +use std::mem::MaybeUninit; |
| 8 | + |
| 9 | +#[derive(Debug)] |
| 10 | +pub struct Context { |
| 11 | + inner: cuda::CUcontext, |
| 12 | + device: cuda::CUdevice, |
| 13 | +} |
| 14 | + |
| 15 | +impl Context { |
| 16 | + /// Retains the primary context for this device, incrementing the internal reference cycle |
| 17 | + /// that CUDA keeps track of. There is only one primary context associated with a device, multiple |
| 18 | + /// calls to this function with the same device will return the same internal context. |
| 19 | + /// |
| 20 | + /// This will **NOT** push the context to the stack, primary contexts do not interoperate |
| 21 | + /// with the context stack. |
| 22 | + pub fn new(device: &Device) -> CudaResult<Self> { |
| 23 | + let mut inner = MaybeUninit::uninit(); |
| 24 | + unsafe { |
| 25 | + cuda::cuDevicePrimaryCtxRetain(inner.as_mut_ptr(), device.as_raw()).to_result()?; |
| 26 | + Ok(Self { |
| 27 | + inner: inner.assume_init(), |
| 28 | + device: device.as_raw(), |
| 29 | + }) |
| 30 | + } |
| 31 | + } |
| 32 | + |
| 33 | + /// Resets the primary context associated with the device, freeing all allocations created |
| 34 | + /// inside of the context. You must make sure that nothing else is using the context or using |
| 35 | + /// CUDA on the device in general. For this reason, it is usually highly advised to not use |
| 36 | + /// this function. |
| 37 | + /// |
| 38 | + /// # Safety |
| 39 | + /// |
| 40 | + /// Nothing else should be using the primary context for this device, otherwise, |
| 41 | + /// spurious errors or segfaults will occur. |
| 42 | + pub unsafe fn reset(device: &Device) -> CudaResult<()> { |
| 43 | + cuda::cuDevicePrimaryCtxReset_v2(device.as_raw()).to_result() |
| 44 | + } |
| 45 | + |
| 46 | + /// Sets the flags for the device context, these flags will apply to any user of the primary |
| 47 | + /// context associated with this device. |
| 48 | + pub fn set_flags(&self, flags: ContextFlags) -> CudaResult<()> { |
| 49 | + unsafe { cuda::cuDevicePrimaryCtxSetFlags_v2(self.device, flags.bits()).to_result() } |
| 50 | + } |
| 51 | + |
| 52 | + /// Returns the raw handle to this context. |
| 53 | + pub fn as_raw(&self) -> cuda::CUcontext { |
| 54 | + self.inner |
| 55 | + } |
| 56 | +} |
| 57 | + |
| 58 | +impl Drop for Context { |
| 59 | + fn drop(&mut self) { |
| 60 | + unsafe { |
| 61 | + cuda::cuDevicePrimaryCtxRelease_v2(self.device); |
| 62 | + } |
| 63 | + } |
| 64 | +} |
0 commit comments