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 / mapflags.c @ 167:bd3cc4d1df30

History | View | Annotate | Download (5.41 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
#include <math.h>
23

    
24
/* a flag operation: x is either a flag, in which case xm == 0, or
25
   a mask, in which case xm == x; using this we can compactly code
26
   the various bit operations via (flags & x) ^ xm or (flags | x) ^ xm. */
27
typedef struct {
28
     unsigned x, xm;
29
} flagmask;
30

    
31
typedef struct {
32
     flagmask flag;
33
     flagmask op;
34
} flagop;
35

    
36
#define FLAGP(f, msk)(((f) & (msk).x) ^ (msk).xm)
37
#define OP(f, msk)(((f) | (msk).x) ^ (msk).xm)
38

    
39
#define YES(x) {x, 0}
40
#define NO(x) {x, x}
41
#define IMPLIES(predicate, consequence) { predicate, consequence }
42
#define EQV(a, b) IMPLIES(YES(a), YES(b)), IMPLIES(NO(a), NO(b))
43
#define NEQV(a, b) IMPLIES(YES(a), NO(b)), IMPLIES(NO(a), YES(b))
44

    
45
static void map_flags(unsigned *iflags, unsigned *oflags,
46
                      const flagop flagmap[], size_t nmap)
47
{
48
     size_t i;
49
     for (i = 0; i < nmap; ++i)
50
          if (FLAGP(*iflags, flagmap[i].flag))
51
               *oflags = OP(*oflags, flagmap[i].op);
52
}
53

    
54
/* encoding of the planner timelimit into a BITS_FOR_TIMELIMIT-bits
55
   nonnegative integer, such that we can still view the integer as
56
   ``impatience'': higher means *lower* time limit, and 0 is the
57
   highest possible value (about 1 year of calendar time) */
58
static unsigned timelimit_to_flags(double timelimit)
59
{
60
     const double tmax = 365 * 24 * 3600;
61
     const double tstep = 1.05;
62
     const int nsteps = (1 << BITS_FOR_TIMELIMIT);
63
     int x;
64
     
65
     if (timelimit < 0 || timelimit >= tmax)
66
          return 0;
67
     if (timelimit <= 1.0e-10)
68
          return nsteps - 1;
69
     
70
     x = (int) (0.5 + (log(tmax / timelimit) / log(tstep)));
71

    
72
     if (x < 0) x = 0;
73
     if (x >= nsteps) x = nsteps - 1;
74
     return x;
75
}
76

    
77
void X(mapflags)(planner *plnr, unsigned flags)
78
{
79
     unsigned l, u, t;
80

    
81
     /* map of api flags -> api flags, to implement consistency rules
82
        and combination flags */
83
     const flagop self_flagmap[] = {
84
          /* in some cases (notably for halfcomplex->real transforms),
85
             DESTROY_INPUT is the default, so we need to support
86
             an inverse flag to disable it.
87

88
             (PRESERVE, DESTROY)   ->   (PRESERVE, DESTROY)
89
               (0, 0)                       (1, 0)
90
               (0, 1)                       (0, 1)
91
               (1, 0)                       (1, 0)
92
               (1, 1)                       (1, 0)
93
          */
94
          IMPLIES(YES(FFTW_PRESERVE_INPUT), NO(FFTW_DESTROY_INPUT)),
95
          IMPLIES(NO(FFTW_DESTROY_INPUT), YES(FFTW_PRESERVE_INPUT)),
96

    
97
          IMPLIES(YES(FFTW_EXHAUSTIVE), YES(FFTW_PATIENT)),
98

    
99
          IMPLIES(YES(FFTW_ESTIMATE), NO(FFTW_PATIENT)),
100
          IMPLIES(YES(FFTW_ESTIMATE),
101
                  YES(FFTW_ESTIMATE_PATIENT 
102
                      | FFTW_NO_INDIRECT_OP
103
                      | FFTW_ALLOW_PRUNING)),
104

    
105
          IMPLIES(NO(FFTW_EXHAUSTIVE), 
106
                  YES(FFTW_NO_SLOW)),
107

    
108
          /* a canonical set of fftw2-like impatience flags */
109
          IMPLIES(NO(FFTW_PATIENT),
110
                  YES(FFTW_NO_VRECURSE
111
                      | FFTW_NO_RANK_SPLITS
112
                      | FFTW_NO_VRANK_SPLITS
113
                      | FFTW_NO_NONTHREADED
114
                      | FFTW_NO_DFT_R2HC
115
                      | FFTW_NO_FIXED_RADIX_LARGE_N
116
                      | FFTW_BELIEVE_PCOST))
117
     };
118

    
119
     /* map of (processed) api flags to internal problem/planner flags */
120
     const flagop l_flagmap[] = {
121
          EQV(FFTW_PRESERVE_INPUT, NO_DESTROY_INPUT),
122
          EQV(FFTW_NO_SIMD, NO_SIMD),
123
          EQV(FFTW_CONSERVE_MEMORY, CONSERVE_MEMORY),
124
          EQV(FFTW_NO_BUFFERING, NO_BUFFERING),
125
          NEQV(FFTW_ALLOW_LARGE_GENERIC, NO_LARGE_GENERIC)
126
     };
127

    
128
     const flagop u_flagmap[] = {
129
          IMPLIES(YES(FFTW_EXHAUSTIVE), NO(0xFFFFFFFF)),
130
          IMPLIES(NO(FFTW_EXHAUSTIVE), YES(NO_UGLY)),
131

    
132
          /* the following are undocumented, "beyond-guru" flags that
133
             require some understanding of FFTW internals */
134
          EQV(FFTW_ESTIMATE_PATIENT, ESTIMATE),
135
          EQV(FFTW_ALLOW_PRUNING, ALLOW_PRUNING),
136
          EQV(FFTW_BELIEVE_PCOST, BELIEVE_PCOST),
137
          EQV(FFTW_NO_DFT_R2HC, NO_DFT_R2HC),
138
          EQV(FFTW_NO_NONTHREADED, NO_NONTHREADED),
139
          EQV(FFTW_NO_INDIRECT_OP, NO_INDIRECT_OP),
140
          EQV(FFTW_NO_RANK_SPLITS, NO_RANK_SPLITS),
141
          EQV(FFTW_NO_VRANK_SPLITS, NO_VRANK_SPLITS),
142
          EQV(FFTW_NO_VRECURSE, NO_VRECURSE),
143
          EQV(FFTW_NO_SLOW, NO_SLOW),
144
          EQV(FFTW_NO_FIXED_RADIX_LARGE_N, NO_FIXED_RADIX_LARGE_N)
145
     };
146

    
147
     map_flags(&flags, &flags, self_flagmap, NELEM(self_flagmap));
148

    
149
     l = u = 0;
150
     map_flags(&flags, &l, l_flagmap, NELEM(l_flagmap));
151
     map_flags(&flags, &u, u_flagmap, NELEM(u_flagmap));
152

    
153
     /* enforce l <= u  */
154
     PLNR_L(plnr) = l;
155
     PLNR_U(plnr) = u | l;
156

    
157
     /* assert that the conversion didn't lose bits */
158
     A(PLNR_L(plnr) == l);
159
     A(PLNR_U(plnr) == (u | l));
160

    
161
     /* compute flags representation of the timelimit */
162
     t = timelimit_to_flags(plnr->timelimit);
163

    
164
     PLNR_TIMELIMIT_IMPATIENCE(plnr) = t;
165
     A(PLNR_TIMELIMIT_IMPATIENCE(plnr) == t);
166
}