remove spmv_coo
This commit is contained in:
parent
41941e62c8
commit
c4285d9fb3
|
@ -1,72 +0,0 @@
|
|||
//! Matrix operations involving sparse matrices.
|
||||
|
||||
use crate::coo::CooMatrix;
|
||||
use nalgebra::base::storage::{Storage, StorageMut};
|
||||
use nalgebra::{ClosedAdd, ClosedMul, Dim, Scalar, Vector};
|
||||
use num_traits::{One, Zero};
|
||||
|
||||
/// Sparse matrix-vector multiplication `y = beta * y + alpha * A * x`.
|
||||
///
|
||||
/// Computes a matrix-vector product with the COO matrix "A" and the vector `x`, storing the
|
||||
/// result in `y`.
|
||||
///
|
||||
/// If `beta == 0`, the elements in `y` are never read.
|
||||
///
|
||||
/// TODO: Rethink this function
|
||||
///
|
||||
/// Panics
|
||||
/// ------
|
||||
///
|
||||
/// Panics if `y`, `a` and `x` do not have compatible dimensions.
|
||||
pub fn spmv_coo<T, Y, X, YDim, XDim>(
|
||||
beta: T,
|
||||
y: &mut Vector<T, YDim, Y>,
|
||||
alpha: T,
|
||||
a: &CooMatrix<T>,
|
||||
x: &Vector<T, XDim, X>,
|
||||
) where
|
||||
T: Scalar + ClosedAdd + ClosedMul + Zero + One,
|
||||
YDim: Dim,
|
||||
XDim: Dim,
|
||||
Y: StorageMut<T, YDim>,
|
||||
X: Storage<T, XDim>,
|
||||
{
|
||||
assert_eq!(
|
||||
y.len(),
|
||||
a.nrows(),
|
||||
"y and a must be dimensionally compatible"
|
||||
);
|
||||
assert_eq!(
|
||||
a.ncols(),
|
||||
x.len(),
|
||||
"a and x must be dimensionally compatible"
|
||||
);
|
||||
|
||||
if beta == T::zero() {
|
||||
// If `y` is constructed through `new_uninitialized()`, we must make sure to not read
|
||||
// any of the elements in order to avoid UB, so we special case beta == 0
|
||||
// in order to ensure that we only write, not read, the elements in y.
|
||||
for y_i in y.iter_mut() {
|
||||
*y_i = T::zero();
|
||||
}
|
||||
} else if beta != T::one() {
|
||||
// Since the COO triplets have no particular structure, we cannot combine initialization
|
||||
// of y with the triplet loop below, and instead have to do it in a pre-pass.
|
||||
for y_i in y.iter_mut() {
|
||||
*y_i *= beta.inlined_clone();
|
||||
}
|
||||
}
|
||||
|
||||
for (i, j, v) in a.triplet_iter() {
|
||||
// TODO: We could skip bounds checks with unsafe here, since COO ensures that all indices
|
||||
// are in bounds and we assert on dimensions up-front.
|
||||
// The compiler will not be able to elide the checks, since we're doing
|
||||
// random/unpredictable access to elements in `x` and `y`.
|
||||
let (alpha, v, x_j) = (
|
||||
alpha.inlined_clone(),
|
||||
v.inlined_clone(),
|
||||
x[j].inlined_clone(),
|
||||
);
|
||||
y[i] += alpha * v * x_j;
|
||||
}
|
||||
}
|
|
@ -30,11 +30,9 @@ macro_rules! assert_compatible_spmm_dims {
|
|||
}
|
||||
}
|
||||
|
||||
mod coo;
|
||||
mod csr;
|
||||
mod pattern;
|
||||
|
||||
pub use coo::*;
|
||||
pub use csr::*;
|
||||
pub use pattern::*;
|
||||
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
use nalgebra_sparse::coo::CooMatrix;
|
||||
use nalgebra_sparse::ops::serial::{spmv_coo, spmm_csr_dense, spadd_build_pattern, spadd_csr};
|
||||
use nalgebra_sparse::ops::serial::{spmm_csr_dense, spadd_build_pattern, spadd_csr};
|
||||
use nalgebra_sparse::ops::{Transpose};
|
||||
use nalgebra_sparse::csr::CsrMatrix;
|
||||
use nalgebra_sparse::proptest::{csr, sparsity_pattern};
|
||||
use nalgebra_sparse::pattern::SparsityPattern;
|
||||
|
||||
use nalgebra::{DVector, DMatrix, Scalar, DMatrixSliceMut, DMatrixSlice};
|
||||
use nalgebra::{DMatrix, Scalar, DMatrixSliceMut, DMatrixSlice};
|
||||
use nalgebra::proptest::matrix;
|
||||
|
||||
use proptest::prelude::*;
|
||||
|
@ -24,31 +23,6 @@ fn dense_csr_pattern(pattern: &SparsityPattern) -> DMatrix<i32> {
|
|||
DMatrix::from(&boolean_csr)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spmv_coo_agrees_with_dense_gemv() {
|
||||
let x = DVector::from_column_slice(&[2, 3, 4, 5]);
|
||||
|
||||
let i = vec![0, 0, 1, 1, 2, 2];
|
||||
let j = vec![0, 3, 0, 1, 1, 3];
|
||||
let v = vec![3, 2, 1, 2, 3, 1];
|
||||
let a = CooMatrix::try_from_triplets(3, 4, i, j, v).unwrap();
|
||||
|
||||
let betas = [0, 1, 2];
|
||||
let alphas = [0, 1, 2];
|
||||
|
||||
for &beta in &betas {
|
||||
for &alpha in &alphas {
|
||||
let mut y = DVector::from_column_slice(&[2, 5, 3]);
|
||||
let mut y_dense = y.clone();
|
||||
spmv_coo(beta, &mut y, alpha, &a, &x);
|
||||
|
||||
y_dense.gemv(alpha, &DMatrix::from(&a), &x, beta);
|
||||
|
||||
assert_eq!(y, y_dense);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SpmmCsrDenseArgs<T: Scalar> {
|
||||
c: DMatrix<T>,
|
||||
|
|
Loading…
Reference in New Issue