从 SBCL 调用 BLAS ddot 例程

Call BLAS ddot routine from SBCL

我正在尝试从 SBCL 调用 BLAS ddot 例程。

基于:

我想出了以下脚本:

(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))))

但是,下面的脚本:

(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*)

产生以下错误:

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

有什么提示吗?

我知道它不会直接回答您的问题,但您是否尝试过使用已编写的 Blas 绑定?例如 Matlisp already provides an lispy interface to dot

找到了。感谢布拉格查尔斯大学的 Miroslav Urbanek 提供提示。

-(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)

ddot 例程是为了 return 双重,而不是无效。结果变量是无用的。事情是如此明显在你意识到它们之后:-)