-
-
Notifications
You must be signed in to change notification settings - Fork 10.9k
Complex128 alignment leads to scipy test failures. #3768
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
the numpy issue is that complex arrays are not classified as aligned when they actually are on the hardware. We could fix that, but the scipy test is still questionable as it expects the data it uses to always be aligned. |
@pv Agree about the test. I also agree that the alignment should match what is needed for efficient operation or to avoid bus errors and that will be architecture dependent. On Intel I suspect the default malloc alignment matches what is needed. |
the question is how to fix it. As we aren't using C99 complex types we have no reliable way of getting the alignment for them. On the other hand I think sparc64 is the only platform that has 16 byte large scalar types so we could just hardcode the double alignment for this platform and keep double alignment for all others. |
or we could search for where numpy accesses the two double as one 16 byte object which caused the issue that was the original reason for the alignment being removed for complex types on transfer. |
I wonder what the Fortran alignment requirements are? In any case, the double alignment seems to have worked for all but the SPARC, so I think hard coding that exception would be the best short term fix. The search for the use of a C99 complex seems more of a long term thing, and for all I know, we might want to move to that at some point in the future rather than fix it ;) Any idea what the situation is with respect to the long double complex type? |
The complex type comes from |
from googling a bit it seems sparc does not even requires 16 byte alignment for complex doubles: so I dug a bit more for the source of the #2668 it can be reproduced on x86 by asserting on alignment in lowlevel_strided_loops.c.src and reverting the alignment increase: --- a/numpy/core/src/multiarray/arraytypes.c.src
+++ b/numpy/core/src/multiarray/arraytypes.c.src
@@ -3819,7 +3819,7 @@ NPY_NO_EXPORT PyArray_Descr @from@_Descr = {
/* elsize */
@num@ * sizeof(@fromtype@),
/* alignment */
- @num@ * _ALIGN(@fromtype@),
+ _ALIGN(@fromtype@),
/* subarray */
NULL,
/* fields */
@@ -4150,7 +4150,6 @@ set_typeinfo(PyObject *dict)
* CFLOAT, CDOUBLE, CLONGDOUBLE#
* #Name = Half, Float, Double, LongDouble,
* CFloat, CDouble, CLongDouble#
- * #num = 1, 1, 1, 1, 2, 2, 2#
*/
PyDict_SetItemString(infodict, "@name@",
@@ -4161,7 +4160,7 @@ set_typeinfo(PyObject *dict)
#endif
NPY_@name@,
NPY_BITSOF_@name@,
- @num@ * _ALIGN(@type@),
+ _ALIGN(@type@),
(PyObject *) &Py@Name@ArrType_Type));
Py_DECREF(s);
--- a/numpy/core/src/multiarray/lowlevel_strided_loops.c.src
+++ b/numpy/core/src/multiarray/lowlevel_strided_loops.c.src
@@ -118,6 +118,10 @@ static void
npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
NpyAuxData *NPY_UNUSED(data))
{
+#if @is_aligned@ && @elsize@ != 16
+ assert((long)dst % sizeof(@type@) == 0);
+ assert((long)src % sizeof(@type@) == 0);
+#endif
/*printf("fn @prefix@_@oper@_size@elsize@\n");*/
while (N > 0) { |
replacing PyArray_ISALIGNED in nditer_constr.c with something like _IsAligned with the itemsize instead of the stored alignment fixes this issue, but its impossible to tell if thats sufficient. |
Sounds like nditer assumes that itemsize and alignment are always the same (Can one reproduce it then with e.g. an S8 array?)
|
you can also argue the other way round, complex can be copied as a type of double size so it should be aligned to that double size. I think sticking with doubled alignment requirement is better than putting check for complex types in all alignment checks (as we don't want to align to S1234). Then we should add a alignment check to NewFromDescr as malloc does not provide this double alignment on i386 and fix a couple failures in test_array_from_pyobj.py. |
This is sounding more like a cleanup task than a 1.8 blocker. Should I just ignore this for 1.8? |
I'm taking this out of the blocker category. |
To break it down,
The second isn't fatal, and the first should be fixed in scipy. |
one just reduce the alignment on platforms we know don't need it. |
x86 can deal with unaligned memory access so it does not need to align complex types to 2 * sizeof(T) for the dtype transfers which work on the full complex number. closes numpy#3768 Does not fix that new complex arrays are reported as aligned when the allocator does not provide the required alignment.
@juliantaylor Do you recall where we are with this issue? |
not fixed but we could by reducing the alignment of complex types but excluding sparc |
OK. I think I can remove this from the 1.9 blockers as we did for 1.8. |
The tests that fail check inplace fft and fail due to copies being made on win 32 when allocated data memory is not 16 byte aligned. The change is c9bf9b0. Discussion at scipy/scipy#2890 (comment).
The text was updated successfully, but these errors were encountered: