如何使用 BLAS 函数将指针传递给子数组?

How to pass a pointer to a subarray with BLAS function?

我正在使用 Julia v0.3.5,它随 WinPython 3.4.2.5 build 4 一起提供。我是 Julia 的新手。我正在测试 Julia 与使用 SciPy 的 DDot() 的 BLAS 包装器相比有多快,ddot() 具有以下参数:x,y,n,offx,incx,offy,incy。 Julia 的 OpenBLAS 库没有偏移参数,所以我想弄清楚如何在最大化速度的同时模拟它们。我多次传递 1GB 数组(向量)的 100MB 子数组,所以我不希望 Julia 创建每个子数组的副本,这会降低速度。 Python 的 SciPy 函数需要几个小时才能执行,所以想优化 Julia 的速度。我一直在阅读有关 Julia 0.4 将如何提供避免不必要的副本的数组视图的信息,但我不清楚 Julia 0.3.5 如何处理这个问题。

至此,使用REPL了解到BLAS dot()函数与linalg/matmul.jl中的方法冲突。因此,我学会了这样访问它:

import Base.LinAlg.BLAS
methods(Base.LinAlg.BLAS.dot)

从方法显示中,我看到我可以将指针传递给 x 和 y 子数组,从而避免复制。例如:

x = [1., 2., 3.]
y = [4., 5., 6.]
Base.LinAlg.BLAS.dot(2, pointer(x), 1, pointer(y), 1)

但是,当我向指针添加整数偏移量(以访问子数组)时,REPL 崩溃。

如何在不减慢该子数组副本的情况下将指向子数组或子数组的指针传递给 Base.LinAlg.BLAS.dot? 还有什么我错过的吗?

它会出现段错误,因为指针算法并不像您可能认为的那样工作(即 C 方式)。 pointer(x)+1pointer(x) 之后的一个字节,但您可能需要 pointer(x)+8,例如

Base.LinAlg.BLAS.dot(2, pointer(x)+1*sizeof(Float64), 1, pointer(y)+1*sizeof(Float64), 1)

或者,更人性化和推荐:

Base.LinAlg.dot(x,2:3,y,2:3)

也就是 defined here.

我想说的是,在 Julia 中使用这样的指针确实不推荐,但我想如果你真的这样做,那是一种特殊情况。