Repository: numpy/numpy
File: numpy/fft/_pocketfft_umath.cpp (C++)

Code before:
    rfft_impl<T>(args, dimensions, steps, func, npts);
}

template <typename T>
static void
rfft_n_odd_loop(char **args, npy_intp const *dimensions, npy_intp const *steps, void *func)
{
    size_t nout = (size_t)dimensions[2];
    assert (nout > 0);
    size_t npts = 2 * nout - 1;
    rfft_impl<T>(args, dimensions, steps, func, npts);
}

template <typename T>
static void
irfft_loop(char **args, npy_intp const *dimensions, npy_intp const *steps, void *func)
{
    char *ip = args[0], *fp = args[1], *op = args[2];
    size_t n_outer = (size_t)dimensions[0];
    ptrdiff_t si = steps[0], sf = steps[1], so = steps[2];
    size_t nin = (size_t)dimensions[1], nout = (size_t)dimensions[2];
    ptrdiff_t step_in = steps[3], step_out = steps[4];

#ifndef POCKETFFT_NO_VECTORS
    size_t npts_in = nout / 2 + 1;
#endif
    assert(nout > 0);

#ifndef POCKETFFT_NO_VECTORS
    /*
     * Call pocketfft directly if vectorization is possible.
     */
    constexpr auto vlen = pocketfft::detail::VLEN<T>::val;
    if (vlen > 1 && n_outer >= vlen && nin >= npts_in && sf == 0) {
        std::vector<size_t> axes = { 1 };
        std::vector<size_t> shape_out = { n_outer, nout };
        std::vector<ptrdiff_t> strides_in = { si, step_in };
        std::vector<ptrdiff_t> strides_out = { so, step_out};
        pocketfft::c2r(shape_out, strides_in, strides_out, axes, pocketfft::BACKWARD,
                       (std::complex<T> *)ip, (T *)op, *(T *)fp);
        return;
    }
#endif
    /*
     * Otherwise, use a non-vectorized loop in which we try to minimize copies.
     * We do still need a buffer if the output is not contiguous.
     */
    auto plan = pocketfft::detail::get_plan<pocketfft::detail::pocketfft_r<T>>(nout);
    auto buffered = (step_out != sizeof(T));
    pocketfft::detail::arr<T> buff(buffered ? nout : 0);
    for (size_t i = 0; i < n_outer; i++, ip += si, fp += sf, op += so) {

Review comment (suggestion):
Would be nicer to just move it into the existing `#ifndef` below, but a small nit, but thanks for fixing the warning!

Code after:
    rfft_impl<T>(args, dimensions, steps, func, npts);
}

template <typename T>
static void
rfft_n_odd_loop(char **args, npy_intp const *dimensions, npy_intp const *steps, void *func)
{
    size_t nout = (size_t)dimensions[2];
    assert (nout > 0);
    size_t npts = 2 * nout - 1;
    rfft_impl<T>(args, dimensions, steps, func, npts);
}

template <typename T>
static void
irfft_loop(char **args, npy_intp const *dimensions, npy_intp const *steps, void *func)
{
    char *ip = args[0], *fp = args[1], *op = args[2];
    size_t n_outer = (size_t)dimensions[0];
    ptrdiff_t si = steps[0], sf = steps[1], so = steps[2];
    size_t nin = (size_t)dimensions[1], nout = (size_t)dimensions[2];
    ptrdiff_t step_in = steps[3], step_out = steps[4];

    assert(nout > 0);

#ifndef POCKETFFT_NO_VECTORS
    /*
     * Call pocketfft directly if vectorization is possible.
     */
    size_t npts_in = nout / 2 + 1;
    constexpr auto vlen = pocketfft::detail::VLEN<T>::val;
    if (vlen > 1 && n_outer >= vlen && nin >= npts_in && sf == 0) {
        std::vector<size_t> axes = { 1 };
        std::vector<size_t> shape_out = { n_outer, nout };
        std::vector<ptrdiff_t> strides_in = { si, step_in };
        std::vector<ptrdiff_t> strides_out = { so, step_out};
        pocketfft::c2r(shape_out, strides_in, strides_out, axes, pocketfft::BACKWARD,
                       (std::complex<T> *)ip, (T *)op, *(T *)fp);
        return;
    }
#endif
    /*
     * Otherwise, use a non-vectorized loop in which we try to minimize copies.
     * We do still need a buffer if the output is not contiguous.
     */
    auto plan = pocketfft::detail::get_plan<pocketfft::detail::pocketfft_r<T>>(nout);
    auto buffered = (step_out != sizeof(T));
    pocketfft::detail::arr<T> buff(buffered ? nout : 0);
    for (size_t i = 0; i < n_outer; i++, ip += si, fp += sf, op += so) {
        T *op_or_buff = buffered ? buff.data() : (T *)op;
        /*