Skip to content

Commit 6ab2b48

Browse files
authored
Merge pull request #243 from rust-ndarray/vec_uninit
Uninitialize working memory
2 parents 73d4e77 + dc2ab7d commit 6ab2b48

13 files changed

+79
-75
lines changed

lax/src/eig.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Eigenvalue decomposition for general matrices
22
3-
use crate::{error::*, layout::MatrixLayout};
3+
use crate::{error::*, layout::MatrixLayout, *};
44
use cauchy::*;
55
use num_traits::{ToPrimitive, Zero};
66

@@ -33,16 +33,16 @@ macro_rules! impl_eig_complex {
3333
} else {
3434
(b'N', b'N')
3535
};
36-
let mut eigs = vec![Self::Complex::zero(); n as usize];
37-
let mut rwork = vec![Self::Real::zero(); 2 * n as usize];
36+
let mut eigs = unsafe { vec_uninit(n as usize) };
37+
let mut rwork = unsafe { vec_uninit(2 * n as usize) };
3838

3939
let mut vl = if jobvl == b'V' {
40-
Some(vec![Self::Complex::zero(); (n * n) as usize])
40+
Some(unsafe { vec_uninit((n * n) as usize) })
4141
} else {
4242
None
4343
};
4444
let mut vr = if jobvr == b'V' {
45-
Some(vec![Self::Complex::zero(); (n * n) as usize])
45+
Some(unsafe { vec_uninit((n * n) as usize) })
4646
} else {
4747
None
4848
};
@@ -72,7 +72,7 @@ macro_rules! impl_eig_complex {
7272

7373
// actal ev
7474
let lwork = work_size[0].to_usize().unwrap();
75-
let mut work = vec![Self::zero(); lwork];
75+
let mut work = unsafe { vec_uninit(lwork) };
7676
unsafe {
7777
$ev(
7878
jobvl,
@@ -128,16 +128,16 @@ macro_rules! impl_eig_real {
128128
} else {
129129
(b'N', b'N')
130130
};
131-
let mut eig_re = vec![Self::zero(); n as usize];
132-
let mut eig_im = vec![Self::zero(); n as usize];
131+
let mut eig_re = unsafe { vec_uninit(n as usize) };
132+
let mut eig_im = unsafe { vec_uninit(n as usize) };
133133

134134
let mut vl = if jobvl == b'V' {
135-
Some(vec![Self::zero(); (n * n) as usize])
135+
Some(unsafe { vec_uninit((n * n) as usize) })
136136
} else {
137137
None
138138
};
139139
let mut vr = if jobvr == b'V' {
140-
Some(vec![Self::zero(); (n * n) as usize])
140+
Some(unsafe { vec_uninit((n * n) as usize) })
141141
} else {
142142
None
143143
};
@@ -167,7 +167,7 @@ macro_rules! impl_eig_real {
167167

168168
// actual ev
169169
let lwork = work_size[0].to_usize().unwrap();
170-
let mut work = vec![Self::zero(); lwork];
170+
let mut work = unsafe { vec_uninit(lwork) };
171171
unsafe {
172172
$ev(
173173
jobvl,
@@ -219,7 +219,7 @@ macro_rules! impl_eig_real {
219219
// ```
220220
let n = n as usize;
221221
let v = vr.or(vl).unwrap();
222-
let mut eigvecs = vec![Self::Complex::zero(); n * n];
222+
let mut eigvecs = unsafe { vec_uninit(n * n) };
223223
let mut is_conjugate_pair = false; // flag for check `j` is complex conjugate
224224
for j in 0..n {
225225
if eig_im[j] == 0.0 {

lax/src/eigh.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@ macro_rules! impl_eigh {
4242
assert_eq!(layout.len(), layout.lda());
4343
let n = layout.len();
4444
let jobz = if calc_v { b'V' } else { b'N' };
45-
let mut eigs = vec![Self::Real::zero(); n as usize];
45+
let mut eigs = unsafe { vec_uninit(n as usize) };
4646

4747
$(
48-
let mut $rwork_ident = vec![Self::Real::zero(); 3 * n as usize - 2];
48+
let mut $rwork_ident = unsafe { vec_uninit(3 * n as usize - 2 as usize) };
4949
)*
5050

5151
// calc work size
@@ -69,7 +69,7 @@ macro_rules! impl_eigh {
6969

7070
// actual ev
7171
let lwork = work_size[0].to_usize().unwrap();
72-
let mut work = vec![Self::zero(); lwork];
72+
let mut work = unsafe { vec_uninit(lwork) };
7373
unsafe {
7474
$ev(
7575
jobz,
@@ -98,10 +98,10 @@ macro_rules! impl_eigh {
9898
assert_eq!(layout.len(), layout.lda());
9999
let n = layout.len();
100100
let jobz = if calc_v { b'V' } else { b'N' };
101-
let mut eigs = vec![Self::Real::zero(); n as usize];
101+
let mut eigs = unsafe { vec_uninit(n as usize) };
102102

103103
$(
104-
let mut $rwork_ident = vec![Self::Real::zero(); 3 * n as usize - 2];
104+
let mut $rwork_ident = unsafe { vec_uninit(3 * n as usize - 2) };
105105
)*
106106

107107
// calc work size
@@ -128,7 +128,7 @@ macro_rules! impl_eigh {
128128

129129
// actual evg
130130
let lwork = work_size[0].to_usize().unwrap();
131-
let mut work = vec![Self::zero(); lwork];
131+
let mut work = unsafe { vec_uninit(lwork) };
132132
unsafe {
133133
$evg(
134134
&[1],

lax/src/least_squares.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Least squares
22
3-
use crate::{error::*, layout::*};
3+
use crate::{error::*, layout::*, *};
44
use cauchy::*;
55
use num_traits::{ToPrimitive, Zero};
66

@@ -68,7 +68,7 @@ macro_rules! impl_least_squares {
6868
let mut a_t = None;
6969
let a_layout = match a_layout {
7070
MatrixLayout::C { .. } => {
71-
a_t = Some(vec![Self::zero(); a.len()]);
71+
a_t = Some(unsafe { vec_uninit( a.len()) });
7272
transpose(a_layout, a, a_t.as_mut().unwrap())
7373
}
7474
MatrixLayout::F { .. } => a_layout,
@@ -78,14 +78,14 @@ macro_rules! impl_least_squares {
7878
let mut b_t = None;
7979
let b_layout = match b_layout {
8080
MatrixLayout::C { .. } => {
81-
b_t = Some(vec![Self::zero(); b.len()]);
81+
b_t = Some(unsafe { vec_uninit( b.len()) });
8282
transpose(b_layout, b, b_t.as_mut().unwrap())
8383
}
8484
MatrixLayout::F { .. } => b_layout,
8585
};
8686

8787
let rcond: Self::Real = -1.;
88-
let mut singular_values: Vec<Self::Real> = vec![Self::Real::zero(); k as usize];
88+
let mut singular_values: Vec<Self::Real> = unsafe { vec_uninit( k as usize) };
8989
let mut rank: i32 = 0;
9090

9191
// eval work size
@@ -118,12 +118,12 @@ macro_rules! impl_least_squares {
118118

119119
// calc
120120
let lwork = work_size[0].to_usize().unwrap();
121-
let mut work = vec![Self::zero(); lwork];
121+
let mut work = unsafe { vec_uninit( lwork) };
122122
let liwork = iwork_size[0].to_usize().unwrap();
123-
let mut iwork = vec![0; liwork];
123+
let mut iwork = unsafe { vec_uninit( liwork) };
124124
$(
125125
let lrwork = $rwork[0].to_usize().unwrap();
126-
let mut $rwork = vec![Self::Real::zero(); lrwork];
126+
let mut $rwork = unsafe { vec_uninit( lrwork) };
127127
)*
128128
unsafe {
129129
$gelsd(

lax/src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,15 @@ impl NormType {
168168
}
169169
}
170170
}
171+
172+
/// Create a vector without initialization
173+
///
174+
/// Safety
175+
/// ------
176+
/// - Memory is not initialized. Do not read the memory before write.
177+
///
178+
unsafe fn vec_uninit<T: Sized>(n: usize) -> Vec<T> {
179+
let mut v = Vec::with_capacity(n);
180+
v.set_len(n);
181+
v
182+
}

lax/src/opnorm.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
//! Operator norms of matrices
22
33
use super::NormType;
4-
use crate::layout::MatrixLayout;
4+
use crate::{layout::MatrixLayout, *};
55
use cauchy::*;
6-
use num_traits::Zero;
76

87
pub trait OperatorNorm_: Scalar {
98
fn opnorm(t: NormType, l: MatrixLayout, a: &[Self]) -> Self::Real;
@@ -20,7 +19,7 @@ macro_rules! impl_opnorm {
2019
MatrixLayout::C { .. } => t.transpose(),
2120
};
2221
let mut work = if matches!(t, NormType::Infinity) {
23-
vec![Self::Real::zero(); m as usize]
22+
unsafe { vec_uninit(m as usize) }
2423
} else {
2524
Vec::new()
2625
};

lax/src/qr.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! QR decomposition
22
3-
use crate::{error::*, layout::MatrixLayout};
3+
use crate::{error::*, layout::MatrixLayout, *};
44
use cauchy::*;
55
use num_traits::{ToPrimitive, Zero};
66

@@ -25,7 +25,7 @@ macro_rules! impl_qr {
2525
let m = l.lda();
2626
let n = l.len();
2727
let k = m.min(n);
28-
let mut tau = vec![Self::zero(); k as usize];
28+
let mut tau = unsafe { vec_uninit(k as usize) };
2929

3030
// eval work size
3131
let mut info = 0;
@@ -44,7 +44,7 @@ macro_rules! impl_qr {
4444

4545
// calc
4646
let lwork = work_size[0].to_usize().unwrap();
47-
let mut work = vec![Self::zero(); lwork];
47+
let mut work = unsafe { vec_uninit(lwork) };
4848
unsafe {
4949
match l {
5050
MatrixLayout::F { .. } => {
@@ -100,7 +100,7 @@ macro_rules! impl_qr {
100100

101101
// calc
102102
let lwork = work_size[0].to_usize().unwrap();
103-
let mut work = vec![Self::zero(); lwork];
103+
let mut work = unsafe { vec_uninit(lwork) };
104104
unsafe {
105105
match l {
106106
MatrixLayout::F { .. } => {

lax/src/rcond.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use super::*;
2-
use crate::{error::*, layout::MatrixLayout};
1+
use crate::{error::*, layout::MatrixLayout, *};
32
use cauchy::*;
43
use num_traits::Zero;
54

@@ -18,8 +17,8 @@ macro_rules! impl_rcond_real {
1817
let mut rcond = Self::Real::zero();
1918
let mut info = 0;
2019

21-
let mut work = vec![Self::zero(); 4 * n as usize];
22-
let mut iwork = vec![0; n as usize];
20+
let mut work = unsafe { vec_uninit(4 * n as usize) };
21+
let mut iwork = unsafe { vec_uninit(n as usize) };
2322
let norm_type = match l {
2423
MatrixLayout::C { .. } => NormType::Infinity,
2524
MatrixLayout::F { .. } => NormType::One,
@@ -55,8 +54,8 @@ macro_rules! impl_rcond_complex {
5554
let (n, _) = l.size();
5655
let mut rcond = Self::Real::zero();
5756
let mut info = 0;
58-
let mut work = vec![Self::zero(); 2 * n as usize];
59-
let mut rwork = vec![Self::Real::zero(); 2 * n as usize];
57+
let mut work = unsafe { vec_uninit(2 * n as usize) };
58+
let mut rwork = unsafe { vec_uninit(2 * n as usize) };
6059
let norm_type = match l {
6160
MatrixLayout::C { .. } => NormType::Infinity,
6261
MatrixLayout::F { .. } => NormType::One,

lax/src/solve.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Solve linear problem using LU decomposition
22
3-
use super::*;
4-
use crate::{error::*, layout::MatrixLayout};
3+
use crate::{error::*, layout::MatrixLayout, *};
54
use cauchy::*;
65
use num_traits::{ToPrimitive, Zero};
76

@@ -34,7 +33,7 @@ macro_rules! impl_solve {
3433
return Ok(Vec::new());
3534
}
3635
let k = ::std::cmp::min(row, col);
37-
let mut ipiv = vec![0; k as usize];
36+
let mut ipiv = unsafe { vec_uninit(k as usize) };
3837
let mut info = 0;
3938
unsafe { $getrf(l.lda(), l.len(), a, l.lda(), &mut ipiv, &mut info) };
4039
info.as_lapack_result()?;
@@ -52,7 +51,7 @@ macro_rules! impl_solve {
5251

5352
// actual
5453
let lwork = work_size[0].to_usize().unwrap();
55-
let mut work = vec![Self::zero(); lwork];
54+
let mut work = unsafe { vec_uninit(lwork) };
5655
unsafe {
5756
$getri(
5857
l.len(),

lax/src/solveh.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
//!
33
//! See also [the manual of dsytrf](http://www.netlib.org/lapack/lapack-3.1.1/html/dsytrf.f.html)
44
5-
use super::*;
6-
use crate::{error::*, layout::MatrixLayout};
5+
use crate::{error::*, layout::MatrixLayout, *};
76
use cauchy::*;
87
use num_traits::{ToPrimitive, Zero};
98

@@ -21,7 +20,7 @@ macro_rules! impl_solveh {
2120
impl Solveh_ for $scalar {
2221
fn bk(l: MatrixLayout, uplo: UPLO, a: &mut [Self]) -> Result<Pivot> {
2322
let (n, _) = l.size();
24-
let mut ipiv = vec![0; n as usize];
23+
let mut ipiv = unsafe { vec_uninit(n as usize) };
2524
if n == 0 {
2625
return Ok(Vec::new());
2726
}
@@ -45,7 +44,7 @@ macro_rules! impl_solveh {
4544

4645
// actual
4746
let lwork = work_size[0].to_usize().unwrap();
48-
let mut work = vec![Self::zero(); lwork];
47+
let mut work = unsafe { vec_uninit(lwork) };
4948
unsafe {
5049
$trf(
5150
uplo as u8,
@@ -65,7 +64,7 @@ macro_rules! impl_solveh {
6564
fn invh(l: MatrixLayout, uplo: UPLO, a: &mut [Self], ipiv: &Pivot) -> Result<()> {
6665
let (n, _) = l.size();
6766
let mut info = 0;
68-
let mut work = vec![Self::zero(); n as usize];
67+
let mut work = unsafe { vec_uninit(n as usize) };
6968
unsafe { $tri(uplo as u8, n, a, l.lda(), ipiv, &mut work, &mut info) };
7069
info.as_lapack_result()?;
7170
Ok(())

lax/src/svd.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Singular-value decomposition
22
3-
use crate::{error::*, layout::MatrixLayout};
3+
use crate::{error::*, layout::MatrixLayout, *};
44
use cauchy::*;
55
use num_traits::{ToPrimitive, Zero};
66

@@ -61,21 +61,21 @@ macro_rules! impl_svd {
6161

6262
let m = l.lda();
6363
let mut u = match ju {
64-
FlagSVD::All => Some(vec![Self::zero(); (m * m) as usize]),
64+
FlagSVD::All => Some(unsafe { vec_uninit( (m * m) as usize) }),
6565
FlagSVD::No => None,
6666
};
6767

6868
let n = l.len();
6969
let mut vt = match jvt {
70-
FlagSVD::All => Some(vec![Self::zero(); (n * n) as usize]),
70+
FlagSVD::All => Some(unsafe { vec_uninit( (n * n) as usize) }),
7171
FlagSVD::No => None,
7272
};
7373

7474
let k = std::cmp::min(m, n);
75-
let mut s = vec![Self::Real::zero(); k as usize];
75+
let mut s = unsafe { vec_uninit( k as usize) };
7676

7777
$(
78-
let mut $rwork_ident = vec![Self::Real::zero(); 5 * k as usize];
78+
let mut $rwork_ident = unsafe { vec_uninit( 5 * k as usize) };
7979
)*
8080

8181
// eval work size
@@ -104,7 +104,7 @@ macro_rules! impl_svd {
104104

105105
// calc
106106
let lwork = work_size[0].to_usize().unwrap();
107-
let mut work = vec![Self::zero(); lwork];
107+
let mut work = unsafe { vec_uninit( lwork) };
108108
unsafe {
109109
$gesvd(
110110
ju as u8,

0 commit comments

Comments
 (0)