* This checks how much space can be buffered without encountering the * same value twice, or for operands whose innermost stride is zero, * without encountering a different value. By reducing the buffered * amount to this size, reductions can be safely buffered. * * Reductions are buffered with two levels of looping, to avoid * frequent copying to the buffers. The return value is the over-
| 2672 | * reduce_innersize. |
| 2673 | */ |
| 2674 | static npy_intp |
| 2675 | npyiter_checkreducesize(NpyIter *iter, npy_intp count, |
| 2676 | npy_intp *reduce_innersize, |
| 2677 | npy_intp *reduce_outerdim) |
| 2678 | { |
| 2679 | npy_uint32 itflags = NIT_ITFLAGS(iter); |
| 2680 | int idim, ndim = NIT_NDIM(iter); |
| 2681 | int iop, nop = NIT_NOP(iter); |
| 2682 | |
| 2683 | NpyIter_AxisData *axisdata; |
| 2684 | npy_intp sizeof_axisdata; |
| 2685 | npy_intp coord, shape, *strides; |
| 2686 | npy_intp reducespace = 1, factor; |
| 2687 | npy_bool nonzerocoord; |
| 2688 | |
| 2689 | npyiter_opitflags *op_itflags = NIT_OPITFLAGS(iter); |
| 2690 | char stride0op[NPY_MAXARGS]; |
| 2691 | |
| 2692 | /* Default to no outer axis */ |
| 2693 | *reduce_outerdim = 0; |
| 2694 | |
| 2695 | /* If there's only one dimension, no need to calculate anything */ |
| 2696 | if (ndim == 1 || count == 0) { |
| 2697 | *reduce_innersize = count; |
| 2698 | return count; |
| 2699 | } |
| 2700 | |
| 2701 | sizeof_axisdata = NIT_AXISDATA_SIZEOF(itflags, ndim, nop); |
| 2702 | axisdata = NIT_AXISDATA(iter); |
| 2703 | |
| 2704 | /* Indicate which REDUCE operands have stride 0 in the inner loop */ |
| 2705 | strides = NAD_STRIDES(axisdata); |
| 2706 | for (iop = 0; iop < nop; ++iop) { |
| 2707 | stride0op[iop] = (op_itflags[iop]&NPY_OP_ITFLAG_REDUCE) && |
| 2708 | (strides[iop] == 0); |
| 2709 | NPY_IT_DBG_PRINT2("Iterator: Operand %d has stride 0 in " |
| 2710 | "the inner loop? %d\n", iop, (int)stride0op[iop]); |
| 2711 | } |
| 2712 | shape = NAD_SHAPE(axisdata); |
| 2713 | coord = NAD_INDEX(axisdata); |
| 2714 | reducespace += (shape-coord-1); |
| 2715 | factor = shape; |
| 2716 | NIT_ADVANCE_AXISDATA(axisdata, 1); |
| 2717 | |
| 2718 | /* Initialize nonzerocoord based on the first coordinate */ |
| 2719 | nonzerocoord = (coord != 0); |
| 2720 | |
| 2721 | /* Go forward through axisdata, calculating the space available */ |
| 2722 | for (idim = 1; idim < ndim && reducespace < count; |
| 2723 | ++idim, NIT_ADVANCE_AXISDATA(axisdata, 1)) { |
| 2724 | NPY_IT_DBG_PRINT2("Iterator: inner loop reducespace %d, count %d\n", |
| 2725 | (int)reducespace, (int)count); |
| 2726 | |
| 2727 | strides = NAD_STRIDES(axisdata); |
| 2728 | for (iop = 0; iop < nop; ++iop) { |
| 2729 | /* |
| 2730 | * If a reduce stride switched from zero to non-zero, or |
| 2731 | * vice versa, that's the point where the data will stop |
no outgoing calls
no test coverage detected