summaryrefslogtreecommitdiff
path: root/numpy/linalg
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/linalg')
-rw-r--r--numpy/linalg/lapack_lite/f2c.c4
-rw-r--r--numpy/linalg/lapack_lite/f2c.h3
-rw-r--r--numpy/linalg/lapack_lite/f2c_blas.c20
-rw-r--r--numpy/linalg/lapack_lite/f2c_blas.c.patch112
-rw-r--r--numpy/linalg/linalg.py36
-rw-r--r--numpy/linalg/meson.build56
-rw-r--r--numpy/linalg/setup.py2
-rw-r--r--numpy/linalg/tests/test_linalg.py5
-rw-r--r--numpy/linalg/tests/test_regression.py5
-rw-r--r--numpy/linalg/umath_linalg.cpp81
10 files changed, 259 insertions, 65 deletions
diff --git a/numpy/linalg/lapack_lite/f2c.c b/numpy/linalg/lapack_lite/f2c.c
index 869fce5d3..ddaa8d172 100644
--- a/numpy/linalg/lapack_lite/f2c.c
+++ b/numpy/linalg/lapack_lite/f2c.c
@@ -7,10 +7,14 @@
it is available, and shipping a static library isn't portable.
*/
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+
#include "f2c.h"
diff --git a/numpy/linalg/lapack_lite/f2c.h b/numpy/linalg/lapack_lite/f2c.h
index b44aaac44..0db1b9ecb 100644
--- a/numpy/linalg/lapack_lite/f2c.h
+++ b/numpy/linalg/lapack_lite/f2c.h
@@ -7,6 +7,9 @@
#ifndef F2C_INCLUDE
#define F2C_INCLUDE
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+
#include <math.h>
#include "numpy/npy_common.h"
#include "npy_cblas.h"
diff --git a/numpy/linalg/lapack_lite/f2c_blas.c b/numpy/linalg/lapack_lite/f2c_blas.c
index 65286892f..9a9fd3f9b 100644
--- a/numpy/linalg/lapack_lite/f2c_blas.c
+++ b/numpy/linalg/lapack_lite/f2c_blas.c
@@ -380,7 +380,6 @@ L20:
static logical nota, notb;
static complex temp;
static logical conja, conjb;
- static integer ncola;
extern logical lsame_(char *, char *);
static integer nrowa, nrowb;
extern /* Subroutine */ int xerbla_(char *, integer *);
@@ -514,7 +513,7 @@ L20:
Set NOTA and NOTB as true if A and B respectively are not
conjugated or transposed, set CONJA and CONJB as true if A and
B respectively are to be transposed but not conjugated and set
- NROWA, NCOLA and NROWB as the number of rows and columns of A
+ NROWA and NROWB as the number of rows and columns of A
and the number of rows of B respectively.
*/
@@ -536,10 +535,8 @@ L20:
conjb = lsame_(transb, "C");
if (nota) {
nrowa = *m;
- ncola = *k;
} else {
nrowa = *k;
- ncola = *m;
}
if (notb) {
nrowb = *k;
@@ -6850,7 +6847,6 @@ L60:
static integer i__, j, l, info;
static logical nota, notb;
static doublereal temp;
- static integer ncola;
extern logical lsame_(char *, char *);
static integer nrowa, nrowb;
extern /* Subroutine */ int xerbla_(char *, integer *);
@@ -6982,7 +6978,7 @@ L60:
Set NOTA and NOTB as true if A and B respectively are not
- transposed and set NROWA, NCOLA and NROWB as the number of rows
+ transposed and set NROWA and NROWB as the number of rows
and columns of A and the number of rows of B respectively.
*/
@@ -7002,10 +6998,8 @@ L60:
notb = lsame_(transb, "N");
if (nota) {
nrowa = *m;
- ncola = *k;
} else {
nrowa = *k;
- ncola = *m;
}
if (notb) {
nrowb = *k;
@@ -11454,7 +11448,6 @@ L60:
static integer i__, j, l, info;
static logical nota, notb;
static real temp;
- static integer ncola;
extern logical lsame_(char *, char *);
static integer nrowa, nrowb;
extern /* Subroutine */ int xerbla_(char *, integer *);
@@ -11586,7 +11579,7 @@ L60:
Set NOTA and NOTB as true if A and B respectively are not
- transposed and set NROWA, NCOLA and NROWB as the number of rows
+ transposed and set NROWA and NROWB as the number of rows
and columns of A and the number of rows of B respectively.
*/
@@ -11606,10 +11599,8 @@ L60:
notb = lsame_(transb, "N");
if (nota) {
nrowa = *m;
- ncola = *k;
} else {
nrowa = *k;
- ncola = *m;
}
if (notb) {
nrowb = *k;
@@ -15667,7 +15658,6 @@ L20:
static logical nota, notb;
static doublecomplex temp;
static logical conja, conjb;
- static integer ncola;
extern logical lsame_(char *, char *);
static integer nrowa, nrowb;
extern /* Subroutine */ int xerbla_(char *, integer *);
@@ -15801,7 +15791,7 @@ L20:
Set NOTA and NOTB as true if A and B respectively are not
conjugated or transposed, set CONJA and CONJB as true if A and
B respectively are to be transposed but not conjugated and set
- NROWA, NCOLA and NROWB as the number of rows and columns of A
+ NROWA and NROWB as the number of rows and columns of A
and the number of rows of B respectively.
*/
@@ -15823,10 +15813,8 @@ L20:
conjb = lsame_(transb, "C");
if (nota) {
nrowa = *m;
- ncola = *k;
} else {
nrowa = *k;
- ncola = *m;
}
if (notb) {
nrowb = *k;
diff --git a/numpy/linalg/lapack_lite/f2c_blas.c.patch b/numpy/linalg/lapack_lite/f2c_blas.c.patch
new file mode 100644
index 000000000..59a6a1919
--- /dev/null
+++ b/numpy/linalg/lapack_lite/f2c_blas.c.patch
@@ -0,0 +1,112 @@
+@@ -380,7 +380,6 @@ L20:
+ static logical nota, notb;
+ static complex temp;
+ static logical conja, conjb;
+- static integer ncola;
+ extern logical lsame_(char *, char *);
+ static integer nrowa, nrowb;
+ extern /* Subroutine */ int xerbla_(char *, integer *);
+@@ -514,7 +513,7 @@ L20:
+ Set NOTA and NOTB as true if A and B respectively are not
+ conjugated or transposed, set CONJA and CONJB as true if A and
+ B respectively are to be transposed but not conjugated and set
+- NROWA, NCOLA and NROWB as the number of rows and columns of A
++ NROWA and NROWB as the number of rows and columns of A
+ and the number of rows of B respectively.
+ */
+
+@@ -536,10 +535,8 @@ L20:
+ conjb = lsame_(transb, "C");
+ if (nota) {
+ nrowa = *m;
+- ncola = *k;
+ } else {
+ nrowa = *k;
+- ncola = *m;
+ }
+ if (notb) {
+ nrowb = *k;
+@@ -6850,7 +6847,6 @@ L60:
+ static integer i__, j, l, info;
+ static logical nota, notb;
+ static doublereal temp;
+- static integer ncola;
+ extern logical lsame_(char *, char *);
+ static integer nrowa, nrowb;
+ extern /* Subroutine */ int xerbla_(char *, integer *);
+@@ -6982,7 +6978,7 @@ L60:
+
+
+ Set NOTA and NOTB as true if A and B respectively are not
+- transposed and set NROWA, NCOLA and NROWB as the number of rows
++ transposed and set NROWA and NROWB as the number of rows
+ and columns of A and the number of rows of B respectively.
+ */
+
+@@ -7002,10 +6998,8 @@ L60:
+ notb = lsame_(transb, "N");
+ if (nota) {
+ nrowa = *m;
+- ncola = *k;
+ } else {
+ nrowa = *k;
+- ncola = *m;
+ }
+ if (notb) {
+ nrowb = *k;
+@@ -11454,7 +11448,6 @@ L60:
+ static integer i__, j, l, info;
+ static logical nota, notb;
+ static real temp;
+- static integer ncola;
+ extern logical lsame_(char *, char *);
+ static integer nrowa, nrowb;
+ extern /* Subroutine */ int xerbla_(char *, integer *);
+@@ -11586,7 +11579,7 @@ L60:
+
+
+ Set NOTA and NOTB as true if A and B respectively are not
+- transposed and set NROWA, NCOLA and NROWB as the number of rows
++ transposed and set NROWA and NROWB as the number of rows
+ and columns of A and the number of rows of B respectively.
+ */
+
+@@ -11606,10 +11599,8 @@ L60:
+ notb = lsame_(transb, "N");
+ if (nota) {
+ nrowa = *m;
+- ncola = *k;
+ } else {
+ nrowa = *k;
+- ncola = *m;
+ }
+ if (notb) {
+ nrowb = *k;
+@@ -15667,7 +15658,6 @@ L20:
+ static logical nota, notb;
+ static doublecomplex temp;
+ static logical conja, conjb;
+- static integer ncola;
+ extern logical lsame_(char *, char *);
+ static integer nrowa, nrowb;
+ extern /* Subroutine */ int xerbla_(char *, integer *);
+@@ -15801,7 +15791,7 @@ L20:
+ Set NOTA and NOTB as true if A and B respectively are not
+ conjugated or transposed, set CONJA and CONJB as true if A and
+ B respectively are to be transposed but not conjugated and set
+- NROWA, NCOLA and NROWB as the number of rows and columns of A
++ NROWA and NROWB as the number of rows and columns of A
+ and the number of rows of B respectively.
+ */
+
+@@ -15823,10 +15813,8 @@ L20:
+ conjb = lsame_(transb, "C");
+ if (nota) {
+ nrowa = *m;
+- ncola = *k;
+ } else {
+ nrowa = *k;
+- ncola = *m;
+ }
+ if (notb) {
+ nrowb = *k;
diff --git a/numpy/linalg/linalg.py b/numpy/linalg/linalg.py
index 697193321..78927d1ae 100644
--- a/numpy/linalg/linalg.py
+++ b/numpy/linalg/linalg.py
@@ -18,17 +18,17 @@ import functools
import operator
import warnings
+from .._utils import set_module
from numpy.core import (
array, asarray, zeros, empty, empty_like, intc, single, double,
csingle, cdouble, inexact, complexfloating, newaxis, all, Inf, dot,
add, multiply, sqrt, sum, isfinite,
- finfo, errstate, geterrobj, moveaxis, amin, amax, product, abs,
+ finfo, errstate, geterrobj, moveaxis, amin, amax, prod, abs,
atleast_2d, intp, asanyarray, object_, matmul,
swapaxes, divide, count_nonzero, isnan, sign, argsort, sort,
reciprocal
)
from numpy.core.multiarray import normalize_axis_index
-from numpy.core.overrides import set_module
from numpy.core import overrides
from numpy.lib.twodim_base import triu, eye
from numpy.linalg import _umath_linalg
@@ -42,11 +42,11 @@ fortran_int = intc
@set_module('numpy.linalg')
-class LinAlgError(Exception):
+class LinAlgError(ValueError):
"""
Generic Python-exception-derived object raised by linalg functions.
- General purpose exception class, derived from Python's exception.Exception
+ General purpose exception class, derived from Python's ValueError
class, programmatically raised in linalg functions when a Linear
Algebra-related condition would prevent further correct execution of the
function.
@@ -138,24 +138,24 @@ def _commonType(*arrays):
result_type = single
is_complex = False
for a in arrays:
- if issubclass(a.dtype.type, inexact):
- if isComplexType(a.dtype.type):
+ type_ = a.dtype.type
+ if issubclass(type_, inexact):
+ if isComplexType(type_):
is_complex = True
- rt = _realType(a.dtype.type, default=None)
- if rt is None:
+ rt = _realType(type_, default=None)
+ if rt is double:
+ result_type = double
+ elif rt is None:
# unsupported inexact scalar
raise TypeError("array type %s is unsupported in linalg" %
(a.dtype.name,))
else:
- rt = double
- if rt is double:
result_type = double
if is_complex:
- t = cdouble
result_type = _complex_types_map[result_type]
+ return cdouble, result_type
else:
- t = double
- return t, result_type
+ return double, result_type
def _to_native_byte_order(*arrays):
@@ -196,7 +196,7 @@ def _assert_finite(*arrays):
def _is_empty_2d(arr):
# check size first for efficiency
- return arr.size == 0 and product(arr.shape[-2:]) == 0
+ return arr.size == 0 and prod(arr.shape[-2:]) == 0
def transpose(a):
@@ -899,12 +899,12 @@ def qr(a, mode='reduced'):
msg = "".join((
"The 'full' option is deprecated in favor of 'reduced'.\n",
"For backward compatibility let mode default."))
- warnings.warn(msg, DeprecationWarning, stacklevel=3)
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)
mode = 'reduced'
elif mode in ('e', 'economic'):
# 2013-04-01, 1.8
msg = "The 'economic' option is deprecated."
- warnings.warn(msg, DeprecationWarning, stacklevel=3)
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)
mode = 'economic'
else:
raise ValueError(f"Unrecognized mode '{mode}'")
@@ -943,7 +943,7 @@ def qr(a, mode='reduced'):
return wrap(a)
# mc is the number of columns in the resulting q
- # matrix. If the mode is complete then it is
+ # matrix. If the mode is complete then it is
# same as number of rows, and if the mode is reduced,
# then it is the minimum of number of rows and columns.
if mode == 'complete' and m > n:
@@ -2267,7 +2267,7 @@ def lstsq(a, b, rcond="warn"):
"To use the future default and silence this warning "
"we advise to pass `rcond=None`, to keep using the old, "
"explicitly pass `rcond=-1`.",
- FutureWarning, stacklevel=3)
+ FutureWarning, stacklevel=2)
rcond = -1
if rcond is None:
rcond = finfo(t).eps * max(n, m)
diff --git a/numpy/linalg/meson.build b/numpy/linalg/meson.build
new file mode 100644
index 000000000..083692913
--- /dev/null
+++ b/numpy/linalg/meson.build
@@ -0,0 +1,56 @@
+lapack_lite_sources = [
+ 'lapack_lite/f2c.c',
+ 'lapack_lite/f2c_c_lapack.c',
+ 'lapack_lite/f2c_d_lapack.c',
+ 'lapack_lite/f2c_s_lapack.c',
+ 'lapack_lite/f2c_z_lapack.c',
+ 'lapack_lite/f2c_blas.c',
+ 'lapack_lite/f2c_config.c',
+ 'lapack_lite/f2c_lapack.c',
+ 'lapack_lite/python_xerbla.c',
+]
+
+# TODO: ILP64 support
+
+lapack_lite_module_src = ['lapack_litemodule.c']
+if not have_lapack
+ warning('LAPACK was not found, NumPy is using an unoptimized, naive build from sources!')
+ lapack_lite_module_src += lapack_lite_sources
+endif
+
+py.extension_module('lapack_lite',
+ lapack_lite_module_src,
+ dependencies: [np_core_dep, lapack],
+ install: true,
+ subdir: 'numpy/linalg',
+)
+
+_umath_linalg_src = ['umath_linalg.cpp'] + lapack_lite_sources
+
+py.extension_module('_umath_linalg',
+ _umath_linalg_src,
+ dependencies: np_core_dep,
+ link_with: npymath_lib,
+ install: true,
+ subdir: 'numpy/linalg',
+)
+
+py.install_sources(
+ [
+ '__init__.py',
+ '__init__.pyi',
+ 'linalg.py',
+ 'linalg.pyi',
+ ],
+ subdir: 'numpy/linalg'
+)
+
+py.install_sources(
+ [
+ 'tests/__init__.py',
+ 'tests/test_deprecations.py',
+ 'tests/test_linalg.py',
+ 'tests/test_regression.py',
+ ],
+ subdir: 'numpy/linalg/tests'
+)
diff --git a/numpy/linalg/setup.py b/numpy/linalg/setup.py
index 1c4e1295e..6f72635ab 100644
--- a/numpy/linalg/setup.py
+++ b/numpy/linalg/setup.py
@@ -4,7 +4,6 @@ import sysconfig
def configuration(parent_package='', top_path=None):
from numpy.distutils.misc_util import Configuration
- from numpy.distutils.ccompiler_opt import NPY_CXX_FLAGS
from numpy.distutils.system_info import get_info, system_info
config = Configuration('linalg', parent_package, top_path)
@@ -81,7 +80,6 @@ def configuration(parent_package='', top_path=None):
sources=['umath_linalg.cpp', get_lapack_lite_sources],
depends=['lapack_lite/f2c.h'],
extra_info=lapack_info,
- extra_cxx_compile_args=NPY_CXX_FLAGS,
libraries=['npymath'],
)
config.add_data_files('*.pyi')
diff --git a/numpy/linalg/tests/test_linalg.py b/numpy/linalg/tests/test_linalg.py
index f871a5f8e..b1dbd4c22 100644
--- a/numpy/linalg/tests/test_linalg.py
+++ b/numpy/linalg/tests/test_linalg.py
@@ -19,7 +19,7 @@ from numpy.linalg.linalg import _multi_dot_matrix_chain_order
from numpy.testing import (
assert_, assert_equal, assert_raises, assert_array_equal,
assert_almost_equal, assert_allclose, suppress_warnings,
- assert_raises_regex, HAS_LAPACK64,
+ assert_raises_regex, HAS_LAPACK64, IS_WASM
)
@@ -1063,6 +1063,7 @@ class TestMatrixPower:
assert_raises(LinAlgError, matrix_power, np.array([[1], [2]], dt), 1)
assert_raises(LinAlgError, matrix_power, np.ones((4, 3, 2), dt), 1)
+ @pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
def test_exceptions_not_invertible(self, dt):
if dt in self.dtnoinv:
return
@@ -1845,6 +1846,7 @@ def test_byteorder_check():
assert_array_equal(res, routine(sw_arr))
+@pytest.mark.skipif(IS_WASM, reason="fp errors don't work in wasm")
def test_generalized_raise_multiloop():
# It should raise an error even if the error doesn't occur in the
# last iteration of the ufunc inner loop
@@ -1908,6 +1910,7 @@ def test_xerbla_override():
pytest.skip('Numpy xerbla not linked in.')
+@pytest.mark.skipif(IS_WASM, reason="Cannot start subprocess")
@pytest.mark.slow
def test_sdot_bug_8577():
# Regression test that loading certain other libraries does not
diff --git a/numpy/linalg/tests/test_regression.py b/numpy/linalg/tests/test_regression.py
index 7ed932bc9..af38443a9 100644
--- a/numpy/linalg/tests/test_regression.py
+++ b/numpy/linalg/tests/test_regression.py
@@ -107,10 +107,7 @@ class TestRegression:
assert_raises(ValueError, linalg.norm, testvector, ord='nuc')
assert_raises(ValueError, linalg.norm, testvector, ord=np.inf)
assert_raises(ValueError, linalg.norm, testvector, ord=-np.inf)
- with warnings.catch_warnings():
- warnings.simplefilter("error", DeprecationWarning)
- assert_raises((AttributeError, DeprecationWarning),
- linalg.norm, testvector, ord=0)
+ assert_raises(ValueError, linalg.norm, testvector, ord=0)
assert_raises(ValueError, linalg.norm, testvector, ord=-1)
assert_raises(ValueError, linalg.norm, testvector, ord=-2)
diff --git a/numpy/linalg/umath_linalg.cpp b/numpy/linalg/umath_linalg.cpp
index bbb4bb896..68db2b2f1 100644
--- a/numpy/linalg/umath_linalg.cpp
+++ b/numpy/linalg/umath_linalg.cpp
@@ -22,6 +22,7 @@
#include <cstdio>
#include <cassert>
#include <cmath>
+#include <type_traits>
#include <utility>
@@ -1148,7 +1149,7 @@ slogdet(char **args,
void *NPY_UNUSED(func))
{
fortran_int m;
- npy_uint8 *tmp_buff = NULL;
+ char *tmp_buff = NULL;
size_t matrix_size;
size_t pivot_size;
size_t safe_m;
@@ -1162,10 +1163,11 @@ slogdet(char **args,
*/
INIT_OUTER_LOOP_3
m = (fortran_int) dimensions[0];
- safe_m = m;
+ /* avoid empty malloc (buffers likely unused) and ensure m is `size_t` */
+ safe_m = m != 0 ? m : 1;
matrix_size = safe_m * safe_m * sizeof(typ);
pivot_size = safe_m * sizeof(fortran_int);
- tmp_buff = (npy_uint8 *)malloc(matrix_size + pivot_size);
+ tmp_buff = (char *)malloc(matrix_size + pivot_size);
if (tmp_buff) {
LINEARIZE_DATA_t lin_data;
@@ -1182,6 +1184,13 @@ slogdet(char **args,
free(tmp_buff);
}
+ else {
+ /* TODO: Requires use of new ufunc API to indicate error return */
+ NPY_ALLOW_C_API_DEF
+ NPY_ALLOW_C_API;
+ PyErr_NoMemory();
+ NPY_DISABLE_C_API;
+ }
}
template<typename typ, typename basetyp>
@@ -1192,7 +1201,7 @@ det(char **args,
void *NPY_UNUSED(func))
{
fortran_int m;
- npy_uint8 *tmp_buff;
+ char *tmp_buff;
size_t matrix_size;
size_t pivot_size;
size_t safe_m;
@@ -1206,10 +1215,11 @@ det(char **args,
*/
INIT_OUTER_LOOP_2
m = (fortran_int) dimensions[0];
- safe_m = m;
+ /* avoid empty malloc (buffers likely unused) and ensure m is `size_t` */
+ safe_m = m != 0 ? m : 1;
matrix_size = safe_m * safe_m * sizeof(typ);
pivot_size = safe_m * sizeof(fortran_int);
- tmp_buff = (npy_uint8 *)malloc(matrix_size + pivot_size);
+ tmp_buff = (char *)malloc(matrix_size + pivot_size);
if (tmp_buff) {
LINEARIZE_DATA_t lin_data;
@@ -1230,6 +1240,13 @@ det(char **args,
free(tmp_buff);
}
+ else {
+ /* TODO: Requires use of new ufunc API to indicate error return */
+ NPY_ALLOW_C_API_DEF
+ NPY_ALLOW_C_API;
+ PyErr_NoMemory();
+ NPY_DISABLE_C_API;
+ }
}
@@ -3737,16 +3754,16 @@ scalar_trait)
fortran_int lda = fortran_int_max(1, m);
fortran_int ldb = fortran_int_max(1, fortran_int_max(m,n));
- mem_buff = (npy_uint8 *)malloc(a_size + b_size + s_size);
-
- if (!mem_buff)
- goto error;
+ size_t msize = a_size + b_size + s_size;
+ mem_buff = (npy_uint8 *)malloc(msize != 0 ? msize : 1);
+ if (!mem_buff) {
+ goto no_memory;
+ }
a = mem_buff;
b = a + a_size;
s = b + b_size;
-
params->M = m;
params->N = n;
params->NRHS = nrhs;
@@ -3766,9 +3783,9 @@ scalar_trait)
params->RWORK = NULL;
params->LWORK = -1;
- if (call_gelsd(params) != 0)
+ if (call_gelsd(params) != 0) {
goto error;
-
+ }
work_count = (fortran_int)work_size_query;
work_size = (size_t) work_size_query * sizeof(ftyp);
@@ -3776,9 +3793,9 @@ scalar_trait)
}
mem_buff2 = (npy_uint8 *)malloc(work_size + iwork_size);
- if (!mem_buff2)
- goto error;
-
+ if (!mem_buff2) {
+ goto no_memory;
+ }
work = mem_buff2;
iwork = work + work_size;
@@ -3788,12 +3805,18 @@ scalar_trait)
params->LWORK = work_count;
return 1;
+
+ no_memory:
+ NPY_ALLOW_C_API_DEF
+ NPY_ALLOW_C_API;
+ PyErr_NoMemory();
+ NPY_DISABLE_C_API;
+
error:
TRACE_TXT("%s failed init\n", __FUNCTION__);
free(mem_buff);
free(mem_buff2);
memset(params, 0, sizeof(*params));
-
return 0;
}
@@ -3857,16 +3880,17 @@ using frealtyp = basetype_t<ftyp>;
fortran_int lda = fortran_int_max(1, m);
fortran_int ldb = fortran_int_max(1, fortran_int_max(m,n));
- mem_buff = (npy_uint8 *)malloc(a_size + b_size + s_size);
+ size_t msize = a_size + b_size + s_size;
+ mem_buff = (npy_uint8 *)malloc(msize != 0 ? msize : 1);
- if (!mem_buff)
- goto error;
+ if (!mem_buff) {
+ goto no_memory;
+ }
a = mem_buff;
b = a + a_size;
s = b + b_size;
-
params->M = m;
params->N = n;
params->NRHS = nrhs;
@@ -3887,8 +3911,9 @@ using frealtyp = basetype_t<ftyp>;
params->RWORK = &rwork_size_query;
params->LWORK = -1;
- if (call_gelsd(params) != 0)
+ if (call_gelsd(params) != 0) {
goto error;
+ }
work_count = (fortran_int)work_size_query.r;
@@ -3898,8 +3923,9 @@ using frealtyp = basetype_t<ftyp>;
}
mem_buff2 = (npy_uint8 *)malloc(work_size + rwork_size + iwork_size);
- if (!mem_buff2)
- goto error;
+ if (!mem_buff2) {
+ goto no_memory;
+ }
work = mem_buff2;
rwork = work + work_size;
@@ -3911,6 +3937,13 @@ using frealtyp = basetype_t<ftyp>;
params->LWORK = work_count;
return 1;
+
+ no_memory:
+ NPY_ALLOW_C_API_DEF
+ NPY_ALLOW_C_API;
+ PyErr_NoMemory();
+ NPY_DISABLE_C_API;
+
error:
TRACE_TXT("%s failed init\n", __FUNCTION__);
free(mem_buff);