25a977
From 34d4897596edd2c517ab57c68d55a55fde1bbcd8 Mon Sep 17 00:00:00 2001
25a977
From: =?UTF-8?q?Nikola=20Forr=C3=B3?= <nforro@redhat.com>
25a977
Date: Wed, 4 Jan 2017 16:59:54 +0100
25a977
Subject: [PATCH] Override LAPACK XERBLA
25a977
25a977
Backported upstream commits:
25a977
374e0b4d2c6f44fdccccfefe0546b607e5291e64
25a977
f0b2dd7d5151878f2b4b3ea20ff551b27243f27d
25a977
---
25a977
 numpy/core/blasdot/python_xerbla.c | 51 +++++++++++++++++++++++++++++++++++
25a977
 numpy/core/setup.py                |  3 ++-
25a977
 numpy/linalg/lapack_litemodule.c   | 54 ++++++++++++++++++++++++++++++++++++++
25a977
 3 files changed, 107 insertions(+), 1 deletion(-)
25a977
 create mode 100644 numpy/core/blasdot/python_xerbla.c
25a977
25a977
diff --git a/numpy/core/blasdot/python_xerbla.c b/numpy/core/blasdot/python_xerbla.c
25a977
new file mode 100644
25a977
index 0000000..bdf0b90
25a977
--- /dev/null
25a977
+++ b/numpy/core/blasdot/python_xerbla.c
25a977
@@ -0,0 +1,51 @@
25a977
+#include "Python.h"
25a977
+
25a977
+/*
25a977
+ * From f2c.h, this should be safe unless fortran is set to use 64
25a977
+ * bit integers. We don't seem to have any good way to detect that.
25a977
+ */
25a977
+typedef int integer;
25a977
+
25a977
+/*
25a977
+  From the original manpage:
25a977
+  --------------------------
25a977
+  XERBLA is an error handler for the LAPACK routines.
25a977
+  It is called by an LAPACK routine if an input parameter has an invalid value.
25a977
+  A message is printed and execution stops.
25a977
+
25a977
+  Instead of printing a message and stopping the execution, a
25a977
+  ValueError is raised with the message.
25a977
+
25a977
+  Parameters:
25a977
+  -----------
25a977
+  srname: Subroutine name to use in error message, maximum six characters.
25a977
+          Spaces at the end are skipped.
25a977
+  info: Number of the invalid parameter.
25a977
+*/
25a977
+
25a977
+int xerbla_(char *srname, integer *info)
25a977
+{
25a977
+        static const char format[] = "On entry to %.*s" \
25a977
+                " parameter number %d had an illegal value";
25a977
+        char buf[sizeof(format) + 6 + 4];   /* 6 for name, 4 for param. num. */
25a977
+
25a977
+        int len = 0; /* length of subroutine name*/
25a977
+#ifdef WITH_THREAD
25a977
+        PyGILState_STATE save;
25a977
+#endif
25a977
+
25a977
+        while( len<6 && srname[len]!='\0' )
25a977
+                len++;
25a977
+        while( len && srname[len-1]==' ' )
25a977
+                len--;
25a977
+#ifdef WITH_THREAD
25a977
+        save = PyGILState_Ensure();
25a977
+#endif
25a977
+        PyOS_snprintf(buf, sizeof(buf), format, len, srname, *info);
25a977
+        PyErr_SetString(PyExc_ValueError, buf);
25a977
+#ifdef WITH_THREAD
25a977
+        PyGILState_Release(save);
25a977
+#endif
25a977
+
25a977
+        return 0;
25a977
+}
25a977
diff --git a/numpy/core/setup.py b/numpy/core/setup.py
25a977
index a1000ae..495e163 100644
25a977
--- a/numpy/core/setup.py
25a977
+++ b/numpy/core/setup.py
25a977
@@ -899,12 +899,13 @@ def configuration(parent_package='',top_path=None):
25a977
         if blas_info:
25a977
             if ('NO_ATLAS_INFO',1) in blas_info.get('define_macros',[]):
25a977
                 return None # dotblas needs ATLAS, Fortran compiled blas will not be sufficient.
25a977
-            return ext.depends[:1]
25a977
+            return ext.depends[:2]
25a977
         return None # no extension module will be built
25a977
 
25a977
     config.add_extension('_dotblas',
25a977
                          sources = [get_dotblas_sources],
25a977
                          depends = [join('blasdot','_dotblas.c'),
25a977
+                                  join('blasdot', 'python_xerbla.c'),
25a977
                                   join('blasdot','cblas.h'),
25a977
                                   ],
25a977
                          include_dirs = ['blasdot'],
25a977
diff --git a/numpy/linalg/lapack_litemodule.c b/numpy/linalg/lapack_litemodule.c
25a977
index cc62382..4f8cab9 100644
25a977
--- a/numpy/linalg/lapack_litemodule.c
25a977
+++ b/numpy/linalg/lapack_litemodule.c
25a977
@@ -171,6 +171,9 @@ lapack_lite_dgeev(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
             FNAME(dgeev)(&jobvl,&jobvr,&n,DDATA(a),&lda,DDATA(wr),DDATA(wi),
25a977
                          DDATA(vl),&ldvl,DDATA(vr),&ldvr,DDATA(work),&lwork,
25a977
                          &info;;
25a977
+    if (PyErr_Occurred()) {
25a977
+        return NULL;
25a977
+    }
25a977
 
25a977
     return Py_BuildValue("{s:i,s:c,s:c,s:i,s:i,s:i,s:i,s:i,s:i}","dgeev_",
25a977
                          lapack_lite_status__,"jobvl",jobvl,"jobvr",jobvr,
25a977
@@ -254,6 +257,9 @@ lapack_lite_dsyevd(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
     lapack_lite_status__ = \
25a977
             FNAME(dsyevd)(&jobz,&uplo,&n,DDATA(a),&lda,DDATA(w),DDATA(work),
25a977
                           &lwork,IDATA(iwork),&liwork,&info;;
25a977
+    if (PyErr_Occurred()) {
25a977
+        return NULL;
25a977
+    }
25a977
 
25a977
     return Py_BuildValue("{s:i,s:c,s:c,s:i,s:i,s:i,s:i,s:i}","dsyevd_",
25a977
                          lapack_lite_status__,"jobz",jobz,"uplo",uplo,
25a977
@@ -341,6 +347,9 @@ lapack_lite_zheevd(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
     lapack_lite_status__ = \
25a977
     FNAME(zheevd)(&jobz,&uplo,&n,ZDATA(a),&lda,DDATA(w),ZDATA(work),
25a977
                   &lwork,DDATA(rwork),&lrwork,IDATA(iwork),&liwork,&info;;
25a977
+    if (PyErr_Occurred()) {
25a977
+        return NULL;
25a977
+    }
25a977
 
25a977
     return Py_BuildValue("{s:i,s:c,s:c,s:i,s:i,s:i,s:i,s:i,s:i}","zheevd_",
25a977
                          lapack_lite_status__,"jobz",jobz,"uplo",uplo,"n",n,
25a977
@@ -380,6 +389,9 @@ lapack_lite_dgelsd(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
             FNAME(dgelsd)(&m,&n,&nrhs,DDATA(a),&lda,DDATA(b),&ldb,
25a977
                           DDATA(s),&rcond,&rank,DDATA(work),&lwork,
25a977
                           IDATA(iwork),&info;;
25a977
+    if (PyErr_Occurred()) {
25a977
+        return NULL;
25a977
+    }
25a977
 
25a977
     return Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:d,s:i,s:i,s:i}","dgelsd_",
25a977
                          lapack_lite_status__,"m",m,"n",n,"nrhs",nrhs,
25a977
@@ -407,6 +419,9 @@ lapack_lite_dgesv(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
 
25a977
     lapack_lite_status__ = \
25a977
     FNAME(dgesv)(&n,&nrhs,DDATA(a),&lda,IDATA(ipiv),DDATA(b),&ldb,&info;;
25a977
+    if (PyErr_Occurred()) {
25a977
+        return NULL;
25a977
+    }
25a977
 
25a977
     return Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i}","dgesv_",
25a977
                          lapack_lite_status__,"n",n,"nrhs",nrhs,"lda",lda,
25a977
@@ -446,6 +461,9 @@ lapack_lite_dgesdd(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
             FNAME(dgesdd)(&jobz,&m,&n,DDATA(a),&lda,DDATA(s),DDATA(u),&ldu,
25a977
                           DDATA(vt),&ldvt,DDATA(work),&lwork,IDATA(iwork),
25a977
                           &info;;
25a977
+    if (PyErr_Occurred()) {
25a977
+        return NULL;
25a977
+    }
25a977
 
25a977
     if (info == 0 && lwork == -1) {
25a977
             /* We need to check the result because
25a977
@@ -496,6 +514,9 @@ lapack_lite_dgetrf(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
 
25a977
     lapack_lite_status__ = \
25a977
             FNAME(dgetrf)(&m,&n,DDATA(a),&lda,IDATA(ipiv),&info;;
25a977
+    if (PyErr_Occurred()) {
25a977
+        return NULL;
25a977
+    }
25a977
 
25a977
     return Py_BuildValue("{s:i,s:i,s:i,s:i,s:i}","dgetrf_",lapack_lite_status__,
25a977
                          "m",m,"n",n,"lda",lda,"info",info);
25a977
@@ -516,6 +537,9 @@ lapack_lite_dpotrf(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
 
25a977
     lapack_lite_status__ = \
25a977
             FNAME(dpotrf)(&uplo,&n,DDATA(a),&lda,&info;;
25a977
+    if (PyErr_Occurred()) {
25a977
+        return NULL;
25a977
+    }
25a977
 
25a977
     return Py_BuildValue("{s:i,s:i,s:i,s:i}","dpotrf_",lapack_lite_status__,
25a977
                          "n",n,"lda",lda,"info",info);
25a977
@@ -540,6 +564,9 @@ lapack_lite_dgeqrf(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
         lapack_lite_status__ = \
25a977
                 FNAME(dgeqrf)(&m, &n, DDATA(a), &lda, DDATA(tau),
25a977
                               DDATA(work), &lwork, &info;;
25a977
+	if (PyErr_Occurred()) {
25a977
+            return NULL;
25a977
+	}
25a977
 
25a977
         return Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i}","dgeqrf_",
25a977
                              lapack_lite_status__,"m",m,"n",n,"lda",lda,
25a977
@@ -562,6 +589,9 @@ lapack_lite_dorgqr(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
         TRY(check_object(work,NPY_DOUBLE,"work","NPY_DOUBLE","dorgqr"));
25a977
         lapack_lite_status__ = \
25a977
         FNAME(dorgqr)(&m, &n, &k, DDATA(a), &lda, DDATA(tau), DDATA(work), &lwork, &info;;
25a977
+	if (PyErr_Occurred()) {
25a977
+            return NULL;
25a977
+	}
25a977
 
25a977
         return Py_BuildValue("{s:i,s:i}","dorgqr_",lapack_lite_status__,
25a977
                              "info",info);
25a977
@@ -601,6 +631,9 @@ lapack_lite_zgeev(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
             FNAME(zgeev)(&jobvl,&jobvr,&n,ZDATA(a),&lda,ZDATA(w),ZDATA(vl),
25a977
                          &ldvl,ZDATA(vr),&ldvr,ZDATA(work),&lwork,
25a977
                          DDATA(rwork),&info;;
25a977
+    if (PyErr_Occurred()) {
25a977
+        return NULL;
25a977
+    }
25a977
 
25a977
     return Py_BuildValue("{s:i,s:c,s:c,s:i,s:i,s:i,s:i,s:i,s:i}","zgeev_",
25a977
                          lapack_lite_status__,"jobvl",jobvl,"jobvr",jobvr,
25a977
@@ -641,6 +674,9 @@ lapack_lite_zgelsd(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
     lapack_lite_status__ = \
25a977
     FNAME(zgelsd)(&m,&n,&nrhs,ZDATA(a),&lda,ZDATA(b),&ldb,DDATA(s),&rcond,
25a977
                   &rank,ZDATA(work),&lwork,DDATA(rwork),IDATA(iwork),&info;;
25a977
+    if (PyErr_Occurred()) {
25a977
+        return NULL;
25a977
+    }
25a977
 
25a977
     return Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i}","zgelsd_",
25a977
                          lapack_lite_status__,"m",m,"n",n,"nrhs",nrhs,"lda",lda,
25a977
@@ -667,6 +703,9 @@ lapack_lite_zgesv(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
 
25a977
     lapack_lite_status__ = \
25a977
     FNAME(zgesv)(&n,&nrhs,ZDATA(a),&lda,IDATA(ipiv),ZDATA(b),&ldb,&info;;
25a977
+    if (PyErr_Occurred()) {
25a977
+        return NULL;
25a977
+    }
25a977
 
25a977
     return Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i}","zgesv_",
25a977
                          lapack_lite_status__,"n",n,"nrhs",nrhs,"lda",lda,
25a977
@@ -708,6 +747,9 @@ lapack_lite_zgesdd(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
     FNAME(zgesdd)(&jobz,&m,&n,ZDATA(a),&lda,DDATA(s),ZDATA(u),&ldu,
25a977
                   ZDATA(vt),&ldvt,ZDATA(work),&lwork,DDATA(rwork),
25a977
                   IDATA(iwork),&info;;
25a977
+    if (PyErr_Occurred()) {
25a977
+        return NULL;
25a977
+    }
25a977
 
25a977
     return Py_BuildValue("{s:i,s:c,s:i,s:i,s:i,s:i,s:i,s:i,s:i}","zgesdd_",
25a977
                          lapack_lite_status__,"jobz",jobz,"m",m,"n",n,
25a977
@@ -732,6 +774,9 @@ lapack_lite_zgetrf(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
 
25a977
     lapack_lite_status__ = \
25a977
     FNAME(zgetrf)(&m,&n,ZDATA(a),&lda,IDATA(ipiv),&info;;
25a977
+    if (PyErr_Occurred()) {
25a977
+        return NULL;
25a977
+    }
25a977
 
25a977
     return Py_BuildValue("{s:i,s:i,s:i,s:i,s:i}","zgetrf_",
25a977
                          lapack_lite_status__,"m",m,"n",n,"lda",lda,"info",info);
25a977
@@ -751,6 +796,9 @@ lapack_lite_zpotrf(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
     TRY(check_object(a,NPY_CDOUBLE,"a","NPY_CDOUBLE","zpotrf"));
25a977
     lapack_lite_status__ = \
25a977
     FNAME(zpotrf)(&uplo,&n,ZDATA(a),&lda,&info;;
25a977
+    if (PyErr_Occurred()) {
25a977
+        return NULL;
25a977
+    }
25a977
 
25a977
     return Py_BuildValue("{s:i,s:i,s:i,s:i}","zpotrf_",
25a977
                          lapack_lite_status__,"n",n,"lda",lda,"info",info);
25a977
@@ -774,6 +822,9 @@ lapack_lite_zgeqrf(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
 
25a977
         lapack_lite_status__ = \
25a977
         FNAME(zgeqrf)(&m, &n, ZDATA(a), &lda, ZDATA(tau), ZDATA(work), &lwork, &info;;
25a977
+	if (PyErr_Occurred()) {
25a977
+            return NULL;
25a977
+	}
25a977
 
25a977
         return Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i}","zgeqrf_",lapack_lite_status__,"m",m,"n",n,"lda",lda,"lwork",lwork,"info",info);
25a977
 }
25a977
@@ -797,6 +848,9 @@ lapack_lite_zungqr(PyObject *NPY_UNUSED(self), PyObject *args)
25a977
         lapack_lite_status__ = \
25a977
         FNAME(zungqr)(&m, &n, &k, ZDATA(a), &lda, ZDATA(tau), ZDATA(work),
25a977
                       &lwork, &info;;
25a977
+	if (PyErr_Occurred()) {
25a977
+            return NULL;
25a977
+	}
25a977
 
25a977
         return Py_BuildValue("{s:i,s:i}","zungqr_",lapack_lite_status__,
25a977
                              "info",info);
25a977
-- 
25a977
2.7.4
25a977