File: | /tmp/pyrefcon/scipy/scipy/sparse/linalg/dsolve/_superlu_utils.c |
Warning: | line 46, column 33 PyObject ownership leak with reference count of 1 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /*! \file | |||
2 | Copyright (c) 2003, The Regents of the University of California, through | |||
3 | Lawrence Berkeley National Laboratory (subject to receipt of any required | |||
4 | approvals from U.S. Dept. of Energy) | |||
5 | ||||
6 | All rights reserved. | |||
7 | ||||
8 | The source code is distributed under BSD license, see the file License.txt | |||
9 | at the top-level directory. | |||
10 | */ | |||
11 | /*! @file util.c | |||
12 | * \brief Utility functions | |||
13 | * | |||
14 | * <pre> | |||
15 | * -- SuperLU routine (version 4.1) -- | |||
16 | * Univ. of California Berkeley, Xerox Palo Alto Research Center, | |||
17 | * and Lawrence Berkeley National Lab. | |||
18 | * November, 2010 | |||
19 | * | |||
20 | * Copyright (c) 1994 by Xerox Corporation. All rights reserved. | |||
21 | * | |||
22 | * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY | |||
23 | * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. | |||
24 | * | |||
25 | * Permission is hereby granted to use or copy this program for any | |||
26 | * purpose, provided the above notices are retained on all copies. | |||
27 | * Permission to modify the code and to distribute modified code is | |||
28 | * granted, provided the above notices are retained, and a notice that | |||
29 | * the code was modified is included with the above copyright notice. | |||
30 | * </pre> | |||
31 | */ | |||
32 | ||||
33 | ||||
34 | #include <math.h> | |||
35 | #include "slu_ddefs.h" | |||
36 | ||||
37 | /*! \brief Global statistics variale | |||
38 | */ | |||
39 | ||||
40 | void superlu_abort_and_exit(char* msg) | |||
41 | { | |||
42 | fprintf(stderr, "%s", msg)__fprintf_chk (stderr, 2 - 1, "%s", msg); | |||
43 | exit (-1); | |||
44 | } | |||
45 | ||||
46 | /*! \brief Set the default values for the options argument. | |||
47 | */ | |||
48 | void set_default_options(superlu_options_t *options) | |||
49 | { | |||
50 | options->Fact = DOFACT; | |||
51 | options->Equil = YES; | |||
52 | options->ColPerm = COLAMD; | |||
53 | options->Trans = NOTRANS; | |||
54 | options->IterRefine = NOREFINE; | |||
55 | options->DiagPivotThresh = 1.0; | |||
56 | options->SymmetricMode = NO; | |||
57 | options->PivotGrowth = NO; | |||
58 | options->ConditionNumber = NO; | |||
59 | options->PrintStat = YES; | |||
60 | } | |||
61 | ||||
62 | /*! \brief Set the default values for the options argument for ILU. | |||
63 | */ | |||
64 | void ilu_set_default_options(superlu_options_t *options) | |||
65 | { | |||
66 | set_default_options(options); | |||
67 | ||||
68 | /* further options for incomplete factorization */ | |||
69 | options->DiagPivotThresh = 0.1; | |||
70 | options->RowPerm = LargeDiag_MC64; | |||
71 | options->ILU_DropRule = DROP_BASIC( 0x0001 ) | DROP_AREA( 0x0008 ); | |||
72 | options->ILU_DropTol = 1e-4; | |||
73 | options->ILU_FillFactor = 10.0; | |||
74 | options->ILU_Norm = INF_NORM; | |||
75 | options->ILU_MILU = SILU; | |||
76 | options->ILU_MILU_Dim = 3.0; /* -log(n)/log(h) is perfect */ | |||
77 | options->ILU_FillTol = 1e-2; | |||
78 | } | |||
79 | ||||
80 | /*! \brief Print the options setting. | |||
81 | */ | |||
82 | void print_options(superlu_options_t *options) | |||
83 | { | |||
84 | printf(".. options:\n")__printf_chk (2 - 1, ".. options:\n"); | |||
85 | printf("\tFact\t %8d\n", options->Fact)__printf_chk (2 - 1, "\tFact\t %8d\n", options->Fact); | |||
86 | printf("\tEquil\t %8d\n", options->Equil)__printf_chk (2 - 1, "\tEquil\t %8d\n", options->Equil); | |||
87 | printf("\tColPerm\t %8d\n", options->ColPerm)__printf_chk (2 - 1, "\tColPerm\t %8d\n", options->ColPerm ); | |||
88 | printf("\tDiagPivotThresh %8.4f\n", options->DiagPivotThresh)__printf_chk (2 - 1, "\tDiagPivotThresh %8.4f\n", options-> DiagPivotThresh); | |||
89 | printf("\tTrans\t %8d\n", options->Trans)__printf_chk (2 - 1, "\tTrans\t %8d\n", options->Trans); | |||
90 | printf("\tIterRefine\t%4d\n", options->IterRefine)__printf_chk (2 - 1, "\tIterRefine\t%4d\n", options->IterRefine ); | |||
91 | printf("\tSymmetricMode\t%4d\n", options->SymmetricMode)__printf_chk (2 - 1, "\tSymmetricMode\t%4d\n", options->SymmetricMode ); | |||
92 | printf("\tPivotGrowth\t%4d\n", options->PivotGrowth)__printf_chk (2 - 1, "\tPivotGrowth\t%4d\n", options->PivotGrowth ); | |||
93 | printf("\tConditionNumber\t%4d\n", options->ConditionNumber)__printf_chk (2 - 1, "\tConditionNumber\t%4d\n", options-> ConditionNumber); | |||
94 | printf("..\n")__printf_chk (2 - 1, "..\n"); | |||
95 | } | |||
96 | ||||
97 | /*! \brief Print the options setting. | |||
98 | */ | |||
99 | void print_ilu_options(superlu_options_t *options) | |||
100 | { | |||
101 | printf(".. ILU options:\n")__printf_chk (2 - 1, ".. ILU options:\n"); | |||
102 | printf("\tDiagPivotThresh\t%6.2e\n", options->DiagPivotThresh)__printf_chk (2 - 1, "\tDiagPivotThresh\t%6.2e\n", options-> DiagPivotThresh); | |||
103 | printf("\ttau\t%6.2e\n", options->ILU_DropTol)__printf_chk (2 - 1, "\ttau\t%6.2e\n", options->ILU_DropTol ); | |||
104 | printf("\tgamma\t%6.2f\n", options->ILU_FillFactor)__printf_chk (2 - 1, "\tgamma\t%6.2f\n", options->ILU_FillFactor ); | |||
105 | printf("\tDropRule\t%0x\n", options->ILU_DropRule)__printf_chk (2 - 1, "\tDropRule\t%0x\n", options->ILU_DropRule ); | |||
106 | printf("\tMILU\t%d\n", options->ILU_MILU)__printf_chk (2 - 1, "\tMILU\t%d\n", options->ILU_MILU); | |||
107 | printf("\tMILU_ALPHA\t%6.2e\n", MILU_ALPHA)__printf_chk (2 - 1, "\tMILU_ALPHA\t%6.2e\n", (1.0e-2)); | |||
108 | printf("\tDiagFillTol\t%6.2e\n", options->ILU_FillTol)__printf_chk (2 - 1, "\tDiagFillTol\t%6.2e\n", options->ILU_FillTol ); | |||
109 | printf("..\n")__printf_chk (2 - 1, "..\n"); | |||
110 | } | |||
111 | ||||
112 | /*! \brief Deallocate the structure pointing to the actual storage of the matrix. */ | |||
113 | void | |||
114 | Destroy_SuperMatrix_Store(SuperMatrix *A) | |||
115 | { | |||
116 | SUPERLU_FREE ( A->Store )superlu_python_module_free(A->Store); | |||
117 | } | |||
118 | ||||
119 | void | |||
120 | Destroy_CompCol_Matrix(SuperMatrix *A) | |||
121 | { | |||
122 | SUPERLU_FREE( ((NCformat *)A->Store)->rowind )superlu_python_module_free(((NCformat *)A->Store)->rowind ); | |||
123 | SUPERLU_FREE( ((NCformat *)A->Store)->colptr )superlu_python_module_free(((NCformat *)A->Store)->colptr ); | |||
124 | SUPERLU_FREE( ((NCformat *)A->Store)->nzval )superlu_python_module_free(((NCformat *)A->Store)->nzval ); | |||
125 | SUPERLU_FREE( A->Store )superlu_python_module_free(A->Store); | |||
126 | } | |||
127 | ||||
128 | void | |||
129 | Destroy_CompRow_Matrix(SuperMatrix *A) | |||
130 | { | |||
131 | SUPERLU_FREE( ((NRformat *)A->Store)->colind )superlu_python_module_free(((NRformat *)A->Store)->colind ); | |||
132 | SUPERLU_FREE( ((NRformat *)A->Store)->rowptr )superlu_python_module_free(((NRformat *)A->Store)->rowptr ); | |||
133 | SUPERLU_FREE( ((NRformat *)A->Store)->nzval )superlu_python_module_free(((NRformat *)A->Store)->nzval ); | |||
134 | SUPERLU_FREE( A->Store )superlu_python_module_free(A->Store); | |||
135 | } | |||
136 | ||||
137 | void | |||
138 | Destroy_SuperNode_Matrix(SuperMatrix *A) | |||
139 | { | |||
140 | SUPERLU_FREE ( ((SCformat *)A->Store)->rowind )superlu_python_module_free(((SCformat *)A->Store)->rowind ); | |||
141 | SUPERLU_FREE ( ((SCformat *)A->Store)->rowind_colptr )superlu_python_module_free(((SCformat *)A->Store)->rowind_colptr ); | |||
142 | SUPERLU_FREE ( ((SCformat *)A->Store)->nzval )superlu_python_module_free(((SCformat *)A->Store)->nzval ); | |||
143 | SUPERLU_FREE ( ((SCformat *)A->Store)->nzval_colptr )superlu_python_module_free(((SCformat *)A->Store)->nzval_colptr ); | |||
144 | SUPERLU_FREE ( ((SCformat *)A->Store)->col_to_sup )superlu_python_module_free(((SCformat *)A->Store)->col_to_sup ); | |||
145 | SUPERLU_FREE ( ((SCformat *)A->Store)->sup_to_col )superlu_python_module_free(((SCformat *)A->Store)->sup_to_col ); | |||
146 | SUPERLU_FREE ( A->Store )superlu_python_module_free(A->Store); | |||
147 | } | |||
148 | ||||
149 | /*! \brief A is of type Stype==NCP */ | |||
150 | void | |||
151 | Destroy_CompCol_Permuted(SuperMatrix *A) | |||
152 | { | |||
153 | SUPERLU_FREE ( ((NCPformat *)A->Store)->colbeg )superlu_python_module_free(((NCPformat *)A->Store)->colbeg ); | |||
154 | SUPERLU_FREE ( ((NCPformat *)A->Store)->colend )superlu_python_module_free(((NCPformat *)A->Store)->colend ); | |||
155 | SUPERLU_FREE ( A->Store )superlu_python_module_free(A->Store); | |||
156 | } | |||
157 | ||||
158 | /*! \brief A is of type Stype==DN */ | |||
159 | void | |||
160 | Destroy_Dense_Matrix(SuperMatrix *A) | |||
161 | { | |||
162 | DNformat* Astore = A->Store; | |||
163 | SUPERLU_FREE (Astore->nzval)superlu_python_module_free(Astore->nzval); | |||
164 | SUPERLU_FREE ( A->Store )superlu_python_module_free(A->Store); | |||
165 | } | |||
166 | ||||
167 | /*! \brief Reset repfnz[] for the current column | |||
168 | */ | |||
169 | void | |||
170 | resetrep_col (const int nseg, const int *segrep, int *repfnz) | |||
171 | { | |||
172 | int i, irep; | |||
173 | ||||
174 | for (i = 0; i < nseg; i++) { | |||
175 | irep = segrep[i]; | |||
176 | repfnz[irep] = EMPTY(-1); | |||
177 | } | |||
178 | } | |||
179 | ||||
180 | ||||
181 | /*! \brief Count the total number of nonzeros in factors L and U, and in the symmetrically reduced L. | |||
182 | */ | |||
183 | void | |||
184 | countnz(const int n, int *xprune, int *nnzL, int *nnzU, GlobalLU_t *Glu) | |||
185 | { | |||
186 | int nsuper, fsupc, i, j; | |||
187 | int nnzL0, jlen, irep; | |||
188 | int *xsup, *xlsub; | |||
189 | ||||
190 | xsup = Glu->xsup; | |||
191 | xlsub = Glu->xlsub; | |||
192 | *nnzL = 0; | |||
193 | *nnzU = (Glu->xusub)[n]; | |||
194 | nnzL0 = 0; | |||
195 | nsuper = (Glu->supno)[n]; | |||
196 | ||||
197 | if ( n <= 0 ) return; | |||
198 | ||||
199 | /* | |||
200 | * For each supernode | |||
201 | */ | |||
202 | for (i = 0; i <= nsuper; i++) { | |||
203 | fsupc = xsup[i]; | |||
204 | jlen = xlsub[fsupc+1] - xlsub[fsupc]; | |||
205 | ||||
206 | for (j = fsupc; j < xsup[i+1]; j++) { | |||
207 | *nnzL += jlen; | |||
208 | *nnzU += j - fsupc + 1; | |||
209 | jlen--; | |||
210 | } | |||
211 | irep = xsup[i+1] - 1; | |||
212 | nnzL0 += xprune[irep] - xlsub[irep]; | |||
213 | } | |||
214 | ||||
215 | /* printf("\tNo of nonzeros in symm-reduced L = %d\n", nnzL0);*/ | |||
216 | } | |||
217 | ||||
218 | /*! \brief Count the total number of nonzeros in factors L and U. | |||
219 | */ | |||
220 | void | |||
221 | ilu_countnz(const int n, int *nnzL, int *nnzU, GlobalLU_t *Glu) | |||
222 | { | |||
223 | int nsuper, fsupc, i, j; | |||
224 | int jlen, irep; | |||
225 | int *xsup, *xlsub; | |||
226 | ||||
227 | xsup = Glu->xsup; | |||
228 | xlsub = Glu->xlsub; | |||
229 | *nnzL = 0; | |||
230 | *nnzU = (Glu->xusub)[n]; | |||
231 | nsuper = (Glu->supno)[n]; | |||
232 | ||||
233 | if ( n <= 0 ) return; | |||
234 | ||||
235 | /* | |||
236 | * For each supernode | |||
237 | */ | |||
238 | for (i = 0; i <= nsuper; i++) { | |||
239 | fsupc = xsup[i]; | |||
240 | jlen = xlsub[fsupc+1] - xlsub[fsupc]; | |||
241 | ||||
242 | for (j = fsupc; j < xsup[i+1]; j++) { | |||
243 | *nnzL += jlen; | |||
244 | *nnzU += j - fsupc + 1; | |||
245 | jlen--; | |||
246 | } | |||
247 | irep = xsup[i+1] - 1; | |||
248 | } | |||
249 | } | |||
250 | ||||
251 | ||||
252 | /*! \brief Fix up the data storage lsub for L-subscripts. It removes the subscript sets for structural pruning, and applies permuation to the remaining subscripts. | |||
253 | */ | |||
254 | void | |||
255 | fixupL(const int n, const int *perm_r, GlobalLU_t *Glu) | |||
256 | { | |||
257 | register int nsuper, fsupc, nextl, i, j, k, jstrt; | |||
258 | int *xsup, *lsub, *xlsub; | |||
259 | ||||
260 | if ( n <= 1 ) return; | |||
261 | ||||
262 | xsup = Glu->xsup; | |||
263 | lsub = Glu->lsub; | |||
264 | xlsub = Glu->xlsub; | |||
265 | nextl = 0; | |||
266 | nsuper = (Glu->supno)[n]; | |||
267 | ||||
268 | /* | |||
269 | * For each supernode ... | |||
270 | */ | |||
271 | for (i = 0; i <= nsuper; i++) { | |||
272 | fsupc = xsup[i]; | |||
273 | jstrt = xlsub[fsupc]; | |||
274 | xlsub[fsupc] = nextl; | |||
275 | for (j = jstrt; j < xlsub[fsupc+1]; j++) { | |||
276 | lsub[nextl] = perm_r[lsub[j]]; /* Now indexed into P*A */ | |||
277 | nextl++; | |||
278 | } | |||
279 | for (k = fsupc+1; k < xsup[i+1]; k++) | |||
280 | xlsub[k] = nextl; /* Other columns in supernode i */ | |||
281 | ||||
282 | } | |||
283 | ||||
284 | xlsub[n] = nextl; | |||
285 | } | |||
286 | ||||
287 | ||||
288 | /*! \brief Diagnostic print of segment info after panel_dfs(). | |||
289 | */ | |||
290 | void print_panel_seg(int n, int w, int jcol, int nseg, | |||
291 | int *segrep, int *repfnz) | |||
292 | { | |||
293 | int j, k; | |||
294 | ||||
295 | for (j = jcol; j < jcol+w; j++) { | |||
296 | printf("\tcol %d:\n", j)__printf_chk (2 - 1, "\tcol %d:\n", j); | |||
297 | for (k = 0; k < nseg; k++) | |||
298 | printf("\t\tseg %d, segrep %d, repfnz %d\n", k,__printf_chk (2 - 1, "\t\tseg %d, segrep %d, repfnz %d\n", k, segrep[k], repfnz[(j-jcol)*n + segrep[k]]) | |||
299 | segrep[k], repfnz[(j-jcol)*n + segrep[k]])__printf_chk (2 - 1, "\t\tseg %d, segrep %d, repfnz %d\n", k, segrep[k], repfnz[(j-jcol)*n + segrep[k]]); | |||
300 | } | |||
301 | ||||
302 | } | |||
303 | ||||
304 | ||||
305 | void | |||
306 | StatInit(SuperLUStat_t *stat) | |||
307 | { | |||
308 | register int i, w, panel_size, relax; | |||
309 | ||||
310 | panel_size = sp_ienv(1); | |||
311 | relax = sp_ienv(2); | |||
312 | w = SUPERLU_MAX(panel_size, relax)( (panel_size) > (relax) ? (panel_size) : (relax) ); | |||
313 | stat->panel_histo = intCalloc(w+1); | |||
314 | stat->utime = (double *) SUPERLU_MALLOC(NPHASES * sizeof(double))superlu_python_module_malloc(NPHASES * sizeof(double)); | |||
315 | if (!stat->utime) ABORT("SUPERLU_MALLOC fails for stat->utime"){ char msg[256]; __builtin___sprintf_chk (msg, 2 - 1, __builtin_object_size (msg, 2 > 1), "%s at line %d in file %s\n","SUPERLU_MALLOC fails for stat->utime" ,315, "scipy/sparse/linalg/dsolve/SuperLU/SRC/util.c"); superlu_python_module_abort (msg); }; | |||
316 | stat->ops = (flops_t *) SUPERLU_MALLOC(NPHASES * sizeof(flops_t))superlu_python_module_malloc(NPHASES * sizeof(flops_t)); | |||
317 | if (!stat->ops) ABORT("SUPERLU_MALLOC fails for stat->ops"){ char msg[256]; __builtin___sprintf_chk (msg, 2 - 1, __builtin_object_size (msg, 2 > 1), "%s at line %d in file %s\n","SUPERLU_MALLOC fails for stat->ops" ,317, "scipy/sparse/linalg/dsolve/SuperLU/SRC/util.c"); superlu_python_module_abort (msg); }; | |||
318 | for (i = 0; i < NPHASES; ++i) { | |||
319 | stat->utime[i] = 0.; | |||
320 | stat->ops[i] = 0.; | |||
321 | } | |||
322 | stat->TinyPivots = 0; | |||
323 | stat->RefineSteps = 0; | |||
324 | stat->expansions = 0; | |||
325 | #if ( PRNTlevel >= 1 ) | |||
326 | printf(".. parameters in sp_ienv():\n")__printf_chk (2 - 1, ".. parameters in sp_ienv():\n"); | |||
327 | printf("\t 1: panel size \t %4d \n"__printf_chk (2 - 1, "\t 1: panel size \t %4d \n" "\t 2: relax \t %4d \n" "\t 3: max. super \t %4d \n" "\t 4: row-dim 2D \t %4d \n" "\t 5: col-dim 2D \t %4d \n" "\t 6: fill ratio \t %4d \n", sp_ienv(1), sp_ienv(2), sp_ienv (3), sp_ienv(4), sp_ienv(5), sp_ienv(6)) | |||
328 | "\t 2: relax \t %4d \n"__printf_chk (2 - 1, "\t 1: panel size \t %4d \n" "\t 2: relax \t %4d \n" "\t 3: max. super \t %4d \n" "\t 4: row-dim 2D \t %4d \n" "\t 5: col-dim 2D \t %4d \n" "\t 6: fill ratio \t %4d \n", sp_ienv(1), sp_ienv(2), sp_ienv (3), sp_ienv(4), sp_ienv(5), sp_ienv(6)) | |||
329 | "\t 3: max. super \t %4d \n"__printf_chk (2 - 1, "\t 1: panel size \t %4d \n" "\t 2: relax \t %4d \n" "\t 3: max. super \t %4d \n" "\t 4: row-dim 2D \t %4d \n" "\t 5: col-dim 2D \t %4d \n" "\t 6: fill ratio \t %4d \n", sp_ienv(1), sp_ienv(2), sp_ienv (3), sp_ienv(4), sp_ienv(5), sp_ienv(6)) | |||
330 | "\t 4: row-dim 2D \t %4d \n"__printf_chk (2 - 1, "\t 1: panel size \t %4d \n" "\t 2: relax \t %4d \n" "\t 3: max. super \t %4d \n" "\t 4: row-dim 2D \t %4d \n" "\t 5: col-dim 2D \t %4d \n" "\t 6: fill ratio \t %4d \n", sp_ienv(1), sp_ienv(2), sp_ienv (3), sp_ienv(4), sp_ienv(5), sp_ienv(6)) | |||
331 | "\t 5: col-dim 2D \t %4d \n"__printf_chk (2 - 1, "\t 1: panel size \t %4d \n" "\t 2: relax \t %4d \n" "\t 3: max. super \t %4d \n" "\t 4: row-dim 2D \t %4d \n" "\t 5: col-dim 2D \t %4d \n" "\t 6: fill ratio \t %4d \n", sp_ienv(1), sp_ienv(2), sp_ienv (3), sp_ienv(4), sp_ienv(5), sp_ienv(6)) | |||
332 | "\t 6: fill ratio \t %4d \n",__printf_chk (2 - 1, "\t 1: panel size \t %4d \n" "\t 2: relax \t %4d \n" "\t 3: max. super \t %4d \n" "\t 4: row-dim 2D \t %4d \n" "\t 5: col-dim 2D \t %4d \n" "\t 6: fill ratio \t %4d \n", sp_ienv(1), sp_ienv(2), sp_ienv (3), sp_ienv(4), sp_ienv(5), sp_ienv(6)) | |||
333 | sp_ienv(1), sp_ienv(2), sp_ienv(3),__printf_chk (2 - 1, "\t 1: panel size \t %4d \n" "\t 2: relax \t %4d \n" "\t 3: max. super \t %4d \n" "\t 4: row-dim 2D \t %4d \n" "\t 5: col-dim 2D \t %4d \n" "\t 6: fill ratio \t %4d \n", sp_ienv(1), sp_ienv(2), sp_ienv (3), sp_ienv(4), sp_ienv(5), sp_ienv(6)) | |||
334 | sp_ienv(4), sp_ienv(5), sp_ienv(6))__printf_chk (2 - 1, "\t 1: panel size \t %4d \n" "\t 2: relax \t %4d \n" "\t 3: max. super \t %4d \n" "\t 4: row-dim 2D \t %4d \n" "\t 5: col-dim 2D \t %4d \n" "\t 6: fill ratio \t %4d \n", sp_ienv(1), sp_ienv(2), sp_ienv (3), sp_ienv(4), sp_ienv(5), sp_ienv(6)); | |||
335 | #endif | |||
336 | } | |||
337 | ||||
338 | ||||
339 | void | |||
340 | StatPrint(SuperLUStat_t *stat) | |||
341 | { | |||
342 | double *utime; | |||
343 | flops_t *ops; | |||
344 | ||||
345 | utime = stat->utime; | |||
346 | ops = stat->ops; | |||
347 | printf("Factor time = %8.5f\n", utime[FACT])__printf_chk (2 - 1, "Factor time = %8.5f\n", utime[FACT]); | |||
348 | if ( utime[FACT] != 0.0 ) | |||
349 | printf("Factor flops = %e\tMflops = %8.2f\n", ops[FACT],__printf_chk (2 - 1, "Factor flops = %e\tMflops = %8.2f\n", ops [FACT], ops[FACT]*1e-6/utime[FACT]) | |||
350 | ops[FACT]*1e-6/utime[FACT])__printf_chk (2 - 1, "Factor flops = %e\tMflops = %8.2f\n", ops [FACT], ops[FACT]*1e-6/utime[FACT]); | |||
351 | ||||
352 | printf("Solve time = %8.4f\n", utime[SOLVE])__printf_chk (2 - 1, "Solve time = %8.4f\n", utime[SOLVE]); | |||
353 | if ( utime[SOLVE] != 0.0 ) | |||
354 | printf("Solve flops = %e\tMflops = %8.2f\n", ops[SOLVE],__printf_chk (2 - 1, "Solve flops = %e\tMflops = %8.2f\n", ops [SOLVE], ops[SOLVE]*1e-6/utime[SOLVE]) | |||
355 | ops[SOLVE]*1e-6/utime[SOLVE])__printf_chk (2 - 1, "Solve flops = %e\tMflops = %8.2f\n", ops [SOLVE], ops[SOLVE]*1e-6/utime[SOLVE]); | |||
356 | ||||
357 | printf("Number of memory expansions: %d\n", stat->expansions)__printf_chk (2 - 1, "Number of memory expansions: %d\n", stat ->expansions); | |||
358 | ||||
359 | } | |||
360 | ||||
361 | ||||
362 | void | |||
363 | StatFree(SuperLUStat_t *stat) | |||
364 | { | |||
365 | SUPERLU_FREE(stat->panel_histo)superlu_python_module_free(stat->panel_histo); | |||
| ||||
366 | SUPERLU_FREE(stat->utime)superlu_python_module_free(stat->utime); | |||
367 | SUPERLU_FREE(stat->ops)superlu_python_module_free(stat->ops); | |||
368 | } | |||
369 | ||||
370 | ||||
371 | flops_t | |||
372 | LUFactFlops(SuperLUStat_t *stat) | |||
373 | { | |||
374 | return (stat->ops[FACT]); | |||
375 | } | |||
376 | ||||
377 | flops_t | |||
378 | LUSolveFlops(SuperLUStat_t *stat) | |||
379 | { | |||
380 | return (stat->ops[SOLVE]); | |||
381 | } | |||
382 | ||||
383 | ||||
384 | ||||
385 | ||||
386 | ||||
387 | /*! \brief Fills an integer array with a given value. | |||
388 | */ | |||
389 | void ifill(int *a, int alen, int ival) | |||
390 | { | |||
391 | register int i; | |||
392 | for (i = 0; i < alen; i++) a[i] = ival; | |||
393 | } | |||
394 | ||||
395 | ||||
396 | ||||
397 | /*! \brief Get the statistics of the supernodes | |||
398 | */ | |||
399 | #define NBUCKS10 10 | |||
400 | ||||
401 | void super_stats(int nsuper, int *xsup) | |||
402 | { | |||
403 | register int nsup1 = 0; | |||
404 | int i, isize, whichb, bl, bh; | |||
405 | int bucket[NBUCKS10]; | |||
406 | int max_sup_size = 0; | |||
407 | ||||
408 | for (i = 0; i <= nsuper; i++) { | |||
409 | isize = xsup[i+1] - xsup[i]; | |||
410 | if ( isize == 1 ) nsup1++; | |||
411 | if ( max_sup_size < isize ) max_sup_size = isize; | |||
412 | } | |||
413 | ||||
414 | printf(" Supernode statistics:\n\tno of super = %d\n", nsuper+1)__printf_chk (2 - 1, " Supernode statistics:\n\tno of super = %d\n" , nsuper+1); | |||
415 | printf("\tmax supernode size = %d\n", max_sup_size)__printf_chk (2 - 1, "\tmax supernode size = %d\n", max_sup_size ); | |||
416 | printf("\tno of size 1 supernodes = %d\n", nsup1)__printf_chk (2 - 1, "\tno of size 1 supernodes = %d\n", nsup1 ); | |||
417 | ||||
418 | /* Histogram of the supernode sizes */ | |||
419 | ifill (bucket, NBUCKS10, 0); | |||
420 | ||||
421 | for (i = 0; i <= nsuper; i++) { | |||
422 | isize = xsup[i+1] - xsup[i]; | |||
423 | whichb = (float) isize / max_sup_size * NBUCKS10; | |||
424 | if (whichb >= NBUCKS10) whichb = NBUCKS10 - 1; | |||
425 | bucket[whichb]++; | |||
426 | } | |||
427 | ||||
428 | printf("\tHistogram of supernode sizes:\n")__printf_chk (2 - 1, "\tHistogram of supernode sizes:\n"); | |||
429 | for (i = 0; i < NBUCKS10; i++) { | |||
430 | bl = (float) i * max_sup_size / NBUCKS10; | |||
431 | bh = (float) (i+1) * max_sup_size / NBUCKS10; | |||
432 | printf("\tsnode: %d-%d\t\t%d\n", bl+1, bh, bucket[i])__printf_chk (2 - 1, "\tsnode: %d-%d\t\t%d\n", bl+1, bh, bucket [i]); | |||
433 | } | |||
434 | ||||
435 | } | |||
436 | ||||
437 | ||||
438 | float SpaSize(int n, int np, float sum_npw) | |||
439 | { | |||
440 | return (sum_npw*8 + np*8 + n*4)/1024.; | |||
441 | } | |||
442 | ||||
443 | float DenseSize(int n, float sum_nw) | |||
444 | { | |||
445 | return (sum_nw*8 + n*8)/1024.;; | |||
446 | } | |||
447 | ||||
448 | ||||
449 | ||||
450 | /*! \brief Check whether repfnz[] == EMPTY after reset. | |||
451 | */ | |||
452 | void check_repfnz(int n, int w, int jcol, int *repfnz) | |||
453 | { | |||
454 | int jj, k; | |||
455 | ||||
456 | for (jj = jcol; jj < jcol+w; jj++) | |||
457 | for (k = 0; k < n; k++) | |||
458 | if ( repfnz[(jj-jcol)*n + k] != EMPTY(-1) ) { | |||
459 | fprintf(stderr, "col %d, repfnz_col[%d] = %d\n", jj,__fprintf_chk (stderr, 2 - 1, "col %d, repfnz_col[%d] = %d\n" , jj, k, repfnz[(jj-jcol)*n + k]) | |||
460 | k, repfnz[(jj-jcol)*n + k])__fprintf_chk (stderr, 2 - 1, "col %d, repfnz_col[%d] = %d\n" , jj, k, repfnz[(jj-jcol)*n + k]); | |||
461 | ABORT("check_repfnz"){ char msg[256]; __builtin___sprintf_chk (msg, 2 - 1, __builtin_object_size (msg, 2 > 1), "%s at line %d in file %s\n","check_repfnz" ,461, "scipy/sparse/linalg/dsolve/SuperLU/SRC/util.c"); superlu_python_module_abort (msg); }; | |||
462 | } | |||
463 | } | |||
464 | ||||
465 | ||||
466 | /*! \brief Print a summary of the testing results. */ | |||
467 | void | |||
468 | PrintSumm(char *type, int nfail, int nrun, int nerrs) | |||
469 | { | |||
470 | if ( nfail > 0 ) | |||
471 | printf("%3s driver: %d out of %d tests failed to pass the threshold\n",__printf_chk (2 - 1, "%3s driver: %d out of %d tests failed to pass the threshold\n" , type, nfail, nrun) | |||
472 | type, nfail, nrun)__printf_chk (2 - 1, "%3s driver: %d out of %d tests failed to pass the threshold\n" , type, nfail, nrun); | |||
473 | else | |||
474 | printf("All tests for %3s driver passed the threshold (%6d tests run)\n", type, nrun)__printf_chk (2 - 1, "All tests for %3s driver passed the threshold (%6d tests run)\n" , type, nrun); | |||
475 | ||||
476 | if ( nerrs > 0 ) | |||
477 | printf("%6d error messages recorded\n", nerrs)__printf_chk (2 - 1, "%6d error messages recorded\n", nerrs); | |||
478 | } | |||
479 | ||||
480 | ||||
481 | int print_int_vec(char *what, int n, int *vec) | |||
482 | { | |||
483 | int i; | |||
484 | printf("%s\n", what)__printf_chk (2 - 1, "%s\n", what); | |||
485 | for (i = 0; i < n; ++i) printf("%d\t%d\n", i, vec[i])__printf_chk (2 - 1, "%d\t%d\n", i, vec[i]); | |||
486 | return 0; | |||
487 | } | |||
488 | ||||
489 | int slu_PrintInt10(char *name, int len, int *x) | |||
490 | { | |||
491 | register int i; | |||
492 | ||||
493 | printf("%10s:", name)__printf_chk (2 - 1, "%10s:", name); | |||
494 | for (i = 0; i < len; ++i) | |||
495 | { | |||
496 | if ( i % 10 == 0 ) printf("\n\t[%2d-%2d]", i, i + 9)__printf_chk (2 - 1, "\n\t[%2d-%2d]", i, i + 9); | |||
497 | printf("%6d", x[i])__printf_chk (2 - 1, "%6d", x[i]); | |||
498 | } | |||
499 | printf("\n")__printf_chk (2 - 1, "\n"); | |||
500 | return 0; | |||
501 | } | |||
502 | ||||
503 |
1 | /* Should be imported before Python.h */ | ||||||
2 | |||||||
3 | #include <Python.h> | ||||||
4 | |||||||
5 | #define NO_IMPORT_ARRAY | ||||||
6 | #define PY_ARRAY_UNIQUE_SYMBOL _scipy_sparse_superlu_ARRAY_API | ||||||
7 | |||||||
8 | #include "_superluobject.h" | ||||||
9 | #include <setjmp.h> | ||||||
10 | |||||||
11 | |||||||
12 | /* Abort to be used inside the superlu module so that memory allocation | ||||||
13 | errors don't exit Python and memory allocated internal to SuperLU is freed. | ||||||
14 | Calling program should deallocate (using SUPERLU_FREE) all memory that could have | ||||||
15 | been allocated. (It's ok to FREE unallocated memory)---will be ignored. | ||||||
16 | */ | ||||||
17 | |||||||
18 | #ifndef WITH_THREAD | ||||||
19 | static SuperLUGlobalObject superlu_py_global = {0}; | ||||||
20 | #endif | ||||||
21 | |||||||
22 | static SuperLUGlobalObject *get_tls_global(void) | ||||||
23 | { | ||||||
24 | #ifndef WITH_THREAD | ||||||
25 | if (superlu_py_global.memory_dict == NULL((void*)0)) { | ||||||
26 | superlu_py_global.memory_dict = PyDict_New(); | ||||||
27 | } | ||||||
28 | return &superlu_py_global; | ||||||
29 | #else | ||||||
30 | PyObject *thread_dict; | ||||||
31 | SuperLUGlobalObject *obj; | ||||||
32 | const char *key = "scipy.sparse.linalg.dsolve._superlu.__global_object"; | ||||||
33 | |||||||
34 | thread_dict = PyThreadState_GetDict(); | ||||||
35 | if (thread_dict == NULL((void*)0)) { | ||||||
36 | /* Should never happen */ | ||||||
37 | PyErr_SetString(PyExc_SystemError, "no thread state obtained"); | ||||||
38 | return NULL((void*)0); | ||||||
39 | } | ||||||
40 | |||||||
41 | obj = (SuperLUGlobalObject*)PyDict_GetItemString(thread_dict, key); | ||||||
42 | if (obj && Py_TYPE(obj) == &SuperLUGlobalType) { | ||||||
43 | return obj; | ||||||
44 | } | ||||||
45 | |||||||
46 | obj = (SuperLUGlobalObject*)PyObject_New(SuperLUGlobalObject, &SuperLUGlobalType); | ||||||
| |||||||
47 | if (obj == NULL((void*)0)) { | ||||||
48 | return (SuperLUGlobalObject*)PyErr_NoMemory(); | ||||||
49 | } | ||||||
50 | obj->memory_dict = PyDict_New(); | ||||||
51 | obj->jmpbuf_valid = 0; | ||||||
52 | |||||||
53 | PyDict_SetItemString(thread_dict, key, (PyObject *)obj); | ||||||
54 | |||||||
55 | return obj; | ||||||
56 | #endif | ||||||
57 | } | ||||||
58 | |||||||
59 | jmp_buf *superlu_python_jmpbuf(void) | ||||||
60 | { | ||||||
61 | SuperLUGlobalObject *g; | ||||||
62 | |||||||
63 | g = get_tls_global(); | ||||||
64 | if (g == NULL((void*)0)) { | ||||||
65 | abort(); | ||||||
66 | } | ||||||
67 | g->jmpbuf_valid = 1; | ||||||
68 | return &g->jmpbuf; | ||||||
69 | } | ||||||
70 | |||||||
71 | void superlu_python_module_abort(char *msg) | ||||||
72 | { | ||||||
73 | SuperLUGlobalObject *g; | ||||||
74 | NPY_ALLOW_C_API_DEF; | ||||||
75 | |||||||
76 | NPY_ALLOW_C_API; | ||||||
77 | g = get_tls_global(); | ||||||
78 | if (g == NULL((void*)0)) { | ||||||
79 | /* We have to longjmp (or SEGV results), but the | ||||||
80 | destination is not known --- no choice but abort. | ||||||
81 | However, this should never happen. | ||||||
82 | */ | ||||||
83 | abort(); | ||||||
84 | } | ||||||
85 | PyErr_SetString(PyExc_RuntimeError, msg); | ||||||
86 | |||||||
87 | if (!g->jmpbuf_valid) { | ||||||
88 | abort(); | ||||||
89 | } | ||||||
90 | |||||||
91 | g->jmpbuf_valid = 0; | ||||||
92 | NPY_DISABLE_C_API; | ||||||
93 | |||||||
94 | longjmp(g->jmpbuf, -1); | ||||||
95 | } | ||||||
96 | |||||||
97 | void *superlu_python_module_malloc(size_t size) | ||||||
98 | { | ||||||
99 | SuperLUGlobalObject *g; | ||||||
100 | PyObject *key = NULL((void*)0); | ||||||
101 | void *mem_ptr; | ||||||
102 | NPY_ALLOW_C_API_DEF; | ||||||
103 | |||||||
104 | NPY_ALLOW_C_API; | ||||||
105 | g = get_tls_global(); | ||||||
106 | if (g == NULL((void*)0)) { | ||||||
107 | return NULL((void*)0); | ||||||
108 | } | ||||||
109 | mem_ptr = malloc(size); | ||||||
110 | if (mem_ptr == NULL((void*)0)) { | ||||||
111 | NPY_DISABLE_C_API; | ||||||
112 | return NULL((void*)0); | ||||||
113 | } | ||||||
114 | key = PyLong_FromVoidPtr(mem_ptr); | ||||||
115 | if (key == NULL((void*)0)) | ||||||
116 | goto fail; | ||||||
117 | if (PyDict_SetItem(g->memory_dict, key, Py_None)) | ||||||
118 | goto fail; | ||||||
119 | Py_DECREF(key); | ||||||
120 | NPY_DISABLE_C_API; | ||||||
121 | |||||||
122 | return mem_ptr; | ||||||
123 | |||||||
124 | fail: | ||||||
125 | Py_XDECREF(key); | ||||||
126 | NPY_DISABLE_C_API; | ||||||
127 | free(mem_ptr); | ||||||
128 | superlu_python_module_abort | ||||||
129 | ("superlu_malloc: Cannot set dictionary key value in malloc."); | ||||||
130 | return NULL((void*)0); | ||||||
131 | |||||||
132 | } | ||||||
133 | |||||||
134 | void superlu_python_module_free(void *ptr) | ||||||
135 | { | ||||||
136 | SuperLUGlobalObject *g; | ||||||
137 | PyObject *key; | ||||||
138 | PyObject *ptype, *pvalue, *ptraceback; | ||||||
139 | NPY_ALLOW_C_API_DEF; | ||||||
140 | |||||||
141 | if (ptr == NULL((void*)0)) | ||||||
142 | return; | ||||||
143 | |||||||
144 | NPY_ALLOW_C_API; | ||||||
145 | g = get_tls_global(); | ||||||
146 | if (g
| ||||||
147 | abort(); | ||||||
148 | } | ||||||
149 | PyErr_Fetch(&ptype, &pvalue, &ptraceback); | ||||||
150 | key = PyLong_FromVoidPtr(ptr); | ||||||
151 | /* This will only free the pointer if it could find it in the dictionary | ||||||
152 | * of already allocated pointers --- thus after abort, the module can free all | ||||||
153 | * the memory that "might" have been allocated to avoid memory leaks on abort | ||||||
154 | * calls. | ||||||
155 | */ | ||||||
156 | if (!PyDict_DelItem(g->memory_dict, key)) { | ||||||
157 | free(ptr); | ||||||
158 | } | ||||||
159 | Py_DECREF(key); | ||||||
160 | PyErr_Restore(ptype, pvalue, ptraceback); | ||||||
161 | NPY_DISABLE_C_API; | ||||||
162 | return; | ||||||
163 | } | ||||||
164 | |||||||
165 | |||||||
166 | static void SuperLUGlobal_dealloc(SuperLUGlobalObject *self) | ||||||
167 | { | ||||||
168 | PyObject *key, *value; | ||||||
169 | Py_ssize_t pos = 0; | ||||||
170 | |||||||
171 | while (PyDict_Next(self->memory_dict, &pos, &key, &value)) { | ||||||
172 | void *ptr; | ||||||
173 | ptr = PyLong_AsVoidPtr(value); | ||||||
174 | free(ptr); | ||||||
175 | } | ||||||
176 | |||||||
177 | Py_XDECREF(self->memory_dict); | ||||||
178 | PyObject_Del(self); | ||||||
179 | } | ||||||
180 | |||||||
181 | |||||||
182 | PyTypeObject SuperLUGlobalType = { | ||||||
183 | PyVarObject_HEAD_INIT(NULL((void*)0), 0) | ||||||
184 | "_SuperLUGlobal", | ||||||
185 | sizeof(SuperLUGlobalObject), | ||||||
186 | 0, | ||||||
187 | (destructor)SuperLUGlobal_dealloc, /* tp_dealloc */ | ||||||
188 | 0, /* tp_print */ | ||||||
189 | 0, /* tp_getattr */ | ||||||
190 | 0, /* tp_setattr */ | ||||||
191 | 0, /* tp_compare / tp_reserved */ | ||||||
192 | 0, /* tp_repr */ | ||||||
193 | 0, /* tp_as_number */ | ||||||
194 | 0, /* tp_as_sequence */ | ||||||
195 | 0, /* tp_as_mapping */ | ||||||
196 | 0, /* tp_hash */ | ||||||
197 | 0, /* tp_call */ | ||||||
198 | 0, /* tp_str */ | ||||||
199 | 0, /* tp_getattro */ | ||||||
200 | 0, /* tp_setattro */ | ||||||
201 | 0, /* tp_as_buffer */ | ||||||
202 | Py_TPFLAGS_DEFAULT, /* tp_flags */ | ||||||
203 | NULL((void*)0), /* tp_doc */ | ||||||
204 | 0, /* tp_traverse */ | ||||||
205 | 0, /* tp_clear */ | ||||||
206 | 0, /* tp_richcompare */ | ||||||
207 | 0, /* tp_weaklistoffset */ | ||||||
208 | 0, /* tp_iter */ | ||||||
209 | 0, /* tp_iternext */ | ||||||
210 | 0, /* tp_methods */ | ||||||
211 | 0, /* tp_members */ | ||||||
212 | 0, /* tp_getset */ | ||||||
213 | 0, /* tp_base */ | ||||||
214 | 0, /* tp_dict */ | ||||||
215 | 0, /* tp_descr_get */ | ||||||
216 | 0, /* tp_descr_set */ | ||||||
217 | 0, /* tp_dictoffset */ | ||||||
218 | 0, /* tp_init */ | ||||||
219 | 0, /* tp_alloc */ | ||||||
220 | 0, /* tp_new */ | ||||||
221 | 0, /* tp_free */ | ||||||
222 | 0, /* tp_is_gc */ | ||||||
223 | 0, /* tp_bases */ | ||||||
224 | 0, /* tp_mro */ | ||||||
225 | 0, /* tp_cache */ | ||||||
226 | 0, /* tp_subclasses */ | ||||||
227 | 0, /* tp_weaklist */ | ||||||
228 | 0, /* tp_del */ | ||||||
229 | 0, /* tp_version_tag */ | ||||||
230 | }; | ||||||
231 | |||||||
232 | |||||||
233 | /* | ||||||
234 | * Stub for error handling; does nothing, as we don't want to spew debug output. | ||||||
235 | */ | ||||||
236 | |||||||
237 | int input_error(char *srname, int *info) | ||||||
238 | { | ||||||
239 | return 0; | ||||||
240 | } | ||||||
241 | |||||||
242 | /* | ||||||
243 | * Stubs for Harwell Subroutine Library functions that SuperLU tries to call. | ||||||
244 | */ | ||||||
245 | |||||||
246 | void mc64id_(int *a) | ||||||
247 | { | ||||||
248 | superlu_python_module_abort("chosen functionality not available"); | ||||||
249 | } | ||||||
250 | |||||||
251 | void mc64ad_(int *a, int *b, int *c, int d[], int e[], double f[], | ||||||
252 | int *g, int h[], int *i, int j[], int *k, double l[], | ||||||
253 | int m[], int n[]) | ||||||
254 | { | ||||||
255 | superlu_python_module_abort("chosen functionality not available"); | ||||||
256 | } |
1 | #ifndef _PyObject_New |
2 | struct _object; |
3 | typedef struct _object PyObject; |
4 | PyObject* clang_analyzer_PyObject_New_Reference(); |
5 | PyObject* _PyObject_New(PyTypeObject *type) { |
6 | return clang_analyzer_PyObject_New_Reference(); |
7 | } |
8 | #else |
9 | #warning "API _PyObject_New is defined as a macro." |
10 | #endif |