Skip to main content

burn_tensor/tensor/api/
options.rs

1use burn_std::DType;
2
3use crate::{Device, bridge::BasicOps, ops::Kind};
4
5/// Options for tensor creation.
6///
7/// This struct allows specifying the `device` and overriding the data type when creating a tensor.
8/// When the `dtype` is not specified, the [device's default settings](crate::DeviceSettings) is used.
9#[derive(Debug, Clone)]
10pub struct TensorCreationOptions {
11    /// Device where the tensor will be created.
12    pub device: Device,
13    /// Optional data type.
14    /// If `None`, the dtype will be inferred on creation from the [device settings](crate::DeviceSettings).
15    pub dtype: Option<DType>,
16}
17
18impl Default for TensorCreationOptions {
19    /// Returns new options with the backend's default device.
20    fn default() -> Self {
21        Self::new(Default::default())
22    }
23}
24
25impl TensorCreationOptions {
26    /// Create new options with a specific device.
27    ///
28    /// Data type will follow the [device settings](crate::DeviceSettings) on tensor creation.
29    pub fn new(device: Device) -> Self {
30        Self {
31            device,
32            dtype: None,
33        }
34    }
35
36    /// Set the tensor creation data type.
37    pub fn with_dtype(mut self, dtype: DType) -> Self {
38        self.dtype = Some(dtype);
39
40        self
41    }
42
43    /// Set the tensor creation device.
44    pub fn with_device(mut self, device: Device) -> Self {
45        self.device = device;
46
47        self
48    }
49
50    /// Returns the tensor data type, or a provided default if not set.
51    ///
52    /// This is useful for cases where [`TensorCreationOptions`] may not have an explicit `dtype`.
53    pub fn dtype_or(&self, dtype: DType) -> DType {
54        self.dtype.unwrap_or(dtype)
55    }
56
57    /// Returns the tensor data type, or the default from the [device settings](crate::DeviceSettings).
58    pub(crate) fn resolve_dtype<K: BasicOps>(&self) -> DType {
59        let settings = self.device.settings();
60        let default = match K::KIND {
61            Kind::Float => settings.float_dtype.into(),
62            Kind::Int => settings.int_dtype.into(),
63            Kind::Bool => settings.bool_dtype.into(),
64        };
65        match K::KIND {
66            // `BoolStore` variants are backend-specific storage layouts rather than
67            // semantic types, and a requested variant (e.g. forced from a serialized
68            // snapshot by `burn-store`) may be unsupported on the target device, so
69            // always resolve bool tensors to the device's default bool storage.
70            Kind::Bool => default,
71            _ => self.dtype.unwrap_or(default),
72        }
73    }
74}
75
76impl From<&Device> for TensorCreationOptions {
77    /// Convenience conversion from a reference to a device.
78    ///
79    /// Example:
80    /// ```rust
81    /// use burn_tensor::TensorCreationOptions;
82    /// use burn_tensor::Device;
83    ///
84    /// fn example(device: Device) {
85    ///     let options: TensorCreationOptions = (&device).into();
86    /// }
87    /// ```
88    fn from(device: &Device) -> Self {
89        TensorCreationOptions::new(device.clone())
90    }
91}
92
93impl From<(&crate::Device, DType)> for TensorCreationOptions {
94    /// Convenience conversion for a specified `(&device, dtype)` tuple.
95    fn from(args: (&crate::Device, DType)) -> Self {
96        TensorCreationOptions::new(args.0.clone()).with_dtype(args.1)
97    }
98}