[Gsll-devel] small modification to blas2.lisp

Mirko Vukovic mirko.vukovic at gmail.com
Mon May 19 15:23:19 UTC 2008


On Sat, May 17, 2008 at 8:56 PM, Mirko Vukovic <mirko.vukovic at gmail.com> wrote:
> On Sat, May 17, 2008 at 6:11 PM, Liam Healy <lhealy at common-lisp.net> wrote:
>> Mirko,
>>
>> Your error is that your function isn't defined in the GSL library;
>> that is what sb-kernel::undefined-alien-function-error means.  A quick
>> glance at "fft_complex_radix2_forward" makes me suspicious, as I
>> believe all GSL functions start with "gsl_" and this doesn't have
>> that.  Since you're on linux, use the shell script "list" which is
>> at top level in the GSLL files, thus:
>>  list | grep -i fft_complex_radix2_forward
>>  gsl_fft_complex_radix2_forward
>>

You were absolutely correct.  The name is gsl_fft...

I am now getting a memory fault:

Unhandled memory fault at #x0.
   [Condition of type SB-SYS:MEMORY-FAULT-ERROR]

Restarts:
  0: [ABORT-REQUEST] Abort handling SLIME request.
  1: [ABORT] Exit debugger, returning to top level.

Backtrace:
  0: (SB-SYS:MEMORY-FAULT-ERROR)
  1: (SB-SYS:MEMORY-FAULT-ERROR)
  2: ("foreign function: #x419F72")
  3: ("foreign function: #x41A040")
  4: ("foreign function: #x3919E4AEA4")
  5: ((LAMBDA (SB-PCL::.PV. SB-PCL::.NEXT-METHOD-CALL.
SB-PCL::.ARG0.)) #<error printing object>)

I have modified the defmfun to include a return declaration as :int
and also declared the function as a :function.  But that did not
change the above error.  Here is the new code.

(in-package :gsll)

(defmfun fft-c2f (x stride n)
  "gsl_fft_complex_radix2_forward"
;; for gsl doc and example see
;; http://www.gnu.org/software/gsl/manual/html_node/Radix_002d2-FFT-routines-for-complex-data.html
  (((pointer x) gsl-vector-c) (stride :int) (n :int))
  :type :function
  :c-return :int
  :documentation
  "Forward FFT for a complex double radix-2 vector")

;; test run
(let ((arg (make-array 4 :element-type 'complex :initial-element #c(0d0 0d0))))
  (setf (aref arg 2) #c(1d0 0d0))
  (let* ((dim (length arg))
	(double (make-array (* 2 dim)
			     :element-type 'double-float
			     :initial-element 0d0)))
    ;; repackaging complex as double -- is there a built-in?
    (loop
       for re-im across arg
       for i from 0 to (* 2 (1- dim)) by 2
       do (progn
	    (setf (aref double i) (realpart re-im))
	    (setf (aref double (1+ i)) (imagpart re-im))))

    (letm ((double* (vector-double-float double)))
      (fft-c2f double* 1 dim))))

I am essentially trying to replicate example3.lisp from nlisp's
distribution.  I am including it here:
;;; Low level wrapper for gsl fft routine
(cffi:defcfun "gsl_fft_complex_radix2_forward"
	      :int (a :pointer) (stride :int) (n :int))

;;; A high level NLISP style function
(defun fft (a)
  (let ((rn (.* a 1d0)))
    (with-accessors ((r val)) rn
       (sb-sys:without-gcing)
       (let ((r-addr (sb-sys:vector-sap r)))
	 (declare (type (simple-array (complex double-float)) r))
	 (gsl-fft-complex-radix2-forward r-addr 1 (array-dimension r 0)))) rn))

;;; Example program
(defun example3 (n)
  (let ((a (make-complex-double-array 128)))
    (setf (.aref a n) (complex 1d0 0d0))
    (let ((z (fft a)))
      (nplot (list (.realpart z) (.imagpart z)) nil
	     :legends (list "Real Part" "Imaginary Part")))))


Should I wait to for you to finish your transition to ffa-based arrays
before pursuing this further?

I could check the correctness of the call once I have something working right.

Mirko



More information about the gsll-devel mailing list