Common lisp 使用公共Lisp中的BLAS进行矩阵乘法

Common lisp 使用公共Lisp中的BLAS进行矩阵乘法,common-lisp,matrix-multiplication,blas,sbcl,Common Lisp,Matrix Multiplication,Blas,Sbcl,假设我有两个矩阵,其形式为公共Lisp数组foo和bar,如下所示: (defvar foo #2A((2 1 6) (7 3 4))) (defvar bar #2A((3 1) (6 5) (2 3))) 我想使用BLAS执行矩阵乘法,而不使用诸如Matlisp、GSLL、LLA和co之类的包装器。这样我就可以得到一个结果如下的数组: #2A((24 25) (47 34)) 我应该采取哪些步骤来执行此类操作 我的理解是,我应该从REPL调用BLAS矩阵乘法函数,并将参数foo和bar传

假设我有两个矩阵,其形式为公共Lisp数组foo和bar,如下所示:

(defvar foo #2A((2 1 6) (7 3 4)))
(defvar bar #2A((3 1) (6 5) (2 3)))
我想使用BLAS执行矩阵乘法,而不使用诸如Matlisp、GSLL、LLA和co之类的包装器。这样我就可以得到一个结果如下的数组:

#2A((24 25) (47 34))
我应该采取哪些步骤来执行此类操作

我的理解是,我应该从REPL调用BLAS矩阵乘法函数,并将参数foo和bar传递给它

在R中,我可以很容易地这样做:

foo %*% bar
如何使用Common Lisp进行此操作

免责声明: 1我使用SBCL
2我在R方面不是一个经验丰富的计算机科学家

你在使用R包装器。您无法避免使用包装器。所以你应该用最适合你的

抱歉,如果这没有多大帮助,但事情就是这样


Marco

在R中,您正在使用R包装器。您无法避免使用包装器。所以你应该用最适合你的

抱歉,如果这没有多大帮助,但事情就是这样


马可

这是我一直在寻找的完美答案。布拉格查尔斯大学Miroslav Urbanek的学分

这是基本的想法。我从中找到一个要使用的函数 布拉斯/拉帕克。在矩阵乘法的情况下,它是DGEMM。D站 对于双浮点数,GE表示一般矩阵,不带特殊的 形状如对称、三角形等,MM代表矩阵 乘法。文件如下:

然后我使用SBCL FFI定义一个外来例程。我通过Lisp数组 直接使用一些特殊的SBCL函数。Lisp数组必须是 使用选项创建:元素类型“双浮点”

重要的一点是,SBCL将数组元素存储在主行中 顺序,类似于C。Fortran使用列主顺序。这 有效地对应于转置矩阵。矩阵的阶 因此,从调用DGEMM时,必须更改其尺寸 口齿不清


这是我一直在寻找的完美答案。布拉格查尔斯大学Miroslav Urbanek的学分

这是基本的想法。我从中找到一个要使用的函数 布拉斯/拉帕克。在矩阵乘法的情况下,它是DGEMM。D站 对于双浮点数,GE表示一般矩阵,不带特殊的 形状如对称、三角形等,MM代表矩阵 乘法。文件如下:

然后我使用SBCL FFI定义一个外来例程。我通过Lisp数组 直接使用一些特殊的SBCL函数。Lisp数组必须是 使用选项创建:元素类型“双浮点”

重要的一点是,SBCL将数组元素存储在主行中 顺序,类似于C。Fortran使用列主顺序。这 有效地对应于转置矩阵。矩阵的阶 因此,从调用DGEMM时,必须更改其尺寸 口齿不清


我目前的理解是,您需要一些外部函数接口绑定,以确保BLAS函数与其来自Common Lisp的调用之间的链接。如果我的理解是准确的,从这个意义上说,是的,你确实需要一个包装。更精确地重新表述我的问题将导致:如何在不使用任何其他更高级的Lisp库(如Matlisp等)的情况下直接使用ffi?我试图理解如何使用已有的BLAS函数在两个CL数组foo和bar上执行矩阵乘法,或者在某些数组baz上计算协方差矩阵。我目前的理解是,您需要一些外部函数接口绑定,以确保BLAS函数与其从Common Lisp调用之间的链接。如果我的理解是准确的,从这个意义上说,是的,你确实需要一个包装。更精确地重新表述我的问题将导致:如何在不使用任何其他更高级的Lisp库(如Matlisp等)的情况下直接使用ffi?我试图理解如何在两个CL数组foo和bar上执行矩阵乘法,或者使用已有的BLAS函数在某些数组baz上计算协方差矩阵。
;; Matrix multiplication in SBCL using BLAS
;; Miroslav Urbanek <mu@miroslavurbanek.com>

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

(declaim (inline dgemm))

(define-alien-routine ("dgemm_" dgemm) void
  (transa c-string)
  (transb c-string)
  (m int :copy)
  (n int :copy)
  (k int :copy)
  (alpha double :copy)
  (a (* double))
  (lda int :copy)
  (b (* double))
  (ldb int :copy)
  (beta double :copy)
  (c (* double))
  (ldc int :copy))

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

(defun mm (a b)
  (unless (= (array-dimension a 1) (array-dimension b 0))
    (error "Matrix dimensions do not match."))
  (let* ((m (array-dimension a 0))
     (n (array-dimension b 1))
     (k (array-dimension a 1))
     (c (make-array (list m n) :element-type 'double-float)))
    (sb-sys:with-pinned-objects (a b c)
      (dgemm "n" "n" n m k 1d0 (pointer b) n (pointer a) k 0d0 (pointer c) n))
    c))

(defparameter a (make-array '(2 3) :element-type 'double-float :initial-contents '((2d0 1d0 6d0) (7d0 3d0 4d0))))
(defparameter b (make-array '(3 2) :element-type 'double-float :initial-contents '((3d0 1d0) (6d0 5d0) (2d0 3d0))))

(format t "a = ~A~%b = ~A~%" a b)

(defparameter c (mm a b))