changed reading hint
[gromacs/adressmacs.git] / src / fftw / wisdom.c
blob1b811c351e7f50934b12d4e4ddcee6076126d690
1 /*
2 * Copyright (c) 1997-1999 Massachusetts Institute of Technology
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.
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.
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
21 * wisdom.c -- manage the wisdom
24 #include <fftw-int.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <ctype.h>
29 struct wisdom {
30 int n;
31 int flags;
32 fftw_direction dir;
33 enum fftw_wisdom_category category;
34 int istride;
35 int ostride;
36 enum fftw_node_type type; /* this is the wisdom */
37 int signature; /* this is the wisdom */
38 struct wisdom *next;
41 /* list of wisdom */
42 static struct wisdom *wisdom_list = (struct wisdom *) 0;
44 int fftw_wisdom_lookup(int n, int flags, fftw_direction dir,
45 enum fftw_wisdom_category category,
46 int istride, int ostride,
47 enum fftw_node_type *type,
48 int *signature, int replacep)
50 struct wisdom *p;
52 if (!(flags & FFTW_USE_WISDOM))
53 return 0; /* simply ignore if wisdom is disabled */
55 flags |= FFTW_MEASURE; /*
56 * always use (only) wisdom from
57 * measurements
60 for (p = wisdom_list; p; p = p->next) {
61 if (p->n == n && p->flags == flags && p->dir == dir &&
62 p->istride == istride && p->ostride == ostride &&
63 p->category == category) {
64 /* found wisdom */
65 if (replacep) {
66 /* replace old wisdom with new */
67 p->type = *type;
68 p->signature = *signature;
69 } else {
70 *type = p->type;
71 *signature = p->signature;
73 return 1;
77 return 0;
80 void fftw_wisdom_add(int n, int flags, fftw_direction dir,
81 enum fftw_wisdom_category category,
82 int istride, int ostride,
83 enum fftw_node_type type,
84 int signature)
86 struct wisdom *p;
88 if (!(flags & FFTW_USE_WISDOM))
89 return; /* simply ignore if wisdom is disabled */
91 if (!(flags & FFTW_MEASURE))
92 return; /* only measurements produce wisdom */
94 if (fftw_wisdom_lookup(n, flags, dir, category, istride, ostride,
95 &type, &signature, 1))
96 return; /* wisdom overwrote old wisdom */
98 p = (struct wisdom *) fftw_malloc(sizeof(struct wisdom));
100 p->n = n;
101 p->flags = flags;
102 p->dir = dir;
103 p->category = category;
104 p->istride = istride;
105 p->ostride = ostride;
106 p->type = type;
107 p->signature = signature;
109 /* remember this wisdom */
110 p->next = wisdom_list;
111 wisdom_list = p;
114 void fftw_forget_wisdom(void)
116 while (wisdom_list) {
117 struct wisdom *p;
119 p = wisdom_list;
120 wisdom_list = wisdom_list->next;
121 fftw_free(p);
126 * user-visible routines, to convert wisdom into strings etc.
128 static const char *WISDOM_FORMAT_VERSION = "FFTW-" FFTW_VERSION;
130 static void (*emit) (char c, void *data);
132 static void emit_string(const char *s, void *data)
134 while (*s)
135 emit(*s++, data);
138 static void emit_int(int n, void *data)
140 char buf[128];
142 sprintf(buf, "%d", n);
143 emit_string(buf, data);
146 /* dump wisdom in lisp-like format */
147 void fftw_export_wisdom(void (*emitter) (char c, void *), void *data)
149 struct wisdom *p;
151 /* install the output handler */
152 emit = emitter;
154 emit('(', data);
155 emit_string(WISDOM_FORMAT_VERSION, data);
157 for (p = wisdom_list; p; p = p->next) {
158 emit(' ', data); /* separator to make the output nicer */
159 emit('(', data);
160 emit_int((int) p->n, data);
161 emit(' ', data);
162 emit_int((int) p->flags, data);
163 emit(' ', data);
164 emit_int((int) p->dir, data);
165 emit(' ', data);
166 emit_int((int) p->category, data);
167 emit(' ', data);
168 emit_int((int) p->istride, data);
169 emit(' ', data);
170 emit_int((int) p->ostride, data);
171 emit(' ', data);
172 emit_int((int) p->type, data);
173 emit(' ', data);
174 emit_int((int) p->signature, data);
175 emit(')', data);
177 emit(')', data);
180 /* input part */
181 static int next_char;
182 static int (*get_input) (void *data);
183 static fftw_status input_error;
185 static void read_char(void *data)
187 next_char = get_input(data);
188 if (next_char == 0 ||
189 next_char == EOF)
190 input_error = FFTW_FAILURE;
193 /* skip blanks, newlines, tabs, etc */
194 static void eat_blanks(void *data)
196 while (isspace(next_char))
197 read_char(data);
200 static int read_int(void *data)
202 int sign = 1;
203 int n = 0;
205 eat_blanks(data);
206 if (next_char == '-') {
207 sign = -1;
208 read_char(data);
209 eat_blanks(data);
211 if (!isdigit(next_char)) {
212 /* error, no digit */
213 input_error = FFTW_FAILURE;
214 return 0;
216 while (isdigit(next_char)) {
217 n = n * 10 + (next_char - '0');
218 read_char(data);
221 return sign * n;
224 #define EXPECT(c) \
226 eat_blanks(data); \
227 if (input_error == FFTW_FAILURE || \
228 next_char != c) \
229 return FFTW_FAILURE; \
230 read_char(data); \
233 #define EXPECT_INT(n) \
235 n = read_int(data); \
236 if (input_error == FFTW_FAILURE) \
237 return FFTW_FAILURE; \
240 #define EXPECT_STRING(s) \
242 const char *s1 = s; \
243 while (*s1) { \
244 EXPECT(*s1); \
245 ++s1; \
249 fftw_status fftw_import_wisdom(int (*g) (void *), void *data)
251 int n;
252 int flags;
253 fftw_direction dir;
254 int dir_int;
255 enum fftw_wisdom_category category;
256 int category_int;
257 enum fftw_node_type type;
258 int type_int;
259 int signature;
260 int istride, ostride;
262 get_input = g;
263 input_error = FFTW_SUCCESS;
265 read_char(data);
267 eat_blanks(data);
268 EXPECT('(');
269 eat_blanks(data);
270 EXPECT_STRING(WISDOM_FORMAT_VERSION);
271 eat_blanks(data);
273 while (next_char != ')') {
274 EXPECT('(');
275 EXPECT_INT(n);
276 EXPECT_INT(flags);
277 /* paranoid respect for enumerated types */
278 EXPECT_INT(dir_int);
279 dir = (fftw_direction) dir_int;
280 EXPECT_INT(category_int);
281 category = (enum fftw_wisdom_category) category_int;
282 EXPECT_INT(istride);
283 EXPECT_INT(ostride);
284 EXPECT_INT(type_int);
285 type = (enum fftw_node_type) type_int;
286 EXPECT_INT(signature);
287 eat_blanks(data);
288 EXPECT(')');
290 /* the wisdom has been read properly. Add it */
291 fftw_wisdom_add(n, flags, dir, category,
292 istride, ostride, type, signature);
294 /* prepare for next morsel of wisdom */
295 eat_blanks(data);
298 return FFTW_SUCCESS;