Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions nalgebra-glm/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ pub fn clamp_vec<T: Number, const D: usize>(
///
/// The floating-point value's bit-level representation is preserved.
///
/// Using unsafe is sound because the bitwise representation of f32 fits in i32
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This documentation goes inside the function, on the unsafe block. The use of unsafety in the implementation is not public; the purpose of the comment is to help a developer or auditor who is looking at the implementation.

///
/// # See also:
///
/// * [`float_bits_to_int_vec()`]
Expand Down Expand Up @@ -167,6 +169,8 @@ pub fn float_bits_to_int_vec<const D: usize>(v: &TVec<f32, D>) -> TVec<i32, D> {
///
/// The floating-point value's bit-level representation is preserved.
///
/// Using unsafe is sound because the bitwise representation of f32 fits in i32
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above.

///
/// # See also:
///
/// * [`float_bits_to_int()`]
Expand Down
4 changes: 4 additions & 0 deletions nalgebra-lapack/src/cholesky.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ where
lapack_check!(info);

// Copy lower triangle to upper triangle.
// Using unsafe to ensure the bounds i and j are always valid indices,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment doesn't make sense. The unsafe operation requires that the indices are in bounds; it does nothing to ensure that is actually the case. The comment should explain how we know it's the case.

for i in 0..dim {
for j in i + 1..dim {
unsafe { *self.l.get_unchecked_mut((i, j)) = *self.l.get_unchecked((j, i)) };
Expand Down Expand Up @@ -196,6 +197,9 @@ pub trait CholeskyScalar: Scalar + Copy {
fn xpotri(uplo: u8, n: i32, a: &mut [Self], lda: i32, info: &mut i32);
}

/// This macro uses unsafe to manually ensure memory safety for external functions
/// For incorrectly sized and initialized matrices and arrays, undefined behavior will occur
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment seems to be arguing that the use of unsafety is incorrect. If that's true, then we should fix the unsoundness, not just declare its presence. Several similar looking instances below.

/// Also, it helps with pointer dereferencing
macro_rules! cholesky_scalar_impl(
($N: ty, $xpotrf: path, $xpotrs: path, $xpotri: path) => (
impl CholeskyScalar for $N {
Expand Down
2 changes: 2 additions & 0 deletions nalgebra-lapack/src/eigen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,8 @@ pub trait EigenScalar: Scalar {
) -> i32;
}

/// This macro uses unsafe to manually ensure memory safety for external function xgeev
/// For incorrectly sized and initialized matrices and arrays, undefined behavior will occur
macro_rules! real_eigensystem_scalar_impl (
($N: ty, $xgeev: path) => (
impl EigenScalar for $N {
Expand Down
2 changes: 2 additions & 0 deletions nalgebra-lapack/src/generalized_eigenvalues.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@ pub trait GeneralizedEigenScalar: Scalar {
) -> i32;
}

/// This macro uses unsafe to manually ensure memory safety for external function xggev
/// For incorrectly sized and initialized matrices and arrays, undefined behavior will occur
macro_rules! generalized_eigen_scalar_impl (
($N: ty, $xggev: path) => (
impl GeneralizedEigenScalar for $N {
Expand Down
3 changes: 3 additions & 0 deletions nalgebra-lapack/src/hessenberg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ pub trait HessenbergReal: HessenbergScalar {
) -> i32;
}

/// This macro uses unsafe to manually ensure memory safety for external function xgehrd
/// For incorrectly sized and initialized matrices and arrays, undefined behavior will occur
macro_rules! hessenberg_scalar_impl(
($N: ty, $xgehrd: path) => (
impl HessenbergScalar for $N {
Expand All @@ -209,6 +211,7 @@ macro_rules! hessenberg_scalar_impl(
)
);

/// This macro uses unsafe to manually ensure memory safety for external function xorghr
macro_rules! hessenberg_real_impl(
($N: ty, $xorghr: path) => (
impl HessenbergReal for $N {
Expand Down
2 changes: 2 additions & 0 deletions nalgebra-lapack/src/lu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ pub trait LUScalar: Scalar + Copy {
fn xgetri_work_size(n: i32, a: &mut [Self], lda: i32, ipiv: &[i32], info: &mut i32) -> i32;
}

/// This macro uses unsafe to manually ensure memory safety for external functions
/// For incorrectly sized and initialized matrices and arrays, undefined behavior will occur
macro_rules! lup_scalar_impl(
($N: ty, $xgetrf: path, $xlaswp: path, $xgetrs: path, $xgetri: path) => (
impl LUScalar for $N {
Expand Down
4 changes: 4 additions & 0 deletions nalgebra-lapack/src/qr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ pub trait QRReal: QRScalar {
) -> i32;
}

/// This macro uses unsafe to manually ensure memory safety for external function xgeqrf
/// For incorrectly sized and initialized matrices and arrays, undefined behavior will occur
macro_rules! qr_scalar_impl(
($N: ty, $xgeqrf: path) => (
impl QRScalar for $N {
Expand All @@ -239,6 +241,8 @@ macro_rules! qr_scalar_impl(
)
);

/// This macro uses unsafe to manually ensure memory safety for external function xorgqr
/// For incorrectly sized and initialized matrices and arrays, undefined behavior will occur
macro_rules! qr_real_impl(
($N: ty, $xorgqr: path) => (
impl QRReal for $N {
Expand Down
2 changes: 2 additions & 0 deletions nalgebra-lapack/src/qz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ pub trait QZScalar: Scalar {
) -> i32;
}

/// This macro uses unsafe to manually ensure memory safety for external function xgges
/// For incorrectly sized and initialized matrices and arrays, undefined behavior will occur
macro_rules! qz_scalar_impl (
($N: ty, $xgges: path) => (
impl QZScalar for $N {
Expand Down
2 changes: 2 additions & 0 deletions nalgebra-lapack/src/schur.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ pub trait SchurScalar: Scalar {
) -> i32;
}

/// This macro uses unsafe to manually ensure memory safety for external function xgees
/// For incorrectly sized and initialized matrices and arrays, undefined behavior will occur
macro_rules! real_eigensystem_scalar_impl (
($N: ty, $xgees: path) => (
impl SchurScalar for $N {
Expand Down
4 changes: 3 additions & 1 deletion nalgebra-lapack/src/svd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ macro_rules! svd_impl(
let mut lwork = -1 as i32;
let mut info = 0;
let mut iwork = vec![0; 8 * cmp::min(nrows.value(), ncols.value())];


// Using unsafe to manually ensure memory safety for external function lapack_func
// Rust cannot check the slices' or raw poinnters' safety
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and below, the comment must explain exactly what the safety invariants are, and how we know they're satisfied.

unsafe {
$lapack_func(job, nrows.value() as i32, ncols.value() as i32, m.as_mut_slice(),
lda, &mut s.as_mut_slice(), u.as_mut_slice(), ldu as i32, vt.as_mut_slice(),
Expand Down
2 changes: 2 additions & 0 deletions nalgebra-lapack/src/symmetric_eigen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ pub trait SymmetricEigenScalar: Scalar {
-> i32;
}

/// This macro uses unsafe to manually ensure memory safety for external function xsyev
/// For incorrectly sized and initialized matrices and arrays, undefined behavior will occur
macro_rules! real_eigensystem_scalar_impl (
($N: ty, $xsyev: path) => (
impl SymmetricEigenScalar for $N {
Expand Down
2 changes: 2 additions & 0 deletions nalgebra-sparse/src/csc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ impl<T> CscMatrix<T> {
true,
);

// Using unsafe for efficiency and performance reasons in a custom memory layout
// SparsityPattern assumes offset and indices are valid; may lead to undefined behavior
match result {
Ok(()) => {
let pattern = unsafe {
Expand Down
2 changes: 2 additions & 0 deletions nalgebra-sparse/src/csr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ impl<T> CsrMatrix<T> {
true,
);

// Using unsafe for efficiency and performance reasons in a custom memory layout
// SparsityPattern assumes offset and indices are valid; may lead to undefined behavior
match result {
Ok(()) => {
let pattern = unsafe {
Expand Down
2 changes: 2 additions & 0 deletions nalgebra-sparse/src/factorization/cholesky.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ impl<T: RealField> CscCholesky<T> {
self.work_c.clear();
self.work_c.extend_from_slice(self.l_factor.col_offsets());

// Using unsafe to ensure validity of raw pointers and slices obtained with get_unchecked
// Also, data integrity is enforced in case the matrix is not positive definite
unsafe {
for k in 0..n {
// Scatter the k-th column of the original matrix with the values provided.
Expand Down
2 changes: 2 additions & 0 deletions nalgebra-sparse/src/ops/serial/cs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@ where
let alpha_aik = alpha.clone() * a_ik.clone();
for (j, b_kj) in b_lane_k.minor_indices().iter().zip(b_lane_k.values()) {
// use a dense scatter vector to accumulate non-zeros quickly
// using unsafe to ensure *j index and get_unchecked memory access are always valid
unsafe {
*scratchpad_values.get_unchecked_mut(*j) += alpha_aik.clone() * b_kj.clone();
}
}
}

//Get indices from C pattern and gather from the dense scratchpad_values
//Using unsafe to ensure *index is always valid
let (indices, values) = c_lane_i.indices_and_values_mut();
values
.iter_mut()
Expand Down