diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2015-04-21 22:25:06 -0400 |
---|---|---|
committer | Charles Harris <charlesr.harris@gmail.com> | 2015-04-21 22:25:06 -0400 |
commit | 02b858326dac217607a83ed0bf4d7d51d5bfbfbe (patch) | |
tree | 2e4b5cb84e762d860950c668fe2830642b785e0f | |
parent | efcf028dcca34099f9e8506c7189715a5dc9a5dd (diff) | |
parent | 7d106d590697fcbb7199b00e1f40ec835fe809f6 (diff) | |
download | numpy-02b858326dac217607a83ed0bf4d7d51d5bfbfbe.tar.gz |
Merge pull request #5316 from juliantaylor/align-fixes
fix 1.9 alignment issues
-rw-r--r-- | numpy/core/setup.py | 1 | ||||
-rw-r--r-- | numpy/core/src/multiarray/common.c | 11 | ||||
-rw-r--r-- | numpy/core/src/private/npy_config.h | 5 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 11 |
4 files changed, 27 insertions, 1 deletions
diff --git a/numpy/core/setup.py b/numpy/core/setup.py index 7f0649158..11b443cf8 100644 --- a/numpy/core/setup.py +++ b/numpy/core/setup.py @@ -758,6 +758,7 @@ def configuration(parent_package='',top_path=None): join('src', 'multiarray', 'ucsnarrow.h'), join('src', 'multiarray', 'usertypes.h'), join('src', 'multiarray', 'vdot.h'), + join('src', 'private', 'npy_config.h'), join('src', 'private', 'templ_common.h.src'), join('src', 'private', 'lowlevel_strided_loops.h'), join('include', 'numpy', 'arrayobject.h'), diff --git a/numpy/core/src/multiarray/common.c b/numpy/core/src/multiarray/common.c index 816778b91..a5f3b3d55 100644 --- a/numpy/core/src/multiarray/common.c +++ b/numpy/core/src/multiarray/common.c @@ -684,7 +684,16 @@ _IsAligned(PyArrayObject *ap) /* alignment 1 types should have a efficient alignment for copy loops */ if (PyArray_ISFLEXIBLE(ap) || PyArray_ISSTRING(ap)) { - alignment = NPY_MAX_COPY_ALIGNMENT; + npy_intp itemsize = PyArray_ITEMSIZE(ap); + /* power of two sizes may be loaded in larger moves */ + if (((itemsize & (itemsize - 1)) == 0)) { + alignment = itemsize > NPY_MAX_COPY_ALIGNMENT ? + NPY_MAX_COPY_ALIGNMENT : itemsize; + } + else { + /* if not power of two it will be accessed bytewise */ + alignment = 1; + } } if (alignment == 1) { diff --git a/numpy/core/src/private/npy_config.h b/numpy/core/src/private/npy_config.h index 6e98dc7e9..580b00706 100644 --- a/numpy/core/src/private/npy_config.h +++ b/numpy/core/src/private/npy_config.h @@ -3,6 +3,7 @@ #include "config.h" #include "numpy/numpyconfig.h" +#include "numpy/npy_cpu.h" /* * largest alignment the copy loops might require @@ -13,7 +14,11 @@ * amd64 is not harmed much by the bloat as the system provides 16 byte * alignment by default. */ +#if (defined NPY_CPU_X86 || defined _WIN32) +#define NPY_MAX_COPY_ALIGNMENT 8 +#else #define NPY_MAX_COPY_ALIGNMENT 16 +#endif /* blacklist */ diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index eab512eea..3ee17859f 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -69,6 +69,17 @@ class TestFlags(TestCase): assert_equal(self.a.flags.aligned, True) assert_equal(self.a.flags.updateifcopy, False) + def test_string_align(self): + a = np.zeros(4, dtype=np.dtype('|S4')) + assert_(a.flags.aligned) + # not power of two are accessed bytewise and thus considered aligned + a = np.zeros(5, dtype=np.dtype('|S4')) + assert_(a.flags.aligned) + + def test_void_align(self): + a = np.zeros(4, dtype=np.dtype([("a", "i4"), ("b", "i4")])) + assert_(a.flags.aligned) + class TestHash(TestCase): # see #3793 def test_int(self): |