cust/
util.rs

1use crate::{
2    error::CudaResult,
3    memory::{
4        array::{ArrayObject, ArrayPrimitive},
5        DeviceBox, DeviceCopy, UnifiedBuffer,
6    },
7    prelude::DeviceBuffer,
8    surface::Surface,
9    texture::Texture,
10};
11
12pub trait DeviceCopyExt: DeviceCopy {
13    /// Makes a new [`DeviceBox`] from this value.
14    fn as_dbox(&self) -> CudaResult<DeviceBox<Self>> {
15        DeviceBox::new(self)
16    }
17}
18
19impl<T: DeviceCopy> DeviceCopyExt for T {}
20
21/// Utilities for slices and slice-like things such as arrays.
22pub trait SliceExt<T: DeviceCopy> {
23    /// Allocate memory on the GPU and convert this slice into a DBuffer.
24    fn as_dbuf(&self) -> CudaResult<DeviceBuffer<T>>;
25    /// Convert this slice to a [`UnifiedBuffer`] which can be accessed from the CPU and GPU
26    /// without conversions back and forth.
27    fn as_unified_buf(&self) -> CudaResult<UnifiedBuffer<T>>;
28
29    fn as_1d_array(&self) -> CudaResult<ArrayObject>
30    where
31        T: ArrayPrimitive;
32
33    fn as_2d_array(&self, width: usize, height: usize) -> CudaResult<ArrayObject>
34    where
35        T: ArrayPrimitive;
36
37    fn as_1d_texture(&self) -> CudaResult<Texture>
38    where
39        T: ArrayPrimitive,
40    {
41        Texture::from_array(self.as_1d_array()?)
42    }
43
44    fn as_2d_texture(&self, width: usize, height: usize) -> CudaResult<Texture>
45    where
46        T: ArrayPrimitive,
47    {
48        Texture::from_array(self.as_2d_array(width, height)?)
49    }
50
51    fn as_1d_surface(&self) -> CudaResult<Surface>
52    where
53        T: ArrayPrimitive,
54    {
55        Surface::from_array(self.as_1d_array()?)
56    }
57
58    fn as_2d_surface(&self, width: usize, height: usize) -> CudaResult<Surface>
59    where
60        T: ArrayPrimitive,
61    {
62        Surface::from_array(self.as_2d_array(width, height)?)
63    }
64}
65
66impl<T: DeviceCopy> SliceExt<T> for &[T] {
67    fn as_dbuf(&self) -> CudaResult<DeviceBuffer<T>> {
68        DeviceBuffer::from_slice(*self)
69    }
70
71    fn as_unified_buf(&self) -> CudaResult<UnifiedBuffer<T>> {
72        UnifiedBuffer::from_slice(*self)
73    }
74
75    fn as_1d_array(&self) -> CudaResult<ArrayObject>
76    where
77        T: ArrayPrimitive,
78    {
79        let mut arr = ArrayObject::new_1d(self.len(), T::array_format(), 1)?;
80        arr.copy_from(self)?;
81        Ok(arr)
82    }
83
84    fn as_2d_array(&self, width: usize, height: usize) -> CudaResult<ArrayObject>
85    where
86        T: ArrayPrimitive,
87    {
88        let mut arr = ArrayObject::new_2d([width, height], T::array_format(), 1)?;
89        arr.copy_from(self)?;
90        Ok(arr)
91    }
92}
93
94impl<T: DeviceCopy, const N: usize> SliceExt<T> for [T; N] {
95    fn as_dbuf(&self) -> CudaResult<DeviceBuffer<T>> {
96        DeviceBuffer::from_slice(self)
97    }
98
99    fn as_unified_buf(&self) -> CudaResult<UnifiedBuffer<T>> {
100        UnifiedBuffer::from_slice(self)
101    }
102
103    fn as_1d_array(&self) -> CudaResult<ArrayObject>
104    where
105        T: ArrayPrimitive,
106    {
107        let mut arr = ArrayObject::new_1d(self.len(), T::array_format(), 1)?;
108        arr.copy_from(self)?;
109        Ok(arr)
110    }
111
112    fn as_2d_array(&self, width: usize, height: usize) -> CudaResult<ArrayObject>
113    where
114        T: ArrayPrimitive,
115    {
116        let mut arr = ArrayObject::new_2d([width, height], T::array_format(), 1)?;
117        arr.copy_from(self)?;
118        Ok(arr)
119    }
120}