gunrock / graphblast

High-Performance Linear Algebra-based Graph Primitives on GPUs
Apache License 2.0
211 stars 27 forks source link

Incorrect MinPlus semiring output #20

Open Tiltedprogrammer opened 3 years ago

Tiltedprogrammer commented 3 years ago

I've built the library using CMake with the corresponding script and tried to run test/gspgemm.cu example. I have modified it a bit for it to read the matrix of mine. I had one run with PlusMultipliesSemiring and got the correct output. Then I ran the same example with MinimumPlusSemiring and got the same result as the PlusMultipliesSemiring one (which is incorrect in the case of minplus semiring).

The minimal reproducible example (Note: another issue is that uncommenting the lines at the bottom leads to segfault):

#define GRB_USE_CUDA
#define private public
#include <iostream>
#include <algorithm>
#include <string>

#include <cstdio>
#include <cstdlib>

#include <boost/program_options.hpp>

#include "graphblas/graphblas.hpp"
#include "test/test.hpp"

int main( int argc, char** argv )
{
  bool DEBUG = true;

  std::vector<graphblas::Index> a_row_indices, b_row_indices;
  std::vector<graphblas::Index> a_col_indices, b_col_indices;
  std::vector<float> a_values, b_values;
  graphblas::Index a_num_rows, a_num_cols, a_num_edges;
  graphblas::Index b_num_rows, b_num_cols, b_num_edges;
  char* dat_name;

  // Load A
  std::cout << "loading A" << std::endl;
  readMtx("path/to/example/matrix", &a_row_indices, &a_col_indices,
      &a_values, &a_num_rows, &a_num_cols, &a_num_edges, 1, false);
  graphblas::Matrix<float> a(a_num_rows, a_num_cols);
  a.build(&a_row_indices, &a_col_indices, &a_values, a_num_edges, GrB_NULL,
     GrB_NULL);
  if(DEBUG) a.print();

  // Load B, i.e. the matrix is squared
  std::cout << "loading B" << std::endl;
  readMtx("path/to/example/matrix", &b_row_indices, &b_col_indices,
      &b_values, &b_num_rows, &b_num_cols, &b_num_edges, 1, false);
  graphblas::Matrix<float> b(b_num_rows, b_num_cols);
  b.build(&b_row_indices, &b_col_indices, &b_values, b_num_edges, GrB_NULL,
     GrB_NULL );
  if(DEBUG) b.print();

  //
  graphblas::Matrix<float> c(a_num_rows, b_num_cols);
  graphblas::Descriptor desc;
  desc.descriptor_.debug_ = true;
  graphblas::mxm<float,float,float,float>(
      &c,
      GrB_NULL,
      GrB_NULL,
      graphblas::MinimumPlusSemiring<float>(),
      &a,
      &b,
      &desc
  );
  if(DEBUG) c.print();

//   // Multiply using GPU array initialization.
//   graphblas::Matrix<float> A(a_num_rows, a_num_cols);
//   graphblas::Matrix<float> B(b_num_rows, b_num_cols);
//   graphblas::Matrix<float> C(a_num_rows, b_num_cols);

//   A.build(a.matrix_.sparse_.d_csrRowPtr_, a.matrix_.sparse_.d_csrColInd_, a.matrix_.sparse_.d_csrVal_, a.matrix_.sparse_.nvals_);
//   B.build(b.matrix_.sparse_.d_csrRowPtr_, b.matrix_.sparse_.d_csrColInd_, b.matrix_.sparse_.d_csrVal_, b.matrix_.sparse_.nvals_);

//   desc.descriptor_.debug_ = true;

//   graphblas::mxm<T, T, T, T>(&C, GrB_NULL, GrB_NULL, graphblas::PlusMultipliesSemiring<float>(),
//                              &A, &B, &desc);

  // Multiply using CPU array initialization.
  // TODO(ctcyang): Add EXPECT_FAIL, because require pointers to be GPU.
  /*graphblas::Matrix<float> a_(a_num_rows, a_num_cols);
  graphblas::Matrix<float> b_(b_num_rows, b_num_cols);
  graphblas::Matrix<float> c_(a_num_rows, b_num_cols);

  a_.build(a.matrix_.sparse_.h_csrRowPtr_, a.matrix_.sparse_.h_csrColInd_, a.matrix_.sparse_.h_csrVal_, a.matrix_.sparse_.nvals_);
  b_.build(b.matrix_.sparse_.h_csrRowPtr_, b.matrix_.sparse_.h_csrColInd_, b.matrix_.sparse_.h_csrVal_, b.matrix_.sparse_.nvals_);

  desc.descriptor_.debug_ = true;

  graphblas::mxm<T, T, T, T>(&c_, GrB_NULL, GrB_NULL, graphblas::PlusMultipliesSemiring<float>(),
                             &a_, &b_, &desc);*/
}

example matrix:

%%MatrixMarket matrix coordinate real general
3 3 6
1   1   1
1   2   2
1   3   3
2   1   2
2   3   1
3   3   2

gspgemm with PlusMultipliesSemiring yields:

%%MatrixMarket matrix coordinate real general
3 3 7
1   1   5
1   2   2
1   3   11
2   1   2
2   2   4
2   3   8
3   3   4

which is correct, while MinimumPlusSemiring yields the same result as above when the correct one is:

%%MatrixMarket matrix coordinate real general
3 3 7
1   1   2
1   2   3
1   3   3
2   1   3
2   2   4
2   3   3
3   3   4