Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supernode-based SpTrsv updates #739

Merged
merged 4 commits into from
Jun 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 95 additions & 16 deletions perf_test/sparse/KokkosSparse_sptrsv_cholmod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ using namespace KokkosSparse;
using namespace KokkosSparse::Experimental;
using namespace KokkosSparse::PerfTest::Experimental;

enum {CUSPARSE, SUPERNODAL_NAIVE, SUPERNODAL_ETREE};
enum {CUSPARSE, SUPERNODAL_NAIVE, SUPERNODAL_ETREE, SUPERNODAL_SPMV};


/* ========================================================================================= */
Expand Down Expand Up @@ -150,10 +150,18 @@ cholmod_factor* factor_cholmod(const size_type nrow, const size_type nnz, scalar
}


/* ========================================================================================= */
void free_cholmod(cholmod_factor *L, cholmod_common *cm) {
/* free matrices */
cholmod_free_factor (&L, cm);
cholmod_finish (cm);
}


/* ========================================================================================= */
template<typename scalar_type>
int test_sptrsv_perf(std::vector<int> tests, std::string& filename, int loop) {
int test_sptrsv_perf(std::vector<int> tests, std::string& filename, bool u_in_csr, bool invert_diag, bool invert_offdiag,
int block_size, int loop) {

using STS = Kokkos::Details::ArithTraits<scalar_type>;
using mag_type = typename STS::mag_type;
Expand Down Expand Up @@ -225,9 +233,14 @@ int test_sptrsv_perf(std::vector<int> tests, std::string& filename, int loop) {
L = factor_cholmod<cholmod_int_type, scalar_type>
(nrows, Mtx.nnz(), values_host.data(), const_cast<size_type*> (row_map_host.data()), entries_host.data(),
&cm, &etree);
std::cout << " Factorization Time: " << timer.seconds() << std::endl << std::endl;
int* iperm = new int[nrows];
int* perm = new int[nrows];
double factor_time = timer.seconds();
std::cout << " Factorization Time: " << factor_time << std::endl << std::endl;
using integer_view_host_t = typename KernelHandle::SPTRSVHandleType::integer_view_host_t;
integer_view_host_t iperm_view ("perm view", nrows);
integer_view_host_t perm_view ("iperm view", nrows);

int* iperm = iperm_view.data ();
int* perm = perm_view.data ();
for (int i = 0; i < nrows; i++) {
iperm[i] = ((cholmod_int_type*)(L->Perm))[i];
perm[iperm[i]] = i;
Expand All @@ -242,17 +255,22 @@ int test_sptrsv_perf(std::vector<int> tests, std::string& filename, int loop) {
switch(test) {
case SUPERNODAL_NAIVE:
case SUPERNODAL_ETREE:
case SUPERNODAL_SPMV:
{
// ==============================================
// Create handles for U and U^T solves
if (test == SUPERNODAL_NAIVE) {
std::cout << " > create handle for SUPERNODAL_NAIVE" << std::endl << std::endl;
khL.create_sptrsv_handle (SPTRSVAlgorithm::SUPERNODAL_NAIVE, nrows, true);
khU.create_sptrsv_handle (SPTRSVAlgorithm::SUPERNODAL_NAIVE, nrows, false);
} else {
if (test == SUPERNODAL_ETREE) {
std::cout << " > create handle for SUPERNODAL_ETREE" << std::endl << std::endl;
khL.create_sptrsv_handle (SPTRSVAlgorithm::SUPERNODAL_ETREE, nrows, true);
khU.create_sptrsv_handle (SPTRSVAlgorithm::SUPERNODAL_ETREE, nrows, false);
} else if (test == SUPERNODAL_SPMV) {
std::cout << " > create handle for SUPERNODAL_SPMV" << std::endl << std::endl;
khL.create_sptrsv_handle (SPTRSVAlgorithm::SUPERNODAL_SPMV, nrows, true);
khU.create_sptrsv_handle (SPTRSVAlgorithm::SUPERNODAL_SPMV, nrows, false);
} else {
std::cout << " > create handle for SUPERNODAL_NAIVE" << std::endl << std::endl;
khL.create_sptrsv_handle (SPTRSVAlgorithm::SUPERNODAL_NAIVE, nrows, true);
khU.create_sptrsv_handle (SPTRSVAlgorithm::SUPERNODAL_NAIVE, nrows, false);
}

// ==============================================
Expand All @@ -265,13 +283,46 @@ int test_sptrsv_perf(std::vector<int> tests, std::string& filename, int loop) {
khL.set_sptrsv_perm (perm);
khU.set_sptrsv_perm (perm);

// ==============================================
// specify if U is stored in CSR or CSC
std::cout << "=============================== " << std::endl;
std::cout << " U in CSR : " << u_in_csr << std::endl;
khU.set_sptrsv_column_major (!u_in_csr);

// ==============================================
// specify wheather to invert diagonal blocks
std::cout << " Invert diagonal : " << invert_diag << std::endl;
khL.set_sptrsv_invert_diagonal (invert_diag);
khU.set_sptrsv_invert_diagonal (invert_diag);

// ==============================================
// specify wheather to apply diagonal-inversion to off-diagonal blocks (optional, default is false)
std::cout << " Invert Off-diagonal: " << invert_offdiag << std::endl;
khL.set_sptrsv_invert_offdiagonal (invert_offdiag);
khU.set_sptrsv_invert_offdiagonal (invert_offdiag);

// ==============================================
// block size to switch to device call
if (block_size >= 0) {
std::cout << " Block Size : " << block_size << std::endl;
khL.set_sptrsv_diag_supernode_sizes (block_size, block_size);
khU.set_sptrsv_diag_supernode_sizes (block_size, block_size);
}
std::cout << std::endl;

// ==============================================
// Do symbolic analysis
timer.reset();
sptrsv_symbolic<cholmod_int_type> (&khL, &khU, L, &cm);
double symbolic_time = timer.seconds();
std::cout << " Symbolic Time : " << symbolic_time << std::endl << std::endl;

// ==============================================
// Do numerical compute
timer.reset();
sptrsv_compute<cholmod_int_type> (&khL, &khU, L, &cm);
double compute_time = timer.seconds();
std::cout << " Numeric Time : " << compute_time << std::endl << std::endl;

// ==============================================
// Create the known solution and set to all 1's ** on host **
Expand Down Expand Up @@ -324,6 +375,7 @@ int test_sptrsv_perf(std::vector<int> tests, std::string& filename, int loop) {
// ==============================================
// Error Check ** on host **
Kokkos::fence();
std::cout << std::endl;
if (!check_errors(tol, Mtx, rhs_host, sol_host)) {
num_failed ++;
}
Expand Down Expand Up @@ -415,6 +467,9 @@ int test_sptrsv_perf(std::vector<int> tests, std::string& filename, int loop) {
exit(0);
}
}

// free cholmod data structures
free_cholmod(L, &cm);
}
std::cout << std::endl << std::endl;

Expand Down Expand Up @@ -443,6 +498,14 @@ int main(int argc, char **argv)
std::string filename;

int loop = 1;
// store U in CSR, or CSC
bool u_in_csr = true;
// invert diagonal of L-factor
bool invert_diag = false;
// apply invert of diagonal to offdiagonal
bool invert_offdiag = false;
// block size to switch to device call (default is 100)
int block_size = -1;
// scalar type
std::string char_scalar = "d";

Expand All @@ -458,11 +521,11 @@ int main(int argc, char **argv)
i++;
if((strcmp(argv[i],"cholmod-naive")==0)) {
tests.push_back( SUPERNODAL_NAIVE );
}
if((strcmp(argv[i],"cholmod-etree")==0)) {
} else if((strcmp(argv[i],"cholmod-etree")==0)) {
tests.push_back( SUPERNODAL_ETREE );
}
if((strcmp(argv[i],"cusparse")==0)) {
} else if((strcmp(argv[i],"cholmod-spmv")==0)) {
tests.push_back( SUPERNODAL_SPMV );
} else if((strcmp(argv[i],"cusparse")==0)) {
tests.push_back( CUSPARSE );
}
continue;
Expand All @@ -475,6 +538,22 @@ int main(int argc, char **argv)
loop = atoi(argv[++i]);
continue;
}
if((strcmp(argv[i],"--u-in-csc")==0)) {
u_in_csr = false;
continue;
}
if((strcmp(argv[i],"--invert-diag")==0)) {
invert_diag = true;
continue;
}
if((strcmp(argv[i],"--invert-offdiag")==0)) {
invert_offdiag = true;
continue;
}
if((strcmp(argv[i],"--block-size")==0)) {
block_size = atoi(argv[++i]);
continue;
}
if((strcmp(argv[i],"--scalar-type")==0)) {
char_scalar = argv[++i];
}
Expand All @@ -496,13 +575,13 @@ int main(int argc, char **argv)
Kokkos::ScopeGuard kokkosScope (argc, argv);
if (char_scalar == "z") {
#if defined(KOKKOSKERNELS_INST_COMPLEX_DOUBLE)
total_errors = test_sptrsv_perf<Kokkos::complex<double>>(tests, filename, loop);
total_errors = test_sptrsv_perf<Kokkos::complex<double>>(tests, filename, u_in_csr, invert_diag, invert_offdiag, block_size, loop);
#else
std::cout << std::endl << " KOKKOSKERNELS_INST_COMPLEX_DOUBLE is not enabled ** " << std::endl << std::endl;
#endif
} else if (char_scalar == "d") {
#if defined(KOKKOSKERNELS_INST_DOUBLE)
total_errors = test_sptrsv_perf<double>(tests, filename, loop);
total_errors = test_sptrsv_perf<double>(tests, filename, u_in_csr, invert_diag, invert_offdiag, block_size, loop);
#else
std::cout << std::endl << " KOKKOSKERNELS_INST_DOUBLE is not enabled ** " << std::endl << std::endl;
#endif
Expand Down
7 changes: 4 additions & 3 deletions perf_test/sparse/KokkosSparse_sptrsv_superlu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,6 @@ void factor_superlu (bool symm_mode, bool metis,


/* ========================================================================================= */
template<typename scalar_type>
void free_superlu (SuperMatrix &L, SuperMatrix &U,
int *perm_r, int *perm_c, int *parents) {

Expand Down Expand Up @@ -351,7 +350,8 @@ int test_sptrsv_perf (std::vector<int> tests, bool verbose, std::string &filenam
factor_superlu<scalar_type> (symm_mode, metis, nrows,
values_host.data(), const_cast<int*> (row_map_host.data()), entries_host.data(),
panel_size, relax_size, L, U, &perm_r, &perm_c, &etree);
std::cout << " Factorization Time: " << timer.seconds() << std::endl << std::endl;
double factor_time = timer.seconds();
std::cout << " Factorization Time: " << factor_time << std::endl << std::endl;

// ==============================================
// Run all requested algorithms
Expand Down Expand Up @@ -404,6 +404,7 @@ int test_sptrsv_perf (std::vector<int> tests, bool verbose, std::string &filenam
khU.set_sptrsv_merge_supernodes (merge);

// specify wheather to invert diagonal blocks
std::cout << " Invert diagonal : " << invert_diag << std::endl;
khL.set_sptrsv_invert_diagonal (invert_diag);
khU.set_sptrsv_invert_diagonal (invert_diag);

Expand Down Expand Up @@ -624,7 +625,7 @@ int test_sptrsv_perf (std::vector<int> tests, bool verbose, std::string &filenam
}
}
// free SuperLU data structures
free_superlu<scalar_type> (L, U, perm_r, perm_c, etree);
free_superlu (L, U, perm_r, perm_c, etree);
}
std::cout << std::endl << std::endl;

Expand Down
4 changes: 4 additions & 0 deletions src/common/KokkosKernels_Handle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -718,6 +718,10 @@ class KokkosKernelsHandle
this->sptrsvHandle->set_supernode_size_blocked(blocked);
}

void set_sptrsv_unit_diagonal(bool flag) {
this->sptrsvHandle->set_unit_diagonal (flag);
}

void set_sptrsv_merge_supernodes (bool flag) {
this->sptrsvHandle->set_merge_supernodes (flag);
}
Expand Down
Loading