use std::cell::Cell;
use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DeviceKind {
Cpu,
Gpu,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Device {
pub kind: DeviceKind,
pub index: u32,
}
impl Device {
pub const fn cpu() -> Self {
Self {
kind: DeviceKind::Cpu,
index: 0,
}
}
pub const fn gpu(index: u32) -> Self {
Self {
kind: DeviceKind::Gpu,
index,
}
}
}
impl fmt::Display for Device {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.kind {
DeviceKind::Cpu => write!(f, "cpu:{}", self.index),
DeviceKind::Gpu => write!(f, "gpu:{}", self.index),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Stream {
pub index: u32,
pub device: Device,
}
impl Stream {
pub const fn default_for(device: Device) -> Self {
Self { index: 0, device }
}
}
thread_local! {
static DEFAULT_STREAM: Cell<Stream> = const { Cell::new(Stream::default_for(Device::cpu())) };
}
pub fn default_stream() -> Stream {
DEFAULT_STREAM.get()
}
pub fn set_default_stream(stream: Stream) {
DEFAULT_STREAM.set(stream);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_is_cpu_and_settable_per_thread() {
assert_eq!(default_stream().device, Device::cpu());
set_default_stream(Stream::default_for(Device::gpu(0)));
assert_eq!(default_stream().device, Device::gpu(0));
std::thread::spawn(|| assert_eq!(default_stream().device, Device::cpu()))
.join()
.unwrap();
set_default_stream(Stream::default_for(Device::cpu()));
}
#[test]
fn display() {
assert_eq!(Device::gpu(1).to_string(), "gpu:1");
}
}