#![cfg(feature = "curand-quasirandom")]
use crate::error::GpuError;
use crate::sys::curand as csys;
use crate::sys::curand::RngGeneratorKind;
use super::LIB;
pub unsafe fn set_dimensions(
gen: cudarc::curand::sys::curandGenerator_t,
dimensions: u32,
) -> Result<(), GpuError> {
csys::set_quasi_random_dimensions(gen, dimensions).map_err(|e| GpuError::LibraryError {
lib: LIB,
msg: format!("set_quasi_random_dimensions({dimensions}): {e}"),
})
}
impl super::RngActor {
pub fn set_quasi_dimensions(&self, dimensions: u32) -> Result<(), GpuError> {
let (gen_lock, kind_lock) = match &self.inner {
super::RngInner::Real { gen, kind, .. } => (gen, kind),
super::RngInner::Mock => {
return Err(GpuError::Unrecoverable("RngActor in mock mode".into()))
}
};
let active = *kind_lock.lock();
if !active.is_quasi() {
return Err(GpuError::LibraryError {
lib: LIB,
msg: format!(
"set_quasi_dimensions called on non-quasi generator ({active:?}); \
SetGenerator {{ kind: Sobol* }} first"
),
});
}
let g = gen_lock.lock();
unsafe { set_dimensions(g.0, dimensions) }
}
}
pub fn max_dimensions(kind: RngGeneratorKind) -> Option<u32> {
match kind {
RngGeneratorKind::Sobol32 | RngGeneratorKind::ScrambledSobol32 => Some(20_000),
RngGeneratorKind::Sobol64 | RngGeneratorKind::ScrambledSobol64 => Some(20_000),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sobol32_sobol64_kind_correct() {
assert_eq!(RngGeneratorKind::Sobol32.to_sys() as u32, 201);
assert_eq!(RngGeneratorKind::ScrambledSobol32.to_sys() as u32, 202);
assert_eq!(RngGeneratorKind::Sobol64.to_sys() as u32, 203);
assert_eq!(RngGeneratorKind::ScrambledSobol64.to_sys() as u32, 204);
for k in [
RngGeneratorKind::Sobol32,
RngGeneratorKind::ScrambledSobol32,
RngGeneratorKind::Sobol64,
RngGeneratorKind::ScrambledSobol64,
] {
assert!(k.is_quasi());
assert_eq!(max_dimensions(k), Some(20_000));
}
for k in [
RngGeneratorKind::PseudoDefault,
RngGeneratorKind::Philox4_32_10,
RngGeneratorKind::XorWow,
RngGeneratorKind::Mrg32K3A,
RngGeneratorKind::Mtgp32,
] {
assert!(!k.is_quasi());
assert_eq!(max_dimensions(k), None);
}
}
}