-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgluRefactor.cpp
More file actions
279 lines (241 loc) · 7.9 KB
/
gluRefactor.cpp
File metadata and controls
279 lines (241 loc) · 7.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
/**
* @file gpuRefactor.cpp
* @author Slaven Peles (peless@ornl.gov)
* @author Kasia Swirydowicz (kasia.swirydowicz@amd.com)
*
* @brief Example of solving linear systems using refactorization on a GPU.
*
* A series of linear systems is read from files specified at command line
* input and solved with refactorization approach on GPU. First system
* is solved with KLU solver on CPU, using full factorization, and the
* subsequent systems are solved with GLU solver on GPU, using refactorization
* approach. It is assumed that all systems in the series have the same
* sparsity pattern, so the analysis is done only once for the entire series.
*
*/
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
#include <resolve/LinSolverDirectKLU.hpp>
#include <resolve/Profiling.hpp>
#include <resolve/matrix/Csc.hpp>
#include <resolve/matrix/Csr.hpp>
#include <resolve/matrix/MatrixHandler.hpp>
#include <resolve/matrix/io.hpp>
#include <resolve/utilities/params/CliOptions.hpp>
#include <resolve/vector/Vector.hpp>
#include <resolve/vector/VectorHandler.hpp>
#include <resolve/workspace/LinAlgWorkspace.hpp>
#ifdef RESOLVE_USE_CUDA
#include <resolve/LinSolverDirectCuSolverGLU.hpp>
#endif
#include "ExampleHelper.hpp"
/// Prints help message describing system usage.
void printHelpInfo()
{
std::cout << "\ngluRefactor.exe loads from files and solves a series of linear systems.\n\n";
std::cout << "System matrices are in files with names <pathname>XX.mtx, where XX are\n";
std::cout << "consecutive integer numbers 00, 01, 02, ...\n\n";
std::cout << "System right hand side vectors are stored in files with matching numbering\n";
std::cout << "and file extension.\n\n";
std::cout << "Usage:\n\t./";
std::cout << "gluRefactor.exe -m <matrix pathname> -r <rhs pathname> -n <number of systems>\n\n";
std::cout << "Optional features:\n";
std::cout << "\t-e <ext> \tSelects custom extension for input files (default 'mtx').\n";
std::cout << "\t-h\tPrints this message.\n";
}
/// Prototype of the example function
template <class workspace_type>
static int gluRefactor(int argc, char* argv[]);
/// Main function selects example to be run.
int main(int argc, char* argv[])
{
#ifdef RESOLVE_USE_CUDA
gluRefactor<ReSolve::LinAlgWorkspaceCUDA>(argc, argv);
return 0;
#else
std::cout << "gluRefactor example works only with CUDA!\n";
return 1;
#endif
}
/**
* @brief Example of using refactorization solvers on GPU
*
* @tparam workspace_type - Type of the workspace to use
* @param[in] argc - Number of command line arguments
* @param[in] argv - Command line arguments
* @return 0 if the example ran successfully, -1 otherwise
*/
template <class workspace_type>
int gluRefactor(int argc, char* argv[])
{
using namespace ReSolve::examples;
using namespace ReSolve;
using index_type = ReSolve::index_type;
using vector_type = ReSolve::vector::Vector;
CliOptions options(argc, argv);
bool is_help = options.hasKey("-h");
if (is_help)
{
printHelpInfo();
return 0;
}
index_type num_systems = 0;
auto opt = options.getParamFromKey("-n");
if (opt)
{
num_systems = atoi((opt->second).c_str());
}
else
{
std::cout << "Incorrect input!\n\n";
printHelpInfo();
return 1;
}
std::string matrix_pathname("");
opt = options.getParamFromKey("-m");
if (opt)
{
matrix_pathname = opt->second;
}
else
{
std::cout << "Incorrect input!\n\n";
printHelpInfo();
return 1;
}
std::string rhs_pathname("");
opt = options.getParamFromKey("-r");
if (opt)
{
rhs_pathname = opt->second;
}
else
{
std::cout << "Incorrect input!\n\n";
printHelpInfo();
return 1;
}
std::string file_extension("");
opt = options.getParamFromKey("-e");
if (opt)
{
file_extension = opt->second;
}
else
{
file_extension = "mtx";
}
std::cout << "Family mtx file name: " << matrix_pathname
<< ", total number of matrices: " << num_systems << "\n"
<< "Family rhs file name: " << rhs_pathname
<< ", total number of RHSes: " << num_systems << "\n";
// Create workspace
workspace_type workspace;
workspace.initializeHandles();
// Create a helper object (computing errors, printing summaries, etc.)
ExampleHelper<workspace_type> helper(workspace);
std::cout << "gluRefactor with " << helper.getHardwareBackend() << " backend\n";
// Direct solvers instantiation
LinSolverDirectKLU KLU;
LinSolverDirectCuSolverGLU Rf(&workspace);
// Pointers to matrix and vectors defining the linear system
matrix::Csr* A = nullptr;
vector_type* vec_rhs = nullptr;
vector_type* vec_x = nullptr;
RESOLVE_RANGE_PUSH(__FUNCTION__);
for (int i = 0; i < num_systems; ++i)
{
std::cout << "System " << i << ":\n";
RESOLVE_RANGE_PUSH("File input");
std::ostringstream matname;
std::ostringstream rhsname;
matname << matrix_pathname << std::setfill('0') << std::setw(2) << i << "." << file_extension;
rhsname << rhs_pathname << std::setfill('0') << std::setw(2) << i << "." << file_extension;
std::string matrix_pathname_full = matname.str();
std::string rhs_pathname_full = rhsname.str();
// Read matrix and right-hand-side vector
std::ifstream mat_file(matrix_pathname_full);
if (!mat_file.is_open())
{
std::cout << "Failed to open file " << matrix_pathname_full << "\n";
return -1;
}
std::ifstream rhs_file(rhs_pathname_full);
if (!rhs_file.is_open())
{
std::cout << "Failed to open file " << rhs_pathname_full << "\n";
return -1;
}
bool is_expand_symmetric = true;
if (i == 0)
{
A = io::createCsrFromFile(mat_file, is_expand_symmetric);
vec_rhs = io::createVectorFromFile(rhs_file);
vec_x = new vector_type(A->getNumRows());
vec_x->allocate(memory::HOST);
vec_x->allocate(memory::DEVICE);
}
else
{
io::updateMatrixFromFile(mat_file, A);
io::updateVectorFromFile(rhs_file, vec_rhs);
}
mat_file.close();
rhs_file.close();
// Copy data to device
A->syncData(memory::DEVICE);
vec_rhs->syncData(memory::DEVICE);
RESOLVE_RANGE_POP("File input");
printSystemInfo(matrix_pathname_full, A);
std::cout << "CSR matrix loaded. Expanded NNZ: " << A->getNnz() << std::endl;
int status = 0;
if (i < 1)
{
RESOLVE_RANGE_PUSH("KLU");
// Setup factorization solver
KLU.setup(A);
// Analysis (symbolic factorization)
status = KLU.analyze();
std::cout << "KLU analysis status: " << status << std::endl;
// Numeric factorization
status = KLU.factorize();
std::cout << "KLU factorization status: " << status << std::endl;
// Triangular solve
status = KLU.solve(vec_rhs, vec_x);
std::cout << "KLU solve status: " << status << std::endl;
// Extract factors and configure refactorization solver
matrix::Csr* L = (matrix::Csr*) KLU.getLFactorCsr();
matrix::Csr* U = (matrix::Csr*) KLU.getUFactorCsr();
if (L == nullptr || U == nullptr)
{
std::cout << "Factor extraction from KLU failed!\n";
}
index_type* P = KLU.getPOrdering();
index_type* Q = KLU.getQOrdering();
status = Rf.setupCsr(A, L, U, P, Q);
std::cout << "Refactorization setup status: " << status << std::endl;
RESOLVE_RANGE_POP("KLU");
}
else
{
RESOLVE_RANGE_PUSH("Refactorization");
// Refactorize on the device
status = Rf.refactorize();
RESOLVE_RANGE_POP("Refactorization");
}
RESOLVE_RANGE_PUSH("Triangular solve");
// Triangular solve on the device
status = Rf.solve(vec_rhs, vec_x);
RESOLVE_RANGE_POP("Triangular solve");
// Print summary of the results
helper.resetSystem(A, vec_rhs, vec_x);
helper.printSummary();
} // for (int i = 0; i < num_systems; ++i)
RESOLVE_RANGE_POP(__FUNCTION__);
delete A;
delete vec_x;
delete vec_rhs;
return 0;
}