diff --git a/lightmotif/src/dense.rs b/lightmotif/src/dense.rs index 7486f640bc0a6872b59d595dccbfd425bcd10f7e..82ca168e0c942f31c203df6e5e55f937808a2fb7 100644 --- a/lightmotif/src/dense.rs +++ b/lightmotif/src/dense.rs @@ -30,6 +30,34 @@ impl<T: Default + Copy, C: Unsigned> DenseMatrix<T, C> { matrix } + /// Create a new *uninitialized* matrix with the given number of rows. + pub unsafe fn uninitialized(rows: usize) -> Self { + // alway over-allocate columns to avoid alignment issues. + let c = C::USIZE.next_power_of_two(); + + // NOTE: this is unsafe but given that we require `T` to be + // copy, this should be fine, as `Copy` prevents the + // type to be `Dorp` as well. + // reserve the vector without initializing the data + let mut data = Vec::with_capacity((rows + 1) * c); + data.set_len((rows + 1) * c); + + // compute offset to aligned memory + let mut offset = 0; + while data[offset..].as_ptr() as usize % c > 0 { + offset += 1 + } + + // record indices to each rows + let indices = (0..rows).into_iter().map(|i| offset + i * c).collect(); + + Self { + data, + indices, + _columns: std::marker::PhantomData, + } + } + /// The number of columns of the matrix. #[inline] pub const fn columns(&self) -> usize {