* Check that array data is both uint-aligned and true-aligned for all array * elements, as required by the copy/casting code in lowlevel_strided_loops.c */
| 34 | * elements, as required by the copy/casting code in lowlevel_strided_loops.c |
| 35 | */ |
| 36 | NPY_NO_EXPORT int |
| 37 | copycast_isaligned(int ndim, npy_intp const *shape, |
| 38 | PyArray_Descr *dtype, char *data, npy_intp const *strides) |
| 39 | { |
| 40 | int aligned; |
| 41 | int big_aln, small_aln; |
| 42 | |
| 43 | int uint_aln = npy_uint_alignment(dtype->elsize); |
| 44 | int true_aln = dtype->alignment; |
| 45 | |
| 46 | /* uint alignment can be 0, meaning not uint alignable */ |
| 47 | if (uint_aln == 0) { |
| 48 | return 0; |
| 49 | } |
| 50 | |
| 51 | /* |
| 52 | * As an optimization, it is unnecessary to check the alignment to the |
| 53 | * smaller of (uint_aln, true_aln) if the data is aligned to the bigger of |
| 54 | * the two and the big is a multiple of the small aln. We check the bigger |
| 55 | * one first and only check the smaller if necessary. |
| 56 | */ |
| 57 | if (true_aln >= uint_aln) { |
| 58 | big_aln = true_aln; |
| 59 | small_aln = uint_aln; |
| 60 | } |
| 61 | else { |
| 62 | big_aln = uint_aln; |
| 63 | small_aln = true_aln; |
| 64 | } |
| 65 | |
| 66 | aligned = raw_array_is_aligned(ndim, shape, data, strides, big_aln); |
| 67 | if (aligned && big_aln % small_aln != 0) { |
| 68 | aligned = raw_array_is_aligned(ndim, shape, data, strides, small_aln); |
| 69 | } |
| 70 | return aligned; |
| 71 | } |
| 72 | |
| 73 | /* |
| 74 | * Assigns the array from 'src' to 'dst'. The strides must already have |
no test coverage detected