use crate::error::{CudaError, CudaResult};
use crate::ffi::CUlimit;
use crate::loader::try_driver;
pub fn get_limit(limit: CUlimit) -> CudaResult<usize> {
let api = try_driver()?;
let f = api.cu_ctx_get_limit.ok_or(CudaError::NotSupported)?;
let mut value: usize = 0;
crate::cuda_call!(f(&mut value, limit as u32))?;
Ok(value)
}
pub fn set_limit(limit: CUlimit, value: usize) -> CudaResult<()> {
let api = try_driver()?;
let f = api.cu_ctx_set_limit.ok_or(CudaError::NotSupported)?;
crate::cuda_call!(f(limit as u32, value))
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum CacheConfig {
PreferNone = 0,
PreferShared = 1,
PreferL1 = 2,
PreferEqual = 3,
}
impl CacheConfig {
fn from_raw(val: u32) -> CudaResult<Self> {
match val {
0 => Ok(Self::PreferNone),
1 => Ok(Self::PreferShared),
2 => Ok(Self::PreferL1),
3 => Ok(Self::PreferEqual),
_ => Err(CudaError::InvalidValue),
}
}
}
pub fn get_cache_config() -> CudaResult<CacheConfig> {
let api = try_driver()?;
let f = api.cu_ctx_get_cache_config.ok_or(CudaError::NotSupported)?;
let mut raw: u32 = 0;
crate::cuda_call!(f(&mut raw))?;
CacheConfig::from_raw(raw)
}
pub fn set_cache_config(config: CacheConfig) -> CudaResult<()> {
let api = try_driver()?;
let f = api.cu_ctx_set_cache_config.ok_or(CudaError::NotSupported)?;
crate::cuda_call!(f(config as u32))
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(u32)]
pub enum SharedMemConfig {
Default = 0,
FourByte = 1,
EightByte = 2,
}
impl SharedMemConfig {
fn from_raw(val: u32) -> CudaResult<Self> {
match val {
0 => Ok(Self::Default),
1 => Ok(Self::FourByte),
2 => Ok(Self::EightByte),
_ => Err(CudaError::InvalidValue),
}
}
}
pub fn get_shared_mem_config() -> CudaResult<SharedMemConfig> {
let api = try_driver()?;
let f = api
.cu_ctx_get_shared_mem_config
.ok_or(CudaError::NotSupported)?;
let mut raw: u32 = 0;
crate::cuda_call!(f(&mut raw))?;
SharedMemConfig::from_raw(raw)
}
pub fn set_shared_mem_config(config: SharedMemConfig) -> CudaResult<()> {
let api = try_driver()?;
let f = api
.cu_ctx_set_shared_mem_config
.ok_or(CudaError::NotSupported)?;
crate::cuda_call!(f(config as u32))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn cache_config_round_trip() {
assert_eq!(CacheConfig::from_raw(0).ok(), Some(CacheConfig::PreferNone));
assert_eq!(
CacheConfig::from_raw(1).ok(),
Some(CacheConfig::PreferShared)
);
assert_eq!(CacheConfig::from_raw(2).ok(), Some(CacheConfig::PreferL1));
assert_eq!(
CacheConfig::from_raw(3).ok(),
Some(CacheConfig::PreferEqual)
);
assert!(CacheConfig::from_raw(99).is_err());
}
#[test]
fn shared_mem_config_round_trip() {
assert_eq!(
SharedMemConfig::from_raw(0).ok(),
Some(SharedMemConfig::Default)
);
assert_eq!(
SharedMemConfig::from_raw(1).ok(),
Some(SharedMemConfig::FourByte)
);
assert_eq!(
SharedMemConfig::from_raw(2).ok(),
Some(SharedMemConfig::EightByte)
);
assert!(SharedMemConfig::from_raw(99).is_err());
}
#[test]
fn cache_config_repr_values() {
assert_eq!(CacheConfig::PreferNone as u32, 0);
assert_eq!(CacheConfig::PreferShared as u32, 1);
assert_eq!(CacheConfig::PreferL1 as u32, 2);
assert_eq!(CacheConfig::PreferEqual as u32, 3);
}
#[test]
fn get_limit_returns_error_without_gpu() {
let result = get_limit(CUlimit::StackSize);
let _ = result;
}
}