Skip to content

Commit

Permalink
example/gmres: Switch scalar to bhalf_t
Browse files Browse the repository at this point in the history
  • Loading branch information
e10harvey committed Feb 2, 2022
1 parent 30a4c4e commit 9ae5c4f
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 95 deletions.
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
2 changes: 1 addition & 1 deletion example/gmres/test_cmplx_A.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
#include "gmres.hpp"

int main(int /*argc*/, char** /*argv[]*/) {
typedef Kokkos::complex<double> ST;
typedef Kokkos::complex<Kokkos::Experimental::bhalf_t> ST;
typedef int OT;
typedef Kokkos::DefaultExecutionSpace EXSP;

Expand Down
198 changes: 104 additions & 94 deletions example/gmres/test_real_A.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,19 @@
//@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[]*/) {
typedef double ST;
int main(int /*argc*/, char** /*argv[]*/) {
typedef Kokkos::Experimental::bhalf_t 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);
}

0 comments on commit 9ae5c4f

Please sign in to comment.