-
Notifications
You must be signed in to change notification settings - Fork 9
Adding asymmetric tests (from the data folder) for KLU, CuSolver, and RocSolver. #364
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
Changes from 8 commits
3cc3ae0
81fc4a4
c5b898a
e8d2032
9d5df32
5d6bfff
e0ec030
2b95d98
fdfafb4
e8acb76
85368b7
ef6f549
883b88a
af9bc3f
65af129
5707b80
8f08701
d61e235
a72c93c
ddf501e
abdf871
9010f37
746c2bb
f84bb2e
9e09b87
1c28664
2573468
270d13b
9956b01
9ed9c53
3da9823
6d8a85d
6b20508
b273b0c
7575fc4
0cfb149
8383ab6
ae4fb5c
9fa393b
415b81f
1da657f
55ee465
a1b5d4f
ad7b224
45ff111
ef8f5cf
b6a4810
3222810
f5e93d1
40f90ac
9e64fd3
84693a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -180,6 +180,13 @@ namespace ReSolve | |
| io::Logger::misc() << "it 0: norm of residual " | ||
| << std::scientific << std::setprecision(16) | ||
| << rnorm << " Norm of rhs: " << bnorm << "\n"; | ||
| if (rnorm / bnorm < MACHINE_EPSILON) | ||
| { | ||
| std::cout << "Iterative solve skipped. Initial residual is accurate to machine precision.\n" | ||
| << std::scientific << std::setprecision(16) << rnorm | ||
| << " / " << bnorm << "\n"; | ||
| return 0; | ||
| } | ||
|
||
| initial_residual_norm_ = rnorm; | ||
| while (outer_flag) | ||
| { | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -13,7 +13,6 @@ | |||||||
| #ifdef RESOLVE_USE_KLU | ||||||||
| #include <resolve/LinSolverDirectKLU.hpp> | ||||||||
| #endif | ||||||||
|
|
||||||||
| #include <resolve/LinSolverIterativeRandFGMRES.hpp> | ||||||||
|
|
||||||||
| #ifdef RESOLVE_USE_CUDA | ||||||||
|
|
@@ -563,7 +562,8 @@ namespace ReSolve | |||||||
| { | ||||||||
| int status = 0; | ||||||||
|
|
||||||||
| status += iterativeSolver_->resetMatrix(A_); | ||||||||
| // status += iterativeSolver_->resetMatrix(A_); | ||||||||
| std::cout << "Refining solution with iterative refinement ...\n"; | ||||||||
|
||||||||
| // status += iterativeSolver_->resetMatrix(A_); | |
| std::cout << "Refining solution with iterative refinement ...\n"; | |
| status += iterativeSolver_->resetMatrix(A_); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is resetMatrix() function called here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was for debugging and I missed removing it. Good catch.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| # LUSOL disclaimer | ||
| LUSOL code is experimental and not actively maintained or supported. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -232,9 +232,6 @@ class TestHelper | |
| std::cout << "\t Residual norm on CPU ||b-A*x|| (CPU) : " << getNormResidualCpu() << "\n"; | ||
| } | ||
| std::cout << "\t Relative residual norm ||b-A*x||/||b|| : " << getNormResidualScaled() << "\n"; | ||
| std::cout << "\t Error norm ||x-x_true|| : " << getNormDiff() << "\n"; | ||
| std::cout << "\t Relative error norm ||x-x_true||/||x_true|| : " << getNormDiffScaled() << "\n"; | ||
| std::cout << "\t Exact solution residual ||b-A*x_true|| : " << getNormResidualTrue() << "\n"; | ||
|
Comment on lines
-235
to
-237
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is helpful debugging information. I would keep it. |
||
| } | ||
|
|
||
| /// Summary of error norms for an iterative refinement test. | ||
|
|
@@ -269,7 +266,6 @@ class TestHelper | |
| { | ||
| int error_sum = 0; | ||
| ReSolve::real_type norm = norm_res_ / norm_rhs_; | ||
|
|
||
| if (!std::isfinite(norm)) | ||
| { | ||
| std::cout << "Result is not a finite number!\n"; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -58,6 +58,30 @@ int runTest(int argc, char* argv[], std::string& solver_name) | |
| auto opt = options.getParamFromKey("-d"); | ||
| std::string data_path = opt ? (*opt).second : "."; | ||
|
|
||
| // Get matrix file name | ||
| opt = options.getParamFromKey("-m"); | ||
| if (!opt) | ||
| { | ||
| std::cout << "Matrix file name not provided. Use -m <matrix_file_name>.\n"; | ||
| return -1; | ||
| } | ||
| std::string matrix_temp = (*opt).second; | ||
|
|
||
| // Get rhs file name | ||
| opt = options.getParamFromKey("-r"); | ||
| if (!opt) | ||
| { | ||
| std::cout << "RHS file name not provided. Use -r <rhs_file_name>.\n"; | ||
| return -1; | ||
| } | ||
| std::string rhs_temp = (*opt).second; | ||
|
|
||
| // Construct matrix and rhs file names from inputs | ||
| std::string matrix_file_name_1 = data_path + matrix_temp + "01.mtx"; | ||
| std::string matrix_file_name_2 = data_path + matrix_temp + "02.mtx"; | ||
| std::string rhs_file_name_1 = data_path + rhs_temp + "01.mtx"; | ||
| std::string rhs_file_name_2 = data_path + rhs_temp + "02.mtx"; | ||
|
|
||
| // Whether to use iterative refinement | ||
| opt = options.getParamFromKey("-i"); | ||
| bool is_ir = opt ? true : false; | ||
|
|
@@ -78,13 +102,6 @@ int runTest(int argc, char* argv[], std::string& solver_name) | |
| ReSolve::GramSchmidt GS(&vector_handler, ReSolve::GramSchmidt::CGS2); | ||
| ReSolve::LinSolverIterativeFGMRES FGMRES(&matrix_handler, &vector_handler, &GS); | ||
|
|
||
| // Input data | ||
| std::string matrix_file_name_1 = data_path + "/data/matrix_ACTIVSg200_AC_10.mtx"; | ||
| std::string matrix_file_name_2 = data_path + "/data/matrix_ACTIVSg200_AC_11.mtx"; | ||
|
|
||
| std::string rhs_file_name_1 = data_path + "/data/rhs_ACTIVSg200_AC_10.mtx.ones"; | ||
| std::string rhs_file_name_2 = data_path + "/data/rhs_ACTIVSg200_AC_11.mtx.ones"; | ||
|
|
||
| // Read first matrix | ||
| std::ifstream mat1(matrix_file_name_1); | ||
| if (!mat1.is_open()) | ||
|
|
@@ -125,8 +142,9 @@ int runTest(int argc, char* argv[], std::string& solver_name) | |
|
|
||
| status = KLU.solve(&vec_rhs, &vec_x); | ||
| error_sum += status; | ||
| helper.setSystem(A, &vec_rhs, &vec_x); | ||
|
|
||
| if (is_ir) | ||
| if (is_ir && helper.checkResult(ReSolve::constants::MACHINE_EPSILON)) // only perform IR if you haven't reached machine accuracy | ||
| { | ||
|
||
| test_name += " + IR"; | ||
|
|
||
|
|
@@ -141,16 +159,16 @@ int runTest(int argc, char* argv[], std::string& solver_name) | |
| } | ||
|
|
||
| // Compute error norms for the system | ||
| helper.setSystem(A, &vec_rhs, &vec_x); | ||
| helper.resetSystem(A, &vec_rhs, &vec_x); | ||
|
|
||
| // Print result summary and check solution | ||
| std::cout << "\nResults (first matrix): \n\n"; | ||
| helper.printSummary(); | ||
| if (is_ir) | ||
| if (is_ir && helper.checkResult(ReSolve::constants::MACHINE_EPSILON)) // only perform IR if you haven't reached machine accuracy | ||
| { | ||
|
||
| helper.printIrSummary(&FGMRES); | ||
| } | ||
| error_sum += helper.checkResult(ReSolve::constants::MACHINE_EPSILON); | ||
| error_sum += helper.checkResult(10 * ReSolve::constants::MACHINE_EPSILON); // tolerance increased to deal with system | ||
|
||
|
|
||
| // Load the second matrix | ||
| std::ifstream mat2(matrix_file_name_2); | ||
|
|
@@ -177,8 +195,9 @@ int runTest(int argc, char* argv[], std::string& solver_name) | |
| error_sum += status; | ||
| std::cout << "KLU refactorization status: " << status << std::endl; | ||
|
|
||
| if (is_ir) | ||
| if (is_ir && helper.checkResult(ReSolve::constants::MACHINE_EPSILON)) // only perform IR if you haven't reached machine accuracy | ||
| { | ||
| std::cout << "Second matrix: Performing iterative refinement...\n"; | ||
| FGMRES.resetMatrix(A); | ||
| status = FGMRES.setupPreconditioner("LU", &KLU); | ||
| error_sum += status; | ||
|
|
@@ -196,11 +215,11 @@ int runTest(int argc, char* argv[], std::string& solver_name) | |
|
|
||
| std::cout << "\nResults (second matrix): \n\n"; | ||
| helper.printSummary(); | ||
| if (is_ir) | ||
| if (is_ir && helper.checkResult(ReSolve::constants::MACHINE_EPSILON)) // only perform IR if you haven't reached machine accuracy | ||
| { | ||
| helper.printIrSummary(&FGMRES); | ||
| } | ||
| error_sum += helper.checkResult(ReSolve::constants::MACHINE_EPSILON); | ||
| error_sum += helper.checkResult(100 * ReSolve::constants::MACHINE_EPSILON); // tolerance increased to deal with system | ||
|
|
||
|
||
| isTestPass(error_sum, test_name); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be no hard-wired output in the code. This is a violation of xSDK requirements. Also, iterative solver can use different exit criteria in which case this "shortcut" might not be applicable. I suggest removing this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can remove the print, no issues. But I maintain that if you give an initial guess that is accurate to machine precision, an iterative solver can't help you. Unless you want me to change the RHS in that case (so the RHS is always the residual). In any case, if we remove this, what are we replacing it with? We can't do iterative refinement when the solution is already accurate to machine precision.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shakedregev my interpretation of Slaven's comments:
out::warning()There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a catch 22. I want a system that I can solve to machine precision, so the non-iterative refinement test passes. But I also want a system that I can't solve to machine precision, so I use IR. They would have to be different systems.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One suggestion I have for the iterative solvers (IR or otherwise) is to always set$rhs=b-Ax$ and then solve $Ay=rhs$ . $Ax=b-rhs$ and $Ay=rhs$ , so $A(x+y)=b$ . This requires extra memory and probably requires significant reworking. Mathematically and numerically, it is the most sound solution. It has no effect when you give $\vec{0}$ as your initial guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have separate tests for iterative solvers, so I wouldn't worry about testing iterative refinement here. We could set required precision for the IR a little higher just to force an iteration or two.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IR and iterative solvers are combined. There is no way to separate the two. We cannot have what you suggest with passing tests because if you solve too accurately, you get an error within Gram Schmidt of a zero norm residual vector.