Call BLAS ddot routine from SBCL
Asked Answered
M

2

5

I am trying to call the BLAS ddot routine from SBCL.

Based on:

I came up with the following script:

(load-shared-object "libblas.so.3")

(declaim (inline ddot))

(define-alien-routine ("ddot_" ddot) void
  (n int :copy)
  (dx (* double))
  (incx int :copy)
  (dy (* double))
  (incy int :copy))

(defun pointer (array)
  (sap-alien (sb-sys:vector-sap (array-storage-vector array)) (* double)))

(defun dot (dx dy)
  (unless (= (length dx) (length dy))
    (error "Vectors length does not match"))
  (let ((n (length dx))
    (result 0.0d0))
    (sb-sys:with-pinned-objects (dx dy result)
      (ddot n (pointer dx) 1 (pointer dy) 1))))

However, the following script:

(defvar *a* (make-array 4 :initial-element 1.0d0 :element-type 'double-float))
(defvar *b* (make-array 4 :initial-element 2.0d0 :element-type 'double-float))
(dot *a* *b*)

produces the following error:

arithmetic error FLOATING-POINT-INVALID-OPERATION signalled
   [Condition of type FLOATING-POINT-INVALID-OPERATION]

Any hint?

Minh answered 16/7, 2015 at 10:46 Comment(0)
M
4

Found it. Credits to Miroslav Urbanek from Charles University in Prague for the hint.

-(define-alien-routine ("ddot_" ddot) void
+(define-alien-routine ("ddot_" ddot) double

 (defun dot (dx dy)
   (unless (= (length dx) (length dy))
     (error "Vectors length does not match"))
-  (let ((n (length dx))
-        (result 0.0d0))
-    (sb-sys:with-pinned-objects (dx dy result)
+  (let ((n (length dx)))
+    (sb-sys:with-pinned-objects (dx dy)

The ddot routine is meant to return a double, not a void. And the result variable is useless. Things are so obvious after you realize them :-)

Minh answered 18/7, 2015 at 7:34 Comment(0)
S
3

I know it doesn't directly answer your question but have you tried using an already written binding to Blas? For exampme Matlisp already provides an lispy interface to dot

Santoro answered 18/7, 2015 at 7:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.