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?
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 :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With