annotate Lib/fftw-3.2.1/api/.svn/text-base/apiplan.c.svn-base @ 9:262e084a15a9

Vectorised everything and made use of unique_ptr so there should be no more memory leaks. Hurrah for RAII
author Geogaddi\David <d.m.ronan@qmul.ac.uk>
date Wed, 12 Aug 2015 22:25:06 +0100
parents 25bf17994ef1
children
rev   line source
d@0 1 /*
d@0 2 * Copyright (c) 2003, 2007-8 Matteo Frigo
d@0 3 * Copyright (c) 2003, 2007-8 Massachusetts Institute of Technology
d@0 4 *
d@0 5 * This program is free software; you can redistribute it and/or modify
d@0 6 * it under the terms of the GNU General Public License as published by
d@0 7 * the Free Software Foundation; either version 2 of the License, or
d@0 8 * (at your option) any later version.
d@0 9 *
d@0 10 * This program is distributed in the hope that it will be useful,
d@0 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
d@0 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d@0 13 * GNU General Public License for more details.
d@0 14 *
d@0 15 * You should have received a copy of the GNU General Public License
d@0 16 * along with this program; if not, write to the Free Software
d@0 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
d@0 18 *
d@0 19 */
d@0 20
d@0 21 #include "api.h"
d@0 22
d@0 23 static plan *mkplan0(planner *plnr, unsigned flags,
d@0 24 const problem *prb, int hash_info,
d@0 25 wisdom_state_t wisdom_state)
d@0 26 WITH_ALIGNED_STACK({
d@0 27 /* map API flags into FFTW flags */
d@0 28 X(mapflags)(plnr, flags);
d@0 29
d@0 30 plnr->flags.hash_info = hash_info;
d@0 31 plnr->wisdom_state = wisdom_state;
d@0 32
d@0 33 /* create plan */
d@0 34 return plnr->adt->mkplan(plnr, prb);
d@0 35 })
d@0 36
d@0 37 static void aligned_awake(plan *ego, enum wakefulness wakefulness)
d@0 38 WITH_ALIGNED_STACK({
d@0 39 X(plan_awake)(ego, wakefulness);
d@0 40 })
d@0 41
d@0 42 static unsigned force_estimator(unsigned flags)
d@0 43 {
d@0 44 flags &= ~(FFTW_MEASURE | FFTW_PATIENT | FFTW_EXHAUSTIVE);
d@0 45 return (flags | FFTW_ESTIMATE);
d@0 46 }
d@0 47
d@0 48 static plan *mkplan(planner *plnr, unsigned flags,
d@0 49 const problem *prb, int hash_info)
d@0 50 {
d@0 51 plan *pln;
d@0 52
d@0 53 pln = mkplan0(plnr, flags, prb, hash_info, WISDOM_NORMAL);
d@0 54
d@0 55 if (plnr->wisdom_state == WISDOM_NORMAL && !pln) {
d@0 56 /* maybe the planner failed because of inconsistent wisdom;
d@0 57 plan again ignoring infeasible wisdom */
d@0 58 pln = mkplan0(plnr, force_estimator(flags), prb,
d@0 59 hash_info, WISDOM_IGNORE_INFEASIBLE);
d@0 60 }
d@0 61
d@0 62 if (plnr->wisdom_state == WISDOM_IS_BOGUS) {
d@0 63 /* if the planner detected a wisdom inconsistency,
d@0 64 forget all wisdom and plan again */
d@0 65 plnr->adt->forget(plnr, FORGET_EVERYTHING);
d@0 66
d@0 67 A(!pln);
d@0 68 pln = mkplan0(plnr, flags, prb, hash_info, WISDOM_NORMAL);
d@0 69
d@0 70 if (plnr->wisdom_state == WISDOM_IS_BOGUS) {
d@0 71 /* if it still fails, plan without wisdom */
d@0 72 plnr->adt->forget(plnr, FORGET_EVERYTHING);
d@0 73
d@0 74 A(!pln);
d@0 75 pln = mkplan0(plnr, force_estimator(flags),
d@0 76 prb, hash_info, WISDOM_IGNORE_ALL);
d@0 77 }
d@0 78 }
d@0 79
d@0 80 return pln;
d@0 81 }
d@0 82
d@0 83 apiplan *X(mkapiplan)(int sign, unsigned flags, problem *prb)
d@0 84 {
d@0 85 apiplan *p = 0;
d@0 86 plan *pln;
d@0 87 unsigned flags_used_for_planning;
d@0 88 planner *plnr = X(the_planner)();
d@0 89 unsigned int pats[] = {FFTW_ESTIMATE, FFTW_MEASURE,
d@0 90 FFTW_PATIENT, FFTW_EXHAUSTIVE};
d@0 91 int pat, pat_max;
d@0 92
d@0 93 if (flags & FFTW_WISDOM_ONLY) {
d@0 94 /* Special mode that returns a plan only if wisdom is present,
d@0 95 and returns 0 otherwise. This is now documented in the manual,
d@0 96 as a way to detect whether wisdom is available for a problem. */
d@0 97 flags_used_for_planning = flags;
d@0 98 pln = mkplan0(plnr, flags, prb, 0, WISDOM_ONLY);
d@0 99 } else {
d@0 100 pat_max = flags & FFTW_ESTIMATE ? 0 :
d@0 101 (flags & FFTW_EXHAUSTIVE ? 3 :
d@0 102 (flags & FFTW_PATIENT ? 2 : 1));
d@0 103 pat = plnr->timelimit >= 0 ? 0 : pat_max;
d@0 104
d@0 105 flags &= ~(FFTW_ESTIMATE | FFTW_MEASURE |
d@0 106 FFTW_PATIENT | FFTW_EXHAUSTIVE);
d@0 107
d@0 108 plnr->start_time = X(get_crude_time)();
d@0 109
d@0 110 /* plan at incrementally increasing patience until we run
d@0 111 out of time */
d@0 112 for (pln = 0, flags_used_for_planning = 0; pat <= pat_max; ++pat) {
d@0 113 plan *pln1;
d@0 114 unsigned tmpflags = flags | pats[pat];
d@0 115 pln1 = mkplan(plnr, tmpflags, prb, 0);
d@0 116
d@0 117 if (!pln1) {
d@0 118 /* don't bother continuing if planner failed or timed out */
d@0 119 A(!pln || plnr->timed_out);
d@0 120 break;
d@0 121 }
d@0 122
d@0 123 X(plan_destroy_internal)(pln);
d@0 124 pln = pln1;
d@0 125 flags_used_for_planning = tmpflags;
d@0 126 }
d@0 127 }
d@0 128
d@0 129 if (pln) {
d@0 130 /* build apiplan */
d@0 131 p = (apiplan *) MALLOC(sizeof(apiplan), PLANS);
d@0 132 p->prb = prb;
d@0 133 p->sign = sign; /* cache for execute_dft */
d@0 134
d@0 135 /* re-create plan from wisdom, adding blessing */
d@0 136 p->pln = mkplan(plnr, flags_used_for_planning, prb, BLESSING);
d@0 137
d@0 138 if (sizeof(trigreal) > sizeof(R)) {
d@0 139 /* this is probably faster, and we have enough trigreal
d@0 140 bits to maintain accuracy */
d@0 141 aligned_awake(p->pln, AWAKE_SQRTN_TABLE);
d@0 142 } else {
d@0 143 /* more accurate */
d@0 144 aligned_awake(p->pln, AWAKE_SINCOS);
d@0 145 }
d@0 146
d@0 147 /* we don't use pln for p->pln, above, since by re-creating the
d@0 148 plan we might use more patient wisdom from a timed-out mkplan */
d@0 149 X(plan_destroy_internal)(pln);
d@0 150 } else
d@0 151 X(problem_destroy)(prb);
d@0 152
d@0 153 /* discard all information not necessary to reconstruct the plan */
d@0 154 plnr->adt->forget(plnr, FORGET_ACCURSED);
d@0 155
d@0 156 return p;
d@0 157 }
d@0 158
d@0 159 void X(destroy_plan)(X(plan) p)
d@0 160 {
d@0 161 if (p) {
d@0 162 X(plan_awake)(p->pln, SLEEPY);
d@0 163 X(plan_destroy_internal)(p->pln);
d@0 164 X(problem_destroy)(p->prb);
d@0 165 X(ifree)(p);
d@0 166 }
d@0 167 }