NUMPY_API * Get an array of strides which are fixed. Any strides which may * change during iteration receive the value NPY_MAX_INTP. Once * the iterator is ready to iterate, call this to get the strides * which will always be fixed in the inner loop, then choose optimized * inner loop functions which take advantage of those fixed strides. * * This function may be safely called without hol
| 1337 | * This function may be safely called without holding the Python GIL. |
| 1338 | */ |
| 1339 | NPY_NO_EXPORT void |
| 1340 | NpyIter_GetInnerFixedStrideArray(NpyIter *iter, npy_intp *out_strides) |
| 1341 | { |
| 1342 | npy_uint32 itflags = NIT_ITFLAGS(iter); |
| 1343 | int ndim = NIT_NDIM(iter); |
| 1344 | int iop, nop = NIT_NOP(iter); |
| 1345 | |
| 1346 | NpyIter_AxisData *axisdata0 = NIT_AXISDATA(iter); |
| 1347 | npy_intp sizeof_axisdata = NIT_AXISDATA_SIZEOF(itflags, ndim, nop); |
| 1348 | |
| 1349 | if (itflags&NPY_ITFLAG_BUFFER) { |
| 1350 | NpyIter_BufferData *data = NIT_BUFFERDATA(iter); |
| 1351 | npyiter_opitflags *op_itflags = NIT_OPITFLAGS(iter); |
| 1352 | npy_intp stride, *strides = NBF_STRIDES(data), |
| 1353 | *ad_strides = NAD_STRIDES(axisdata0); |
| 1354 | PyArray_Descr **dtypes = NIT_DTYPES(iter); |
| 1355 | |
| 1356 | for (iop = 0; iop < nop; ++iop) { |
| 1357 | stride = strides[iop]; |
| 1358 | /* |
| 1359 | * Operands which are always/never buffered have fixed strides, |
| 1360 | * and everything has fixed strides when ndim is 0 or 1 |
| 1361 | */ |
| 1362 | if (ndim <= 1 || (op_itflags[iop]& |
| 1363 | (NPY_OP_ITFLAG_CAST|NPY_OP_ITFLAG_BUFNEVER))) { |
| 1364 | out_strides[iop] = stride; |
| 1365 | } |
| 1366 | /* If it's a reduction, 0-stride inner loop may have fixed stride */ |
| 1367 | else if (stride == 0 && (itflags&NPY_ITFLAG_REDUCE)) { |
| 1368 | /* If it's a reduction operand, definitely fixed stride */ |
| 1369 | if (op_itflags[iop]&NPY_OP_ITFLAG_REDUCE) { |
| 1370 | out_strides[iop] = stride; |
| 1371 | } |
| 1372 | /* |
| 1373 | * Otherwise it's guaranteed to be a fixed stride if the |
| 1374 | * stride is 0 for all the dimensions. |
| 1375 | */ |
| 1376 | else { |
| 1377 | NpyIter_AxisData *axisdata = axisdata0; |
| 1378 | int idim; |
| 1379 | for (idim = 0; idim < ndim; ++idim) { |
| 1380 | if (NAD_STRIDES(axisdata)[iop] != 0) { |
| 1381 | break; |
| 1382 | } |
| 1383 | NIT_ADVANCE_AXISDATA(axisdata, 1); |
| 1384 | } |
| 1385 | /* If all the strides were 0, the stride won't change */ |
| 1386 | if (idim == ndim) { |
| 1387 | out_strides[iop] = stride; |
| 1388 | } |
| 1389 | else { |
| 1390 | out_strides[iop] = NPY_MAX_INTP; |
| 1391 | } |
| 1392 | } |
| 1393 | } |
| 1394 | /* |
| 1395 | * Inner loop contiguous array means its stride won't change when |
| 1396 | * switching between buffering and not buffering |
no outgoing calls
no test coverage detected