1 (declaim (optimize (speed 2) (debug 3) (safety 3)))
4 (defconstant +forward
+ 1)
5 (defconstant +backward
+ -
1)
6 (defconstant +estimate
+ (ash 1 6))
8 (defmacro def-ffi
(&optional
(library "libfftw3.so") (prefix "fftw"))
10 (load-shared-object ,(format nil
"~a" library
))
11 (define-alien-routine (,(format nil
"~a_execute" prefix
)
12 ,(vol:format-symbol
"~a-execute" prefix
))
15 ,@(loop for rank in
'(1 2 3) collect
16 `(define-alien-routine
17 (,(format nil
"~a_plan_dft_~ad" prefix rank
)
18 ,(format-symbol "~a-plan-dft-~ad" prefix rank
))
20 ,@(loop for i below rank collect
21 `(,(format-symbol "n~d" i
) int
))
23 (out (* double-float
))
25 (flags unsigned-int
)))))
27 ;; define the foreign functions
28 ;; fftw{f}-execute, fftw{f}-plan-dft-{1,2,3}d
29 (def-ffi "libfftw3.so.3" "fftw")
30 (def-ffi "libfftw3f.so.3" "fftwf")
34 (load-shared-object "/usr/lib/libfftw3_threads.so")
36 (define-alien-routine ("fftw_init_threads" init-threads
)
38 (define-alien-routine ("fftw_plan_with_nthreads" plan-with-nthreads
)
44 (plan-with-nthreads 4)))
46 ;; to clean up completely call void fftw_cleanup_threads(void)
50 (def-generator (ft (rank type
))
51 (let* ((prefix (ecase type
54 (rlong-type (ecase type
55 (csf (get-long-type 'sf
))
56 (cdf (get-long-type 'df
))))
57 (plan (format-symbol "~a-plan-dft-~ad" prefix rank
))
58 (execute (format-symbol "~a-execute" prefix
)))
59 `(defun ,name
(in &key
(forward t
))
60 (declare ((simple-array ,long-type
,rank
) in
)
62 (values (simple-array ,long-type
,rank
) &optional
))
63 (let* ((dims (array-dimensions in
))
64 (out (make-array dims
:element-type
',long-type
))
65 (in-sap (sb-sys:vector-sap
66 (sb-ext:array-storage-vector in
)))
67 (out-sap (sb-sys:vector-sap
68 (sb-ext:array-storage-vector out
)))
69 (dir (if forward
+forward
+ +backward
+)))
70 (sb-sys:with-pinned-objects
(in out
)
72 (1 `(destructuring-bind (x) dims
73 (let ((p (,plan x in-sap out-sap
76 (2 `(destructuring-bind (y x
) dims
77 (let ((p (,plan y x in-sap out-sap
80 (3 `(destructuring-bind (z y x
) dims
81 (let ((p (,plan z y x in-sap out-sap
84 (when forward
;; normalize if forward
85 (s* (/ ,(coerce 1 rlong-type
) (array-total-size out
)) out
))
89 (def-ft-rank-type 1 csf
)
91 (defmacro def-ft-functions
(ranks types
)
92 (let* ((specifics nil
)
94 (name (format-symbol "ft")))
95 (loop for rank in ranks do
96 (loop for type in types do
97 (let ((def-name (format-symbol "def-~a-rank-type" name
))
98 (specific-name (format-symbol "~a-~a-~a" name rank type
)))
99 (push `(,def-name
,rank
,type
) specifics
)
100 (push `((simple-array ,(get-long-type type
) ,rank
)
101 (,specific-name a
:forward forward
))
103 (store-new-function name
)
105 (defun ,name
(a &key forward
)
108 (t (error "The given type can't be handled with a generic ~a function." ',name
)))))))
110 (def-ft-functions (1 2 3) (csf cdf
))
113 `(ft ,in
:forward nil
))
121 (a (convert-3-ub8/csf-mul
122 (draw-sphere-ub8 20.0 nz ny nx
))))
123 (write-pgm "/home/martin/tmp/fftw.pgm"
124 (normalize-2-csf/ub8-abs
125 (cross-section-xz-csf (ft a
)))))))