1use burn_backend::{ElementConversion, Scalar, ops::IntTensorOps};
2use burn_dispatch::Dispatch;
3
4use crate::{
5 Cast, Device, Float, Int, Shape, Tensor, TensorCreationOptions, TensorData, cartesian_grid,
6 ops::BridgeTensor,
7};
8
9use core::ops::Range;
10
11impl Tensor<1, Int> {
12 pub fn arange(range: Range<i64>, options: impl Into<TensorCreationOptions>) -> Self {
19 let opt = options.into();
20 let dtype = opt.resolve_dtype::<Int>();
21 Tensor::new(arange_impl(range, opt.device, dtype))
22 }
23
24 pub fn arange_step(
31 range: Range<i64>,
32 step: usize,
33 options: impl Into<TensorCreationOptions>,
34 ) -> Self {
35 let opt = options.into();
36 let dtype = opt.resolve_dtype::<Int>();
37 Tensor::new(arange_step_impl(range, step, opt.device, dtype))
38 }
39}
40
41impl<const D: usize> Tensor<D, Int> {
42 pub fn from_ints<A: Into<TensorData>>(ints: A, device: &Device) -> Self {
56 Self::from_data(ints.into().convert::<i32>(), device)
57 }
58
59 pub fn float(self) -> Tensor<D, Float> {
74 let device = self.device();
75 Tensor::new(int_to_float_impl(self.primitive, device))
76 }
77
78 pub fn cartesian_grid<S: Into<Shape>, const D2: usize>(
102 shape: S,
103 device: &Device,
104 ) -> Tensor<D2, Int> {
105 cartesian_grid::<S, D, D2>(shape, device)
106 }
107
108 #[cfg_attr(doc, doc = r#"$y_i = x_i * x_i$"#)]
111 #[cfg_attr(not(doc), doc = "`y_i = x_i * x_i`")]
112 pub fn square(self) -> Self {
113 Self::new(square_impl(self.primitive))
114 }
115
116 pub fn bitwise_and(self, other: Self) -> Self {
118 Self::new(bitwise_and_impl(self.primitive, other.primitive))
119 }
120
121 pub fn bitwise_or(self, other: Self) -> Self {
123 Self::new(bitwise_or_impl(self.primitive, other.primitive))
124 }
125
126 pub fn bitwise_xor(self, other: Self) -> Self {
128 Self::new(bitwise_xor_impl(self.primitive, other.primitive))
129 }
130
131 pub fn bitwise_not(self) -> Self {
133 Self::new(bitwise_not_impl(self.primitive))
134 }
135
136 pub fn bitwise_and_scalar(self, other: impl ElementConversion) -> Self {
138 let other = Scalar::new(other, &self.dtype());
139 Self::new(bitwise_and_scalar_impl(self.primitive, other))
140 }
141
142 pub fn bitwise_or_scalar(self, other: impl ElementConversion) -> Self {
144 let other = Scalar::new(other, &self.dtype());
145 Self::new(bitwise_or_scalar_impl(self.primitive, other))
146 }
147
148 pub fn bitwise_xor_scalar(self, other: impl ElementConversion) -> Self {
150 let other = Scalar::new(other, &self.dtype());
151 Self::new(bitwise_xor_scalar_impl(self.primitive, other))
152 }
153
154 pub fn bitwise_left_shift(self, other: Self) -> Self {
156 Self::new(bitwise_left_shift_impl(self.primitive, other.primitive))
157 }
158
159 pub fn bitwise_right_shift(self, other: Self) -> Self {
161 Self::new(bitwise_right_shift_impl(self.primitive, other.primitive))
162 }
163
164 pub fn bitwise_left_shift_scalar(self, other: impl ElementConversion) -> Self {
166 let other = Scalar::new(other, &self.dtype());
167 Self::new(bitwise_left_shift_scalar_impl(self.primitive, other))
168 }
169
170 pub fn bitwise_right_shift_scalar(self, other: impl ElementConversion) -> Self {
172 let other = Scalar::new(other, &self.dtype());
173 Self::new(bitwise_right_shift_scalar_impl(self.primitive, other))
174 }
175
176 #[must_use]
200 pub fn cast<T: Cast<D, Int>>(self, dtype: T) -> Tensor<D, T::OutputKind> {
201 T::cast(self, dtype)
202 }
203}
204
205fn arange_impl(range: Range<i64>, device: Device, dtype: burn_std::DType) -> BridgeTensor {
211 BridgeTensor::int(Dispatch::int_arange(
212 range,
213 device.as_dispatch(),
214 dtype.into(),
215 ))
216}
217
218fn arange_step_impl(
219 range: Range<i64>,
220 step: usize,
221 device: Device,
222 dtype: burn_std::DType,
223) -> BridgeTensor {
224 BridgeTensor::int(Dispatch::int_arange_step(
225 range,
226 step,
227 device.as_dispatch(),
228 dtype.into(),
229 ))
230}
231
232fn int_to_float_impl(p: BridgeTensor, device: Device) -> BridgeTensor {
233 let out_dtype = device.settings().float_dtype;
234 BridgeTensor::float(Dispatch::int_into_float(p.into(), out_dtype))
235}
236fn square_impl(tensor: BridgeTensor) -> BridgeTensor {
237 BridgeTensor::int(Dispatch::int_square(tensor.into()))
238}
239fn bitwise_and_impl(lhs: BridgeTensor, rhs: BridgeTensor) -> BridgeTensor {
240 BridgeTensor::int(Dispatch::bitwise_and(lhs.into(), rhs.into()))
241}
242fn bitwise_or_impl(lhs: BridgeTensor, rhs: BridgeTensor) -> BridgeTensor {
243 BridgeTensor::int(Dispatch::bitwise_or(lhs.into(), rhs.into()))
244}
245fn bitwise_xor_impl(lhs: BridgeTensor, rhs: BridgeTensor) -> BridgeTensor {
246 BridgeTensor::int(Dispatch::bitwise_xor(lhs.into(), rhs.into()))
247}
248fn bitwise_not_impl(p: BridgeTensor) -> BridgeTensor {
249 BridgeTensor::int(Dispatch::bitwise_not(p.into()))
250}
251fn bitwise_and_scalar_impl(p: BridgeTensor, other: Scalar) -> BridgeTensor {
252 BridgeTensor::int(Dispatch::bitwise_and_scalar(p.into(), other))
253}
254fn bitwise_or_scalar_impl(p: BridgeTensor, other: Scalar) -> BridgeTensor {
255 BridgeTensor::int(Dispatch::bitwise_or_scalar(p.into(), other))
256}
257fn bitwise_xor_scalar_impl(p: BridgeTensor, other: Scalar) -> BridgeTensor {
258 BridgeTensor::int(Dispatch::bitwise_xor_scalar(p.into(), other))
259}
260fn bitwise_left_shift_impl(lhs: BridgeTensor, rhs: BridgeTensor) -> BridgeTensor {
261 BridgeTensor::int(Dispatch::bitwise_left_shift(lhs.into(), rhs.into()))
262}
263fn bitwise_right_shift_impl(lhs: BridgeTensor, rhs: BridgeTensor) -> BridgeTensor {
264 BridgeTensor::int(Dispatch::bitwise_right_shift(lhs.into(), rhs.into()))
265}
266fn bitwise_left_shift_scalar_impl(p: BridgeTensor, other: Scalar) -> BridgeTensor {
267 BridgeTensor::int(Dispatch::bitwise_left_shift_scalar(p.into(), other))
268}
269fn bitwise_right_shift_scalar_impl(p: BridgeTensor, other: Scalar) -> BridgeTensor {
270 BridgeTensor::int(Dispatch::bitwise_right_shift_scalar(p.into(), other))
271}