* This function wraps a regular unmasked strided-loop as a * masked strided-loop, only calling the function for elements * where the mask is True. * * TODO: Reductions also use this code to implement masked reductions. * Before consolidating them, reductions had a special case for * broadcasts: when the mask stride was 0 the code does not check all * elements as `npy_memch
| 857 | * masks are common enough. |
| 858 | */ |
| 859 | static int |
| 860 | generic_masked_strided_loop(PyArrayMethod_Context *context, |
| 861 | char *const *data, const npy_intp *dimensions, |
| 862 | const npy_intp *strides, NpyAuxData *_auxdata) |
| 863 | { |
| 864 | _masked_stridedloop_data *auxdata = (_masked_stridedloop_data *)_auxdata; |
| 865 | int nargs = auxdata->nargs; |
| 866 | PyArrayMethod_StridedLoop *strided_loop = auxdata->unmasked_stridedloop; |
| 867 | NpyAuxData *strided_loop_auxdata = auxdata->unmasked_auxdata; |
| 868 | |
| 869 | char **dataptrs = auxdata->dataptrs; |
| 870 | memcpy(dataptrs, data, nargs * sizeof(char *)); |
| 871 | char *mask = data[nargs]; |
| 872 | npy_intp mask_stride = strides[nargs]; |
| 873 | |
| 874 | npy_intp N = dimensions[0]; |
| 875 | /* Process the data as runs of unmasked values */ |
| 876 | do { |
| 877 | Py_ssize_t subloopsize; |
| 878 | |
| 879 | /* Skip masked values */ |
| 880 | mask = npy_memchr(mask, 0, mask_stride, N, &subloopsize, 1); |
| 881 | for (int i = 0; i < nargs; i++) { |
| 882 | dataptrs[i] += subloopsize * strides[i]; |
| 883 | } |
| 884 | N -= subloopsize; |
| 885 | |
| 886 | /* Process unmasked values */ |
| 887 | mask = npy_memchr(mask, 0, mask_stride, N, &subloopsize, 0); |
| 888 | if (subloopsize > 0) { |
| 889 | int res = strided_loop(context, |
| 890 | dataptrs, &subloopsize, strides, strided_loop_auxdata); |
| 891 | if (res != 0) { |
| 892 | return res; |
| 893 | } |
| 894 | for (int i = 0; i < nargs; i++) { |
| 895 | dataptrs[i] += subloopsize * strides[i]; |
| 896 | } |
| 897 | N -= subloopsize; |
| 898 | } |
| 899 | } while (N > 0); |
| 900 | |
| 901 | return 0; |
| 902 | } |
| 903 | |
| 904 | |
| 905 | /* |
nothing calls this directly
no test coverage detected