1 |
jgs |
472 |
|
2 |
ksteube |
1312 |
/* $Id$ */ |
3 |
|
|
|
4 |
|
|
/******************************************************* |
5 |
|
|
* |
6 |
|
|
* Copyright 2003-2007 by ACceSS MNRF |
7 |
|
|
* Copyright 2007 by University of Queensland |
8 |
|
|
* |
9 |
|
|
* http://esscc.uq.edu.au |
10 |
|
|
* Primary Business: Queensland, Australia |
11 |
|
|
* Licensed under the Open Software License version 3.0 |
12 |
|
|
* http://www.opensource.org/licenses/osl-3.0.php |
13 |
|
|
* |
14 |
|
|
*******************************************************/ |
15 |
|
|
|
16 |
ksteube |
817 |
#ifdef PASO_MPI |
17 |
|
|
#include <mpi.h> |
18 |
|
|
#endif |
19 |
jgs |
203 |
#include "SystemMatrixAdapter.h" |
20 |
jgs |
82 |
|
21 |
|
|
using namespace std; |
22 |
|
|
|
23 |
|
|
namespace finley { |
24 |
|
|
|
25 |
jgs |
102 |
struct null_deleter |
26 |
|
|
{ |
27 |
|
|
void operator()(void const *ptr) const |
28 |
|
|
{ |
29 |
|
|
} |
30 |
|
|
}; |
31 |
|
|
|
32 |
|
|
|
33 |
jgs |
82 |
SystemMatrixAdapter::SystemMatrixAdapter() |
34 |
|
|
{ |
35 |
|
|
throw FinleyAdapterException("Error - Illegal to generate default SystemMatrixAdapter."); |
36 |
|
|
} |
37 |
|
|
|
38 |
jgs |
150 |
SystemMatrixAdapter::SystemMatrixAdapter(Paso_SystemMatrix* system_matrix, |
39 |
jgs |
82 |
const int row_blocksize, |
40 |
|
|
const escript::FunctionSpace& row_functionspace, |
41 |
|
|
const int column_blocksize, |
42 |
|
|
const escript::FunctionSpace& column_functionspace): |
43 |
jgs |
102 |
AbstractSystemMatrix(row_blocksize,row_functionspace,column_blocksize,column_functionspace) |
44 |
jgs |
82 |
{ |
45 |
jgs |
102 |
m_system_matrix.reset(system_matrix,null_deleter()); |
46 |
jgs |
82 |
} |
47 |
|
|
|
48 |
|
|
SystemMatrixAdapter::~SystemMatrixAdapter() |
49 |
|
|
{ |
50 |
|
|
if (m_system_matrix.unique()) { |
51 |
jgs |
150 |
Paso_SystemMatrix* mat=m_system_matrix.get(); |
52 |
ksteube |
1312 |
Paso_SystemMatrix_free(mat); |
53 |
jgs |
82 |
} |
54 |
|
|
} |
55 |
|
|
|
56 |
jgs |
150 |
Paso_SystemMatrix* SystemMatrixAdapter::getPaso_SystemMatrix() const |
57 |
jgs |
82 |
{ |
58 |
|
|
return m_system_matrix.get(); |
59 |
|
|
} |
60 |
|
|
|
61 |
jgs |
153 |
void SystemMatrixAdapter::ypAx(escript::Data& y,escript::Data& x) const |
62 |
jgs |
82 |
{ |
63 |
jgs |
150 |
Paso_SystemMatrix* mat=getPaso_SystemMatrix(); |
64 |
|
|
|
65 |
jgs |
153 |
if ( x.getDataPointSize() != getColumnBlockSize()) { |
66 |
jgs |
150 |
throw FinleyAdapterException("matrix vector product : column block size does not match the number of components in input."); |
67 |
|
|
} else if (y.getDataPointSize() != getRowBlockSize()) { |
68 |
|
|
throw FinleyAdapterException("matrix vector product : row block size does not match the number of components in output."); |
69 |
|
|
} else if ( x.getFunctionSpace() != getColumnFunctionSpace()) { |
70 |
|
|
throw FinleyAdapterException("matrix vector product : column function space and function space of input don't match."); |
71 |
|
|
} else if (y.getFunctionSpace() != getRowFunctionSpace()) { |
72 |
|
|
throw FinleyAdapterException("matrix vector product : row function space and function space of output don't match."); |
73 |
|
|
} |
74 |
jgs |
153 |
x.expand(); |
75 |
|
|
y.expand(); |
76 |
|
|
double* x_dp=x.getSampleData(0); |
77 |
jgs |
150 |
double* y_dp=y.getSampleData(0); |
78 |
|
|
Paso_SystemMatrix_MatrixVector(1., mat,x_dp, 1.,y_dp); |
79 |
|
|
checkPasoError(); |
80 |
jgs |
82 |
} |
81 |
|
|
|
82 |
jgs |
150 |
int SystemMatrixAdapter::mapOptionToPaso(const int option) { |
83 |
|
|
switch (option) { |
84 |
|
|
case ESCRIPT_DEFAULT: |
85 |
|
|
return PASO_DEFAULT; |
86 |
|
|
case ESCRIPT_DIRECT: |
87 |
|
|
return PASO_DIRECT; |
88 |
|
|
case ESCRIPT_CHOLEVSKY: |
89 |
|
|
return PASO_CHOLEVSKY; |
90 |
|
|
case ESCRIPT_PCG: |
91 |
|
|
return PASO_PCG; |
92 |
|
|
case ESCRIPT_CR: |
93 |
|
|
return PASO_CR; |
94 |
|
|
case ESCRIPT_CGS: |
95 |
|
|
return PASO_CGS; |
96 |
|
|
case ESCRIPT_BICGSTAB: |
97 |
|
|
return PASO_BICGSTAB; |
98 |
|
|
case ESCRIPT_SSOR: |
99 |
|
|
return PASO_SSOR; |
100 |
|
|
case ESCRIPT_ILU0: |
101 |
|
|
return PASO_ILU0; |
102 |
|
|
case ESCRIPT_ILUT: |
103 |
|
|
return PASO_ILUT; |
104 |
|
|
case ESCRIPT_JACOBI: |
105 |
|
|
return PASO_JACOBI; |
106 |
|
|
case ESCRIPT_GMRES: |
107 |
|
|
return PASO_GMRES; |
108 |
|
|
case ESCRIPT_PRES20: |
109 |
|
|
return PASO_PRES20; |
110 |
|
|
case ESCRIPT_NO_REORDERING: |
111 |
|
|
return PASO_NO_REORDERING; |
112 |
|
|
case ESCRIPT_MINIMUM_FILL_IN: |
113 |
|
|
return PASO_MINIMUM_FILL_IN; |
114 |
|
|
case ESCRIPT_NESTED_DISSECTION: |
115 |
|
|
return PASO_NESTED_DISSECTION; |
116 |
|
|
case ESCRIPT_SCSL: |
117 |
|
|
return PASO_SCSL; |
118 |
|
|
case ESCRIPT_MKL: |
119 |
|
|
return PASO_MKL; |
120 |
|
|
case ESCRIPT_UMFPACK: |
121 |
|
|
return PASO_UMFPACK; |
122 |
|
|
case ESCRIPT_ITERATIVE: |
123 |
|
|
return PASO_ITERATIVE; |
124 |
|
|
case ESCRIPT_PASO: |
125 |
|
|
return PASO_PASO; |
126 |
|
|
case ESCRIPT_LUMPING: |
127 |
|
|
return PASO_LUMPING; |
128 |
gross |
430 |
case ESCRIPT_AMG: |
129 |
|
|
return PASO_AMG; |
130 |
|
|
case ESCRIPT_RILU: |
131 |
|
|
return PASO_RILU; |
132 |
ksteube |
1312 |
case ESCRIPT_TRILINOS: |
133 |
|
|
return PASO_TRILINOS; |
134 |
jgs |
150 |
default: |
135 |
|
|
stringstream temp; |
136 |
|
|
temp << "Error - Cannot map option value "<< option << " onto Paso"; |
137 |
|
|
throw FinleyAdapterException(temp.str()); |
138 |
|
|
} |
139 |
|
|
} |
140 |
|
|
|
141 |
ksteube |
1339 |
void finley::SystemMatrixAdapter::Print_Matrix_Info(const bool full=false) const |
142 |
|
|
{ |
143 |
|
|
Paso_SystemMatrix* mat=m_system_matrix.get(); |
144 |
|
|
int first_row_index = mat->row_distribution->first_component[mat->mpi_info->rank]; |
145 |
|
|
int last_row_index = mat->row_distribution->first_component[mat->mpi_info->rank+1]-1; |
146 |
|
|
int first_col_index = mat->col_distribution->first_component[mat->mpi_info->rank]; |
147 |
|
|
int last_col_index = mat->col_distribution->first_component[mat->mpi_info->rank+1]-1; |
148 |
|
|
|
149 |
|
|
fprintf(stdout, "Print_Matrix_Info running on CPU %d of %d\n", mat->mpi_info->rank, mat->mpi_info->size); |
150 |
|
|
|
151 |
|
|
switch (mat->type) { |
152 |
|
|
case MATRIX_FORMAT_DEFAULT: fprintf(stdout, "\tMatrix type MATRIX_FORMAT_DEFAULT\n"); break; |
153 |
|
|
case MATRIX_FORMAT_CSC: fprintf(stdout, "\tMatrix type MATRIX_FORMAT_CSC\n"); break; |
154 |
|
|
case MATRIX_FORMAT_SYM: fprintf(stdout, "\tMatrix type MATRIX_FORMAT_SYM\n"); break; |
155 |
|
|
case MATRIX_FORMAT_BLK1: fprintf(stdout, "\tMatrix type MATRIX_FORMAT_BLK1\n"); break; |
156 |
|
|
case MATRIX_FORMAT_OFFSET1: fprintf(stdout, "\tMatrix type MATRIX_FORMAT_OFFSET1\n"); break; |
157 |
|
|
case MATRIX_FORMAT_TRILINOS_CRS: fprintf(stdout, "\tMatrix type MATRIX_FORMAT_TRILINOS_CRS\n"); break; |
158 |
|
|
default: fprintf(stdout, "\tMatrix type unknown\n"); break; |
159 |
|
|
} |
160 |
|
|
|
161 |
|
|
fprintf(stdout, "\trow indices run from %d to %d\n", first_row_index, last_row_index); |
162 |
|
|
fprintf(stdout, "\tcol indices run from %d to %d\n", first_col_index, last_col_index); |
163 |
|
|
fprintf(stdout, "\tmainBlock numRows %d\n", mat->mainBlock->numRows); |
164 |
|
|
fprintf(stdout, "\tmainBlock numCols %d\n", mat->mainBlock->numCols); |
165 |
|
|
fprintf(stdout, "\tmainBlock pattern numOutput %d\n", mat->mainBlock->pattern->numOutput); |
166 |
|
|
fprintf(stdout, "\tcoupleBlock numRows %d\n", mat->coupleBlock->numRows); |
167 |
|
|
fprintf(stdout, "\tcoupleBlock numCols %d\n", mat->coupleBlock->numCols); |
168 |
|
|
fprintf(stdout, "\tcoupleBlock pattern numOutput %d\n", mat->coupleBlock->pattern->numOutput); |
169 |
|
|
fprintf(stdout, "\trow_block_size %d\n", mat->row_block_size); |
170 |
|
|
fprintf(stdout, "\tcol_block_size %d\n", mat->col_block_size); |
171 |
|
|
fprintf(stdout, "\tblock_size %d\n", mat->block_size); |
172 |
|
|
fprintf(stdout, "\tlogical_row_block_size %d\n", mat->logical_row_block_size); |
173 |
|
|
fprintf(stdout, "\tlogical_col_block_size %d\n", mat->logical_col_block_size); |
174 |
|
|
fprintf(stdout, "\tlogical_block_size %d\n", mat->logical_block_size); |
175 |
|
|
|
176 |
|
|
if (full) { |
177 |
|
|
printf("\trow_distribution: "); |
178 |
|
|
for(int i=0; i<=mat->mpi_info->size; i++) printf("%3d ", mat->row_distribution[i]); |
179 |
|
|
printf("\n"); |
180 |
|
|
printf("\tcol_distribution: "); |
181 |
|
|
for(int i=0; i<=mat->mpi_info->size; i++) printf("%3d ", mat->col_distribution[i]); |
182 |
|
|
printf("\n"); |
183 |
|
|
} |
184 |
|
|
|
185 |
|
|
} |
186 |
|
|
|
187 |
jgs |
153 |
void SystemMatrixAdapter::setToSolution(escript::Data& out,escript::Data& in, const boost::python::dict& options) const |
188 |
jgs |
82 |
{ |
189 |
jgs |
150 |
Paso_SystemMatrix* mat=getPaso_SystemMatrix(); |
190 |
|
|
Paso_Options paso_options; |
191 |
gross |
1364 |
dictToPasoOptions(&paso_options,options); |
192 |
jgs |
153 |
if ( out.getDataPointSize() != getColumnBlockSize()) { |
193 |
jgs |
150 |
throw FinleyAdapterException("solve : column block size does not match the number of components of solution."); |
194 |
|
|
} else if ( in.getDataPointSize() != getRowBlockSize()) { |
195 |
|
|
throw FinleyAdapterException("solve : row block size does not match the number of components of right hand side."); |
196 |
|
|
} else if ( out.getFunctionSpace() != getColumnFunctionSpace()) { |
197 |
|
|
throw FinleyAdapterException("solve : column function space and function space of solution don't match."); |
198 |
|
|
} else if (in.getFunctionSpace() != getRowFunctionSpace()) { |
199 |
|
|
throw FinleyAdapterException("solve : row function space and function space of right hand side don't match."); |
200 |
|
|
} |
201 |
jgs |
153 |
out.expand(); |
202 |
|
|
in.expand(); |
203 |
jgs |
150 |
double* out_dp=out.getSampleData(0); |
204 |
jgs |
153 |
double* in_dp=in.getSampleData(0); |
205 |
jgs |
150 |
Paso_solve(mat,out_dp,in_dp,&paso_options); |
206 |
|
|
checkPasoError(); |
207 |
jgs |
82 |
} |
208 |
|
|
|
209 |
jgs |
153 |
void SystemMatrixAdapter::nullifyRowsAndCols(escript::Data& row_q,escript::Data& col_q, const double mdv) const |
210 |
jgs |
82 |
{ |
211 |
jgs |
150 |
Paso_SystemMatrix* mat = getPaso_SystemMatrix(); |
212 |
jgs |
153 |
if ( col_q.getDataPointSize() != getColumnBlockSize()) { |
213 |
jgs |
150 |
throw FinleyAdapterException("nullifyRowsAndCols : column block size does not match the number of components of column mask."); |
214 |
|
|
} else if ( row_q.getDataPointSize() != getRowBlockSize()) { |
215 |
|
|
throw FinleyAdapterException("nullifyRowsAndCols : row block size does not match the number of components of row mask."); |
216 |
|
|
} else if ( col_q.getFunctionSpace() != getColumnFunctionSpace()) { |
217 |
|
|
throw FinleyAdapterException("nullifyRowsAndCols : column function space and function space of column mask don't match."); |
218 |
|
|
} else if (row_q.getFunctionSpace() != getRowFunctionSpace()) { |
219 |
|
|
throw FinleyAdapterException("nullifyRowsAndCols : row function space and function space of row mask don't match."); |
220 |
|
|
} |
221 |
jgs |
153 |
row_q.expand(); |
222 |
|
|
col_q.expand(); |
223 |
|
|
double* row_q_dp=row_q.getSampleData(0); |
224 |
|
|
double* col_q_dp=col_q.getSampleData(0); |
225 |
jgs |
150 |
Paso_SystemMatrix_nullifyRowsAndCols(mat,row_q_dp,col_q_dp, mdv); |
226 |
|
|
checkPasoError(); |
227 |
jgs |
82 |
} |
228 |
|
|
|
229 |
jgs |
102 |
void SystemMatrixAdapter::saveMM(const std::string& fileName) const |
230 |
|
|
{ |
231 |
woo409 |
757 |
char *fName = (fileName.size()+1>0) ? TMPMEMALLOC(fileName.size()+1,char) : (char*)NULL; |
232 |
|
|
|
233 |
|
|
strcpy(fName,fileName.c_str()); |
234 |
jgs |
150 |
Paso_SystemMatrix* mat = getPaso_SystemMatrix(); |
235 |
|
|
Paso_SystemMatrix_saveMM(mat,fName); |
236 |
|
|
checkPasoError(); |
237 |
woo409 |
757 |
TMPMEMFREE(fName); |
238 |
|
|
|
239 |
jgs |
102 |
} |
240 |
|
|
|
241 |
jgs |
123 |
void SystemMatrixAdapter::saveHB(const std::string& fileName) const |
242 |
|
|
{ |
243 |
woo409 |
757 |
char *fName = (fileName.size()+1>0) ? TMPMEMALLOC(fileName.size()+1,char) : (char*)NULL; |
244 |
|
|
|
245 |
jgs |
123 |
strcpy(fName,fileName.c_str()); |
246 |
jgs |
150 |
Paso_SystemMatrix* mat = getPaso_SystemMatrix(); |
247 |
|
|
Paso_SystemMatrix_saveHB(mat,fName); |
248 |
|
|
checkPasoError(); |
249 |
woo409 |
757 |
TMPMEMFREE(fName); |
250 |
|
|
|
251 |
jgs |
123 |
} |
252 |
|
|
|
253 |
jgs |
149 |
void SystemMatrixAdapter::resetValues() const |
254 |
jgs |
102 |
{ |
255 |
jgs |
150 |
Paso_SystemMatrix* mat = getPaso_SystemMatrix(); |
256 |
|
|
Paso_SystemMatrix_setValues(mat,0.); |
257 |
|
|
Paso_solve_free(mat); |
258 |
|
|
checkPasoError(); |
259 |
jgs |
108 |
} |
260 |
jgs |
102 |
|
261 |
gross |
1364 |
void SystemMatrixAdapter::dictToPasoOptions(Paso_Options* paso_options, const boost::python::dict& options) |
262 |
|
|
{ |
263 |
|
|
Paso_Options_setDefaults(paso_options); |
264 |
|
|
#define EXTRACT(__key__,__val__,__type__) if ( options.has_key(__key__)) paso_options->__val__=boost::python::extract<__type__>(options.get(__key__)) |
265 |
|
|
#define EXTRACT_OPTION(__key__,__val__,__type__) if ( options.has_key(__key__)) paso_options->__val__=mapOptionToPaso(boost::python::extract<__type__>(options.get(__key__))) |
266 |
|
|
EXTRACT("verbose",verbose,int); |
267 |
|
|
EXTRACT_OPTION("reordering",reordering,int); |
268 |
|
|
EXTRACT(ESCRIPT_TOLERANCE_KEY,tolerance,double); |
269 |
|
|
EXTRACT_OPTION(ESCRIPT_METHOD_KEY,method,int); |
270 |
|
|
EXTRACT(ESCRIPT_SYMMETRY_KEY,symmetric,int); |
271 |
|
|
EXTRACT_OPTION(ESCRIPT_PACKAGE_KEY,package,int); |
272 |
|
|
EXTRACT_OPTION("preconditioner",preconditioner,int); |
273 |
|
|
EXTRACT("iter_max",iter_max,int); |
274 |
|
|
EXTRACT("drop_tolerance",drop_tolerance,double); |
275 |
|
|
EXTRACT("drop_storage",drop_storage,double); |
276 |
|
|
EXTRACT("truncation",truncation,int); |
277 |
|
|
EXTRACT("restart",restart,int); |
278 |
|
|
#undef EXTRACT |
279 |
|
|
#undef EXTRACT_OPTION |
280 |
|
|
} |
281 |
|
|
|
282 |
|
|
|
283 |
jgs |
82 |
} // end of namespace |