static INT min_nbuf(const problem_rdft2 *p, INT n, INT vl) { INT is, os, ivs, ovs; if (p->r0 != p->cr) return 1; if (X(rdft2_inplace_strides(p, RNK_MINFTY))) return 1; A(p->vecsz->rnk == 1); /* rank 0 and MINFTY are inplace */ X(rdft2_strides)(p->kind, p->sz->dims, &is, &os); X(rdft2_strides)(p->kind, p->vecsz->dims, &ivs, &ovs); /* handle one potentially common case: "contiguous" real and complex arrays, which overlap because of the differing sizes. */ if (n * X(iabs)(is) <= X(iabs)(ivs) && (n/2 + 1) * X(iabs)(os) <= X(iabs)(ovs) && ( ((p->cr - p->ci) <= X(iabs)(os)) || ((p->ci - p->cr) <= X(iabs)(os)) ) && ivs > 0 && ovs > 0) { INT vsmin = X(imin)(ivs, ovs); INT vsmax = X(imax)(ivs, ovs); return(((vsmax - vsmin) * vl + vsmin - 1) / vsmin); } return vl; /* punt: just buffer the whole vector */ }
static int applicable0(const problem *p_, const planner *plnr) { const problem_rdft2 *p = (const problem_rdft2 *) p_; iodim *d = p->sz->dims; if (1 && p->vecsz->rnk <= 1 && p->sz->rnk == 1 /* we assume even n throughout */ && (p->sz->dims[0].n % 2) == 0 /* and we only consider these two cases */ && (p->kind == R2HC || p->kind == HC2R) ) { if (X(toobig)(p->sz->dims[0].n) && CONSERVE_MEMORYP(plnr)) return 0; if (p->r0 != p->cr) { if (p->kind == HC2R) { /* Allow HC2R problems only if the input is to be preserved. This solver sets NO_DESTROY_INPUT, which prevents infinite loops */ return (NO_DESTROY_INPUTP(plnr)); } else { /* In principle, the buffered transforms might be useful when working out of place. However, in order to prevent infinite loops in the planner, we require that the output stride of the buffered transforms be greater than 2. */ return (d[0].os > 2); } } /* * If the problem is in place, the input/output strides must * be the same or the whole thing must fit in the buffer. */ if (X(rdft2_inplace_strides(p, RNK_MINFTY))) return 1; if (/* fits into buffer: */ ((p->vecsz->rnk == 0) || (X(nbuf)(d[0].n, p->vecsz->dims[0].n) == p->vecsz->dims[0].n))) return 1; } return 0; }