static PyObject * Py_gstrf(PyObject *self, PyObject *args, PyObject *keywds) { /* default value for SuperLU parameters*/ int N, nnz; PyArrayObject *rowind, *colptr, *nzvals; SuperMatrix A; PyObject *result; PyObject *option_dict = NULL; int type; int ilu = 0; static char *kwlist[] = {"N","nnz","nzvals","colind","rowptr", "options", "ilu", NULL}; int res = PyArg_ParseTupleAndKeywords( args, keywds, "iiO!O!O!|Oi", kwlist, &N, &nnz, &PyArray_Type, &nzvals, &PyArray_Type, &rowind, &PyArray_Type, &colptr, &option_dict, &ilu); if (!res) return NULL; if (!_CHECK_INTEGER(colptr) || !_CHECK_INTEGER(rowind)) { PyErr_SetString(PyExc_TypeError, "rowind and colptr must be of type cint"); return NULL; } type = PyArray_TYPE(nzvals); if (!CHECK_SLU_TYPE(type)) { PyErr_SetString(PyExc_TypeError, "nzvals is not of a type supported by SuperLU"); return NULL; } if (NCFormat_from_spMatrix(&A, N, N, nnz, nzvals, rowind, colptr, type)) { goto fail; } result = newSciPyLUObject(&A, option_dict, type, ilu); if (result == NULL) { goto fail; } /* arrays of input matrix will not be freed */ Destroy_SuperMatrix_Store(&A); return result; fail: /* arrays of input matrix will not be freed */ Destroy_SuperMatrix_Store(&A); return NULL; }
int DenseSuper_from_Numeric(SuperMatrix *X, PyObject *PyX) { PyArrayObject *aX; int m, n, ldx, nd; if (!PyArray_Check(PyX)) { PyErr_SetString(PyExc_TypeError, "argument is not an array."); return -1; } aX = (PyArrayObject*)PyX; if (!CHECK_SLU_TYPE(aX->descr->type_num)) { PyErr_SetString(PyExc_ValueError, "unsupported array data type"); return -1; } if (!(aX->flags & NPY_F_CONTIGUOUS)) { PyErr_SetString(PyExc_ValueError, "array is not fortran contiguous"); return -1; } nd = aX->nd; if (nd == 1) { m = aX->dimensions[0]; n = 1; ldx = m; } else if (nd == 2) { m = aX->dimensions[0]; n = aX->dimensions[1]; ldx = m; } else { PyErr_SetString(PyExc_ValueError, "wrong number of dimensions in array"); return -1; } if (setjmp(_superlu_py_jmpbuf)) return -1; else { Create_Dense_Matrix(aX->descr->type_num, X, m, n, aX->data, ldx, SLU_DN, NPY_TYPECODE_TO_SLU(aX->descr->type_num), SLU_GE); } return 0; }
int NCFormat_from_spMatrix(SuperMatrix * A, int m, int n, int nnz, PyArrayObject * nzvals, PyArrayObject * rowind, PyArrayObject * colptr, int typenum) { int ok = 0; ok = (PyArray_EquivTypenums(PyArray_DESCR(nzvals)->type_num, typenum) && PyArray_EquivTypenums(PyArray_DESCR(rowind)->type_num, NPY_INT) && PyArray_EquivTypenums(PyArray_DESCR(colptr)->type_num, NPY_INT) && PyArray_NDIM(nzvals) == 1 && PyArray_NDIM(rowind) == 1 && PyArray_NDIM(colptr) == 1 && PyArray_IS_C_CONTIGUOUS(nzvals) && PyArray_IS_C_CONTIGUOUS(rowind) && PyArray_IS_C_CONTIGUOUS(colptr) && nnz <= PyArray_DIM(nzvals, 0) && nnz <= PyArray_DIM(rowind, 0) && n+1 <= PyArray_DIM(colptr, 0)); if (!ok) { PyErr_SetString(PyExc_ValueError, "sparse matrix arrays must be 1-D C-contiguous and of proper " "sizes and types"); return -1; } if (setjmp(_superlu_py_jmpbuf)) return -1; else { if (!CHECK_SLU_TYPE(nzvals->descr->type_num)) { PyErr_SetString(PyExc_TypeError, "Invalid type for array."); return -1; } Create_CompCol_Matrix(nzvals->descr->type_num, A, m, n, nnz, nzvals->data, (int *) rowind->data, (int *) colptr->data, SLU_NC, NPY_TYPECODE_TO_SLU(nzvals->descr->type_num), SLU_GE); } return 0; }
static PyObject * Py_gssv(PyObject *self, PyObject *args, PyObject *kwdict) { PyObject *Py_B=NULL, *Py_X=NULL; PyArrayObject *nzvals=NULL; PyArrayObject *colind=NULL, *rowptr=NULL; int N, nnz; int info; int csc=0; int *perm_r=NULL, *perm_c=NULL; SuperMatrix A, B, L, U; superlu_options_t options; SuperLUStat_t stat; PyObject *option_dict = NULL; int type; int ssv_finished = 0; static char *kwlist[] = {"N","nnz","nzvals","colind","rowptr","B", "csc", "options",NULL}; /* Get input arguments */ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO!O!O!O|iO", kwlist, &N, &nnz, &PyArray_Type, &nzvals, &PyArray_Type, &colind, &PyArray_Type, &rowptr, &Py_B, &csc, &option_dict)) { return NULL; } if (!_CHECK_INTEGER(colind) || !_CHECK_INTEGER(rowptr)) { PyErr_SetString(PyExc_TypeError, "colind and rowptr must be of type cint"); return NULL; } type = PyArray_TYPE(nzvals); if (!CHECK_SLU_TYPE(type)) { PyErr_SetString(PyExc_TypeError, "nzvals is not of a type supported by SuperLU"); return NULL; } if (!set_superlu_options_from_dict(&options, 0, option_dict, NULL, NULL)) { return NULL; } /* Create Space for output */ Py_X = PyArray_CopyFromObject(Py_B, type, 1, 2); if (Py_X == NULL) return NULL; if (csc) { if (NCFormat_from_spMatrix(&A, N, N, nnz, nzvals, colind, rowptr, type)) { Py_DECREF(Py_X); return NULL; } } else { if (NRFormat_from_spMatrix(&A, N, N, nnz, nzvals, colind, rowptr, type)) { Py_DECREF(Py_X); return NULL; } } if (DenseSuper_from_Numeric(&B, Py_X)) { Destroy_SuperMatrix_Store(&A); Py_DECREF(Py_X); return NULL; } /* B and Py_X share same data now but Py_X "owns" it */ /* Setup options */ if (setjmp(_superlu_py_jmpbuf)) { goto fail; } else { perm_c = intMalloc(N); perm_r = intMalloc(N); StatInit(&stat); /* Compute direct inverse of sparse Matrix */ gssv(type, &options, &A, perm_c, perm_r, &L, &U, &B, &stat, &info); } ssv_finished = 1; SUPERLU_FREE(perm_r); SUPERLU_FREE(perm_c); Destroy_SuperMatrix_Store(&A); /* holds just a pointer to the data */ Destroy_SuperMatrix_Store(&B); Destroy_SuperNode_Matrix(&L); Destroy_CompCol_Matrix(&U); StatFree(&stat); return Py_BuildValue("Ni", Py_X, info); fail: SUPERLU_FREE(perm_r); SUPERLU_FREE(perm_c); Destroy_SuperMatrix_Store(&A); /* holds just a pointer to the data */ Destroy_SuperMatrix_Store(&B); if (ssv_finished) { /* Avoid trying to free partially initialized matrices; might leak some memory, but avoids a crash */ Destroy_SuperNode_Matrix(&L); Destroy_CompCol_Matrix(&U); } StatFree(&stat); Py_XDECREF(Py_X); return NULL; }
PyObject *newSuperLUObject(SuperMatrix * A, PyObject * option_dict, int intype, int ilu) { /* A must be in SLU_NC format used by the factorization routine. */ SuperLUObject *self; SuperMatrix AC = { 0 }; /* Matrix postmultiplied by Pc */ int lwork = 0; int *etree = NULL; int info; int n; superlu_options_t options; SuperLUStat_t stat = { 0 }; int panel_size, relax; n = A->ncol; if (!set_superlu_options_from_dict(&options, ilu, option_dict, &panel_size, &relax)) { return NULL; } /* Create SLUObject */ self = PyObject_New(SuperLUObject, &SuperLUType); if (self == NULL) return PyErr_NoMemory(); self->m = A->nrow; self->n = n; self->perm_r = NULL; self->perm_c = NULL; self->L.Store = NULL; self->U.Store = NULL; self->cached_U = NULL; self->cached_L = NULL; self->type = intype; if (setjmp(_superlu_py_jmpbuf)) goto fail; /* Calculate and apply minimum degree ordering */ etree = intMalloc(n); self->perm_r = intMalloc(n); self->perm_c = intMalloc(n); StatInit(&stat); get_perm_c(options.ColPerm, A, self->perm_c); /* calc column permutation */ sp_preorder(&options, A, self->perm_c, etree, &AC); /* apply column * permutation */ /* Perform factorization */ if (!CHECK_SLU_TYPE(SLU_TYPECODE_TO_NPY(A->Dtype))) { PyErr_SetString(PyExc_ValueError, "Invalid type in SuperMatrix."); goto fail; } if (ilu) { gsitrf(SLU_TYPECODE_TO_NPY(A->Dtype), &options, &AC, relax, panel_size, etree, NULL, lwork, self->perm_c, self->perm_r, &self->L, &self->U, &stat, &info); } else { gstrf(SLU_TYPECODE_TO_NPY(A->Dtype), &options, &AC, relax, panel_size, etree, NULL, lwork, self->perm_c, self->perm_r, &self->L, &self->U, &stat, &info); } if (info) { if (info < 0) PyErr_SetString(PyExc_SystemError, "gstrf was called with invalid arguments"); else { if (info <= n) PyErr_SetString(PyExc_RuntimeError, "Factor is exactly singular"); else PyErr_NoMemory(); } goto fail; } /* free memory */ SUPERLU_FREE(etree); Destroy_CompCol_Permuted(&AC); StatFree(&stat); return (PyObject *) self; fail: SUPERLU_FREE(etree); XDestroy_CompCol_Permuted(&AC); XStatFree(&stat); Py_DECREF(self); return NULL; }
static PyObject *SuperLU_solve(SuperLUObject * self, PyObject * args, PyObject * kwds) { PyArrayObject *b, *x = NULL; SuperMatrix B = { 0 }; #ifndef NPY_PY3K char itrans = 'N'; #else int itrans = 'N'; #endif int info; trans_t trans; SuperLUStat_t stat = { 0 }; static char *kwlist[] = { "rhs", "trans", NULL }; if (!CHECK_SLU_TYPE(self->type)) { PyErr_SetString(PyExc_ValueError, "unsupported data type"); return NULL; } #ifndef NPY_PY3K if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|c", kwlist, &PyArray_Type, &b, &itrans)) #else if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!|C", kwlist, &PyArray_Type, &b, &itrans)) #endif return NULL; /* solve transposed system: matrix was passed row-wise instead of * column-wise */ if (itrans == 'n' || itrans == 'N') trans = NOTRANS; else if (itrans == 't' || itrans == 'T') trans = TRANS; else if (itrans == 'h' || itrans == 'H') trans = CONJ; else { PyErr_SetString(PyExc_ValueError, "trans must be N, T, or H"); return NULL; } x = (PyArrayObject*)PyArray_FROMANY( (PyObject*)b, self->type, 1, 2, NPY_F_CONTIGUOUS | NPY_ENSURECOPY); if (x == NULL) { goto fail; } if (x->dimensions[0] != self->n) { PyErr_SetString(PyExc_ValueError, "b is of incompatible size"); goto fail; } if (setjmp(_superlu_py_jmpbuf)) goto fail; if (DenseSuper_from_Numeric(&B, (PyObject *)x)) goto fail; StatInit(&stat); /* Solve the system, overwriting vector x. */ gstrs(self->type, trans, &self->L, &self->U, self->perm_c, self->perm_r, &B, &stat, &info); if (info) { PyErr_SetString(PyExc_SystemError, "gstrs was called with invalid arguments"); goto fail; } /* free memory */ Destroy_SuperMatrix_Store(&B); StatFree(&stat); return (PyObject *) x; fail: XDestroy_SuperMatrix_Store(&B); XStatFree(&stat); Py_XDECREF(x); return NULL; }