summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2015-04-21 22:25:06 -0400
committerCharles Harris <charlesr.harris@gmail.com>2015-04-21 22:25:06 -0400
commit02b858326dac217607a83ed0bf4d7d51d5bfbfbe (patch)
tree2e4b5cb84e762d860950c668fe2830642b785e0f
parentefcf028dcca34099f9e8506c7189715a5dc9a5dd (diff)
parent7d106d590697fcbb7199b00e1f40ec835fe809f6 (diff)
downloadnumpy-02b858326dac217607a83ed0bf4d7d51d5bfbfbe.tar.gz
Merge pull request #5316 from juliantaylor/align-fixes
fix 1.9 alignment issues
-rw-r--r--numpy/core/setup.py1
-rw-r--r--numpy/core/src/multiarray/common.c11
-rw-r--r--numpy/core/src/private/npy_config.h5
-rw-r--r--numpy/core/tests/test_multiarray.py11
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):