[Scipy-svn] r6354 - in trunk/scipy/sparse/linalg/dsolve: . SuperLU SuperLU/SRC

scipy-svn at scipy.org scipy-svn at scipy.org
Tue Apr 27 17:57:16 EDT 2010


Author: ptvirtan
Date: 2010-04-27 16:57:15 -0500 (Tue, 27 Apr 2010)
New Revision: 6354

Modified:
   trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/cpivotL.c
   trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/dpivotL.c
   trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/scipy_slu_config.h
   trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/spivotL.c
   trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/zpivotL.c
   trunk/scipy/sparse/linalg/dsolve/SuperLU/scipychanges.txt
   trunk/scipy/sparse/linalg/dsolve/_superlumodule.c
Log:
BUG: sparse.linalg.dsolve/SuperLU: patch SuperLU sources to eliminate a crash for singular matrices for which pivoting fails

Modified: trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/cpivotL.c
===================================================================
--- trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/cpivotL.c	2010-04-27 21:57:04 UTC (rev 6353)
+++ trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/cpivotL.c	2010-04-27 21:57:15 UTC (rev 6354)
@@ -108,7 +108,11 @@
        Also search for user-specified pivot, and diagonal element. */
     if ( *usepr ) *pivrow = iperm_r[jcol];
     diagind = iperm_c[jcol];
+#ifdef SCIPY_SPECIFIC_FIX
+    pivmax = -1.0;
+#else
     pivmax = 0.0;
+#endif
     pivptr = nsupc;
     diag = EMPTY;
     old_pivptr = nsupc;
@@ -123,6 +127,13 @@
     }
 
     /* Test for singularity */
+#ifdef SCIPY_SPECIFIC_FIX
+    if (pivmax < 0.0) {
+        perm_r[diagind] = jcol;
+        *usepr = 0;
+        return (jcol+1);
+    }
+#endif
     if ( pivmax == 0.0 ) {
 #if 1
 	*pivrow = lsub_ptr[pivptr];

Modified: trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/dpivotL.c
===================================================================
--- trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/dpivotL.c	2010-04-27 21:57:04 UTC (rev 6353)
+++ trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/dpivotL.c	2010-04-27 21:57:15 UTC (rev 6354)
@@ -107,7 +107,11 @@
        Also search for user-specified pivot, and diagonal element. */
     if ( *usepr ) *pivrow = iperm_r[jcol];
     diagind = iperm_c[jcol];
+#ifdef SCIPY_SPECIFIC_FIX
+    pivmax = -1.0;
+#else
     pivmax = 0.0;
+#endif
     pivptr = nsupc;
     diag = EMPTY;
     old_pivptr = nsupc;
@@ -122,6 +126,13 @@
     }
 
     /* Test for singularity */
+#ifdef SCIPY_SPECIFIC_FIX
+    if (pivmax < 0.0) {
+        perm_r[diagind] = jcol;
+        *usepr = 0;
+        return (jcol+1);
+    }
+#endif
     if ( pivmax == 0.0 ) {
 #if 1
 	*pivrow = lsub_ptr[pivptr];

Modified: trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/scipy_slu_config.h
===================================================================
--- trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/scipy_slu_config.h	2010-04-27 21:57:04 UTC (rev 6353)
+++ trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/scipy_slu_config.h	2010-04-27 21:57:15 UTC (rev 6354)
@@ -14,6 +14,8 @@
 #define USER_MALLOC superlu_python_module_malloc
 #define USER_FREE   superlu_python_module_free
 
+#define SCIPY_SPECIFIC_FIX 1
+
 /* 
  * Fortran configuration 
  */

Modified: trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/spivotL.c
===================================================================
--- trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/spivotL.c	2010-04-27 21:57:04 UTC (rev 6353)
+++ trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/spivotL.c	2010-04-27 21:57:15 UTC (rev 6354)
@@ -107,7 +107,11 @@
        Also search for user-specified pivot, and diagonal element. */
     if ( *usepr ) *pivrow = iperm_r[jcol];
     diagind = iperm_c[jcol];
+#ifdef SCIPY_SPECIFIC_FIX
+    pivmax = -1.0;
+#else
     pivmax = 0.0;
+#endif
     pivptr = nsupc;
     diag = EMPTY;
     old_pivptr = nsupc;
@@ -122,6 +126,13 @@
     }
 
     /* Test for singularity */
+#ifdef SCIPY_SPECIFIC_FIX
+    if (pivmax < 0.0) {
+        perm_r[diagind] = jcol;
+        *usepr = 0;
+        return (jcol+1);
+    }
+#endif
     if ( pivmax == 0.0 ) {
 #if 1
 	*pivrow = lsub_ptr[pivptr];

Modified: trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/zpivotL.c
===================================================================
--- trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/zpivotL.c	2010-04-27 21:57:04 UTC (rev 6353)
+++ trunk/scipy/sparse/linalg/dsolve/SuperLU/SRC/zpivotL.c	2010-04-27 21:57:15 UTC (rev 6354)
@@ -108,7 +108,11 @@
        Also search for user-specified pivot, and diagonal element. */
     if ( *usepr ) *pivrow = iperm_r[jcol];
     diagind = iperm_c[jcol];
+#ifdef SCIPY_SPECIFIC_FIX
+    pivmax = -1.0;
+#else
     pivmax = 0.0;
+#endif
     pivptr = nsupc;
     diag = EMPTY;
     old_pivptr = nsupc;
@@ -123,6 +127,13 @@
     }
 
     /* Test for singularity */
+#ifdef SCIPY_SPECIFIC_FIX
+    if (pivmax < 0.0) {
+        perm_r[diagind] = jcol;
+        *usepr = 0;
+        return (jcol+1);
+    }
+#endif
     if ( pivmax == 0.0 ) {
 #if 1
 	*pivrow = lsub_ptr[pivptr];

Modified: trunk/scipy/sparse/linalg/dsolve/SuperLU/scipychanges.txt
===================================================================
--- trunk/scipy/sparse/linalg/dsolve/SuperLU/scipychanges.txt	2010-04-27 21:57:04 UTC (rev 6353)
+++ trunk/scipy/sparse/linalg/dsolve/SuperLU/scipychanges.txt	2010-04-27 21:57:15 UTC (rev 6354)
@@ -15,3 +15,5 @@
 2) ENH: sparse.linalg.dsolve/SuperLU: patch SuperLU upstream sources to get some variables from Scipy
 
 3) BUG: scipy.sparse.dsolve/SuperLU: sprinkle volatile into dlamc/slamc implementation to avoid an infinite loop
+
+4) BUG: sparse.linalg.dsolve/SuperLU: patch SuperLU sources to eliminate a crash for singular matrices for which pivoting fails

Modified: trunk/scipy/sparse/linalg/dsolve/_superlumodule.c
===================================================================
--- trunk/scipy/sparse/linalg/dsolve/_superlumodule.c	2010-04-27 21:57:04 UTC (rev 6353)
+++ trunk/scipy/sparse/linalg/dsolve/_superlumodule.c	2010-04-27 21:57:15 UTC (rev 6354)
@@ -40,6 +40,7 @@
     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};
@@ -109,7 +110,8 @@
         /* 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 */
@@ -125,8 +127,12 @@
     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);
+    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;




More information about the Scipy-svn mailing list