To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

The primary repository for this project is hosted at https://github.com/sonic-visualiser/sv-dependency-builds .
This repository is a read-only copy which is updated automatically every hour.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / src / fftw-3.3.8 / api / apiplan.c @ 167:bd3cc4d1df30

History | View | Annotate | Download (5.73 KB)

1
/*
2
 * Copyright (c) 2003, 2007-14 Matteo Frigo
3
 * Copyright (c) 2003, 2007-14 Massachusetts Institute of Technology
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18
 *
19
 */
20

    
21
#include "api/api.h"
22

    
23
static planner_hook_t before_planner_hook = 0, after_planner_hook = 0;
24

    
25
void X(set_planner_hooks)(planner_hook_t before, planner_hook_t after)
26
{
27
     before_planner_hook = before;
28
     after_planner_hook = after;
29
}
30

    
31
static plan *mkplan0(planner *plnr, unsigned flags,
32
                     const problem *prb, unsigned hash_info,
33
                     wisdom_state_t wisdom_state)
34
{
35
     /* map API flags into FFTW flags */
36
     X(mapflags)(plnr, flags);
37

    
38
     plnr->flags.hash_info = hash_info;
39
     plnr->wisdom_state = wisdom_state;
40

    
41
     /* create plan */
42
     return plnr->adt->mkplan(plnr, prb);
43
}
44

    
45
static unsigned force_estimator(unsigned flags)
46
{
47
     flags &= ~(FFTW_MEASURE | FFTW_PATIENT | FFTW_EXHAUSTIVE);
48
     return (flags | FFTW_ESTIMATE);
49
}
50

    
51
static plan *mkplan(planner *plnr, unsigned flags,
52
                    const problem *prb, unsigned hash_info)
53
{
54
     plan *pln;
55
     
56
     pln = mkplan0(plnr, flags, prb, hash_info, WISDOM_NORMAL);
57

    
58
     if (plnr->wisdom_state == WISDOM_NORMAL && !pln) {
59
          /* maybe the planner failed because of inconsistent wisdom;
60
             plan again ignoring infeasible wisdom */
61
          pln = mkplan0(plnr, force_estimator(flags), prb,
62
                        hash_info, WISDOM_IGNORE_INFEASIBLE);
63
     }
64

    
65
     if (plnr->wisdom_state == WISDOM_IS_BOGUS) {
66
          /* if the planner detected a wisdom inconsistency,
67
             forget all wisdom and plan again */
68
          plnr->adt->forget(plnr, FORGET_EVERYTHING);
69

    
70
          A(!pln);
71
          pln = mkplan0(plnr, flags, prb, hash_info, WISDOM_NORMAL);
72

    
73
          if (plnr->wisdom_state == WISDOM_IS_BOGUS) {
74
               /* if it still fails, plan without wisdom */
75
               plnr->adt->forget(plnr, FORGET_EVERYTHING);
76

    
77
               A(!pln);
78
               pln = mkplan0(plnr, force_estimator(flags),
79
                             prb, hash_info, WISDOM_IGNORE_ALL);
80
          }
81
     }
82

    
83
     return pln;
84
}
85

    
86
apiplan *X(mkapiplan)(int sign, unsigned flags, problem *prb)
87
{
88
     apiplan *p = 0;
89
     plan *pln;
90
     unsigned flags_used_for_planning;
91
     planner *plnr;
92
     static const unsigned int pats[] = {FFTW_ESTIMATE, FFTW_MEASURE,
93
                                         FFTW_PATIENT, FFTW_EXHAUSTIVE};
94
     int pat, pat_max;
95
     double pcost = 0;
96
     
97
     if (before_planner_hook)
98
          before_planner_hook();
99
     
100
     plnr = X(the_planner)();
101

    
102
     if (flags & FFTW_WISDOM_ONLY) {
103
          /* Special mode that returns a plan only if wisdom is present,
104
             and returns 0 otherwise.  This is now documented in the manual,
105
             as a way to detect whether wisdom is available for a problem. */
106
          flags_used_for_planning = flags;
107
          pln = mkplan0(plnr, flags, prb, 0, WISDOM_ONLY);
108
     } else {
109
          pat_max = flags & FFTW_ESTIMATE ? 0 :
110
               (flags & FFTW_EXHAUSTIVE ? 3 :
111
                (flags & FFTW_PATIENT ? 2 : 1));
112
          pat = plnr->timelimit >= 0 ? 0 : pat_max;
113

    
114
          flags &= ~(FFTW_ESTIMATE | FFTW_MEASURE |
115
                     FFTW_PATIENT | FFTW_EXHAUSTIVE);
116

    
117
          plnr->start_time = X(get_crude_time)();
118

    
119
          /* plan at incrementally increasing patience until we run
120
             out of time */
121
          for (pln = 0, flags_used_for_planning = 0; pat <= pat_max; ++pat) {
122
               plan *pln1;
123
               unsigned tmpflags = flags | pats[pat];
124
               pln1 = mkplan(plnr, tmpflags, prb, 0u);
125

    
126
               if (!pln1) {
127
                    /* don't bother continuing if planner failed or timed out */
128
                    A(!pln || plnr->timed_out);
129
                    break;
130
               }
131

    
132
               X(plan_destroy_internal)(pln);
133
               pln = pln1;
134
               flags_used_for_planning = tmpflags;
135
               pcost = pln->pcost;
136
          }
137
     }
138

    
139
     if (pln) {
140
          /* build apiplan */
141
          p = (apiplan *) MALLOC(sizeof(apiplan), PLANS);
142
          p->prb = prb;
143
          p->sign = sign; /* cache for execute_dft */
144

    
145
          /* re-create plan from wisdom, adding blessing */
146
          p->pln = mkplan(plnr, flags_used_for_planning, prb, BLESSING);
147

    
148
          /* record pcost from most recent measurement for use in X(cost) */
149
          p->pln->pcost = pcost;
150

    
151
          if (sizeof(trigreal) > sizeof(R)) {
152
               /* this is probably faster, and we have enough trigreal
153
                  bits to maintain accuracy */
154
               X(plan_awake)(p->pln, AWAKE_SQRTN_TABLE);
155
          } else {
156
               /* more accurate */
157
               X(plan_awake)(p->pln, AWAKE_SINCOS);
158
          }
159

    
160
          /* we don't use pln for p->pln, above, since by re-creating the
161
             plan we might use more patient wisdom from a timed-out mkplan */
162
          X(plan_destroy_internal)(pln);
163
     } else
164
          X(problem_destroy)(prb);
165

    
166
     /* discard all information not necessary to reconstruct the plan */
167
     plnr->adt->forget(plnr, FORGET_ACCURSED);
168

    
169
#ifdef FFTW_RANDOM_ESTIMATOR
170
     X(random_estimate_seed)++; /* subsequent "random" plans are distinct */
171
#endif
172

    
173
     if (after_planner_hook)
174
          after_planner_hook();
175
     
176
     return p;
177
}
178

    
179
void X(destroy_plan)(X(plan) p)
180
{
181
     if (p) {
182
          if (before_planner_hook)
183
               before_planner_hook();
184
     
185
          X(plan_awake)(p->pln, SLEEPY);
186
          X(plan_destroy_internal)(p->pln);
187
          X(problem_destroy)(p->prb);
188
          X(ifree)(p);
189

    
190
          if (after_planner_hook)
191
               after_planner_hook();
192
     }
193
}
194

    
195
int X(alignment_of)(R *p)
196
{
197
     return X(ialignment_of(p));
198
}