Anyone understand this?

"David McClain (as dbm at refined-audiometrics dot com)" <[email protected]>
Newsgroups gmane.lisp.lispworks.general
Message-ID <[email protected]>
I’m clearly doing something wrong, but I can’t see it. 

The following routines call a simple vector dot-product routine provided as an external C function. The routines both work correctly - but only if the START2 parameter is zero. For any other START2 offset, these both produce the same answer as for START2=0, which is incorrect.

The same error occurs on both WIndows and MacOS. While you can’t test the WINDOWS version because it calls my own C routine, the MacOS version is available to everyone.

It appears to act as though the FLI:WITH-DYNAMIC-LISP-ARRAY-POINTER produces an object that carries both the base array address, and the offset index. Certainly reasonable to expect that. But when the C Interface routine gets its hands on this “displaced pointer” it takes only the base address for itself.

The LW manual shows examples of using FLI:WITH-DYNAMIC-LISP-ARRAY-POINTER together with FLI:DEREFERENCE to access elements of the “displaced” array.  And I trust that it works as shown. But I could more easily do that directly in Lisp with AREF.

I had the initial impression that this FLI:WITH-DYNAMIC-LISP-ARRAY-POINTER was invented for the purposes that I am using here, for passing an offset address into a Lisp array for access in an external C routine. So the problem is likely to be with the way that I’m passing the argument to the C interface, or with the way I have (incorrectly?) declared the parameter in the C interface.

I have tried numerous interface declarations that all end up doing the same thing. Two are shown below, one for Mac, the other for Windows. 

Any ideas how to do this correctly?

=================

#+:MACOSX
(defvar *vdsp-lib*
  "/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libvDSP.dylib")

#+:MACOSX
(fli:define-foreign-function (_vdsp-dotprd "vDSP_dotprD" :source)
    ((va  :lisp-simple-1d-array)
     (ia  :long)
     (vb  :pointer)
     (ib  :long)
     (pc  (:pointer :double-float))
     (nel :long))
  :result-type :void
  :language :c
  :calling-convention :cdecl
  :module *vdsp-lib*)

#+:MACOSX
(defun vdot (arr1 arr2 &key (start2 0))
  ;; intended for pre-decimation FIR filtering, where:
  ;;   arr1 = FIR filter kernel
  ;;   arr2 = input data buffer
  ;;   nel  = length of FIR filter (ntaps)
  ;;   start2 = starting position in data buffer for filtering,
  ;;            as kernel steps along by ndec
  (declare ((simple-array double-float *) arr1 arr2))
  (fli:with-dynamic-foreign-objects ()
    (let ((ans (fli:allocate-dynamic-foreign-object :type :double-float)))
      (hcl:with-pinned-objects (arr2)
        (fli:with-dynamic-lisp-array-pointer (parr arr2 :type :double-float :start start2)
          (_vdsp-dotprd arr1 1 parr 1 ans (length arr1))
          (fli:dereference ans))
        ))))

#+:MSWINDOWS
(fli:define-foreign-function (dotprD "dotprD" :source)
    ((va  :lisp-simple-1d-array)
     (vb  (:pointer :double-float))
     (nel :long))
  :result-type :double-float
  :language :c
  :calling-convention :cdecl
  :module *wave-lib*)

#+:MSWINDOWS
(defun vdot (arr1 arr2 &key (start2 0))
  (declare ((simple-array double-float *) arr1 arr2))
  (hcl:with-pinned-objects (arr2)
    (fli:with-dynamic-lisp-array-pointer (parr arr2 :type :double-float :start start2)
      (dotprd arr1 parr (length arr1))
      )))

#|
(let* ((arr2 (make-array 5
                         :element-type 'double-float
                         :allocation :pinnable
                         :initial-contents '(1d0 2d0 3d0 4d0 5d0)))
       (arr1 (make-array 3
                         :element-type 'double-float
                         :allocation :pinnable
                         :initial-contents '(10d0 20d0 30d0))))
  (vdot arr1 arr2 :start2 1)) ;; should produce 200.0, but produces 140.0.
|#
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.