diff options
Diffstat (limited to 'numpy/linalg/umath_linalg.c.src')
-rw-r--r-- | numpy/linalg/umath_linalg.c.src | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/numpy/linalg/umath_linalg.c.src b/numpy/linalg/umath_linalg.c.src index 3c2b316e2..b38038fc2 100644 --- a/numpy/linalg/umath_linalg.c.src +++ b/numpy/linalg/umath_linalg.c.src @@ -812,24 +812,32 @@ linearize_@TYPE@_matrix(void *dst_in, @typ@ *dst = (@typ@ *) dst_in; if (dst) { - int i; + int i, j; @typ@* rv = dst; fortran_int columns = (fortran_int)data->columns; fortran_int column_strides = (fortran_int)(data->column_strides/sizeof(@typ@)); fortran_int one = 1; for (i=0; i< data->rows; i++) { - if (column_strides >= 0) { + if (column_strides > 0) { FNAME(@copy@)(&columns, (void*)src, &column_strides, (void*)dst, &one); } - else { + else if (column_strides < 0) { FNAME(@copy@)(&columns, (void*)((@typ@*)src + (columns-1)*column_strides), &column_strides, (void*)dst, &one); } + else { + /* Zero stride has undefined behavior in some BLAS + implementations (e.g. OSX Accelerate), so do it + manually */ + for (j = 0; j < columns; ++j) { + memcpy((@typ@*)dst + j, (@typ@*)src, sizeof(@typ@)); + } + } src += data->row_strides/sizeof(@typ@); dst += data->columns; } @@ -855,17 +863,25 @@ delinearize_@TYPE@_matrix(void *dst_in, (fortran_int)(data->column_strides/sizeof(@typ@)); fortran_int one = 1; for (i=0; i < data->rows; i++) { - if (column_strides >= 0) { + if (column_strides > 0) { FNAME(@copy@)(&columns, (void*)src, &one, (void*)dst, &column_strides); } - else { + else if (column_strides < 0) { FNAME(@copy@)(&columns, (void*)src, &one, (void*)((@typ@*)dst + (columns-1)*column_strides), &column_strides); } + else { + /* Zero stride has undefined behavior in some BLAS + implementations (e.g. OSX Accelerate), so do it + manually */ + if (columns > 0) { + memcpy((@typ@*)dst, (@typ@*)src + (columns-1), sizeof(@typ@)); + } + } src += data->columns; dst += data->row_strides/sizeof(@typ@); } |