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
33 enum fftw_wisdom_category category
;
36 enum fftw_node_type type
; /* this is the wisdom */
37 int signature
; /* this is the 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
)
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
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
) {
66 /* replace old wisdom with new */
68 p
->signature
= *signature
;
71 *signature
= p
->signature
;
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
,
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
));
103 p
->category
= category
;
104 p
->istride
= istride
;
105 p
->ostride
= ostride
;
107 p
->signature
= signature
;
109 /* remember this wisdom */
110 p
->next
= wisdom_list
;
114 void fftw_forget_wisdom(void)
116 while (wisdom_list
) {
120 wisdom_list
= wisdom_list
->next
;
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
)
138 static void emit_int(int n
, void *data
)
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
)
151 /* install the output handler */
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 */
160 emit_int((int) p
->n
, data
);
162 emit_int((int) p
->flags
, data
);
164 emit_int((int) p
->dir
, data
);
166 emit_int((int) p
->category
, data
);
168 emit_int((int) p
->istride
, data
);
170 emit_int((int) p
->ostride
, data
);
172 emit_int((int) p
->type
, data
);
174 emit_int((int) p
->signature
, data
);
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 ||
190 input_error
= FFTW_FAILURE
;
193 /* skip blanks, newlines, tabs, etc */
194 static void eat_blanks(void *data
)
196 while (isspace(next_char
))
200 static int read_int(void *data
)
206 if (next_char
== '-') {
211 if (!isdigit(next_char
)) {
212 /* error, no digit */
213 input_error
= FFTW_FAILURE
;
216 while (isdigit(next_char
)) {
217 n
= n
* 10 + (next_char
- '0');
227 if (input_error == FFTW_FAILURE || \
229 return FFTW_FAILURE; \
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; \
249 fftw_status
fftw_import_wisdom(int (*g
) (void *), void *data
)
255 enum fftw_wisdom_category category
;
257 enum fftw_node_type type
;
260 int istride
, ostride
;
263 input_error
= FFTW_SUCCESS
;
270 EXPECT_STRING(WISDOM_FORMAT_VERSION
);
273 while (next_char
!= ')') {
277 /* paranoid respect for enumerated types */
279 dir
= (fftw_direction
) dir_int
;
280 EXPECT_INT(category_int
);
281 category
= (enum fftw_wisdom_category
) category_int
;
284 EXPECT_INT(type_int
);
285 type
= (enum fftw_node_type
) type_int
;
286 EXPECT_INT(signature
);
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 */