Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cb740cb

Browse files
ENH: Adopt new macOS Accelerate BLAS/LAPACK Interfaces, including ILP64 (#24053)
macOS 13.3 shipped with an updated Accelerate framework that provides BLAS / LAPACK. The new version is aligned with Netlib's v3.9.1 and also supports ILP64. The changes here adopt those new interfaces when available. - New interfaces are used when ACCELERATE_NEW_LAPACK is defined. - ILP64 interfaces are used when both ACCELERATE_NEW_LAPACK and ACCELERATE_LAPACK_ILP64 are defined. macOS 13.3 now ships with 3 different sets of BLAS / LAPACK interfaces: - LP64 / LAPACK v3.2.1 - legacy interfaces kept for compatibility - LP64 / LAPACK v3.9.1 - new interfaces - ILP64 / LAPACK v3.9.1 - new interfaces with ILP64 support For LP64, we want to support building against macOS 13.3+ SDK, but having it work on pre-13.3 systems. To that end, we created wrappers for each API that do a runtime check on which set of API is available and should be used. However, these were deemed potentially too complex to include during review of gh-24053, and left out in this commit. Please see gh-24053 for those. ILP64 is only supported on macOS 13.3+ and does not use additional wrappers. We've included support for both distutils and Meson builds. All tests pass on Apple silicon and Intel based Macs. A new CI job for Accelerate ILP64 on x86-64 was added as well. Benchmarks ILP64 Accelerate vs OpenBLAS before after ratio [73f0cf4f] [d1572653] <openblas-ilp64> <accelerate-ilp64> n/a n/a n/a bench_linalg.Linalg.time_op('det', 'float16') n/a n/a n/a bench_linalg.Linalg.time_op('pinv', 'float16') n/a n/a n/a bench_linalg.Linalg.time_op('svd', 'float16') failed failed n/a bench_linalg.LinalgSmallArrays.time_det_small_array + 3.96±0.1μs 5.04±0.4μs 1.27 bench_linalg.Linalg.time_op('norm', 'float32') 1.43±0.04ms 1.43±0ms 1.00 bench_linalg.Einsum.time_einsum_outer(<class 'numpy.float32'>) 12.7±0.4μs 12.7±0.3μs 1.00 bench_linalg.Einsum.time_einsum_sum_mul2(<class 'numpy.float32'>) 24.1±0.8μs 24.1±0.04μs 1.00 bench_linalg.Linalg.time_op('norm', 'float16') 9.48±0.2ms 9.48±0.3ms 1.00 bench_linalg.Einsum.time_einsum_outer(<class 'numpy.float64'>) 609±20μs 609±2μs 1.00 bench_linalg.Einsum.time_einsum_noncon_outer(<class 'numpy.float32'>) 64.9±2μs 64.7±0.07μs 1.00 bench_linalg.Einsum.time_einsum_contig_outstride0(<class 'numpy.float64'>) 1.24±0.03ms 1.24±0.01ms 1.00 bench_linalg.Einsum.time_einsum_noncon_outer(<class 'numpy.float64'>) 102±3μs 102±0.2μs 1.00 bench_linalg.Einsum.time_einsum_contig_contig(<class 'numpy.float64'>) 21.9±0.8μs 21.8±0.02μs 1.00 bench_linalg.Einsum.time_einsum_multiply(<class 'numpy.float64'>) 22.8±0.2ms 22.7±0.3ms 0.99 bench_linalg.Eindot.time_einsum_ijk_jil_kl 13.3±0.4μs 13.3±0.02μs 0.99 bench_linalg.Einsum.time_einsum_sum_mul2(<class 'numpy.float64'>) 9.56±0.3μs 9.49±0.2μs 0.99 bench_linalg.Einsum.time_einsum_noncon_contig_contig(<class 'numpy.float64'>) 7.31±0.2μs 7.26±0.08μs 0.99 bench_linalg.Einsum.time_einsum_noncon_contig_outstride0(<class 'numpy.float32'>) 5.60±0.2ms 5.55±0.02ms 0.99 bench_linalg.Eindot.time_einsum_ij_jk_a_b 37.1±1μs 36.7±0.1μs 0.99 bench_linalg.Einsum.time_einsum_contig_outstride0(<class 'numpy.float32'>) 13.5±0.4μs 13.4±0.05μs 0.99 bench_linalg.Einsum.time_einsum_sum_mul(<class 'numpy.float64'>) 1.03±0.03μs 1.02±0μs 0.99 bench_linalg.LinalgSmallArrays.time_norm_small_array 51.6±2μs 51.0±0.09μs 0.99 bench_linalg.Einsum.time_einsum_contig_contig(<class 'numpy.float32'>) 15.2±0.5μs 15.0±0.04μs 0.99 bench_linalg.Einsum.time_einsum_noncon_sum_mul2(<class 'numpy.float64'>) 13.9±0.4μs 13.7±0.02μs 0.99 bench_linalg.Einsum.time_einsum_noncon_sum_mul2(<class 'numpy.float32'>) 415±10μs 409±0.4μs 0.99 bench_linalg.Eindot.time_einsum_i_ij_j 9.29±0.3μs 9.01±0.03μs 0.97 bench_linalg.Einsum.time_einsum_noncon_mul(<class 'numpy.float64'>) 18.2±0.6μs 17.6±0.04μs 0.97 bench_linalg.Einsum.time_einsum_multiply(<class 'numpy.float32'>) 509±40μs 492±10μs 0.97 bench_linalg.Einsum.time_einsum_mul(<class 'numpy.float64'>) 9.63±0.3μs 9.28±0.09μs 0.96 bench_linalg.Einsum.time_einsum_noncon_contig_contig(<class 'numpy.float32'>) 9.08±0.2μs 8.73±0.02μs 0.96 bench_linalg.Einsum.time_einsum_noncon_mul(<class 'numpy.float32'>) 15.6±0.5μs 15.0±0.04μs 0.96 bench_linalg.Einsum.time_einsum_noncon_sum_mul(<class 'numpy.float64'>) 7.74±0.2μs 7.39±0.04μs 0.95 bench_linalg.Einsum.time_einsum_noncon_contig_outstride0(<class 'numpy.float64'>) 18.6±0.6μs 17.7±0.03μs 0.95 bench_linalg.Einsum.time_einsum_noncon_multiply(<class 'numpy.float32'>) 14.5±0.4μs 13.7±0.03μs 0.95 bench_linalg.Einsum.time_einsum_noncon_sum_mul(<class 'numpy.float32'>) 13.3±0.6μs 12.5±0.3μs 0.94 bench_linalg.Einsum.time_einsum_sum_mul(<class 'numpy.float32'>) 23.5±0.5μs 21.9±0.05μs 0.93 bench_linalg.Einsum.time_einsum_noncon_multiply(<class 'numpy.float64'>) 264±20μs 243±4μs 0.92 bench_linalg.Einsum.time_einsum_mul(<class 'numpy.float32'>) - 177±50μs 132±0.6μs 0.75 bench_linalg.Eindot.time_dot_trans_at_a - 10.7±0.3μs 7.13±0.01μs 0.67 bench_linalg.Linalg.time_op('norm', 'int16') - 97.5±2μs 64.7±0.1μs 0.66 bench_linalg.Eindot.time_matmul_trans_a_at - 8.87±0.3μs 5.76±0μs 0.65 bench_linalg.Linalg.time_op('norm', 'longfloat') - 8.90±0.3μs 5.77±0.01μs 0.65 bench_linalg.Linalg.time_op('norm', 'float64') - 8.48±0.3μs 5.40±0.01μs 0.64 bench_linalg.Linalg.time_op('norm', 'int64') - 106±2μs 66.5±8μs 0.63 bench_linalg.Eindot.time_inner_trans_a_a - 8.25±0.3μs 5.16±0μs 0.62 bench_linalg.Linalg.time_op('norm', 'int32') - 103±5ms 64.6±0.5ms 0.62 bench_import.Import.time_linalg - 106±3μs 66.0±0.1μs 0.62 bench_linalg.Eindot.time_dot_trans_a_at - 202±20μs 124±0.6μs 0.61 bench_linalg.Eindot.time_matmul_trans_at_a - 31.5±10μs 19.3±0.02μs 0.61 bench_linalg.Eindot.time_dot_d_dot_b_c - 32.4±20μs 19.7±0.03μs 0.61 bench_linalg.Eindot.time_matmul_d_matmul_b_c - 5.05±1ms 3.06±0.09ms 0.61 bench_linalg.Linalg.time_op('svd', 'complex128') - 5.35±0.9ms 3.09±0.09ms 0.58 bench_linalg.Linalg.time_op('svd', 'complex64') - 6.37±3ms 3.27±0.1ms 0.51 bench_linalg.Linalg.time_op('pinv', 'complex128') - 7.26±8ms 3.24±0.1ms 0.45 bench_linalg.Linalg.time_op('pinv', 'complex64') - 519±100μs 219±0.8μs 0.42 bench_linalg.Linalg.time_op('det', 'complex64') - 31.3±0.9μs 12.8±0.1μs 0.41 bench_linalg.Linalg.time_op('norm', 'complex128') - 2.44±0.7ms 924±1μs 0.38 bench_linalg.Linalg.time_op('pinv', 'float64') - 29.9±0.8μs 10.8±0.01μs 0.36 bench_linalg.Linalg.time_op('norm', 'complex64') - 2.56±0.5ms 924±1μs 0.36 bench_linalg.Linalg.time_op('pinv', 'float32') - 2.63±0.5ms 924±0.6μs 0.35 bench_linalg.Linalg.time_op('pinv', 'int64') - 2.68±0.7ms 927±10μs 0.35 bench_linalg.Linalg.time_op('pinv', 'int32') - 2.68±0.5ms 927±10μs 0.35 bench_linalg.Linalg.time_op('pinv', 'int16') - 2.93±0.6ms 925±2μs 0.32 bench_linalg.Linalg.time_op('pinv', 'longfloat') - 809±500μs 215±0.2μs 0.27 bench_linalg.Linalg.time_op('det', 'complex128') - 3.67±0.9ms 895±20μs 0.24 bench_linalg.Eindot.time_tensordot_a_b_axes_1_0_0_1 - 489±100μs 114±20μs 0.23 bench_linalg.Eindot.time_inner_trans_a_ac - 3.64±0.7ms 777±0.3μs 0.21 bench_linalg.Lstsq.time_numpy_linalg_lstsq_a__b_float64 - 755±90μs 157±10μs 0.21 bench_linalg.Eindot.time_dot_a_b - 4.63±1ms 899±9μs 0.19 bench_linalg.Linalg.time_op('svd', 'longfloat') - 5.19±1ms 922±10μs 0.18 bench_linalg.Linalg.time_op('svd', 'float64') - 599±200μs 89.4±2μs 0.15 bench_linalg.Eindot.time_matmul_trans_atc_a - 956±200μs 140±10μs 0.15 bench_linalg.Eindot.time_matmul_a_b - 6.45±3ms 903±10μs 0.14 bench_linalg.Linalg.time_op('svd', 'float32') - 6.42±3ms 896±0.7μs 0.14 bench_linalg.Linalg.time_op('svd', 'int32') - 6.47±4ms 902±5μs 0.14 bench_linalg.Linalg.time_op('svd', 'int64') - 6.52±1ms 899±2μs 0.14 bench_linalg.Linalg.time_op('svd', 'int16') - 799±300μs 109±2μs 0.14 bench_linalg.Eindot.time_dot_trans_atc_a - 502±100μs 65.0±0.2μs 0.13 bench_linalg.Eindot.time_dot_trans_a_atc - 542±300μs 64.2±0.05μs 0.12 bench_linalg.Eindot.time_matmul_trans_a_atc - 458±300μs 41.6±0.09μs 0.09 bench_linalg.Linalg.time_op('det', 'int32') - 471±100μs 41.9±0.03μs 0.09 bench_linalg.Linalg.time_op('det', 'float32') - 510±100μs 43.6±0.06μs 0.09 bench_linalg.Linalg.time_op('det', 'int16') - 478±200μs 39.6±0.05μs 0.08 bench_linalg.Linalg.time_op('det', 'longfloat') - 599±200μs 39.6±0.09μs 0.07 bench_linalg.Linalg.time_op('det', 'float64') - 758±300μs 41.6±0.1μs 0.05 bench_linalg.Linalg.time_op('det', 'int64') Co-authored-by: Ralf Gommers <[email protected]>
1 parent a395e3d commit cb740cb

File tree

6 files changed

+139
-12
lines changed

6 files changed

+139
-12
lines changed

.github/workflows/macos.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,38 @@ jobs:
9898
run: |
9999
conda activate numpy-dev
100100
ccache -s
101+
102+
accelerate:
103+
name: Accelerate ILP64
104+
if: "github.repository == 'numpy/numpy'"
105+
runs-on: macos-13
106+
steps:
107+
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
108+
with:
109+
submodules: recursive
110+
fetch-depth: 0
111+
112+
- uses: actions/setup-python@61a6322f88396a6271a6ee3565807d608ecaddd1 # v4.7.0
113+
with:
114+
python-version: '3.10'
115+
116+
- uses: maxim-lobanov/setup-xcode@9a697e2b393340c3cacd97468baa318e4c883d98 # v1.5.1
117+
with:
118+
xcode-version: '14.3'
119+
120+
- name: Install dependencies
121+
run: |
122+
pip install -r build_requirements.txt
123+
pip install pytest pytest-xdist hypothesis
124+
125+
- name: Build NumPy against Accelerate (ILP64)
126+
run: |
127+
spin build -- -Dblas=accelerate -Dlapack=accelerate -Duse-ilp64=true
128+
129+
- name: Show meson-log.txt
130+
if: always()
131+
run: 'cat build/meson-logs/meson-log.txt'
132+
133+
- name: Test
134+
run: |
135+
spin test -j2
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Support for the updated Accelerate BLAS/LAPACK library, including ILP64 (64-bit
2+
integer) support, in macOS 13.3 has been added. This brings arm64 support, and
3+
significant performance improvements of up to 10x for commonly used linear
4+
algebra operations. When Accelerate is selected at build time, the 13.3+
5+
version will automatically be used if available.

numpy/core/src/common/npy_cblas.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,21 @@ enum CBLAS_SIDE {CblasLeft=141, CblasRight=142};
2525

2626
#define CBLAS_INDEX size_t /* this may vary between platforms */
2727

28+
#ifdef ACCELERATE_NEW_LAPACK
29+
#if __MAC_OS_X_VERSION_MAX_ALLOWED < 130300
30+
#ifdef HAVE_BLAS_ILP64
31+
#error "Accelerate ILP64 support is only available with macOS 13.3 SDK or later"
32+
#endif
33+
#else
34+
#define NO_APPEND_FORTRAN
35+
#ifdef HAVE_BLAS_ILP64
36+
#define BLAS_SYMBOL_SUFFIX $NEWLAPACK$ILP64
37+
#else
38+
#define BLAS_SYMBOL_SUFFIX $NEWLAPACK
39+
#endif
40+
#endif
41+
#endif
42+
2843
#ifdef NO_APPEND_FORTRAN
2944
#define BLAS_FORTRAN_SUFFIX
3045
#else

numpy/distutils/system_info.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
_numpy_info:Numeric
4848
_pkg_config_info:None
4949
accelerate_info:accelerate
50+
accelerate_lapack_info:accelerate
5051
agg2_info:agg2
5152
amd_info:amd
5253
atlas_3_10_blas_info:atlas
@@ -534,6 +535,7 @@ def get_info(name, notfound_action=0):
534535
'lapack_ssl2': lapack_ssl2_info,
535536
'blas_ssl2': blas_ssl2_info,
536537
'accelerate': accelerate_info, # use blas_opt instead
538+
'accelerate_lapack': accelerate_lapack_info,
537539
'openblas64_': openblas64__info,
538540
'openblas64__lapack': openblas64__lapack_info,
539541
'openblas_ilp64': openblas_ilp64_info,
@@ -2015,14 +2017,17 @@ def _check_info(self, info):
20152017

20162018
class lapack_ilp64_opt_info(lapack_opt_info, _ilp64_opt_info_mixin):
20172019
notfounderror = LapackILP64NotFoundError
2018-
lapack_order = ['openblas64_', 'openblas_ilp64']
2020+
lapack_order = ['openblas64_', 'openblas_ilp64', 'accelerate']
20192021
order_env_var_name = 'NPY_LAPACK_ILP64_ORDER'
20202022

20212023
def _calc_info(self, name):
2024+
print('lapack_ilp64_opt_info._calc_info(name=%s)' % (name))
20222025
info = get_info(name + '_lapack')
20232026
if self._check_info(info):
20242027
self.set_info(**info)
20252028
return True
2029+
else:
2030+
print('%s_lapack does not exist' % (name))
20262031
return False
20272032

20282033

@@ -2163,7 +2168,7 @@ def calc_info(self):
21632168

21642169
class blas_ilp64_opt_info(blas_opt_info, _ilp64_opt_info_mixin):
21652170
notfounderror = BlasILP64NotFoundError
2166-
blas_order = ['openblas64_', 'openblas_ilp64']
2171+
blas_order = ['openblas64_', 'openblas_ilp64', 'accelerate']
21672172
order_env_var_name = 'NPY_BLAS_ILP64_ORDER'
21682173

21692174
def _calc_info(self, name):
@@ -2625,13 +2630,27 @@ def calc_info(self):
26252630
link_args.extend(['-Wl,-framework', '-Wl,vecLib'])
26262631

26272632
if args:
2633+
macros = [
2634+
('NO_ATLAS_INFO', 3),
2635+
('HAVE_CBLAS', None),
2636+
('ACCELERATE_NEW_LAPACK', None),
2637+
]
2638+
if(os.getenv('NPY_USE_BLAS_ILP64', None)):
2639+
print('Setting HAVE_BLAS_ILP64')
2640+
macros += [
2641+
('HAVE_BLAS_ILP64', None),
2642+
('ACCELERATE_LAPACK_ILP64', None),
2643+
]
26282644
self.set_info(extra_compile_args=args,
26292645
extra_link_args=link_args,
2630-
define_macros=[('NO_ATLAS_INFO', 3),
2631-
('HAVE_CBLAS', None)])
2646+
define_macros=macros)
26322647

26332648
return
26342649

2650+
class accelerate_lapack_info(accelerate_info):
2651+
def _calc_info(self):
2652+
return super()._calc_info()
2653+
26352654
class blas_src_info(system_info):
26362655
# BLAS_SRC is deprecated, please do not use this!
26372656
# Build or install a BLAS library via your package manager or from

numpy/linalg/meson.build

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Note that `python_xerbla.c` was excluded on Windows in setup.py;
22
# unclear why and it seems needed, so unconditionally used here.
3-
lapack_lite_sources = [
4-
'lapack_lite/python_xerbla.c',
5-
]
3+
python_xerbla_sources = ['lapack_lite/python_xerbla.c']
4+
5+
lapack_lite_sources = []
66
if not have_lapack
7-
lapack_lite_sources += [
7+
lapack_lite_sources = [
88
'lapack_lite/f2c.c',
99
'lapack_lite/f2c_c_lapack.c',
1010
'lapack_lite/f2c_d_lapack.c',
@@ -19,6 +19,7 @@ endif
1919
py.extension_module('lapack_lite',
2020
[
2121
'lapack_litemodule.c',
22+
python_xerbla_sources,
2223
lapack_lite_sources,
2324
],
2425
dependencies: [np_core_dep, blas_dep, lapack_dep],
@@ -29,6 +30,7 @@ py.extension_module('lapack_lite',
2930
py.extension_module('_umath_linalg',
3031
[
3132
'umath_linalg.cpp',
33+
python_xerbla_sources,
3234
lapack_lite_sources,
3335
],
3436
dependencies: [np_core_dep, blas_dep, lapack_dep],

numpy/meson.build

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ else
4848
]
4949
endif
5050

51+
macOS13_3_or_later = false
52+
if host_machine.system() == 'darwin'
53+
r = run_command('xcrun', '-sdk', 'macosx', '--show-sdk-version', check: true)
54+
sdkVersion = r.stdout().strip()
55+
56+
macOS13_3_or_later = sdkVersion.version_compare('>=13.3')
57+
endif
5158

5259
# This is currently injected directly into CFLAGS/CXXFLAGS for wheel builds
5360
# (see cibuildwheel settings in pyproject.toml), but used by CI jobs already
@@ -81,6 +88,7 @@ endif
8188
# https://github.com/mesonbuild/meson/issues/2835
8289
blas_name = get_option('blas')
8390
lapack_name = get_option('lapack')
91+
8492
# pkg-config uses a lower-case name while CMake uses a capitalized name, so try
8593
# that too to make the fallback detection with CMake work
8694
if blas_name == 'openblas'
@@ -90,6 +98,23 @@ if blas_name == 'openblas'
9098
_openblas_names = ['openblas', 'OpenBLAS']
9199
endif
92100
blas = dependency(_openblas_names, required: false)
101+
elif blas_name.to_lower() == 'accelerate'
102+
# macOS 13.3+ has updated interfaces aligned with BLAS/LAPACK 3.9.1. Use them if available.
103+
if macOS13_3_or_later
104+
accelerate_compile_args = ['-DACCELERATE_NEW_LAPACK']
105+
if(use_ilp64)
106+
accelerate_compile_args += '-DACCELERATE_LAPACK_ILP64'
107+
endif
108+
blas = declare_dependency(
109+
compile_args: accelerate_compile_args,
110+
dependencies: dependency('Accelerate')
111+
)
112+
else
113+
if(use_ilp64)
114+
error('macOS SDK 13.3+ is required for ILP64 support.')
115+
endif
116+
blas = dependency('Accelerate')
117+
endif
93118
else
94119
blas = dependency(blas_name, required: false)
95120
endif
@@ -112,14 +137,22 @@ if have_blas
112137
# `dependency('blas', modules: cblas)`
113138
# see https://github.com/mesonbuild/meson/pull/10921.
114139
have_cblas = false
115-
if cc.links('''
140+
if blas_name.to_lower() == 'accelerate'
141+
_cblas_header = '<Accelerate/Accelerate.h>'
142+
elif blas_name.to_lower().startswith('mkl')
143+
_cblas_header = '<mkl_cblas.h>'
144+
else
145+
_cblas_header = '<cblas.h>'
146+
endif
147+
if cc.links(f'''
116148
#ifndef BLAS_SYMBOL_SUFFIX
117149
# define BLAS_SYMBOL_SUFFIX
118150
#endif
119151
#define EXPAND(suffix) cblas_ddot ## suffix
120152
#define DDOT(suffix) EXPAND(suffix)
121153
122-
#include <cblas.h>
154+
#include @_cblas_header@
155+
123156
int main(int argc, const char *argv[])
124157
{
125158
double a[4] = {1,2,3,4};
@@ -178,9 +211,27 @@ else
178211
endif
179212

180213
if lapack_name == 'openblas'
181-
lapack_name = ['openblas', 'OpenBLAS']
214+
lapack_dep = dependency(['openblas', 'OpenBLAS'], required: false)
215+
elif lapack_name.to_lower() == 'accelerate'
216+
# macOS 13.3+ has updated interfaces aligned with BLAS/LAPACK 3.9.1. Use them if available.
217+
if macOS13_3_or_later
218+
accelerate_compile_args = ['-DACCELERATE_NEW_LAPACK']
219+
if(use_ilp64)
220+
accelerate_compile_args += '-DACCELERATE_LAPACK_ILP64'
221+
endif
222+
lapack_dep = declare_dependency(
223+
compile_args: accelerate_compile_args,
224+
dependencies: dependency('Accelerate')
225+
)
226+
else
227+
if(use_ilp64)
228+
error('macOS SDK 13.3+ is required for ILP64 support.')
229+
endif
230+
lapack_dep = dependency('Accelerate')
231+
endif
232+
else
233+
lapack_dep = dependency(lapack_name, required: false)
182234
endif
183-
lapack_dep = dependency(lapack_name, required: false)
184235
have_lapack = lapack_dep.found()
185236
if not have_lapack and not allow_noblas
186237
error('No LAPACK library detected! Install one, or use the ' + \

0 commit comments

Comments
 (0)