Miscellaneous improvements

This commit is contained in:
Violeta Hernández 2021-07-17 21:43:50 -05:00
parent 10b5dc9bb6
commit b74be8499f
17 changed files with 86 additions and 69 deletions

View File

@ -57,9 +57,8 @@ where
let (nrows, ncols) = m.data.shape();
let mut info = 0;
let mut tau = unsafe {
Matrix::new_uninitialized_generic(nrows.min(ncols), U1).assume_init()
};
let mut tau =
unsafe { Matrix::new_uninitialized_generic(nrows.min(ncols), U1).assume_init() };
if nrows.value() == 0 || ncols.value() == 0 {
return Self { qr: m, tau: tau };

View File

@ -1,4 +1,5 @@
use std::mem;use std::fmt::{self, Debug, Formatter};
use std::fmt::{self, Debug, Formatter};
use std::mem;
// use std::hash::{Hash, Hasher};
#[cfg(feature = "abomonation-serialize")]
use std::io::{Result as IOResult, Write};
@ -12,8 +13,6 @@ use serde::ser::SerializeSeq;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
#[cfg(feature = "serde-serialize-no-std")]
use std::marker::PhantomData;
#[cfg(feature = "serde-serialize-no-std")]
use std::mem;
#[cfg(feature = "abomonation-serialize")]
use abomonation::Abomonation;

View File

@ -4,7 +4,7 @@
//! heap-allocated buffers for matrices with at least one dimension unknown at compile-time.
use std::cmp;
use std::mem::{self, ManuallyDrop, MaybeUninit};
use std::mem::{ManuallyDrop, MaybeUninit};
use std::ptr;
#[cfg(all(feature = "alloc", not(feature = "std")))]
@ -92,9 +92,8 @@ impl<T, const R: usize, const C: usize> Allocator<T, Const<R>, Const<C>> for Def
// SAFETY:
// * `ManuallyDrop<T>` and T are guaranteed to have the same layout
// * `ManuallyDrop` does not drop, so there are no double-frees
// * `ArrayStorage` is transparent.
// And thus the conversion is safe
ArrayStorage(unsafe { mem::transmute_copy(&ManuallyDrop::new(buf.0)) })
unsafe { ArrayStorage((&ManuallyDrop::new(buf) as *const _ as *const [_; C]).read()) }
}
}
@ -132,32 +131,35 @@ impl<T, C: Dim> Allocator<T, Dynamic, C> for DefaultAllocator {
#[inline]
unsafe fn assume_init(uninit: Owned<MaybeUninit<T>, Dynamic, C>) -> Owned<T, Dynamic, C> {
let mut data = ManuallyDrop::new(uninit.data);
// Avoids a double-drop.
let (nrows, ncols) = uninit.shape();
let vec: Vec<_> = uninit.into();
let mut md = ManuallyDrop::new(vec);
// Safety: MaybeUninit<T> has the same alignment and layout as T.
let new_data =
Vec::from_raw_parts(data.as_mut_ptr() as *mut T, data.len(), data.capacity());
// Safety:
// - MaybeUninit<T> has the same alignment and layout as T.
// - The length and capacity come from a valid vector.
let new_data = Vec::from_raw_parts(md.as_mut_ptr() as *mut _, md.len(), md.capacity());
VecStorage::new(uninit.nrows, uninit.ncols, new_data)
VecStorage::new(nrows, ncols, new_data)
}
#[inline]
fn manually_drop(
buf: <Self as InnerAllocator<T, Dynamic, C>>::Buffer,
) -> <Self as InnerAllocator<ManuallyDrop<T>, Dynamic, C>>::Buffer {
// Avoids dropping the buffer that will be used for the result.
let mut data = ManuallyDrop::new(buf.data);
// Avoids a double-drop.
let (nrows, ncols) = buf.shape();
let vec: Vec<_> = buf.into();
let mut md = ManuallyDrop::new(vec);
// Safety: ManuallyDrop<T> has the same alignment and layout as T.
let new_data = unsafe {
Vec::from_raw_parts(
data.as_mut_ptr() as *mut ManuallyDrop<T>,
data.len(),
data.capacity(),
)
};
// Safety:
// - ManuallyDrop<T> has the same alignment and layout as T.
// - The length and capacity come from a valid vector.
let new_data =
unsafe { Vec::from_raw_parts(md.as_mut_ptr() as *mut _, md.len(), md.capacity()) };
VecStorage::new(buf.nrows, buf.ncols, new_data)
VecStorage::new(nrows, ncols, new_data)
}
}
@ -194,32 +196,35 @@ impl<T, R: DimName> Allocator<T, R, Dynamic> for DefaultAllocator {
#[inline]
unsafe fn assume_init(uninit: Owned<MaybeUninit<T>, R, Dynamic>) -> Owned<T, R, Dynamic> {
let mut data = ManuallyDrop::new(uninit.data);
// Avoids a double-drop.
let (nrows, ncols) = uninit.shape();
let vec: Vec<_> = uninit.into();
let mut md = ManuallyDrop::new(vec);
// Safety: MaybeUninit<T> has the same alignment and layout as T.
let new_data =
Vec::from_raw_parts(data.as_mut_ptr() as *mut T, data.len(), data.capacity());
// Safety:
// - MaybeUninit<T> has the same alignment and layout as T.
// - The length and capacity come from a valid vector.
let new_data = Vec::from_raw_parts(md.as_mut_ptr() as *mut _, md.len(), md.capacity());
VecStorage::new(uninit.nrows, uninit.ncols, new_data)
VecStorage::new(nrows, ncols, new_data)
}
#[inline]
fn manually_drop(
buf: <Self as InnerAllocator<T, R, Dynamic>>::Buffer,
) -> <Self as InnerAllocator<ManuallyDrop<T>, R, Dynamic>>::Buffer {
// Avoids dropping the buffer that will be used for the result.
let mut data = ManuallyDrop::new(buf.data);
// Avoids a double-drop.
let (nrows, ncols) = buf.shape();
let vec: Vec<_> = buf.into();
let mut md = ManuallyDrop::new(vec);
// Safety: ManuallyDrop<T> has the same alignment and layout as T.
let new_data = unsafe {
Vec::from_raw_parts(
data.as_mut_ptr() as *mut ManuallyDrop<T>,
data.len(),
data.capacity(),
)
};
// Safety:
// - ManuallyDrop<T> has the same alignment and layout as T.
// - The length and capacity come from a valid vector.
let new_data =
unsafe { Vec::from_raw_parts(md.as_mut_ptr() as *mut _, md.len(), md.capacity()) };
VecStorage::new(buf.nrows, buf.ncols, new_data)
VecStorage::new(nrows, ncols, new_data)
}
}

View File

@ -385,6 +385,10 @@ where
/// Assumes a matrix's entries to be initialized. This operation should be near zero-cost.
///
/// For the similar method that operates on matrix slices, see [`slice_assume_init`].
///
/// # Safety
/// The user must make sure that every single entry of the buffer has been initialized,
/// or Undefined Behavior will immediately occur.
pub unsafe fn assume_init(self) -> OMatrix<T, R, C> {
OMatrix::from_data(<DefaultAllocator as Allocator<T, R, C>>::assume_init(
self.data,
@ -408,6 +412,10 @@ where
impl<T, R: Dim, C: Dim, S> Matrix<MaybeUninit<T>, R, C, S> {
/// Creates a full slice from `self` and assumes it to be initialized.
///
/// # Safety
/// The user must make sure that every single entry of the buffer has been initialized,
/// or Undefined Behavior will immediately occur.
pub unsafe fn assume_init_ref(&self) -> MatrixSlice<T, R, C, S::RStride, S::CStride>
where
S: Storage<MaybeUninit<T>, R, C>,
@ -416,6 +424,10 @@ impl<T, R: Dim, C: Dim, S> Matrix<MaybeUninit<T>, R, C, S> {
}
/// Creates a full mutable slice from `self` and assumes it to be initialized.
///
/// # Safety
/// The user must make sure that every single entry of the buffer has been initialized,
/// or Undefined Behavior will immediately occur.
pub unsafe fn assume_init_mut(&mut self) -> MatrixSliceMut<T, R, C, S::RStride, S::CStride>
where
S: StorageMut<MaybeUninit<T>, R, C>,

View File

@ -237,6 +237,10 @@ impl<'a, T, R: Dim, C: Dim, RStride: Dim, CStride: Dim>
SliceStorageMut<'a, MaybeUninit<T>, R, C, RStride, CStride>
{
/// Assumes a slice storage's entries to be initialized. This operation should be near zero-cost.
///
/// # Safety
/// The user must make sure that every single entry of the buffer has been initialized,
/// or Undefined Behavior will immediately occur.
pub unsafe fn assume_init(self) -> SliceStorageMut<'a, T, R, C, RStride, CStride> {
SliceStorageMut::from_raw_parts(self.ptr as *mut T, self.shape, self.strides)
}

View File

@ -30,9 +30,9 @@ use abomonation::Abomonation;
/// A Vec-based matrix data storage. It may be dynamically-sized.
#[derive(Eq, Debug, Clone, PartialEq)]
pub struct VecStorage<T, R: Dim, C: Dim> {
pub(crate) data: Vec<T>,
pub(crate) nrows: R,
pub(crate) ncols: C,
data: Vec<T>,
nrows: R,
ncols: C,
}
#[cfg(feature = "serde-serialize")]
@ -193,7 +193,8 @@ where
#[inline]
fn clone_owned(&self) -> Owned<T, Dynamic, C>
where T:Clone,
where
T: Clone,
DefaultAllocator: InnerAllocator<T, Dynamic, C>,
{
self.clone()
@ -242,7 +243,8 @@ where
#[inline]
fn clone_owned(&self) -> Owned<T, R, Dynamic>
where T:Clone,
where
T: Clone,
DefaultAllocator: InnerAllocator<T, R, Dynamic>,
{
self.clone()

View File

@ -1,7 +1,5 @@
use std::fmt;
#[cfg(feature = "arbitrary")]
use crate::base::storage::Owned;
#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};

View File

@ -1,7 +1,5 @@
use std::fmt;
#[cfg(feature = "arbitrary")]
use crate::base::storage::Owned;
#[cfg(feature = "arbitrary")]
use quickcheck::{Arbitrary, Gen};

View File

@ -108,7 +108,7 @@ where
impl<T: Serialize, D: DimName> Serialize for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
<DefaultAllocator as Allocator<T, D>>::Buffer: Serialize,
<DefaultAllocator as InnerAllocator<T, D>>::Buffer: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@ -122,7 +122,7 @@ where
impl<'a, T: Deserialize<'a>, D: DimName> Deserialize<'a> for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
<DefaultAllocator as Allocator<T, D>>::Buffer: Deserialize<'a>,
<DefaultAllocator as InnerAllocator<T, D>>::Buffer: Deserialize<'a>,
{
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
where

View File

@ -1,11 +1,16 @@
//! This module provides the matrix exponent (exp) function to square matrices.
//!
use crate::{ComplexField, OMatrix, RealField, base::{
use crate::{
base::{
allocator::Allocator,
dimension::{Const, Dim, DimMin, DimMinimum},
storage::Storage,
DefaultAllocator,
}, convert, storage::Owned, try_convert};
},
convert,
storage::Owned,
try_convert, ComplexField, OMatrix, RealField,
};
use crate::num::Zero;

View File

@ -327,15 +327,10 @@ where
D: Dim,
DefaultAllocator: Allocator<ScalarStrategy::Value, D>,
{
matrix_(value_strategy, length.into(), U1.into())
matrix_(value_strategy, length.into(), Const::<1>.into())
}
impl<NParameters, R, C> Default for MatrixParameters<NParameters, R, C>
where
NParameters: Default,
R: DimName,
C: DimName,
{
impl<NParameters: Default, R: DimName, C: DimName> Default for MatrixParameters<NParameters, R, C> {
fn default() -> Self {
Self {
rows: DimRange::from(R::name()),

View File

@ -474,7 +474,7 @@ where
{
// Size = R
let nrows = self.data.shape().0;
let mut workspace = Matrix::new_uninitialized_generic(nrows, Const::<1>);
let mut workspace = CsMatrix::new_uninitialized_generic(nrows, Const::<1>);
self.sort_with_workspace(workspace.as_mut_slice());
}