diff --git a/Cargo.toml b/Cargo.toml index f1e50ab9..de5d6176 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,7 @@ compare = [ "matrixcompare-core" ] libm = [ "simba/libm" ] libm-force = [ "simba/libm_force" ] macros = [ "nalgebra-macros" ] +cuda = [ "cust" ] # Conversion convert-mint = [ "mint" ] @@ -86,7 +87,7 @@ pest = { version = "2", optional = true } pest_derive = { version = "2", optional = true } bytemuck = { version = "1.5", optional = true } matrixcompare-core = { version = "0.1", optional = true } -proptest = { version = "1", optional = true, default-features = false, features = ["std"] } +proptest = { version = "1", optional = true, default-features = false, features = ["std"] } glam013 = { package = "glam", version = "0.13", optional = true } glam014 = { package = "glam", version = "0.14", optional = true } glam015 = { package = "glam", version = "0.15", optional = true } @@ -94,6 +95,9 @@ glam016 = { package = "glam", version = "0.16", optional = true } glam017 = { package = "glam", version = "0.17", optional = true } glam018 = { package = "glam", version = "0.18", optional = true } +[target.'cfg(not(target_os = "cuda"))'.dependencies] +cust = { version = "0.1", optional = true } + [dev-dependencies] serde_json = "1.0" diff --git a/src/base/array_storage.rs b/src/base/array_storage.rs index 3fc88ade..b46d442f 100644 --- a/src/base/array_storage.rs +++ b/src/base/array_storage.rs @@ -32,6 +32,10 @@ use std::mem; /// A array-based statically sized matrix data storage. #[repr(transparent)] #[derive(Copy, Clone, PartialEq, Eq, Hash)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] pub struct ArrayStorage(pub [[T; R]; C]); impl ArrayStorage { diff --git a/src/base/dimension.rs b/src/base/dimension.rs index 9a51536c..86006f3d 100644 --- a/src/base/dimension.rs +++ b/src/base/dimension.rs @@ -13,6 +13,10 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; /// Dim of dynamically-sized algebraic entities. #[derive(Clone, Copy, Eq, PartialEq, Debug)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] pub struct Dynamic { value: usize, } @@ -197,6 +201,10 @@ dim_ops!( ); #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] pub struct Const; /// Trait implemented exclusively by type-level integers. diff --git a/src/base/matrix.rs b/src/base/matrix.rs index 983f9a86..5df2f78e 100644 --- a/src/base/matrix.rs +++ b/src/base/matrix.rs @@ -154,6 +154,10 @@ pub type MatrixCross = /// some concrete types for `T` and a compatible data storage type `S`). #[repr(C)] #[derive(Clone, Copy)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] pub struct Matrix { /// The data storage that contains all the matrix components. Disappointed? /// diff --git a/src/base/unit.rs b/src/base/unit.rs index 8d548687..22af401a 100644 --- a/src/base/unit.rs +++ b/src/base/unit.rs @@ -26,6 +26,10 @@ use crate::{Dim, Matrix, OMatrix, RealField, Scalar, SimdComplexField, SimdRealF /// in their documentation, read their dedicated pages directly. #[repr(transparent)] #[derive(Clone, Hash, Copy)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] pub struct Unit { pub(crate) value: T, } diff --git a/src/geometry/dual_quaternion.rs b/src/geometry/dual_quaternion.rs index e597cbf5..4280668a 100644 --- a/src/geometry/dual_quaternion.rs +++ b/src/geometry/dual_quaternion.rs @@ -39,6 +39,10 @@ use simba::scalar::{ClosedNeg, RealField}; /// See #[repr(C)] #[derive(Debug, Copy, Clone)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] pub struct DualQuaternion { /// The real component of the quaternion pub real: Quaternion, diff --git a/src/geometry/isometry.rs b/src/geometry/isometry.rs index bdd2de60..f020c0e9 100755 --- a/src/geometry/isometry.rs +++ b/src/geometry/isometry.rs @@ -54,7 +54,11 @@ use crate::geometry::{AbstractRotation, Point, Translation}; /// * [Conversion to a matrix `to_matrix`…](#conversion-to-a-matrix) /// #[repr(C)] -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] #[cfg_attr(feature = "serde-serialize-no-std", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde-serialize-no-std", @@ -170,20 +174,6 @@ where } } -impl Copy for Isometry where - Owned>: Copy -{ -} - -impl Clone for Isometry { - #[inline] - fn clone(&self) -> Self { - Self { - rotation: self.rotation.clone(), - translation: self.translation.clone(), - } - } -} /// # From the translation and rotation parts impl, const D: usize> Isometry { /// Creates a new isometry from its rotational and translational parts. diff --git a/src/geometry/orthographic.rs b/src/geometry/orthographic.rs index d4008173..18a7852d 100644 --- a/src/geometry/orthographic.rs +++ b/src/geometry/orthographic.rs @@ -19,19 +19,15 @@ use crate::geometry::{Point3, Projective3}; /// A 3D orthographic projection stored as a homogeneous 4x4 matrix. #[repr(C)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] +#[derive(Copy, Clone)] pub struct Orthographic3 { matrix: Matrix4, } -impl Copy for Orthographic3 {} - -impl Clone for Orthographic3 { - #[inline] - fn clone(&self) -> Self { - Self::from_matrix_unchecked(self.matrix.clone()) - } -} - impl fmt::Debug for Orthographic3 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { self.matrix.fmt(f) diff --git a/src/geometry/perspective.rs b/src/geometry/perspective.rs index 34af6f0b..59b7f9f2 100644 --- a/src/geometry/perspective.rs +++ b/src/geometry/perspective.rs @@ -20,19 +20,15 @@ use crate::geometry::{Point3, Projective3}; /// A 3D perspective projection stored as a homogeneous 4x4 matrix. #[repr(C)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] +#[derive(Copy, Clone)] pub struct Perspective3 { matrix: Matrix4, } -impl Copy for Perspective3 {} - -impl Clone for Perspective3 { - #[inline] - fn clone(&self) -> Self { - Self::from_matrix_unchecked(self.matrix.clone()) - } -} - impl fmt::Debug for Perspective3 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { self.matrix.fmt(f) diff --git a/src/geometry/point.rs b/src/geometry/point.rs index 7930e8fb..0953a9ce 100644 --- a/src/geometry/point.rs +++ b/src/geometry/point.rs @@ -74,6 +74,15 @@ where { } +#[cfg(all(not(target_os = "cuda"), feature = "cuda"))] +unsafe impl cust::memory::DeviceCopy + for OPoint +where + DefaultAllocator: Allocator, + OVector: cust::memory::DeviceCopy, +{ +} + #[cfg(feature = "bytemuck")] unsafe impl bytemuck::Zeroable for OPoint where diff --git a/src/geometry/quaternion.rs b/src/geometry/quaternion.rs index 968a9e18..05b73334 100755 --- a/src/geometry/quaternion.rs +++ b/src/geometry/quaternion.rs @@ -28,6 +28,10 @@ use crate::geometry::{Point3, Rotation}; /// that may be used as a rotation. #[repr(C)] #[derive(Copy, Clone)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] pub struct Quaternion { /// This quaternion as a 4D vector of coordinates in the `[ x, y, z, w ]` storage order. pub coords: Vector4, diff --git a/src/geometry/rotation.rs b/src/geometry/rotation.rs index e1da8d67..2d5e5d24 100755 --- a/src/geometry/rotation.rs +++ b/src/geometry/rotation.rs @@ -54,6 +54,11 @@ use crate::geometry::Point; /// * [Conversion to a matrix `matrix`, `to_homogeneous`…](#conversion-to-a-matrix) /// #[repr(C)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] +#[derive(Copy, Clone)] pub struct Rotation { matrix: SMatrix, } @@ -73,21 +78,6 @@ where } } -impl Copy for Rotation where - , Const>>::Buffer: Copy -{ -} - -impl Clone for Rotation -where - , Const>>::Buffer: Clone, -{ - #[inline] - fn clone(&self) -> Self { - Self::from_matrix_unchecked(self.matrix.clone()) - } -} - #[cfg(feature = "bytemuck")] unsafe impl bytemuck::Zeroable for Rotation where diff --git a/src/geometry/scale.rs b/src/geometry/scale.rs index 9f3e778c..b1d278d6 100755 --- a/src/geometry/scale.rs +++ b/src/geometry/scale.rs @@ -22,6 +22,11 @@ use crate::geometry::Point; /// A scale which supports non-uniform scaling. #[repr(C)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] +#[derive(Copy, Clone)] pub struct Scale { /// The scale coordinates, i.e., how much is multiplied to a point's coordinates when it is /// scaled. @@ -43,18 +48,6 @@ where } } -impl Copy for Scale {} - -impl Clone for Scale -where - Owned>: Clone, -{ - #[inline] - fn clone(&self) -> Self { - Scale::from(self.vector.clone()) - } -} - #[cfg(feature = "bytemuck")] unsafe impl bytemuck::Zeroable for Scale where diff --git a/src/geometry/similarity.rs b/src/geometry/similarity.rs index 1b685252..fd6b1d36 100755 --- a/src/geometry/similarity.rs +++ b/src/geometry/similarity.rs @@ -23,7 +23,11 @@ use crate::geometry::{AbstractRotation, Isometry, Point, Translation}; /// A similarity, i.e., an uniform scaling, followed by a rotation, followed by a translation. #[repr(C)] -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] #[cfg_attr(feature = "serde-serialize-no-std", derive(Serialize, Deserialize))] #[cfg_attr( feature = "serde-serialize-no-std", @@ -73,22 +77,6 @@ where } } -impl + Copy, const D: usize> Copy - for Similarity -where - Owned>: Copy, -{ -} - -impl + Clone, const D: usize> Clone - for Similarity -{ - #[inline] - fn clone(&self) -> Self { - Similarity::from_isometry(self.isometry.clone(), self.scaling.clone()) - } -} - impl Similarity where R: AbstractRotation, diff --git a/src/geometry/transform.rs b/src/geometry/transform.rs index d87a815d..b0b5cced 100755 --- a/src/geometry/transform.rs +++ b/src/geometry/transform.rs @@ -60,14 +60,26 @@ where /// Tag representing the most general (not necessarily inversible) `Transform` type. #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] pub enum TGeneral {} /// Tag representing the most general inversible `Transform` type. #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] pub enum TProjective {} /// Tag representing an affine `Transform`. Its bottom-row is equal to `(0, 0 ... 0, 1)`. #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] pub enum TAffine {} impl TCategory for TGeneral { @@ -195,6 +207,16 @@ where { } +#[cfg(all(not(target_os = "cuda"), feature = "cuda"))] +unsafe impl + cust::memory::DeviceCopy for Transform +where + Const: DimNameAdd, + DefaultAllocator: Allocator, U1>, DimNameSum, U1>>, + Owned, U1>, DimNameSum, U1>>: cust::memory::DeviceCopy, +{ +} + impl Clone for Transform where Const: DimNameAdd, diff --git a/src/geometry/translation.rs b/src/geometry/translation.rs index 48656f9c..1ce8cba3 100755 --- a/src/geometry/translation.rs +++ b/src/geometry/translation.rs @@ -22,6 +22,11 @@ use crate::geometry::Point; /// A translation. #[repr(C)] +#[cfg_attr( + all(not(target_os = "cuda"), feature = "cuda"), + derive(cust::DeviceCopy) +)] +#[derive(Copy, Clone)] pub struct Translation { /// The translation coordinates, i.e., how much is added to a point's coordinates when it is /// translated. @@ -43,18 +48,6 @@ where } } -impl Copy for Translation {} - -impl Clone for Translation -where - Owned>: Clone, -{ - #[inline] - fn clone(&self) -> Self { - Translation::from(self.vector.clone()) - } -} - #[cfg(feature = "bytemuck")] unsafe impl bytemuck::Zeroable for Translation where