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

example/gmres: Switch scalar to bhalf_t #1300

Merged
merged 2 commits into from
Feb 8, 2022
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
13 changes: 13 additions & 0 deletions example/gmres/gmres.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,19 @@ Kokkos::Experimental::half_t fabs(
}
#endif // KOKKOS_HALF_T_IS_FLOAT

#if !KOKKOS_BHALF_T_IS_FLOAT
Kokkos::Experimental::bhalf_t fabs(Kokkos::Experimental::bhalf_t arg) {
using AT = Kokkos::Details::ArithTraits<Kokkos::Experimental::bhalf_t>;
return AT::abs(arg);
}

Kokkos::Experimental::bhalf_t fabs(
Kokkos::complex<Kokkos::Experimental::bhalf_t> arg) noexcept {
return Kokkos::Experimental::bhalf_t(Kokkos::abs(
Kokkos::complex<double>((double)arg.real(), (double)arg.imag())));
}
#endif // KOKKOS_BHALF_T_IS_FLOAT

// This fabs wrapper was added to resolve:
// https://github.com/kokkos/kokkos-kernels/issues/1172
template <class T>
Expand Down
196 changes: 103 additions & 93 deletions example/gmres/test_real_A.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,18 @@
//@HEADER
*/

#include<math.h>
#include"KokkosKernels_IOUtils.hpp"
#include<Kokkos_Core.hpp>
#include<Kokkos_Random.hpp>
#include<KokkosBlas.hpp>
#include<KokkosBlas3_trsm.hpp>
#include<KokkosSparse_spmv.hpp>
#include <math.h>
#include "KokkosKernels_IOUtils.hpp"
#include <Kokkos_Core.hpp>
#include <Kokkos_Random.hpp>
#include <KokkosBlas.hpp>
#include <KokkosBlas3_trsm.hpp>
#include <KokkosSparse_spmv.hpp>
#include <KokkosKernels_IOUtils.hpp>

#include"gmres.hpp"
#include "gmres.hpp"

int main(int /*argc*/, char ** /*argv[]*/) {
int main(int /*argc*/, char** /*argv[]*/) {
typedef double ST;
typedef int OT;
typedef Kokkos::DefaultExecutionSpace EXSP;
Expand All @@ -70,101 +70,111 @@ int main(int /*argc*/, char ** /*argv[]*/) {
GmresOpts<ST> solverOpts;
solverOpts.ortho = "CGS2"; // orthog type
solverOpts.m = 15; // Max subspace size before restarting.
solverOpts.tol = 1e-10; //Relative residual convergence tolerance.
solverOpts.tol = 1e-10; // Relative residual convergence tolerance.
solverOpts.maxRestart = 50;
bool pass1 = false;
bool pass2 = false;
bool pass1 = false;
bool pass2 = false;

std::cout << "Convergence tolerance is: " << solverOpts.tol << std::endl;

// Initialize Kokkos AFTER parsing parameters:
Kokkos::initialize();
{
// Create a diagonally dominant sparse matrix to test:
ncST nnz;
cOT n = 5000;
cOT numRows = n;
cOT numCols = n;
cOT diagDominance = 1;
nnz = 10 * numRows;
sp_matrix_type A = KokkosKernels::Impl::kk_generate_diagonally_dominant_sparse_matrix<sp_matrix_type>
(numRows, numCols, nnz, 0, ncOT(0.01 * numRows), diagDominance);

// Set initial vectors:
ViewVectorType X("X",n); //Solution and initial guess
ViewVectorType Wj("Wj",n); //For checking residuals at end.
ViewVectorType B(Kokkos::view_alloc(Kokkos::WithoutInitializing, "B"),n);//right-hand side vec

// Make rhs ones so that results are repeatable:
Kokkos::deep_copy(B,1.0);

std::cout << "Testing GMRES with CGS2 ortho:" << std::endl;
GmresStats solveStats = gmres<ST, Kokkos::LayoutLeft, EXSP>(A, B, X, solverOpts);

// Double check residuals at end of solve:
double nrmB = static_cast<double>(KokkosBlas::nrm2(B));
KokkosSparse::spmv("N", ST(1.0), A, X, ST(0.0), Wj); // wj = Ax
KokkosBlas::axpy(ST(-1.0), Wj, B); // b = b-Ax.
double endRes = KokkosBlas::nrm2(B)/nrmB;
std::cout << "=======================================" << std::endl;
std::cout << "Verify from main: Ending residual is " << endRes << std::endl;
std::cout << "Number of iterations is: " << solveStats.numIters << std::endl;
std::cout << "Diff of residual from main - residual from solver: " << solveStats.endRelRes - endRes << std::endl;
std::cout << "Convergence flag is : " << solveStats.convFlag() << std::endl;

if (solveStats.numIters < 40 && solveStats.numIters > 20 &&
endRes < static_cast<double>(solverOpts.tol)) {
std::cout << "Test CGS2 Passed!" << std::endl;
pass1 = true;
} else {
std::cout
<< "Solver did not converge within the expected number of iterations. "
<< std::endl
<< "CGS2 Test Failed." << std::endl;
}
std::cout << "=======================================" << std::endl << std::endl << std::endl;

solverOpts.ortho = "MGS";
Kokkos::deep_copy(X,0.0);
Kokkos::deep_copy(B,1.0);

std::cout << "Testing GMRES with MGS ortho:" << std::endl;
solveStats = gmres<ST, Kokkos::LayoutLeft, EXSP>(A, B, X, solverOpts);

// Double check residuals at end of solve:
nrmB = static_cast<double>(KokkosBlas::nrm2(B));
KokkosSparse::spmv("N", ST(1.0), A, X, ST(0.0), Wj); // wj = Ax
KokkosBlas::axpy(ST(-1.0), Wj, B); // b = b-Ax.
endRes = KokkosBlas::nrm2(B)/nrmB;
std::cout << "=======================================" << std::endl;
std::cout << "Verify from main: Ending residual is " << endRes << std::endl;
std::cout << "Number of iterations is: " << solveStats.numIters << std::endl;
std::cout << "Diff of residual from main - residual from solver: " << solveStats.endRelRes - endRes << std::endl;
std::cout << "Convergence flag is : " << solveStats.convFlag() << std::endl;

if (solveStats.numIters < 40 && solveStats.numIters > 20 &&
endRes < static_cast<double>(solverOpts.tol)) {
std::cout << "Test MGS Passed!" << std::endl;
if (pass1) {
pass2 = true;
};
} else {
std::cout
<< "Solver did not converge within the expected number of iterations. "
<< std::endl
<< "MGS Test Failed." << std::endl;
}
std::cout << "=======================================" << std::endl << std::endl << std::endl;

// Create a diagonally dominant sparse matrix to test:
ncST nnz;
cOT n = 5000;
cOT numRows = n;
cOT numCols = n;
cOT diagDominance = 1;
nnz = 10 * numRows;
sp_matrix_type A =
KokkosKernels::Impl::kk_generate_diagonally_dominant_sparse_matrix<
sp_matrix_type>(numRows, numCols, nnz, 0, ncOT(0.01 * numRows),
diagDominance);

// Set initial vectors:
ViewVectorType X("X", n); // Solution and initial guess
ViewVectorType Wj("Wj", n); // For checking residuals at end.
ViewVectorType B(Kokkos::view_alloc(Kokkos::WithoutInitializing, "B"),
n); // right-hand side vec

// Make rhs ones so that results are repeatable:
Kokkos::deep_copy(B, 1.0);

std::cout << "Testing GMRES with CGS2 ortho:" << std::endl;
GmresStats solveStats =
gmres<ST, Kokkos::LayoutLeft, EXSP>(A, B, X, solverOpts);

// Double check residuals at end of solve:
double nrmB = static_cast<double>(KokkosBlas::nrm2(B));
KokkosSparse::spmv("N", ST(1.0), A, X, ST(0.0), Wj); // wj = Ax
KokkosBlas::axpy(ST(-1.0), Wj, B); // b = b-Ax.
double endRes = KokkosBlas::nrm2(B) / nrmB;
std::cout << "=======================================" << std::endl;
std::cout << "Verify from main: Ending residual is " << endRes << std::endl;
std::cout << "Number of iterations is: " << solveStats.numIters
<< std::endl;
std::cout << "Diff of residual from main - residual from solver: "
<< solveStats.endRelRes - endRes << std::endl;
std::cout << "Convergence flag is : " << solveStats.convFlag() << std::endl;

if (solveStats.numIters < 40 && solveStats.numIters > 20 &&
endRes < static_cast<double>(solverOpts.tol)) {
std::cout << "Test CGS2 Passed!" << std::endl;
pass1 = true;
} else {
std::cout << "Solver did not converge within the expected number of "
"iterations. "
<< std::endl
<< "CGS2 Test Failed." << std::endl;
}
std::cout << "=======================================" << std::endl
<< std::endl
<< std::endl;

solverOpts.ortho = "MGS";
Kokkos::deep_copy(X, 0.0);
Kokkos::deep_copy(B, 1.0);

std::cout << "Testing GMRES with MGS ortho:" << std::endl;
solveStats = gmres<ST, Kokkos::LayoutLeft, EXSP>(A, B, X, solverOpts);

// Double check residuals at end of solve:
nrmB = static_cast<double>(KokkosBlas::nrm2(B));
KokkosSparse::spmv("N", ST(1.0), A, X, ST(0.0), Wj); // wj = Ax
KokkosBlas::axpy(ST(-1.0), Wj, B); // b = b-Ax.
endRes = KokkosBlas::nrm2(B) / nrmB;
std::cout << "=======================================" << std::endl;
std::cout << "Verify from main: Ending residual is " << endRes << std::endl;
std::cout << "Number of iterations is: " << solveStats.numIters
<< std::endl;
std::cout << "Diff of residual from main - residual from solver: "
<< solveStats.endRelRes - endRes << std::endl;
std::cout << "Convergence flag is : " << solveStats.convFlag() << std::endl;

if (solveStats.numIters < 40 && solveStats.numIters > 20 &&
endRes < static_cast<double>(solverOpts.tol)) {
std::cout << "Test MGS Passed!" << std::endl;
if (pass1) {
pass2 = true;
};
} else {
std::cout << "Solver did not converge within the expected number of "
"iterations. "
<< std::endl
<< "MGS Test Failed." << std::endl;
}
std::cout << "=======================================" << std::endl
<< std::endl
<< std::endl;
}
Kokkos::finalize();

if(pass2){
std::cout << "Both tests have passed!!" << std::endl;
}
else{
if (pass2) {
std::cout << "Both tests have passed!!" << std::endl;
} else {
std::cout << "One or more tests has failed." << std::endl;
}

return ( pass2 ? EXIT_SUCCESS : EXIT_FAILURE );
return (pass2 ? EXIT_SUCCESS : EXIT_FAILURE);
}