File: | /tmp/pyrefcon/scipy/scipy/sparse/linalg/dsolve/_superluobject.c |
Warning: | line 963, column 5 PyObject ownership leak with reference count of 1 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*-c-*- */ | |||
2 | /* | |||
3 | * _superlu object | |||
4 | * | |||
5 | * Python object representing SuperLU factorization + some utility functions. | |||
6 | */ | |||
7 | ||||
8 | #include <Python.h> | |||
9 | ||||
10 | #define NO_IMPORT_ARRAY | |||
11 | #define PY_ARRAY_UNIQUE_SYMBOL_scipy_sparse_superlu_ARRAY_API _scipy_sparse_superlu_ARRAY_API | |||
12 | ||||
13 | #include "_superluobject.h" | |||
14 | #include <ctype.h> | |||
15 | ||||
16 | ||||
17 | /*********************************************************************** | |||
18 | * SuperLUObject methods | |||
19 | */ | |||
20 | ||||
21 | static PyObject *SuperLU_solve(SuperLUObject * self, PyObject * args, | |||
22 | PyObject * kwds) | |||
23 | { | |||
24 | volatile PyArrayObject *b, *x = NULL((void*)0); | |||
25 | volatile SuperMatrix B = { 0 }; | |||
26 | volatile int itrans = 'N'; | |||
27 | volatile int info; | |||
28 | volatile trans_t trans; | |||
29 | volatile SuperLUStat_t stat = { 0 }; | |||
30 | static char *kwlist[] = { "rhs", "trans", NULL((void*)0) }; | |||
31 | volatile jmp_buf *jmpbuf_ptr; | |||
32 | SLU_BEGIN_THREADS_DEFvolatile PyThreadState *_save = ((void*)0); | |||
33 | ||||
34 | if (!CHECK_SLU_TYPE(self->type)(self->type == NPY_FLOAT || self->type == NPY_DOUBLE || self->type == NPY_CFLOAT || self->type == NPY_CDOUBLE)) { | |||
35 | PyErr_SetString(PyExc_ValueError, "unsupported data type"); | |||
36 | return NULL((void*)0); | |||
37 | } | |||
38 | ||||
39 | if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|C", kwlist, | |||
40 | &PyArray_Type(*(PyTypeObject *)_scipy_sparse_superlu_ARRAY_API[2]), &b, &itrans)) | |||
41 | return NULL((void*)0); | |||
42 | ||||
43 | /* solve transposed system: matrix was passed row-wise instead of | |||
44 | * column-wise */ | |||
45 | if (itrans == 'n' || itrans == 'N') | |||
46 | trans = NOTRANS; | |||
47 | else if (itrans == 't' || itrans == 'T') | |||
48 | trans = TRANS; | |||
49 | else if (itrans == 'h' || itrans == 'H') | |||
50 | trans = CONJ; | |||
51 | else { | |||
52 | PyErr_SetString(PyExc_ValueError, "trans must be N, T, or H"); | |||
53 | return NULL((void*)0); | |||
54 | } | |||
55 | ||||
56 | x = (PyArrayObject*)PyArray_FROMANY((*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) _scipy_sparse_superlu_ARRAY_API[69])((PyObject* )b, (*(PyArray_Descr * (*)(int)) _scipy_sparse_superlu_ARRAY_API [45])(self->type), 1, 2, (((0x0002 | 0x0020) & 0x0020) ? (0x0002 | 0x0020) | ((0x0001 | (0x0100 | 0x0400))) : (0x0002 | 0x0020)), ((void*)0)) | |||
57 | (PyObject*)b, self->type, 1, 2,(*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) _scipy_sparse_superlu_ARRAY_API[69])((PyObject* )b, (*(PyArray_Descr * (*)(int)) _scipy_sparse_superlu_ARRAY_API [45])(self->type), 1, 2, (((0x0002 | 0x0020) & 0x0020) ? (0x0002 | 0x0020) | ((0x0001 | (0x0100 | 0x0400))) : (0x0002 | 0x0020)), ((void*)0)) | |||
58 | NPY_ARRAY_F_CONTIGUOUS | NPY_ARRAY_ENSURECOPY)(*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) _scipy_sparse_superlu_ARRAY_API[69])((PyObject* )b, (*(PyArray_Descr * (*)(int)) _scipy_sparse_superlu_ARRAY_API [45])(self->type), 1, 2, (((0x0002 | 0x0020) & 0x0020) ? (0x0002 | 0x0020) | ((0x0001 | (0x0100 | 0x0400))) : (0x0002 | 0x0020)), ((void*)0)); | |||
59 | if (x == NULL((void*)0)) { | |||
60 | goto fail; | |||
61 | } | |||
62 | ||||
63 | if (PyArray_DIM((PyArrayObject*)x, 0) != self->n) { | |||
64 | PyErr_SetString(PyExc_ValueError, "b is of incompatible size"); | |||
65 | goto fail; | |||
66 | } | |||
67 | ||||
68 | if (DenseSuper_from_Numeric((SuperMatrix*)&B, (PyObject *)x)) | |||
69 | goto fail; | |||
70 | ||||
71 | jmpbuf_ptr = (volatile jmp_buf *)superlu_python_jmpbuf(); | |||
72 | if (setjmp(*(jmp_buf*)jmpbuf_ptr)_setjmp (*(jmp_buf*)jmpbuf_ptr)) { | |||
73 | goto fail; | |||
74 | } | |||
75 | ||||
76 | StatInit((SuperLUStat_t *)&stat); | |||
77 | ||||
78 | /* Solve the system, overwriting vector x. */ | |||
79 | jmpbuf_ptr = (volatile jmp_buf *)superlu_python_jmpbuf(); | |||
80 | SLU_BEGIN_THREADSdo { if (_save == ((void*)0)) _save = PyEval_SaveThread(); } while (0); | |||
81 | if (setjmp(*(jmp_buf*)jmpbuf_ptr)_setjmp (*(jmp_buf*)jmpbuf_ptr)) { | |||
82 | SLU_END_THREADSdo { if (_save) { PyEval_RestoreThread((PyThreadState*)_save) ; _save = ((void*)0);} } while (0); | |||
83 | goto fail; | |||
84 | } | |||
85 | gstrs(self->type, | |||
86 | trans, &self->L, &self->U, self->perm_c, self->perm_r, | |||
87 | (SuperMatrix *)&B, (SuperLUStat_t *)&stat, (int *)&info); | |||
88 | SLU_END_THREADSdo { if (_save) { PyEval_RestoreThread((PyThreadState*)_save) ; _save = ((void*)0);} } while (0); | |||
89 | ||||
90 | if (info) { | |||
91 | PyErr_SetString(PyExc_SystemError, | |||
92 | "gstrs was called with invalid arguments"); | |||
93 | goto fail; | |||
94 | } | |||
95 | ||||
96 | /* free memory */ | |||
97 | Destroy_SuperMatrix_Store((SuperMatrix *)&B); | |||
98 | StatFree((SuperLUStat_t *)&stat); | |||
99 | return (PyObject *) x; | |||
100 | ||||
101 | fail: | |||
102 | XDestroy_SuperMatrix_Store((SuperMatrix *)&B); | |||
103 | XStatFree((SuperLUStat_t *)&stat); | |||
104 | Py_XDECREF(x)_Py_XDECREF(((PyObject*)(x))); | |||
105 | return NULL((void*)0); | |||
106 | } | |||
107 | ||||
108 | /** table of object methods | |||
109 | */ | |||
110 | PyMethodDef SuperLU_methods[] = { | |||
111 | {"solve", (PyCFunction) SuperLU_solve, METH_VARARGS0x0001 | METH_KEYWORDS0x0002, NULL((void*)0)}, | |||
112 | {NULL((void*)0), NULL((void*)0)} /* sentinel */ | |||
113 | }; | |||
114 | ||||
115 | ||||
116 | /*********************************************************************** | |||
117 | * SuperLUType methods | |||
118 | */ | |||
119 | ||||
120 | static void SuperLU_dealloc(SuperLUObject * self) | |||
121 | { | |||
122 | Py_XDECREF(self->cached_U)_Py_XDECREF(((PyObject*)(self->cached_U))); | |||
123 | Py_XDECREF(self->cached_L)_Py_XDECREF(((PyObject*)(self->cached_L))); | |||
124 | Py_XDECREF(self->py_csc_construct_func)_Py_XDECREF(((PyObject*)(self->py_csc_construct_func))); | |||
125 | self->cached_U = NULL((void*)0); | |||
126 | self->cached_L = NULL((void*)0); | |||
127 | self->py_csc_construct_func = NULL((void*)0); | |||
128 | SUPERLU_FREE(self->perm_r)superlu_python_module_free(self->perm_r); | |||
129 | SUPERLU_FREE(self->perm_c)superlu_python_module_free(self->perm_c); | |||
130 | self->perm_r = NULL((void*)0); | |||
131 | self->perm_c = NULL((void*)0); | |||
132 | XDestroy_SuperNode_Matrix(&self->L); | |||
133 | XDestroy_CompCol_Matrix(&self->U); | |||
134 | PyObject_DelPyObject_Free(self); | |||
135 | } | |||
136 | ||||
137 | static PyObject *SuperLU_getter(PyObject *selfp, void *data) | |||
138 | { | |||
139 | SuperLUObject *self = (SuperLUObject *)selfp; | |||
140 | char *name = (char*)data; | |||
141 | ||||
142 | if (strcmp(name, "shape") == 0) { | |||
143 | return Py_BuildValue("(i,i)", self->m, self->n); | |||
144 | } | |||
145 | else if (strcmp(name, "nnz") == 0) | |||
146 | return Py_BuildValue("i", | |||
147 | ((SCformat *) self->L.Store)->nnz + | |||
148 | ((SCformat *) self->U.Store)->nnz); | |||
149 | else if (strcmp(name, "perm_r") == 0) { | |||
150 | PyObject *perm_r; | |||
151 | perm_r = PyArray_SimpleNewFromData((*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) _scipy_sparse_superlu_ARRAY_API [93])(&(*(PyTypeObject *)_scipy_sparse_superlu_ARRAY_API[ 2]), 1, (npy_intp *) (&self->n), NPY_INT, ((void*)0), ( void *) self->perm_r, 0, (0x0001 | (0x0100 | 0x0400)), ((void *)0)) | |||
152 | 1, (npy_intp *) (&self->n), NPY_INT,(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) _scipy_sparse_superlu_ARRAY_API [93])(&(*(PyTypeObject *)_scipy_sparse_superlu_ARRAY_API[ 2]), 1, (npy_intp *) (&self->n), NPY_INT, ((void*)0), ( void *) self->perm_r, 0, (0x0001 | (0x0100 | 0x0400)), ((void *)0)) | |||
153 | (void *) self->perm_r)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) _scipy_sparse_superlu_ARRAY_API [93])(&(*(PyTypeObject *)_scipy_sparse_superlu_ARRAY_API[ 2]), 1, (npy_intp *) (&self->n), NPY_INT, ((void*)0), ( void *) self->perm_r, 0, (0x0001 | (0x0100 | 0x0400)), ((void *)0)); | |||
154 | if (perm_r == NULL((void*)0)) { | |||
155 | return NULL((void*)0); | |||
156 | } | |||
157 | ||||
158 | /* For ref counting of the memory */ | |||
159 | PyArray_SetBaseObject(*(int (*)(PyArrayObject *, PyObject *)) _scipy_sparse_superlu_ARRAY_API [282])((PyArrayObject*)perm_r, (PyObject*)self); | |||
160 | Py_INCREF(self)_Py_INCREF(((PyObject*)(self))); | |||
161 | return perm_r; | |||
162 | } | |||
163 | else if (strcmp(name, "perm_c") == 0) { | |||
164 | PyObject *perm_c; | |||
165 | ||||
166 | perm_c = PyArray_SimpleNewFromData((*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) _scipy_sparse_superlu_ARRAY_API [93])(&(*(PyTypeObject *)_scipy_sparse_superlu_ARRAY_API[ 2]), 1, (npy_intp *) (&self->n), NPY_INT, ((void*)0), ( void *) self->perm_c, 0, (0x0001 | (0x0100 | 0x0400)), ((void *)0)) | |||
167 | 1, (npy_intp *) (&self->n), NPY_INT,(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) _scipy_sparse_superlu_ARRAY_API [93])(&(*(PyTypeObject *)_scipy_sparse_superlu_ARRAY_API[ 2]), 1, (npy_intp *) (&self->n), NPY_INT, ((void*)0), ( void *) self->perm_c, 0, (0x0001 | (0x0100 | 0x0400)), ((void *)0)) | |||
168 | (void *) self->perm_c)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) _scipy_sparse_superlu_ARRAY_API [93])(&(*(PyTypeObject *)_scipy_sparse_superlu_ARRAY_API[ 2]), 1, (npy_intp *) (&self->n), NPY_INT, ((void*)0), ( void *) self->perm_c, 0, (0x0001 | (0x0100 | 0x0400)), ((void *)0)); | |||
169 | if (perm_c == NULL((void*)0)) { | |||
170 | return NULL((void*)0); | |||
171 | } | |||
172 | ||||
173 | /* For ref counting of the memory */ | |||
174 | PyArray_SetBaseObject(*(int (*)(PyArrayObject *, PyObject *)) _scipy_sparse_superlu_ARRAY_API [282])((PyArrayObject*)perm_c, (PyObject*)self); | |||
175 | Py_INCREF(self)_Py_INCREF(((PyObject*)(self))); | |||
176 | return perm_c; | |||
177 | } | |||
178 | else if (strcmp(name, "U") == 0 || strcmp(name, "L") == 0) { | |||
179 | int ok; | |||
180 | if (self->cached_U == NULL((void*)0)) { | |||
181 | ok = LU_to_csc_matrix(&self->L, &self->U, | |||
182 | &self->cached_L, &self->cached_U, | |||
183 | self->py_csc_construct_func); | |||
184 | if (ok != 0) { | |||
185 | return NULL((void*)0); | |||
186 | } | |||
187 | } | |||
188 | if (strcmp(name, "U") == 0) { | |||
189 | Py_INCREF(self->cached_U)_Py_INCREF(((PyObject*)(self->cached_U))); | |||
190 | return self->cached_U; | |||
191 | } | |||
192 | else { | |||
193 | Py_INCREF(self->cached_L)_Py_INCREF(((PyObject*)(self->cached_L))); | |||
194 | return self->cached_L; | |||
195 | } | |||
196 | } | |||
197 | else { | |||
198 | PyErr_SetString(PyExc_RuntimeError, | |||
199 | "internal error (this is a bug)"); | |||
200 | return NULL((void*)0); | |||
201 | } | |||
202 | } | |||
203 | ||||
204 | ||||
205 | /*********************************************************************** | |||
206 | * SuperLUType structure | |||
207 | */ | |||
208 | ||||
209 | PyGetSetDef SuperLU_getset[] = { | |||
210 | {"shape", SuperLU_getter, (setter)NULL((void*)0), (char*)NULL((void*)0), (void*)"shape"}, | |||
211 | {"nnz", SuperLU_getter, (setter)NULL((void*)0), (char*)NULL((void*)0), (void*)"nnz"}, | |||
212 | {"perm_r", SuperLU_getter, (setter)NULL((void*)0), (char*)NULL((void*)0), (void*)"perm_r"}, | |||
213 | {"perm_c", SuperLU_getter, (setter)NULL((void*)0), (char*)NULL((void*)0), (void*)"perm_c"}, | |||
214 | {"U", SuperLU_getter, (setter)NULL((void*)0), (char*)NULL((void*)0), (void*)"U"}, | |||
215 | {"L", SuperLU_getter, (setter)NULL((void*)0), (char*)NULL((void*)0), (void*)"L"}, | |||
216 | NULL((void*)0) | |||
217 | }; | |||
218 | ||||
219 | ||||
220 | PyTypeObject SuperLUType = { | |||
221 | PyVarObject_HEAD_INIT(NULL, 0){ { 1, ((void*)0) }, 0 }, | |||
222 | "SuperLU", | |||
223 | sizeof(SuperLUObject), | |||
224 | 0, | |||
225 | (destructor) SuperLU_dealloc, /* tp_dealloc */ | |||
226 | 0, /* tp_print */ | |||
227 | 0, /* tp_getattr */ | |||
228 | 0, /* tp_setattr */ | |||
229 | 0, /* tp_compare / tp_reserved */ | |||
230 | 0, /* tp_repr */ | |||
231 | 0, /* tp_as_number */ | |||
232 | 0, /* tp_as_sequence */ | |||
233 | 0, /* tp_as_mapping */ | |||
234 | 0, /* tp_hash */ | |||
235 | 0, /* tp_call */ | |||
236 | 0, /* tp_str */ | |||
237 | 0, /* tp_getattro */ | |||
238 | 0, /* tp_setattro */ | |||
239 | 0, /* tp_as_buffer */ | |||
240 | Py_TPFLAGS_DEFAULT( 0 | (1UL << 18) | 0), /* tp_flags */ | |||
241 | NULL((void*)0), /* tp_doc */ | |||
242 | 0, /* tp_traverse */ | |||
243 | 0, /* tp_clear */ | |||
244 | 0, /* tp_richcompare */ | |||
245 | 0, /* tp_weaklistoffset */ | |||
246 | 0, /* tp_iter */ | |||
247 | 0, /* tp_iternext */ | |||
248 | SuperLU_methods, /* tp_methods */ | |||
249 | 0, /* tp_members */ | |||
250 | SuperLU_getset, /* tp_getset */ | |||
251 | 0, /* tp_base */ | |||
252 | 0, /* tp_dict */ | |||
253 | 0, /* tp_descr_get */ | |||
254 | 0, /* tp_descr_set */ | |||
255 | 0, /* tp_dictoffset */ | |||
256 | 0, /* tp_init */ | |||
257 | 0, /* tp_alloc */ | |||
258 | 0, /* tp_new */ | |||
259 | 0, /* tp_free */ | |||
260 | 0, /* tp_is_gc */ | |||
261 | 0, /* tp_bases */ | |||
262 | 0, /* tp_mro */ | |||
263 | 0, /* tp_cache */ | |||
264 | 0, /* tp_subclasses */ | |||
265 | 0, /* tp_weaklist */ | |||
266 | 0, /* tp_del */ | |||
267 | 0, /* tp_version_tag */ | |||
268 | }; | |||
269 | ||||
270 | ||||
271 | int DenseSuper_from_Numeric(SuperMatrix *X, PyObject *PyX) | |||
272 | { | |||
273 | volatile PyArrayObject *aX; | |||
274 | volatile int m, n, ldx, nd; | |||
275 | volatile jmp_buf *jmpbuf_ptr; | |||
276 | ||||
277 | if (!PyArray_Check(PyX)((((PyObject*)(PyX))->ob_type) == (&(*(PyTypeObject *) _scipy_sparse_superlu_ARRAY_API[2])) || PyType_IsSubtype((((PyObject *)(PyX))->ob_type), (&(*(PyTypeObject *)_scipy_sparse_superlu_ARRAY_API [2]))))) { | |||
278 | PyErr_SetString(PyExc_TypeError, | |||
279 | "argument is not an array."); | |||
280 | return -1; | |||
281 | } | |||
282 | ||||
283 | aX = (PyArrayObject*)PyX; | |||
284 | ||||
285 | if (!CHECK_SLU_TYPE(PyArray_TYPE((PyArrayObject*)aX))(PyArray_TYPE((PyArrayObject*)aX) == NPY_FLOAT || PyArray_TYPE ((PyArrayObject*)aX) == NPY_DOUBLE || PyArray_TYPE((PyArrayObject *)aX) == NPY_CFLOAT || PyArray_TYPE((PyArrayObject*)aX) == NPY_CDOUBLE )) { | |||
286 | PyErr_SetString(PyExc_ValueError, "unsupported array data type"); | |||
287 | return -1; | |||
288 | } | |||
289 | ||||
290 | if (!(PyArray_FLAGS((PyArrayObject*)aX) & NPY_ARRAY_F_CONTIGUOUS0x0002)) { | |||
291 | PyErr_SetString(PyExc_ValueError, "array is not fortran contiguous"); | |||
292 | return -1; | |||
293 | } | |||
294 | ||||
295 | nd = PyArray_NDIM((PyArrayObject*)aX); | |||
296 | ||||
297 | if (nd == 1) { | |||
298 | m = PyArray_DIM((PyArrayObject*)aX, 0); | |||
299 | n = 1; | |||
300 | ldx = m; | |||
301 | } | |||
302 | else if (nd == 2) { | |||
303 | m = PyArray_DIM((PyArrayObject*)aX, 0); | |||
304 | n = PyArray_DIM((PyArrayObject*)aX, 1); | |||
305 | ldx = m; | |||
306 | } | |||
307 | else { | |||
308 | PyErr_SetString(PyExc_ValueError, "wrong number of dimensions in array"); | |||
309 | return -1; | |||
310 | } | |||
311 | ||||
312 | jmpbuf_ptr = (volatile jmp_buf *)superlu_python_jmpbuf(); | |||
313 | if (setjmp(*(jmp_buf*)jmpbuf_ptr)_setjmp (*(jmp_buf*)jmpbuf_ptr)) { | |||
314 | return -1; | |||
315 | } | |||
316 | else { | |||
317 | Create_Dense_Matrix(PyArray_TYPE((PyArrayObject*)aX), X, m, n, | |||
318 | PyArray_DATA((PyArrayObject*)aX), ldx, SLU_DN, | |||
319 | NPY_TYPECODE_TO_SLU(PyArray_TYPE((PyArrayObject*)aX))( ((PyArray_TYPE((PyArrayObject*)aX)) == NPY_FLOAT) ? SLU_S : ((PyArray_TYPE((PyArrayObject*)aX)) == NPY_DOUBLE) ? SLU_D : ((PyArray_TYPE((PyArrayObject*)aX)) == NPY_CFLOAT) ? SLU_C : ((PyArray_TYPE((PyArrayObject*)aX)) == NPY_CDOUBLE) ? SLU_Z : -1), | |||
320 | SLU_GE); | |||
321 | } | |||
322 | return 0; | |||
323 | } | |||
324 | ||||
325 | /* Natively handles Compressed Sparse Row and CSC */ | |||
326 | ||||
327 | int NRFormat_from_spMatrix(SuperMatrix * A, int m, int n, int nnz, | |||
328 | PyArrayObject * nzvals, PyArrayObject * colind, | |||
329 | PyArrayObject * rowptr, int typenum) | |||
330 | { | |||
331 | volatile int ok = 0; | |||
332 | volatile jmp_buf *jmpbuf_ptr; | |||
333 | ||||
334 | ok = (PyArray_EquivTypenums(*(unsigned char (*)(int, int)) _scipy_sparse_superlu_ARRAY_API [191])(PyArray_TYPE(nzvals), typenum) && | |||
335 | PyArray_EquivTypenums(*(unsigned char (*)(int, int)) _scipy_sparse_superlu_ARRAY_API [191])(PyArray_TYPE(colind), NPY_INT) && | |||
336 | PyArray_EquivTypenums(*(unsigned char (*)(int, int)) _scipy_sparse_superlu_ARRAY_API [191])(PyArray_TYPE(rowptr), NPY_INT) && | |||
337 | PyArray_NDIM(nzvals) == 1 && | |||
338 | PyArray_NDIM(colind) == 1 && | |||
339 | PyArray_NDIM(rowptr) == 1 && | |||
340 | PyArray_IS_C_CONTIGUOUS(nzvals)PyArray_CHKFLAGS((nzvals), 0x0001) && | |||
341 | PyArray_IS_C_CONTIGUOUS(colind)PyArray_CHKFLAGS((colind), 0x0001) && | |||
342 | PyArray_IS_C_CONTIGUOUS(rowptr)PyArray_CHKFLAGS((rowptr), 0x0001) && | |||
343 | nnz <= PyArray_DIM(nzvals, 0) && | |||
344 | nnz <= PyArray_DIM(colind, 0) && | |||
345 | m+1 <= PyArray_DIM(rowptr, 0)); | |||
346 | if (!ok) { | |||
347 | PyErr_SetString(PyExc_ValueError, | |||
348 | "sparse matrix arrays must be 1-D C-contiguous and of proper " | |||
349 | "sizes and types"); | |||
350 | return -1; | |||
351 | } | |||
352 | ||||
353 | jmpbuf_ptr = (volatile jmp_buf *)superlu_python_jmpbuf(); | |||
354 | if (setjmp(*(jmp_buf*)jmpbuf_ptr)_setjmp (*(jmp_buf*)jmpbuf_ptr)) { | |||
355 | return -1; | |||
356 | } | |||
357 | else { | |||
358 | if (!CHECK_SLU_TYPE(PyArray_TYPE(nzvals))(PyArray_TYPE(nzvals) == NPY_FLOAT || PyArray_TYPE(nzvals) == NPY_DOUBLE || PyArray_TYPE(nzvals) == NPY_CFLOAT || PyArray_TYPE (nzvals) == NPY_CDOUBLE)) { | |||
359 | PyErr_SetString(PyExc_TypeError, "Invalid type for array."); | |||
360 | return -1; | |||
361 | } | |||
362 | Create_CompRow_Matrix(PyArray_TYPE(nzvals), | |||
363 | A, m, n, nnz, PyArray_DATA((PyArrayObject*)nzvals), | |||
364 | (int *) PyArray_DATA((PyArrayObject*)colind), | |||
365 | (int *) PyArray_DATA((PyArrayObject*)rowptr), | |||
366 | SLU_NR, | |||
367 | NPY_TYPECODE_TO_SLU(PyArray_TYPE((PyArrayObject*)nzvals))( ((PyArray_TYPE((PyArrayObject*)nzvals)) == NPY_FLOAT) ? SLU_S : ((PyArray_TYPE((PyArrayObject*)nzvals)) == NPY_DOUBLE) ? SLU_D : ((PyArray_TYPE((PyArrayObject*)nzvals)) == NPY_CFLOAT) ? SLU_C : ((PyArray_TYPE((PyArrayObject*)nzvals)) == NPY_CDOUBLE) ? SLU_Z : -1), | |||
368 | SLU_GE); | |||
369 | } | |||
370 | ||||
371 | return 0; | |||
372 | } | |||
373 | ||||
374 | int NCFormat_from_spMatrix(SuperMatrix * A, int m, int n, int nnz, | |||
375 | PyArrayObject * nzvals, PyArrayObject * rowind, | |||
376 | PyArrayObject * colptr, int typenum) | |||
377 | { | |||
378 | volatile int ok = 0; | |||
379 | volatile jmp_buf *jmpbuf_ptr; | |||
380 | ||||
381 | ok = (PyArray_EquivTypenums(*(unsigned char (*)(int, int)) _scipy_sparse_superlu_ARRAY_API [191])(PyArray_TYPE(nzvals), typenum) && | |||
382 | PyArray_EquivTypenums(*(unsigned char (*)(int, int)) _scipy_sparse_superlu_ARRAY_API [191])(PyArray_TYPE(rowind), NPY_INT) && | |||
383 | PyArray_EquivTypenums(*(unsigned char (*)(int, int)) _scipy_sparse_superlu_ARRAY_API [191])(PyArray_TYPE(colptr), NPY_INT) && | |||
384 | PyArray_NDIM(nzvals) == 1 && | |||
385 | PyArray_NDIM(rowind) == 1 && | |||
386 | PyArray_NDIM(colptr) == 1 && | |||
387 | PyArray_IS_C_CONTIGUOUS(nzvals)PyArray_CHKFLAGS((nzvals), 0x0001) && | |||
388 | PyArray_IS_C_CONTIGUOUS(rowind)PyArray_CHKFLAGS((rowind), 0x0001) && | |||
389 | PyArray_IS_C_CONTIGUOUS(colptr)PyArray_CHKFLAGS((colptr), 0x0001) && | |||
390 | nnz <= PyArray_DIM(nzvals, 0) && | |||
391 | nnz <= PyArray_DIM(rowind, 0) && | |||
392 | n+1 <= PyArray_DIM(colptr, 0)); | |||
393 | if (!ok) { | |||
394 | PyErr_SetString(PyExc_ValueError, | |||
395 | "sparse matrix arrays must be 1-D C-contiguous and of proper " | |||
396 | "sizes and types"); | |||
397 | return -1; | |||
398 | } | |||
399 | ||||
400 | jmpbuf_ptr = (volatile jmp_buf *)superlu_python_jmpbuf(); | |||
401 | if (setjmp(*(jmp_buf*)jmpbuf_ptr)_setjmp (*(jmp_buf*)jmpbuf_ptr)) { | |||
402 | return -1; | |||
403 | } | |||
404 | else { | |||
405 | if (!CHECK_SLU_TYPE(PyArray_TYPE(nzvals))(PyArray_TYPE(nzvals) == NPY_FLOAT || PyArray_TYPE(nzvals) == NPY_DOUBLE || PyArray_TYPE(nzvals) == NPY_CFLOAT || PyArray_TYPE (nzvals) == NPY_CDOUBLE)) { | |||
406 | PyErr_SetString(PyExc_TypeError, "Invalid type for array."); | |||
407 | return -1; | |||
408 | } | |||
409 | Create_CompCol_Matrix(PyArray_TYPE(nzvals), | |||
410 | A, m, n, nnz, PyArray_DATA(nzvals), | |||
411 | (int *) PyArray_DATA(rowind), (int *) PyArray_DATA(colptr), | |||
412 | SLU_NC, | |||
413 | NPY_TYPECODE_TO_SLU(PyArray_TYPE(nzvals))( ((PyArray_TYPE(nzvals)) == NPY_FLOAT) ? SLU_S : ((PyArray_TYPE (nzvals)) == NPY_DOUBLE) ? SLU_D : ((PyArray_TYPE(nzvals)) == NPY_CFLOAT) ? SLU_C : ((PyArray_TYPE(nzvals)) == NPY_CDOUBLE ) ? SLU_Z : -1), | |||
414 | SLU_GE); | |||
415 | } | |||
416 | ||||
417 | return 0; | |||
418 | } | |||
419 | ||||
420 | ||||
421 | /* | |||
422 | * Create Scipy sparse matrices out from Superlu LU decomposition. | |||
423 | */ | |||
424 | ||||
425 | static int LU_to_csc(SuperMatrix *L, SuperMatrix *U, | |||
426 | int *U_indices, int *U_indptr, char *U_data, | |||
427 | int *L_indices, int *L_indptr, char *L_data, | |||
428 | Dtype_t dtype); | |||
429 | ||||
430 | int LU_to_csc_matrix(SuperMatrix *L, SuperMatrix *U, | |||
431 | PyObject **L_csc, PyObject **U_csc, | |||
432 | PyObject *py_csc_construct_func) | |||
433 | { | |||
434 | SCformat *Lstore; | |||
435 | NCformat *Ustore; | |||
436 | PyObject *U_indices = NULL((void*)0), *U_indptr = NULL((void*)0), *U_data = NULL((void*)0); | |||
437 | PyObject *L_indices = NULL((void*)0), *L_indptr = NULL((void*)0), *L_data = NULL((void*)0); | |||
438 | PyObject *datatuple = NULL((void*)0), *shape = NULL((void*)0); | |||
439 | int result = -1, ok; | |||
440 | int type; | |||
441 | npy_intp dims[1]; | |||
442 | ||||
443 | *L_csc = NULL((void*)0); | |||
444 | *U_csc = NULL((void*)0); | |||
445 | ||||
446 | if (U->Stype != SLU_NC || L->Stype != SLU_SC || | |||
447 | U->Mtype != SLU_TRU || L->Mtype != SLU_TRLU || | |||
448 | L->nrow != U->nrow || L->ncol != L->nrow || | |||
449 | U->ncol != U->nrow || L->Dtype != U->Dtype) | |||
450 | { | |||
451 | PyErr_SetString(PyExc_RuntimeError, | |||
452 | "internal error: invalid Superlu matrix data"); | |||
453 | return -1; | |||
454 | } | |||
455 | ||||
456 | Ustore = (NCformat*)U->Store; | |||
457 | Lstore = (SCformat*)L->Store; | |||
458 | ||||
459 | type = SLU_TYPECODE_TO_NPY(L->Dtype)( ((L->Dtype) == SLU_S) ? NPY_FLOAT : ((L->Dtype) == SLU_D ) ? NPY_DOUBLE : ((L->Dtype) == SLU_C) ? NPY_CFLOAT : ((L-> Dtype) == SLU_Z) ? NPY_CDOUBLE : -1); | |||
460 | ||||
461 | /* Allocate output */ | |||
462 | #define CREATE_1D_ARRAY(name, type, size) \ | |||
463 | do { \ | |||
464 | dims[0] = size; \ | |||
465 | name = PyArray_EMPTY(1, dims, type, 0)(*(PyObject * (*)(int, npy_intp const *, PyArray_Descr *, int )) _scipy_sparse_superlu_ARRAY_API[184])(1, dims, (*(PyArray_Descr * (*)(int)) _scipy_sparse_superlu_ARRAY_API[45])(type), 0); \ | |||
466 | if (name == NULL((void*)0)) goto fail; \ | |||
467 | } while (0) | |||
468 | ||||
469 | CREATE_1D_ARRAY(L_indices, NPY_INT, Lstore->nnz); | |||
470 | CREATE_1D_ARRAY(L_indptr, NPY_INT, L->ncol + 1); | |||
471 | CREATE_1D_ARRAY(L_data, type, Lstore->nnz); | |||
472 | ||||
473 | CREATE_1D_ARRAY(U_indices, NPY_INT, Ustore->nnz); | |||
474 | CREATE_1D_ARRAY(U_indptr, NPY_INT, U->ncol + 1); | |||
475 | CREATE_1D_ARRAY(U_data, type, Ustore->nnz); | |||
476 | ||||
477 | #undef CREATE_1D_ARRAY | |||
478 | ||||
479 | /* Copy data over */ | |||
480 | ok = LU_to_csc( | |||
481 | L, U, | |||
482 | (int*)PyArray_DATA((PyArrayObject*)L_indices), | |||
483 | (int*)PyArray_DATA((PyArrayObject*)L_indptr), | |||
484 | (void*)PyArray_DATA((PyArrayObject*)L_data), | |||
485 | (int*)PyArray_DATA((PyArrayObject*)U_indices), | |||
486 | (int*)PyArray_DATA((PyArrayObject*)U_indptr), | |||
487 | (void*)PyArray_DATA((PyArrayObject*)U_data), | |||
488 | L->Dtype | |||
489 | ); | |||
490 | ||||
491 | if (ok != 0) { | |||
492 | goto fail; | |||
493 | } | |||
494 | ||||
495 | /* Create sparse matrices */ | |||
496 | shape = Py_BuildValue("ii", L->nrow, L->ncol); | |||
497 | if (shape == NULL((void*)0)) { | |||
498 | goto fail; | |||
499 | } | |||
500 | ||||
501 | datatuple = Py_BuildValue("OOO", L_data, L_indices, L_indptr); | |||
502 | if (datatuple == NULL((void*)0)) { | |||
503 | goto fail; | |||
504 | } | |||
505 | *L_csc = PyObject_CallFunction(py_csc_construct_func, | |||
506 | "OO", datatuple, shape); | |||
507 | if (*L_csc == NULL((void*)0)) { | |||
508 | goto fail; | |||
509 | } | |||
510 | ||||
511 | Py_DECREF(datatuple)_Py_DECREF(((PyObject*)(datatuple))); | |||
512 | datatuple = Py_BuildValue("OOO", U_data, U_indices, U_indptr); | |||
513 | if (datatuple == NULL((void*)0)) { | |||
514 | Py_DECREF(*L_csc)_Py_DECREF(((PyObject*)(*L_csc))); | |||
515 | *L_csc = NULL((void*)0); | |||
516 | goto fail; | |||
517 | } | |||
518 | *U_csc = PyObject_CallFunction(py_csc_construct_func, | |||
519 | "OO", datatuple, shape); | |||
520 | if (*U_csc == NULL((void*)0)) { | |||
521 | Py_DECREF(*L_csc)_Py_DECREF(((PyObject*)(*L_csc))); | |||
522 | *L_csc = NULL((void*)0); | |||
523 | goto fail; | |||
524 | } | |||
525 | ||||
526 | result = 0; | |||
527 | ||||
528 | fail: | |||
529 | Py_XDECREF(U_indices)_Py_XDECREF(((PyObject*)(U_indices))); | |||
530 | Py_XDECREF(U_indptr)_Py_XDECREF(((PyObject*)(U_indptr))); | |||
531 | Py_XDECREF(U_data)_Py_XDECREF(((PyObject*)(U_data))); | |||
532 | Py_XDECREF(L_indices)_Py_XDECREF(((PyObject*)(L_indices))); | |||
533 | Py_XDECREF(L_indptr)_Py_XDECREF(((PyObject*)(L_indptr))); | |||
534 | Py_XDECREF(L_data)_Py_XDECREF(((PyObject*)(L_data))); | |||
535 | Py_XDECREF(shape)_Py_XDECREF(((PyObject*)(shape))); | |||
536 | Py_XDECREF(datatuple)_Py_XDECREF(((PyObject*)(datatuple))); | |||
537 | ||||
538 | return result; | |||
539 | } | |||
540 | ||||
541 | ||||
542 | /* | |||
543 | * Convert SuperLU L and U matrices to CSC format. | |||
544 | * | |||
545 | * The LU decomposition U factor is partly stored in U and partly in the upper | |||
546 | * diagonal of L. The L matrix is stored in column-addressable rectangular | |||
547 | * superblock format. | |||
548 | * | |||
549 | * This routine is partly adapted from SuperLU MATLAB wrappers and the | |||
550 | * SuperLU Print_SuperNode_Matrix routine. | |||
551 | */ | |||
552 | static int | |||
553 | LU_to_csc(SuperMatrix *L, SuperMatrix *U, | |||
554 | int *L_rowind, int *L_colptr, char *L_data, | |||
555 | int *U_rowind, int *U_colptr, char *U_data, | |||
556 | Dtype_t dtype) | |||
557 | { | |||
558 | SCformat *Lstore; | |||
559 | NCformat *Ustore; | |||
560 | npy_intp elsize; | |||
561 | int isup, icol, icolstart, icolend, iptr, istart, iend; | |||
562 | char *src, *dst; | |||
563 | int U_nnz, L_nnz; | |||
564 | ||||
565 | Ustore = (NCformat*)U->Store; | |||
566 | Lstore = (SCformat*)L->Store; | |||
567 | ||||
568 | switch (dtype) { | |||
569 | case SLU_S: elsize = 4; break; | |||
570 | case SLU_D: elsize = 8; break; | |||
571 | case SLU_C: elsize = 8; break; | |||
572 | case SLU_Z: elsize = 16; break; | |||
573 | default: | |||
574 | /* shouldn't occur */ | |||
575 | PyErr_SetString(PyExc_ValueError, "unknown dtype"); | |||
576 | return -1; | |||
577 | } | |||
578 | ||||
579 | #define IS_ZERO(p)((dtype == SLU_S) ? (*(float*)(p) == 0) : ((dtype == SLU_D) ? (*(double*)(p) == 0) : ((dtype == SLU_C) ? (*(float*)(p) == 0 && *((float*)(p)+1) == 0) : (*(double*)(p) == 0 && *((double*)(p)+1) == 0)))) \ | |||
580 | ((dtype == SLU_S) ? (*(float*)(p) == 0) : \ | |||
581 | ((dtype == SLU_D) ? (*(double*)(p) == 0) : \ | |||
582 | ((dtype == SLU_C) ? (*(float*)(p) == 0 && *((float*)(p)+1) == 0) : \ | |||
583 | (*(double*)(p) == 0 && *((double*)(p)+1) == 0)))) | |||
584 | ||||
585 | U_colptr[0] = 0; | |||
586 | L_colptr[0] = 0; | |||
587 | U_nnz = 0; | |||
588 | L_nnz = 0; | |||
589 | ||||
590 | /* For each supernode */ | |||
591 | for (isup = 0; isup <= Lstore->nsuper; ++isup) { | |||
592 | icolstart = Lstore->sup_to_col[isup]; | |||
593 | icolend = Lstore->sup_to_col[isup+1]; | |||
594 | istart = Lstore->rowind_colptr[icolstart]; | |||
595 | iend = Lstore->rowind_colptr[icolstart+1]; | |||
596 | ||||
597 | /* For each column in supernode */ | |||
598 | for (icol = icolstart; icol < icolend; ++icol) { | |||
599 | ||||
600 | /* Process data in Ustore */ | |||
601 | for (iptr = Ustore->colptr[icol]; iptr < Ustore->colptr[icol+1]; ++iptr) { | |||
602 | src = (char*)Ustore->nzval + elsize * iptr; | |||
603 | if (!IS_ZERO(src)((dtype == SLU_S) ? (*(float*)(src) == 0) : ((dtype == SLU_D) ? (*(double*)(src) == 0) : ((dtype == SLU_C) ? (*(float*)(src ) == 0 && *((float*)(src)+1) == 0) : (*(double*)(src) == 0 && *((double*)(src)+1) == 0))))) { | |||
604 | if (U_nnz >= Ustore->nnz) | |||
605 | goto size_error; | |||
606 | U_rowind[U_nnz] = Ustore->rowind[iptr]; | |||
607 | /* "U_data[U_nnz] = Ustore->nzvals[iptr]" */ | |||
608 | dst = U_data + elsize * U_nnz; | |||
609 | memcpy(dst, src, elsize); | |||
610 | ++U_nnz; | |||
611 | } | |||
612 | } | |||
613 | ||||
614 | /* Process data in Lstore */ | |||
615 | src = (char*)Lstore->nzval + elsize * Lstore->nzval_colptr[icol]; | |||
616 | iptr = istart; | |||
617 | ||||
618 | /* Upper triangle part */ | |||
619 | for (; iptr < iend; ++iptr) { | |||
620 | if (Lstore->rowind[iptr] > icol) { | |||
621 | break; | |||
622 | } | |||
623 | if (!IS_ZERO(src)((dtype == SLU_S) ? (*(float*)(src) == 0) : ((dtype == SLU_D) ? (*(double*)(src) == 0) : ((dtype == SLU_C) ? (*(float*)(src ) == 0 && *((float*)(src)+1) == 0) : (*(double*)(src) == 0 && *((double*)(src)+1) == 0))))) { | |||
624 | if (U_nnz >= Ustore->nnz) | |||
625 | goto size_error; | |||
626 | U_rowind[U_nnz] = Lstore->rowind[iptr]; | |||
627 | dst = U_data + elsize * U_nnz; | |||
628 | memcpy(dst, src, elsize); | |||
629 | ++U_nnz; | |||
630 | } | |||
631 | src += elsize; | |||
632 | } | |||
633 | ||||
634 | /* Add unit diagonal in L */ | |||
635 | if (L_nnz >= Lstore->nnz) return -1; | |||
636 | dst = L_data + elsize * L_nnz; | |||
637 | switch (dtype) { | |||
638 | case SLU_S: *(float*)dst = 1.0; break; | |||
639 | case SLU_D: *(double*)dst = 1.0; break; | |||
640 | case SLU_C: *(float*)dst = 1.0; *((float*)dst+1) = 0.0; break; | |||
641 | case SLU_Z: *(double*)dst = 1.0; *((double*)dst+1) = 0.0; break; | |||
642 | } | |||
643 | L_rowind[L_nnz] = icol; | |||
644 | ++L_nnz; | |||
645 | ||||
646 | /* Lower triangle part */ | |||
647 | for (; iptr < iend; ++iptr) { | |||
648 | if (!IS_ZERO(src)((dtype == SLU_S) ? (*(float*)(src) == 0) : ((dtype == SLU_D) ? (*(double*)(src) == 0) : ((dtype == SLU_C) ? (*(float*)(src ) == 0 && *((float*)(src)+1) == 0) : (*(double*)(src) == 0 && *((double*)(src)+1) == 0))))) { | |||
649 | if (L_nnz >= Lstore->nnz) | |||
650 | goto size_error; | |||
651 | L_rowind[L_nnz] = Lstore->rowind[iptr]; | |||
652 | dst = L_data + elsize * L_nnz; | |||
653 | memcpy(dst, src, elsize); | |||
654 | ++L_nnz; | |||
655 | } | |||
656 | src += elsize; | |||
657 | } | |||
658 | ||||
659 | /* Record column pointers */ | |||
660 | U_colptr[icol+1] = U_nnz; | |||
661 | L_colptr[icol+1] = L_nnz; | |||
662 | } | |||
663 | } | |||
664 | ||||
665 | return 0; | |||
666 | ||||
667 | size_error: | |||
668 | PyErr_SetString(PyExc_RuntimeError, | |||
669 | "internal error: superlu matrixes have wrong nnz"); | |||
670 | return -1; | |||
671 | } | |||
672 | ||||
673 | ||||
674 | PyObject *newSuperLUObject(SuperMatrix * A, PyObject * option_dict, | |||
675 | int intype, int ilu, PyObject * py_csc_construct_func) | |||
676 | { | |||
677 | ||||
678 | /* A must be in SLU_NC format used by the factorization routine. */ | |||
679 | volatile SuperLUObject *self; | |||
680 | volatile SuperMatrix AC = { 0 }; /* Matrix postmultiplied by Pc */ | |||
681 | volatile int lwork = 0; | |||
682 | volatile int *etree = NULL((void*)0); | |||
683 | volatile int info; | |||
684 | volatile int n; | |||
685 | volatile superlu_options_t options; | |||
686 | volatile SuperLUStat_t stat = { 0 }; | |||
687 | volatile int panel_size, relax; | |||
688 | volatile GlobalLU_t Glu; | |||
689 | static volatile GlobalLU_t static_Glu; | |||
690 | volatile GlobalLU_t *Glu_ptr; | |||
691 | volatile jmp_buf *jmpbuf_ptr; | |||
692 | SLU_BEGIN_THREADS_DEFvolatile PyThreadState *_save = ((void*)0); | |||
693 | ||||
694 | n = A->ncol; | |||
695 | ||||
696 | if (!set_superlu_options_from_dict((superlu_options_t*)&options, ilu, option_dict, | |||
697 | (int*)&panel_size, (int*)&relax)) { | |||
698 | return NULL((void*)0); | |||
699 | } | |||
700 | ||||
701 | /* Create SLUObject */ | |||
702 | self = PyObject_New(SuperLUObject, &SuperLUType)( (SuperLUObject *) _PyObject_New(&SuperLUType) ); | |||
703 | if (self == NULL((void*)0)) | |||
704 | return PyErr_NoMemory(); | |||
705 | self->m = A->nrow; | |||
706 | self->n = n; | |||
707 | self->perm_r = NULL((void*)0); | |||
708 | self->perm_c = NULL((void*)0); | |||
709 | self->L.Store = NULL((void*)0); | |||
710 | self->U.Store = NULL((void*)0); | |||
711 | self->cached_U = NULL((void*)0); | |||
712 | self->cached_L = NULL((void*)0); | |||
713 | self->py_csc_construct_func = NULL((void*)0); | |||
714 | self->type = intype; | |||
715 | ||||
716 | jmpbuf_ptr = (volatile jmp_buf *)superlu_python_jmpbuf(); | |||
717 | if (setjmp(*(jmp_buf*)jmpbuf_ptr)_setjmp (*(jmp_buf*)jmpbuf_ptr)) { | |||
718 | goto fail; | |||
719 | } | |||
720 | ||||
721 | /* Calculate and apply minimum degree ordering */ | |||
722 | etree = intMalloc(n); | |||
723 | self->perm_r = intMalloc(n); | |||
724 | self->perm_c = intMalloc(n); | |||
725 | StatInit((SuperLUStat_t *)&stat); | |||
726 | ||||
727 | /* calc column permutation */ | |||
728 | get_perm_c(options.ColPerm, A, self->perm_c); | |||
729 | ||||
730 | /* apply column permutation */ | |||
731 | sp_preorder((superlu_options_t*)&options, A, self->perm_c, (int*)etree, | |||
732 | (SuperMatrix*)&AC); | |||
733 | ||||
734 | /* Perform factorization */ | |||
735 | if (!CHECK_SLU_TYPE(SLU_TYPECODE_TO_NPY(A->Dtype))(( ((A->Dtype) == SLU_S) ? NPY_FLOAT : ((A->Dtype) == SLU_D ) ? NPY_DOUBLE : ((A->Dtype) == SLU_C) ? NPY_CFLOAT : ((A-> Dtype) == SLU_Z) ? NPY_CDOUBLE : -1) == NPY_FLOAT || ( ((A-> Dtype) == SLU_S) ? NPY_FLOAT : ((A->Dtype) == SLU_D) ? NPY_DOUBLE : ((A->Dtype) == SLU_C) ? NPY_CFLOAT : ((A->Dtype) == SLU_Z ) ? NPY_CDOUBLE : -1) == NPY_DOUBLE || ( ((A->Dtype) == SLU_S ) ? NPY_FLOAT : ((A->Dtype) == SLU_D) ? NPY_DOUBLE : ((A-> Dtype) == SLU_C) ? NPY_CFLOAT : ((A->Dtype) == SLU_Z) ? NPY_CDOUBLE : -1) == NPY_CFLOAT || ( ((A->Dtype) == SLU_S) ? NPY_FLOAT : ((A->Dtype) == SLU_D) ? NPY_DOUBLE : ((A->Dtype) == SLU_C ) ? NPY_CFLOAT : ((A->Dtype) == SLU_Z) ? NPY_CDOUBLE : -1) == NPY_CDOUBLE)) { | |||
736 | PyErr_SetString(PyExc_ValueError, "Invalid type in SuperMatrix."); | |||
737 | goto fail; | |||
738 | } | |||
739 | ||||
740 | if (options.Fact == SamePattern || options.Fact == SamePattern_SameRowPerm) { | |||
741 | /* XXX: not nice, a better new API should be introduced for this */ | |||
742 | Glu_ptr = &static_Glu; | |||
743 | } | |||
744 | else { | |||
745 | Glu_ptr = &Glu; | |||
746 | jmpbuf_ptr = (volatile jmp_buf *)superlu_python_jmpbuf(); | |||
747 | SLU_BEGIN_THREADSdo { if (_save == ((void*)0)) _save = PyEval_SaveThread(); } while (0); | |||
748 | if (setjmp(*(jmp_buf*)jmpbuf_ptr)_setjmp (*(jmp_buf*)jmpbuf_ptr)) { | |||
749 | SLU_END_THREADSdo { if (_save) { PyEval_RestoreThread((PyThreadState*)_save) ; _save = ((void*)0);} } while (0); | |||
750 | goto fail; | |||
751 | } | |||
752 | } | |||
753 | ||||
754 | if (ilu) { | |||
755 | gsitrf(SLU_TYPECODE_TO_NPY(A->Dtype)( ((A->Dtype) == SLU_S) ? NPY_FLOAT : ((A->Dtype) == SLU_D ) ? NPY_DOUBLE : ((A->Dtype) == SLU_C) ? NPY_CFLOAT : ((A-> Dtype) == SLU_Z) ? NPY_CDOUBLE : -1), | |||
756 | (superlu_options_t*)&options, (SuperMatrix*)&AC, relax, panel_size, | |||
757 | (int*)etree, NULL((void*)0), lwork, self->perm_c, self->perm_r, | |||
758 | (SuperMatrix*)&self->L, (SuperMatrix*)&self->U, (GlobalLU_t*)Glu_ptr, | |||
759 | (SuperLUStat_t*)&stat, (int*)&info); | |||
760 | } | |||
761 | else { | |||
762 | gstrf(SLU_TYPECODE_TO_NPY(A->Dtype)( ((A->Dtype) == SLU_S) ? NPY_FLOAT : ((A->Dtype) == SLU_D ) ? NPY_DOUBLE : ((A->Dtype) == SLU_C) ? NPY_CFLOAT : ((A-> Dtype) == SLU_Z) ? NPY_CDOUBLE : -1), | |||
763 | (superlu_options_t*)&options, (SuperMatrix*)&AC, relax, panel_size, | |||
764 | (int*)etree, NULL((void*)0), lwork, self->perm_c, self->perm_r, | |||
765 | (SuperMatrix*)&self->L, (SuperMatrix*)&self->U, (GlobalLU_t*)Glu_ptr, | |||
766 | (SuperLUStat_t*)&stat, (int*)&info); | |||
767 | } | |||
768 | ||||
769 | SLU_END_THREADSdo { if (_save) { PyEval_RestoreThread((PyThreadState*)_save) ; _save = ((void*)0);} } while (0); | |||
770 | ||||
771 | if (info) { | |||
772 | if (info < 0) | |||
773 | PyErr_SetString(PyExc_SystemError, | |||
774 | "gstrf was called with invalid arguments"); | |||
775 | else { | |||
776 | if (info <= n) | |||
777 | PyErr_SetString(PyExc_RuntimeError, | |||
778 | "Factor is exactly singular"); | |||
779 | else | |||
780 | PyErr_NoMemory(); | |||
781 | } | |||
782 | goto fail; | |||
783 | } | |||
784 | ||||
785 | Py_INCREF(py_csc_construct_func)_Py_INCREF(((PyObject*)(py_csc_construct_func))); | |||
786 | self->py_csc_construct_func = py_csc_construct_func; | |||
787 | ||||
788 | /* free memory */ | |||
789 | SUPERLU_FREE((void*)etree)superlu_python_module_free((void*)etree); | |||
790 | Destroy_CompCol_Permuted((SuperMatrix*)&AC); | |||
791 | StatFree((SuperLUStat_t*)&stat); | |||
792 | ||||
793 | return (PyObject *) self; | |||
794 | ||||
795 | fail: | |||
796 | SUPERLU_FREE((void*)etree)superlu_python_module_free((void*)etree); | |||
797 | XDestroy_CompCol_Permuted((SuperMatrix*)&AC); | |||
798 | XStatFree((SuperLUStat_t*)&stat); | |||
799 | Py_DECREF(self)_Py_DECREF(((PyObject*)(self))); | |||
800 | return NULL((void*)0); | |||
801 | } | |||
802 | ||||
803 | ||||
804 | /*********************************************************************** | |||
805 | * Preparing superlu_options_t | |||
806 | */ | |||
807 | ||||
808 | #define ENUM_CHECK_INITlong i = -1; char *s = ""; PyObject *tmpobj = ((void*)0); if ( input == (&_Py_NoneStruct)) return 1; if (((((((PyObject* )(input))->ob_type))->tp_flags & ((1UL << 27) )) != 0)) { s = (((void) (0)), (((PyBytesObject *)(input))-> ob_sval)); } else if (((((((PyObject*)(input))->ob_type))-> tp_flags & ((1UL << 28))) != 0)) { tmpobj = PyUnicode_AsASCIIString (input); if (tmpobj == ((void*)0)) return 0; s = (((void) (0) ), (((PyBytesObject *)(tmpobj))->ob_sval)); } else if (((( (((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { i = PyLong_AsLong(input); } \ | |||
809 | long i = -1; \ | |||
810 | char *s = ""; \ | |||
811 | PyObject *tmpobj = NULL((void*)0); \ | |||
812 | if (input == Py_None(&_Py_NoneStruct)) return 1; \ | |||
813 | if (PyBytes_Check(input)((((((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 27))) != 0)) { \ | |||
814 | s = PyBytes_AS_STRING(input)(((void) (0)), (((PyBytesObject *)(input))->ob_sval)); \ | |||
815 | } \ | |||
816 | else if (PyUnicode_Check(input)((((((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { \ | |||
817 | tmpobj = PyUnicode_AsASCIIString(input);\ | |||
818 | if (tmpobj == NULL((void*)0)) return 0; \ | |||
819 | s = PyBytes_AS_STRING(tmpobj)(((void) (0)), (((PyBytesObject *)(tmpobj))->ob_sval)); \ | |||
820 | } \ | |||
821 | else if (PyLong_Check(input)((((((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { \ | |||
822 | i = PyLong_AsLong(input); \ | |||
823 | } | |||
824 | ||||
825 | #define ENUM_CHECK_FINISH(message)_Py_XDECREF(((PyObject*)(tmpobj))); PyErr_SetString(PyExc_ValueError , message); return 0; \ | |||
826 | Py_XDECREF(tmpobj)_Py_XDECREF(((PyObject*)(tmpobj))); \ | |||
827 | PyErr_SetString(PyExc_ValueError, message); \ | |||
828 | return 0; | |||
829 | ||||
830 | #define ENUM_CHECK_NAME(name, sname)if (my_strxcmp(s, sname) == 0 || i == (long)name) { *value = name ; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; } \ | |||
831 | if (my_strxcmp(s, sname) == 0 || i == (long)name) { \ | |||
832 | *value = name; \ | |||
833 | Py_XDECREF(tmpobj)_Py_XDECREF(((PyObject*)(tmpobj))); \ | |||
834 | return 1; \ | |||
835 | } | |||
836 | ||||
837 | #define ENUM_CHECK(name)if (my_strxcmp(s, "name") == 0 || i == (long)name) { *value = name; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; } ENUM_CHECK_NAME(name, #name)if (my_strxcmp(s, #name) == 0 || i == (long)name) { *value = name ; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; } | |||
838 | ||||
839 | /* | |||
840 | * Compare strings ignoring case, underscores and whitespace | |||
841 | */ | |||
842 | static int my_strxcmp(const char *a, const char *b) | |||
843 | { | |||
844 | int c; | |||
845 | ||||
846 | while (*a != '\0' && *b != '\0') { | |||
847 | while (*a == '_' || isspace(*a)((*__ctype_b_loc ())[(int) ((*a))] & (unsigned short int) _ISspace)) | |||
848 | ++a; | |||
849 | while (*b == '_' || isspace(*b)((*__ctype_b_loc ())[(int) ((*b))] & (unsigned short int) _ISspace)) | |||
850 | ++b; | |||
851 | c = (int) tolower(*a)(__extension__ ({ int __res; if (sizeof (*a) > 1) { if (__builtin_constant_p (*a)) { int __c = (*a); __res = __c < -128 || __c > 255 ? __c : (*__ctype_tolower_loc ())[__c]; } else __res = tolower (*a); } else __res = (*__ctype_tolower_loc ())[(int) (*a)]; __res ; })) - (int) tolower(*b)(__extension__ ({ int __res; if (sizeof (*b) > 1) { if (__builtin_constant_p (*b)) { int __c = (*b); __res = __c < -128 || __c > 255 ? __c : (*__ctype_tolower_loc ())[__c]; } else __res = tolower (*b); } else __res = (*__ctype_tolower_loc ())[(int) (*b)]; __res ; })); | |||
852 | if (c != 0) { | |||
853 | return c; | |||
854 | } | |||
855 | ++a; | |||
856 | ++b; | |||
857 | } | |||
858 | return (int) tolower(*a)(__extension__ ({ int __res; if (sizeof (*a) > 1) { if (__builtin_constant_p (*a)) { int __c = (*a); __res = __c < -128 || __c > 255 ? __c : (*__ctype_tolower_loc ())[__c]; } else __res = tolower (*a); } else __res = (*__ctype_tolower_loc ())[(int) (*a)]; __res ; })) - (int) tolower(*b)(__extension__ ({ int __res; if (sizeof (*b) > 1) { if (__builtin_constant_p (*b)) { int __c = (*b); __res = __c < -128 || __c > 255 ? __c : (*__ctype_tolower_loc ())[__c]; } else __res = tolower (*b); } else __res = (*__ctype_tolower_loc ())[(int) (*b)]; __res ; })); | |||
859 | } | |||
860 | ||||
861 | static int yes_no_cvt(PyObject * input, yes_no_t * value) | |||
862 | { | |||
863 | if (input == Py_None(&_Py_NoneStruct)) { | |||
864 | return 1; | |||
865 | } | |||
866 | else if (input == Py_True((PyObject *) &_Py_TrueStruct)) { | |||
867 | *value = YES; | |||
868 | } | |||
869 | else if (input == Py_False((PyObject *) &_Py_FalseStruct)) { | |||
870 | *value = NO; | |||
871 | } | |||
872 | else { | |||
873 | PyErr_SetString(PyExc_ValueError, "value not a boolean"); | |||
874 | return 0; | |||
875 | } | |||
876 | return 1; | |||
877 | } | |||
878 | ||||
879 | static int fact_cvt(PyObject * input, fact_t * value) | |||
880 | { | |||
881 | ENUM_CHECK_INITlong i = -1; char *s = ""; PyObject *tmpobj = ((void*)0); if ( input == (&_Py_NoneStruct)) return 1; if (((((((PyObject* )(input))->ob_type))->tp_flags & ((1UL << 27) )) != 0)) { s = (((void) (0)), (((PyBytesObject *)(input))-> ob_sval)); } else if (((((((PyObject*)(input))->ob_type))-> tp_flags & ((1UL << 28))) != 0)) { tmpobj = PyUnicode_AsASCIIString (input); if (tmpobj == ((void*)0)) return 0; s = (((void) (0) ), (((PyBytesObject *)(tmpobj))->ob_sval)); } else if (((( (((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { i = PyLong_AsLong(input); }; | |||
882 | ENUM_CHECK(DOFACT)if (my_strxcmp(s, "DOFACT") == 0 || i == (long)DOFACT) { *value = DOFACT; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
883 | ENUM_CHECK(SamePattern)if (my_strxcmp(s, "SamePattern") == 0 || i == (long)SamePattern ) { *value = SamePattern; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
884 | ENUM_CHECK(SamePattern_SameRowPerm)if (my_strxcmp(s, "SamePattern_SameRowPerm") == 0 || i == (long )SamePattern_SameRowPerm) { *value = SamePattern_SameRowPerm; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
885 | ENUM_CHECK(FACTORED)if (my_strxcmp(s, "FACTORED") == 0 || i == (long)FACTORED) { * value = FACTORED; _Py_XDECREF(((PyObject*)(tmpobj))); return 1 ; }; | |||
886 | ENUM_CHECK_FINISH("invalid value for 'Fact' parameter")_Py_XDECREF(((PyObject*)(tmpobj))); PyErr_SetString(PyExc_ValueError , "invalid value for 'Fact' parameter"); return 0;; | |||
887 | } | |||
888 | ||||
889 | static int rowperm_cvt(PyObject * input, rowperm_t * value) | |||
890 | { | |||
891 | ENUM_CHECK_INITlong i = -1; char *s = ""; PyObject *tmpobj = ((void*)0); if ( input == (&_Py_NoneStruct)) return 1; if (((((((PyObject* )(input))->ob_type))->tp_flags & ((1UL << 27) )) != 0)) { s = (((void) (0)), (((PyBytesObject *)(input))-> ob_sval)); } else if (((((((PyObject*)(input))->ob_type))-> tp_flags & ((1UL << 28))) != 0)) { tmpobj = PyUnicode_AsASCIIString (input); if (tmpobj == ((void*)0)) return 0; s = (((void) (0) ), (((PyBytesObject *)(tmpobj))->ob_sval)); } else if (((( (((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { i = PyLong_AsLong(input); }; | |||
892 | ENUM_CHECK(NOROWPERM)if (my_strxcmp(s, "NOROWPERM") == 0 || i == (long)NOROWPERM) { *value = NOROWPERM; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
893 | ENUM_CHECK(MY_PERMR)if (my_strxcmp(s, "MY_PERMR") == 0 || i == (long)MY_PERMR) { * value = MY_PERMR; _Py_XDECREF(((PyObject*)(tmpobj))); return 1 ; }; | |||
894 | ENUM_CHECK_FINISH("invalid value for 'RowPerm' parameter")_Py_XDECREF(((PyObject*)(tmpobj))); PyErr_SetString(PyExc_ValueError , "invalid value for 'RowPerm' parameter"); return 0;; | |||
895 | } | |||
896 | ||||
897 | static int colperm_cvt(PyObject * input, colperm_t * value) | |||
898 | { | |||
899 | ENUM_CHECK_INITlong i = -1; char *s = ""; PyObject *tmpobj = ((void*)0); if ( input == (&_Py_NoneStruct)) return 1; if (((((((PyObject* )(input))->ob_type))->tp_flags & ((1UL << 27) )) != 0)) { s = (((void) (0)), (((PyBytesObject *)(input))-> ob_sval)); } else if (((((((PyObject*)(input))->ob_type))-> tp_flags & ((1UL << 28))) != 0)) { tmpobj = PyUnicode_AsASCIIString (input); if (tmpobj == ((void*)0)) return 0; s = (((void) (0) ), (((PyBytesObject *)(tmpobj))->ob_sval)); } else if (((( (((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { i = PyLong_AsLong(input); }; | |||
900 | ENUM_CHECK(NATURAL)if (my_strxcmp(s, "NATURAL") == 0 || i == (long)NATURAL) { *value = NATURAL; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
901 | ENUM_CHECK(MMD_ATA)if (my_strxcmp(s, "MMD_ATA") == 0 || i == (long)MMD_ATA) { *value = MMD_ATA; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
902 | ENUM_CHECK(MMD_AT_PLUS_A)if (my_strxcmp(s, "MMD_AT_PLUS_A") == 0 || i == (long)MMD_AT_PLUS_A ) { *value = MMD_AT_PLUS_A; _Py_XDECREF(((PyObject*)(tmpobj)) ); return 1; }; | |||
903 | ENUM_CHECK(COLAMD)if (my_strxcmp(s, "COLAMD") == 0 || i == (long)COLAMD) { *value = COLAMD; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
904 | ENUM_CHECK(MY_PERMC)if (my_strxcmp(s, "MY_PERMC") == 0 || i == (long)MY_PERMC) { * value = MY_PERMC; _Py_XDECREF(((PyObject*)(tmpobj))); return 1 ; }; | |||
905 | ENUM_CHECK_FINISH("invalid value for 'ColPerm' parameter")_Py_XDECREF(((PyObject*)(tmpobj))); PyErr_SetString(PyExc_ValueError , "invalid value for 'ColPerm' parameter"); return 0;; | |||
906 | } | |||
907 | ||||
908 | static int trans_cvt(PyObject * input, trans_t * value) | |||
909 | { | |||
910 | ENUM_CHECK_INITlong i = -1; char *s = ""; PyObject *tmpobj = ((void*)0); if ( input == (&_Py_NoneStruct)) return 1; if (((((((PyObject* )(input))->ob_type))->tp_flags & ((1UL << 27) )) != 0)) { s = (((void) (0)), (((PyBytesObject *)(input))-> ob_sval)); } else if (((((((PyObject*)(input))->ob_type))-> tp_flags & ((1UL << 28))) != 0)) { tmpobj = PyUnicode_AsASCIIString (input); if (tmpobj == ((void*)0)) return 0; s = (((void) (0) ), (((PyBytesObject *)(tmpobj))->ob_sval)); } else if (((( (((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { i = PyLong_AsLong(input); }; | |||
911 | ENUM_CHECK(NOTRANS)if (my_strxcmp(s, "NOTRANS") == 0 || i == (long)NOTRANS) { *value = NOTRANS; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
912 | ENUM_CHECK(TRANS)if (my_strxcmp(s, "TRANS") == 0 || i == (long)TRANS) { *value = TRANS; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
913 | ENUM_CHECK(CONJ)if (my_strxcmp(s, "CONJ") == 0 || i == (long)CONJ) { *value = CONJ; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
914 | if (my_strxcmp(s, "N") == 0) { | |||
915 | *value = NOTRANS; | |||
916 | return 1; | |||
917 | } | |||
918 | if (my_strxcmp(s, "T") == 0) { | |||
919 | *value = TRANS; | |||
920 | return 1; | |||
921 | } | |||
922 | if (my_strxcmp(s, "H") == 0) { | |||
923 | *value = CONJ; | |||
924 | return 1; | |||
925 | } | |||
926 | ENUM_CHECK_FINISH("invalid value for 'Trans' parameter")_Py_XDECREF(((PyObject*)(tmpobj))); PyErr_SetString(PyExc_ValueError , "invalid value for 'Trans' parameter"); return 0;; | |||
927 | } | |||
928 | ||||
929 | static int iterrefine_cvt(PyObject * input, IterRefine_t * value) | |||
930 | { | |||
931 | ENUM_CHECK_INITlong i = -1; char *s = ""; PyObject *tmpobj = ((void*)0); if ( input == (&_Py_NoneStruct)) return 1; if (((((((PyObject* )(input))->ob_type))->tp_flags & ((1UL << 27) )) != 0)) { s = (((void) (0)), (((PyBytesObject *)(input))-> ob_sval)); } else if (((((((PyObject*)(input))->ob_type))-> tp_flags & ((1UL << 28))) != 0)) { tmpobj = PyUnicode_AsASCIIString (input); if (tmpobj == ((void*)0)) return 0; s = (((void) (0) ), (((PyBytesObject *)(tmpobj))->ob_sval)); } else if (((( (((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { i = PyLong_AsLong(input); }; | |||
932 | ENUM_CHECK(NOREFINE)if (my_strxcmp(s, "NOREFINE") == 0 || i == (long)NOREFINE) { * value = NOREFINE; _Py_XDECREF(((PyObject*)(tmpobj))); return 1 ; }; | |||
933 | ENUM_CHECK(SLU_SINGLE)if (my_strxcmp(s, "SLU_SINGLE") == 0 || i == (long)SLU_SINGLE ) { *value = SLU_SINGLE; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
934 | ENUM_CHECK_NAME(SLU_SINGLE, "SINGLE")if (my_strxcmp(s, "SINGLE") == 0 || i == (long)SLU_SINGLE) { * value = SLU_SINGLE; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
935 | ENUM_CHECK(SLU_DOUBLE)if (my_strxcmp(s, "SLU_DOUBLE") == 0 || i == (long)SLU_DOUBLE ) { *value = SLU_DOUBLE; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
936 | ENUM_CHECK_NAME(SLU_DOUBLE, "DOUBLE")if (my_strxcmp(s, "DOUBLE") == 0 || i == (long)SLU_DOUBLE) { * value = SLU_DOUBLE; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
937 | ENUM_CHECK(SLU_EXTRA)if (my_strxcmp(s, "SLU_EXTRA") == 0 || i == (long)SLU_EXTRA) { *value = SLU_EXTRA; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
938 | ENUM_CHECK_NAME(SLU_EXTRA, "EXTRA")if (my_strxcmp(s, "EXTRA") == 0 || i == (long)SLU_EXTRA) { *value = SLU_EXTRA; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
939 | ENUM_CHECK_FINISH("invalid value for 'IterRefine' parameter")_Py_XDECREF(((PyObject*)(tmpobj))); PyErr_SetString(PyExc_ValueError , "invalid value for 'IterRefine' parameter"); return 0;; | |||
940 | } | |||
941 | ||||
942 | static int norm_cvt(PyObject * input, norm_t * value) | |||
943 | { | |||
944 | ENUM_CHECK_INITlong i = -1; char *s = ""; PyObject *tmpobj = ((void*)0); if ( input == (&_Py_NoneStruct)) return 1; if (((((((PyObject* )(input))->ob_type))->tp_flags & ((1UL << 27) )) != 0)) { s = (((void) (0)), (((PyBytesObject *)(input))-> ob_sval)); } else if (((((((PyObject*)(input))->ob_type))-> tp_flags & ((1UL << 28))) != 0)) { tmpobj = PyUnicode_AsASCIIString (input); if (tmpobj == ((void*)0)) return 0; s = (((void) (0) ), (((PyBytesObject *)(tmpobj))->ob_sval)); } else if (((( (((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { i = PyLong_AsLong(input); }; | |||
945 | ENUM_CHECK(ONE_NORM)if (my_strxcmp(s, "ONE_NORM") == 0 || i == (long)ONE_NORM) { * value = ONE_NORM; _Py_XDECREF(((PyObject*)(tmpobj))); return 1 ; }; | |||
946 | ENUM_CHECK(TWO_NORM)if (my_strxcmp(s, "TWO_NORM") == 0 || i == (long)TWO_NORM) { * value = TWO_NORM; _Py_XDECREF(((PyObject*)(tmpobj))); return 1 ; }; | |||
947 | ENUM_CHECK(INF_NORM)if (my_strxcmp(s, "INF_NORM") == 0 || i == (long)INF_NORM) { * value = INF_NORM; _Py_XDECREF(((PyObject*)(tmpobj))); return 1 ; }; | |||
948 | ENUM_CHECK_FINISH("invalid value for 'ILU_Norm' parameter")_Py_XDECREF(((PyObject*)(tmpobj))); PyErr_SetString(PyExc_ValueError , "invalid value for 'ILU_Norm' parameter"); return 0;; | |||
949 | } | |||
950 | ||||
951 | static int milu_cvt(PyObject * input, milu_t * value) | |||
952 | { | |||
953 | ENUM_CHECK_INITlong i = -1; char *s = ""; PyObject *tmpobj = ((void*)0); if ( input == (&_Py_NoneStruct)) return 1; if (((((((PyObject* )(input))->ob_type))->tp_flags & ((1UL << 27) )) != 0)) { s = (((void) (0)), (((PyBytesObject *)(input))-> ob_sval)); } else if (((((((PyObject*)(input))->ob_type))-> tp_flags & ((1UL << 28))) != 0)) { tmpobj = PyUnicode_AsASCIIString (input); if (tmpobj == ((void*)0)) return 0; s = (((void) (0) ), (((PyBytesObject *)(tmpobj))->ob_sval)); } else if (((( (((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { i = PyLong_AsLong(input); }; | |||
954 | ENUM_CHECK(SILU)if (my_strxcmp(s, "SILU") == 0 || i == (long)SILU) { *value = SILU; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
955 | ENUM_CHECK(SMILU_1)if (my_strxcmp(s, "SMILU_1") == 0 || i == (long)SMILU_1) { *value = SMILU_1; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
956 | ENUM_CHECK(SMILU_2)if (my_strxcmp(s, "SMILU_2") == 0 || i == (long)SMILU_2) { *value = SMILU_2; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
957 | ENUM_CHECK(SMILU_3)if (my_strxcmp(s, "SMILU_3") == 0 || i == (long)SMILU_3) { *value = SMILU_3; _Py_XDECREF(((PyObject*)(tmpobj))); return 1; }; | |||
958 | ENUM_CHECK_FINISH("invalid value for 'ILU_MILU' parameter")_Py_XDECREF(((PyObject*)(tmpobj))); PyErr_SetString(PyExc_ValueError , "invalid value for 'ILU_MILU' parameter"); return 0;; | |||
959 | } | |||
960 | ||||
961 | static int droprule_one_cvt(PyObject * input, int *value) | |||
962 | { | |||
963 | ENUM_CHECK_INITlong i = -1; char *s = ""; PyObject *tmpobj = ((void*)0); if ( input == (&_Py_NoneStruct)) return 1; if (((((((PyObject* )(input))->ob_type))->tp_flags & ((1UL << 27) )) != 0)) { s = (((void) (0)), (((PyBytesObject *)(input))-> ob_sval)); } else if (((((((PyObject*)(input))->ob_type))-> tp_flags & ((1UL << 28))) != 0)) { tmpobj = PyUnicode_AsASCIIString (input); if (tmpobj == ((void*)0)) return 0; s = (((void) (0) ), (((PyBytesObject *)(tmpobj))->ob_sval)); } else if (((( (((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { i = PyLong_AsLong(input); }; | |||
| ||||
964 | if (my_strxcmp(s, "BASIC") == 0) { | |||
965 | *value = DROP_BASIC( 0x0001 ); | |||
966 | return 1; | |||
967 | } | |||
968 | if (my_strxcmp(s, "PROWS") == 0) { | |||
969 | *value = DROP_PROWS( 0x0002 ); | |||
970 | return 1; | |||
971 | } | |||
972 | if (my_strxcmp(s, "COLUMN") == 0) { | |||
973 | *value = DROP_COLUMN( 0x0004 ); | |||
974 | return 1; | |||
975 | } | |||
976 | if (my_strxcmp(s, "AREA") == 0) { | |||
977 | *value = DROP_AREA( 0x0008 ); | |||
978 | return 1; | |||
979 | } | |||
980 | if (my_strxcmp(s, "SECONDARY") == 0) { | |||
981 | *value = DROP_SECONDARY( 0x000E ); | |||
982 | return 1; | |||
983 | } | |||
984 | if (my_strxcmp(s, "DYNAMIC") == 0) { | |||
985 | *value = DROP_DYNAMIC( 0x0010 ); | |||
986 | return 1; | |||
987 | } | |||
988 | if (my_strxcmp(s, "INTERP") == 0) { | |||
989 | *value = DROP_INTERP( 0x0100 ); | |||
990 | return 1; | |||
991 | } | |||
992 | ENUM_CHECK_FINISH("invalid value for 'ILU_DropRule' parameter")_Py_XDECREF(((PyObject*)(tmpobj))); PyErr_SetString(PyExc_ValueError , "invalid value for 'ILU_DropRule' parameter"); return 0;; | |||
993 | } | |||
994 | ||||
995 | static int droprule_cvt(PyObject * input, int *value) | |||
996 | { | |||
997 | PyObject *seq = NULL((void*)0); | |||
998 | int i; | |||
999 | int rule = 0; | |||
1000 | ||||
1001 | if (input == Py_None(&_Py_NoneStruct)) { | |||
| ||||
1002 | /* Leave as default */ | |||
1003 | return 1; | |||
1004 | } | |||
1005 | else if (PyLong_Check(input)((((((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 24))) != 0)) { | |||
1006 | *value = PyLong_AsLong(input); | |||
1007 | return 1; | |||
1008 | } | |||
1009 | else if (PyBytes_Check(input)((((((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 27))) != 0) || PyUnicode_Check(input)((((((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 28))) != 0)) { | |||
1010 | /* Comma-separated string */ | |||
1011 | char *fmt = "s"; | |||
1012 | if (PyBytes_Check(input)((((((PyObject*)(input))->ob_type))->tp_flags & ((1UL << 27))) != 0)) { | |||
1013 | fmt = "y"; | |||
1014 | } | |||
1015 | seq = PyObject_CallMethod(input, "split", fmt, ","); | |||
1016 | if (seq == NULL((void*)0) || !PySequence_Check(seq)) | |||
1017 | goto fail; | |||
1018 | } | |||
1019 | else if (PySequence_Check(input)) { | |||
1020 | /* Sequence of strings or integers */ | |||
1021 | seq = input; | |||
1022 | Py_INCREF(seq)_Py_INCREF(((PyObject*)(seq))); | |||
1023 | } | |||
1024 | else { | |||
1025 | PyErr_SetString(PyExc_ValueError, "invalid value for drop rule"); | |||
1026 | goto fail; | |||
1027 | } | |||
1028 | ||||
1029 | /* OR multiple values together */ | |||
1030 | for (i = 0; i < PySequence_Size(seq); ++i) { | |||
1031 | PyObject *item; | |||
1032 | int one_value = 0; | |||
1033 | ||||
1034 | item = PySequence_ITEM(seq, i)( (((PyObject*)(seq))->ob_type)->tp_as_sequence->sq_item (seq, i) ); | |||
1035 | if (item == NULL((void*)0)) { | |||
1036 | goto fail; | |||
1037 | } | |||
1038 | if (!droprule_one_cvt(item, &one_value)) { | |||
1039 | Py_DECREF(item)_Py_DECREF(((PyObject*)(item))); | |||
1040 | goto fail; | |||
1041 | } | |||
1042 | Py_DECREF(item)_Py_DECREF(((PyObject*)(item))); | |||
1043 | rule |= one_value; | |||
1044 | } | |||
1045 | Py_DECREF(seq)_Py_DECREF(((PyObject*)(seq))); | |||
1046 | ||||
1047 | *value = rule; | |||
1048 | return 1; | |||
1049 | ||||
1050 | fail: | |||
1051 | Py_XDECREF(seq)_Py_XDECREF(((PyObject*)(seq))); | |||
1052 | return 0; | |||
1053 | } | |||
1054 | ||||
1055 | static int double_cvt(PyObject * input, double *value) | |||
1056 | { | |||
1057 | if (input == Py_None(&_Py_NoneStruct)) | |||
1058 | return 1; | |||
1059 | *value = PyFloat_AsDouble(input); | |||
1060 | if (PyErr_Occurred()) | |||
1061 | return 0; | |||
1062 | return 1; | |||
1063 | } | |||
1064 | ||||
1065 | static int int_cvt(PyObject * input, int *value) | |||
1066 | { | |||
1067 | if (input == Py_None(&_Py_NoneStruct)) | |||
1068 | return 1; | |||
1069 | *value = PyLong_AsLong(input); | |||
1070 | if (PyErr_Occurred()) | |||
1071 | return 0; | |||
1072 | return 1; | |||
1073 | } | |||
1074 | ||||
1075 | int set_superlu_options_from_dict(superlu_options_t * options, | |||
1076 | int ilu, PyObject * option_dict, | |||
1077 | int *panel_size, int *relax) | |||
1078 | { | |||
1079 | PyObject *args; | |||
1080 | int ret; | |||
1081 | int _relax, _panel_size; | |||
1082 | ||||
1083 | static char *kwlist[] = { | |||
1084 | "Fact", "Equil", "ColPerm", "Trans", "IterRefine", | |||
1085 | "DiagPivotThresh", "PivotGrowth", "ConditionNumber", | |||
1086 | "RowPerm", "SymmetricMode", "PrintStat", "ReplaceTinyPivot", | |||
1087 | "SolveInitialized", "RefineInitialized", "ILU_Norm", | |||
1088 | "ILU_MILU", "ILU_DropTol", "ILU_FillTol", "ILU_FillFactor", | |||
1089 | "ILU_DropRule", "PanelSize", "Relax", NULL((void*)0) | |||
1090 | }; | |||
1091 | ||||
1092 | if (ilu) { | |||
1093 | ilu_set_default_options(options); | |||
1094 | } | |||
1095 | else { | |||
1096 | set_default_options(options); | |||
1097 | } | |||
1098 | ||||
1099 | _panel_size = sp_ienv(1); | |||
1100 | _relax = sp_ienv(2); | |||
1101 | ||||
1102 | if (option_dict == NULL((void*)0)) { | |||
1103 | /* Proceed with default options */ | |||
1104 | ret = 1; | |||
1105 | } | |||
1106 | else { | |||
1107 | args = PyTuple_New(0); | |||
1108 | ret = PyArg_ParseTupleAndKeywords(args, option_dict, | |||
1109 | "|O&O&O&O&O&O&O&O&O&O&O&O&O&O&O&O&O&O&O&O&O&O&", | |||
1110 | kwlist, fact_cvt, &options->Fact, | |||
1111 | yes_no_cvt, &options->Equil, | |||
1112 | colperm_cvt, &options->ColPerm, | |||
1113 | trans_cvt, &options->Trans, | |||
1114 | iterrefine_cvt, &options->IterRefine, | |||
1115 | double_cvt, | |||
1116 | &options->DiagPivotThresh, | |||
1117 | yes_no_cvt, &options->PivotGrowth, | |||
1118 | yes_no_cvt, | |||
1119 | &options->ConditionNumber, | |||
1120 | rowperm_cvt, &options->RowPerm, | |||
1121 | yes_no_cvt, &options->SymmetricMode, | |||
1122 | yes_no_cvt, &options->PrintStat, | |||
1123 | yes_no_cvt, | |||
1124 | &options->ReplaceTinyPivot, | |||
1125 | yes_no_cvt, | |||
1126 | &options->SolveInitialized, | |||
1127 | yes_no_cvt, | |||
1128 | &options->RefineInitialized, | |||
1129 | norm_cvt, &options->ILU_Norm, | |||
1130 | milu_cvt, &options->ILU_MILU, | |||
1131 | double_cvt, &options->ILU_DropTol, | |||
1132 | double_cvt, &options->ILU_FillTol, | |||
1133 | double_cvt, &options->ILU_FillFactor, | |||
1134 | droprule_cvt, &options->ILU_DropRule, | |||
1135 | int_cvt, &_panel_size, int_cvt, | |||
1136 | &_relax); | |||
1137 | Py_DECREF(args)_Py_DECREF(((PyObject*)(args))); | |||
1138 | } | |||
1139 | ||||
1140 | if (panel_size != NULL((void*)0)) { | |||
1141 | *panel_size = _panel_size; | |||
1142 | } | |||
1143 | ||||
1144 | if (relax != NULL((void*)0)) { | |||
1145 | *relax = _relax; | |||
1146 | } | |||
1147 | ||||
1148 | return ret; | |||
1149 | } |
1 | #ifndef PyUnicode_AsASCIIString |
2 | struct _object; |
3 | typedef struct _object PyObject; |
4 | PyObject* clang_analyzer_PyObject_New_Reference(); |
5 | PyObject* PyUnicode_AsASCIIString(PyObject *unicode) { |
6 | return clang_analyzer_PyObject_New_Reference(); |
7 | } |
8 | #else |
9 | #warning "API PyUnicode_AsASCIIString is defined as a macro." |
10 | #endif |