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 csr;
|
||||||
mod pattern;
|
mod pattern;
|
||||||
|
|
||||||
pub use coo::*;
|
|
||||||
pub use csr::*;
|
pub use csr::*;
|
||||||
pub use pattern::*;
|
pub use pattern::*;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
use nalgebra_sparse::coo::CooMatrix;
|
use nalgebra_sparse::ops::serial::{spmm_csr_dense, spadd_build_pattern, spadd_csr};
|
||||||
use nalgebra_sparse::ops::serial::{spmv_coo, spmm_csr_dense, spadd_build_pattern, spadd_csr};
|
|
||||||
use nalgebra_sparse::ops::{Transpose};
|
use nalgebra_sparse::ops::{Transpose};
|
||||||
use nalgebra_sparse::csr::CsrMatrix;
|
use nalgebra_sparse::csr::CsrMatrix;
|
||||||
use nalgebra_sparse::proptest::{csr, sparsity_pattern};
|
use nalgebra_sparse::proptest::{csr, sparsity_pattern};
|
||||||
use nalgebra_sparse::pattern::SparsityPattern;
|
use nalgebra_sparse::pattern::SparsityPattern;
|
||||||
|
|
||||||
use nalgebra::{DVector, DMatrix, Scalar, DMatrixSliceMut, DMatrixSlice};
|
use nalgebra::{DMatrix, Scalar, DMatrixSliceMut, DMatrixSlice};
|
||||||
use nalgebra::proptest::matrix;
|
use nalgebra::proptest::matrix;
|
||||||
|
|
||||||
use proptest::prelude::*;
|
use proptest::prelude::*;
|
||||||
|
@ -24,31 +23,6 @@ fn dense_csr_pattern(pattern: &SparsityPattern) -> DMatrix<i32> {
|
||||||
DMatrix::from(&boolean_csr)
|
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)]
|
#[derive(Debug)]
|
||||||
struct SpmmCsrDenseArgs<T: Scalar> {
|
struct SpmmCsrDenseArgs<T: Scalar> {
|
||||||
c: DMatrix<T>,
|
c: DMatrix<T>,
|
||||||
|
|
Loading…
Reference in New Issue