Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*
2
 * Copyright (c) 1997-1999 Massachusetts Institute of Technology
3
 *
4
 * This program is free software; you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation; either version 2 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software
16
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 *
18
 */
19
 
20
/*
21
 * wisdom.c -- manage the wisdom
22
 */
23
 
24
#include <ports/fftw-int.h>
25
//#include <ports/stdio.h>
26
#include <stdlib.h>
27
//#include <ports/ctype.h>
28
#include <ctype.h>
29
#define EOF -1
30
 
31
struct wisdom {
32
     int n;
33
     int flags;
34
     fftw_direction dir;
35
     enum fftw_wisdom_category category;
36
     int istride;
37
     int ostride;
38
     enum fftw_node_type type;  /* this is the wisdom */
39
     int signature;             /* this is the wisdom */
40
     struct wisdom *next;
41
};
42
 
43
/* list of wisdom */
44
static struct wisdom *wisdom_list = (struct wisdom *) 0;
45
 
46
int fftw_wisdom_lookup(int n, int flags, fftw_direction dir,
47
                       enum fftw_wisdom_category category,
48
                       int istride, int ostride,
49
                       enum fftw_node_type *type,
50
                       int *signature, int replacep)
51
{
52
     struct wisdom *p;
53
 
54
     if (!(flags & FFTW_USE_WISDOM))
55
          return 0;             /* simply ignore if wisdom is disabled */
56
 
57
     flags |= FFTW_MEASURE;     /*
58
                                 * always use (only) wisdom from
59
                                 * measurements
60
                                 */
61
 
62
     for (p = wisdom_list; p; p = p->next) {
63
          if (p->n == n && p->flags == flags && p->dir == dir &&
64
              p->istride == istride && p->ostride == ostride &&
65
              p->category == category) {
66
               /* found wisdom */
67
               if (replacep) {
68
                    /* replace old wisdom with new */
69
                    p->type = *type;
70
                    p->signature = *signature;
71
               } else {
72
                    *type = p->type;
73
                    *signature = p->signature;
74
               }
75
               return 1;
76
          }
77
     }
78
 
79
     return 0;
80
}
81
 
82
void fftw_wisdom_add(int n, int flags, fftw_direction dir,
83
                     enum fftw_wisdom_category category,
84
                     int istride, int ostride,
85
                     enum fftw_node_type type,
86
                     int signature)
87
{
88
     struct wisdom *p;
89
 
90
     if (!(flags & FFTW_USE_WISDOM))
91
          return;               /* simply ignore if wisdom is disabled */
92
 
93
     if (!(flags & FFTW_MEASURE))
94
          return;               /* only measurements produce wisdom */
95
 
96
     if (fftw_wisdom_lookup(n, flags, dir, category, istride, ostride,
97
                            &type, &signature, 1))
98
          return;               /* wisdom overwrote old wisdom */
99
 
100
     p = (struct wisdom *) fftw_malloc(sizeof(struct wisdom));
101
 
102
     p->n = n;
103
     p->flags = flags;
104
     p->dir = dir;
105
     p->category = category;
106
     p->istride = istride;
107
     p->ostride = ostride;
108
     p->type = type;
109
     p->signature = signature;
110
 
111
     /* remember this wisdom */
112
     p->next = wisdom_list;
113
     wisdom_list = p;
114
}
115
 
116
void fftw_forget_wisdom(void)
117
{
118
     while (wisdom_list) {
119
          struct wisdom *p;
120
 
121
          p = wisdom_list;
122
          wisdom_list = wisdom_list->next;
123
          fftw_free(p);
124
     }
125
}
126
 
127
/*
128
 * user-visible routines, to convert wisdom into strings etc.
129
 */
130
static const char *WISDOM_FORMAT_VERSION = "FFTW-" FFTW_VERSION;
131
 
132
static void (*emit) (char c, void *data);
133
 
134
static void emit_string(const char *s, void *data)
135
{
136
     while (*s)
137
          emit(*s++, data);
138
}
139
 
140
static void emit_int(int n, void *data)
141
{
142
     char buf[128];
143
 
144
     sprintf(buf, "%d", n);
145
     emit_string(buf, data);
146
}
147
 
148
/* dump wisdom in lisp-like format */
149
void fftw_export_wisdom(void (*emitter) (char c, void *), void *data)
150
{
151
     struct wisdom *p;
152
 
153
     /* install the output handler */
154
     emit = emitter;
155
 
156
     emit('(', data);
157
     emit_string(WISDOM_FORMAT_VERSION, data);
158
 
159
     for (p = wisdom_list; p; p = p->next) {
160
          emit(' ', data);      /* separator to make the output nicer */
161
          emit('(', data);
162
          emit_int((int) p->n, data);
163
          emit(' ', data);
164
          emit_int((int) p->flags, data);
165
          emit(' ', data);
166
          emit_int((int) p->dir, data);
167
          emit(' ', data);
168
          emit_int((int) p->category, data);
169
          emit(' ', data);
170
          emit_int((int) p->istride, data);
171
          emit(' ', data);
172
          emit_int((int) p->ostride, data);
173
          emit(' ', data);
174
          emit_int((int) p->type, data);
175
          emit(' ', data);
176
          emit_int((int) p->signature, data);
177
          emit(')', data);
178
     }
179
     emit(')', data);
180
}
181
 
182
/* input part */
183
static int next_char;
184
static int (*get_input) (void *data);
185
static fftw_status input_error;
186
 
187
static void read_char(void *data)
188
{
189
     next_char = get_input(data);
190
     if (next_char == 0 ||
191
         next_char == EOF)
192
          input_error = FFTW_FAILURE;
193
}
194
 
195
/* skip blanks, newlines, tabs, etc */
196
static void eat_blanks(void *data)
197
{
198
     while (isspace(next_char))
199
          read_char(data);
200
}
201
 
202
static int read_int(void *data)
203
{
204
     int sign = 1;
205
     int n = 0;
206
 
207
     eat_blanks(data);
208
     if (next_char == '-') {
209
          sign = -1;
210
          read_char(data);
211
          eat_blanks(data);
212
     }
213
     if (!isdigit(next_char)) {
214
          /* error, no digit */
215
          input_error = FFTW_FAILURE;
216
          return 0;
217
     }
218
     while (isdigit(next_char)) {
219
          n = n * 10 + (next_char - '0');
220
          read_char(data);
221
     }
222
 
223
     return sign * n;
224
}
225
 
226
#define EXPECT(c)                     \
227
{                                     \
228
     eat_blanks(data);                \
229
     if (input_error == FFTW_FAILURE || \
230
         next_char != c)              \
231
          return FFTW_FAILURE;        \
232
     read_char(data);                 \
233
}
234
 
235
#define EXPECT_INT(n)                                 \
236
{                                                     \
237
     n = read_int(data);                              \
238
     if (input_error == FFTW_FAILURE)                 \
239
          return FFTW_FAILURE;                        \
240
}
241
 
242
#define EXPECT_STRING(s)             \
243
{                                    \
244
     const char *s1 = s;                     \
245
     while (*s1) {                   \
246
          EXPECT(*s1);               \
247
          ++s1;                      \
248
     }                               \
249
}
250
 
251
fftw_status fftw_import_wisdom(int (*g) (void *), void *data)
252
{
253
     int n;
254
     int flags;
255
     fftw_direction dir;
256
     int dir_int;
257
     enum fftw_wisdom_category category;
258
     int category_int;
259
     enum fftw_node_type type;
260
     int type_int;
261
     int signature;
262
     int istride, ostride;
263
 
264
     get_input = g;
265
     input_error = FFTW_SUCCESS;
266
 
267
     read_char(data);
268
 
269
     eat_blanks(data);
270
     EXPECT('(');
271
     eat_blanks(data);
272
     EXPECT_STRING(WISDOM_FORMAT_VERSION);
273
     eat_blanks(data);
274
 
275
     while (next_char != ')') {
276
          EXPECT('(');
277
          EXPECT_INT(n);
278
          EXPECT_INT(flags);
279
          /* paranoid respect for enumerated types */
280
          EXPECT_INT(dir_int);
281
          dir = (fftw_direction) dir_int;
282
          EXPECT_INT(category_int);
283
          category = (enum fftw_wisdom_category) category_int;
284
          EXPECT_INT(istride);
285
          EXPECT_INT(ostride);
286
          EXPECT_INT(type_int);
287
          type = (enum fftw_node_type) type_int;
288
          EXPECT_INT(signature);
289
          eat_blanks(data);
290
          EXPECT(')');
291
 
292
          /* the wisdom has been read properly. Add it */
293
          fftw_wisdom_add(n, flags, dir, category,
294
                          istride, ostride, type, signature);
295
 
296
          /* prepare for next morsel of wisdom */
297
          eat_blanks(data);
298
     }
299
 
300
     return FFTW_SUCCESS;
301
}