diff options
author | Matthew Badin <mbadin@apple.com> | 2021-04-28 16:56:01 -0700 |
---|---|---|
committer | Matthew Badin <mbadin@apple.com> | 2021-04-28 17:20:11 -0700 |
commit | e28da7a3d50862fa99b8b704d60fc6543b5af631 (patch) | |
tree | 57f4c3684d5333c319d3b7a3cbcdbb087418acc4 /numpy/core | |
parent | 53e34d49d46b0999927160444a7dd0650efafad7 (diff) | |
download | numpy-e28da7a3d50862fa99b8b704d60fc6543b5af631.tar.gz |
BLD: Enable Accelerate Framework
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/setup.py | 9 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 65 |
2 files changed, 69 insertions, 5 deletions
diff --git a/numpy/core/setup.py b/numpy/core/setup.py index df405bcaf..f59b67c88 100644 --- a/numpy/core/setup.py +++ b/numpy/core/setup.py @@ -10,6 +10,10 @@ from os.path import join from numpy.distutils import log from distutils.dep_util import newer from sysconfig import get_config_var + +from numpy._build_utils.apple_accelerate import ( + uses_accelerate_framework + ) from numpy.compat import npy_load_module from setup_common import * # noqa: F403 @@ -405,11 +409,6 @@ def configuration(parent_package='',top_path=None): from numpy.distutils.system_info import (get_info, blas_opt_info, lapack_opt_info) - # Accelerate is buggy, disallow it. See also numpy/linalg/setup.py - for opt_order in (blas_opt_info.blas_order, lapack_opt_info.lapack_order): - if 'accelerate' in opt_order: - opt_order.remove('accelerate') - config = Configuration('core', parent_package, top_path) local_dir = config.local_path codegen_dir = join(local_dir, 'code_generators') diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 073433bd1..40b435f2e 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -6194,6 +6194,71 @@ class TestDot: assert_equal(np.dot(b, a), res) assert_equal(np.dot(b, b), res) + def test_accelerate_framework_sgemv_fix(self): + + def aligned_array(shape, align, dtype, order='C'): + d = dtype(0) + N = np.prod(shape) + tmp = np.zeros(N * d.nbytes + align, dtype=np.uint8) + address = tmp.__array_interface__["data"][0] + for offset in range(align): + if (address + offset) % align == 0: + break + tmp = tmp[offset:offset+N*d.nbytes].view(dtype=dtype) + return tmp.reshape(shape, order=order) + + def as_aligned(arr, align, dtype, order='C'): + aligned = aligned_array(arr.shape, align, dtype, order) + aligned[:] = arr[:] + return aligned + + def assert_dot_close(A, X, desired): + assert_allclose(np.dot(A, X), desired, rtol=1e-5, atol=1e-7) + + m = aligned_array(100, 15, np.float32) + s = aligned_array((100, 100), 15, np.float32) + np.dot(s, m) # this will always segfault if the bug is present + + testdata = itertools.product((15,32), (10000,), (200,89), ('C','F')) + for align, m, n, a_order in testdata: + # Calculation in double precision + A_d = np.random.rand(m, n) + X_d = np.random.rand(n) + desired = np.dot(A_d, X_d) + # Calculation with aligned single precision + A_f = as_aligned(A_d, align, np.float32, order=a_order) + X_f = as_aligned(X_d, align, np.float32) + assert_dot_close(A_f, X_f, desired) + # Strided A rows + A_d_2 = A_d[::2] + desired = np.dot(A_d_2, X_d) + A_f_2 = A_f[::2] + assert_dot_close(A_f_2, X_f, desired) + # Strided A columns, strided X vector + A_d_22 = A_d_2[:, ::2] + X_d_2 = X_d[::2] + desired = np.dot(A_d_22, X_d_2) + A_f_22 = A_f_2[:, ::2] + X_f_2 = X_f[::2] + assert_dot_close(A_f_22, X_f_2, desired) + # Check the strides are as expected + if a_order == 'F': + assert_equal(A_f_22.strides, (8, 8 * m)) + else: + assert_equal(A_f_22.strides, (8 * n, 8)) + assert_equal(X_f_2.strides, (8,)) + # Strides in A rows + cols only + X_f_2c = as_aligned(X_f_2, align, np.float32) + assert_dot_close(A_f_22, X_f_2c, desired) + # Strides just in A cols + A_d_12 = A_d[:, ::2] + desired = np.dot(A_d_12, X_d_2) + A_f_12 = A_f[:, ::2] + assert_dot_close(A_f_12, X_f_2c, desired) + # Strides in A cols and X + assert_dot_close(A_f_12, X_f_2, desired) + + class MatmulCommon: """Common tests for '@' operator and numpy.matmul. |