#图算法 # #BLAS #图BLAS #线性代数 #矩阵-向量 #矩阵运算

rustgraphblas

用于暴露SparseMatrix和SparseVector的GraphBLAS.h包装器

15次重大发布

0.16.0-alpha2021年9月8日
0.14.0-alpha2021年4月30日
0.13.0-alpha2020年9月25日
0.12.0-alpha2020年5月6日
0.9.0-alpha2020年3月28日

#2040 in 算法

38 每月下载次数

Apache-2.0

98KB
2.5K SLoC

rustgraphblas

GraphBLAS.h的包装器,提供了更友好的rust API

提供了一套在稀疏矩阵和稀疏向量上的操作,结合各种半群。这使得图可以表示为稀疏矩阵,并且可以将各种算法(bfs、连通分量、页面排名等)作为一系列线性代数操作实现。

更多关于GraphBLAS的信息 这里

要求:构建并安装GraphBLAS依赖项,详细信息请参阅这里

cd deps/GraphBLAS
make clean install

bfs5m.c中的BFS示例

/**
 * this is the test for the graph on the cover of 
 * Graph Algorithms in the Language of Linear Algebra
 * where by multiplying a boolean matrix with 
 * a boolean vector on the and/or semiring until there are no successor we get BFS
 * */
fn graph_blas_port_bfs(){
    let s:u64 = 0; // start at 0
    let n = 7; //vertices

    let mut A = SparseMatrix::<bool>::empty((n, n));

    let edges_n:usize = 10;
    A.load(edges_n as u64, &vec![true; edges_n],
           &[0, 0, 1, 1, 2, 3, 4, 5, 6, 6],
           &[1, 3, 6, 4, 5, 2, 5, 2, 2, 3]);

    let mut v = SparseVector::<i32>::empty(n);
    let mut q = SparseVector::<bool>::empty(n);

    let mut default_desc = Descriptor::default();

    // GrB_assign (v, NULL, NULL, 0, GrB_ALL, n, NULL) ;   // make v dense
    v.assign_all(empty_mask::<bool>(), None, 0, n, &default_desc);

    //finish pending work on v
    assert_eq!(n, v.nvals());
    // GrB_Vector_setElement (q, true, s) ;   // q[s] = true, false elsewhere
    q.insert(s, true);

    // GrB_Monoid_new (&Lor, GrB_LOR, (bool) false) ;
    // GrB_Semiring_new (&Boolean, Lor, GrB_LAND) ;
    // FIXME: Semirings do not OWN monoids
    let lor_monoid = SparseMonoid::<bool>::new(BinaryOp::<bool, bool, bool>::lor(), false);
    let lor_monoid2 = SparseMonoid::<bool>::new(BinaryOp::<bool, bool, bool>::lor(), false);
    let or_and_semi = Semiring::new(lor_monoid, BinaryOp::<bool, bool, bool>::land());


    let mut desc = Descriptor::default();
    desc.set(Field::Mask, Value::SCMP).set(Field::Output, Value::Replace);

    let mut successor = true;

    let mut level:i32 = 1;
    while successor && level <= (n as i32) {
        v.assign_all(Some(&q), None, level, n, &default_desc);

        q.vxm(Some(&v), None, &A, &or_and_semi, &desc);

        q.reduce(&mut successor, None, &lor_monoid2, &default_desc);

        level = level + 1;
    }
    assert_eq!(v.get(0), Some(1));

    assert_eq!(v.get(1), Some(2));
    assert_eq!(v.get(3), Some(2));

    assert_eq!(v.get(4), Some(3));
    assert_eq!(v.get(6), Some(3));
    assert_eq!(v.get(2), Some(3));

    assert_eq!(v.get(5), Some(4));

}

依赖项

~1.3–3.5MB
~72K SLoC