【问题标题】:Possible workarounds for vector cross product with Arrayfire.jl?Arrayfire.jl 矢量叉积的可能解决方法?
【发布时间】:2017-05-27 19:26:03
【问题描述】:

我正在尝试使用 ArrayFire.jl 进行矢量数学运算,但 Arrayfire 中未实现矢量叉积函数。 是否有一种解决方法可以使用 Julia 的 Arrayfire.jl 包装器以高效的方式计算它?由于设备和主机之间的所有数据传输,以天真的方式定义函数真的很慢,而且我对包装函数的了解还不够,无法弄清楚如何解决这个问题。

cross(a::ArrayFire.AFArray, b::ArrayFire.AFArray) = ArrayFire.AFArray([a[2]*b[3]-a[3]*b[2]; a[3]*b[1]-a[1]*b[3]; a[1]*b[2]-a[2]*b[1]]);

【问题讨论】:

  • 那么你是想使用array fire还是仅仅使用julia的linalg(它有一个非常快的内置交叉函数......)
  • 我想使用 ArrayFire 来完成它,这样我就可以将计算卸载到 GPU 并加快我的代码速度。
  • 你能写一个版本,使用 3 个 AFArray 并使用你给出的定义设置第一个的元素吗?
  • 如果我理解 arrayfire.jl 包的低级包装函数,也许,但使用像 a[i] 这样的索引函数很慢,因为它将数据传入和传出 gpu。跨度>
  • 是的,它应该提供显着的加速。我需要计算大约 175 000 个实例,并且大部分代码都可以利用并行化。我在加速代码方面取得了很好的成功,但现在遇到了这个问题,不幸的是我无法摆脱交叉产品。

标签: julia arrayfire


【解决方案1】:

我认为以下应该可行:

function cross!(c::AFArray, a::AFArray, b::AFArray)
    c[1] = a[2]*b[3]-a[3]*b[2]
    c[2] = a[3]*b[1]-a[1]*b[3]
    c[3] = a[1]*b[2]-a[2]*b[1]
end

c = AFArray(zeros(3))
a = AFArray([1.0, 2, 3])
b = AFArray([3.0, 4, 5])

cross!(c, a, b)

【讨论】:

    【解决方案2】:

    回答我自己,可以使用 circshift() 函数在 GPU 中创建移位向量来完成叉积,然后可以进行元素乘法和减法。这不是最优雅的方式,但确实有效。

    function cross(a::ArrayFire.AFArray{Float32,1}, b::ArrayFire.AFArray{Float32,1})
        ashift = circshift(a, [-1]);
        ashift2 = circshift(a, [-2]);
        bshift = circshift(b, [-2]);
        bshift2 = circshift(b, [-1]);
        c::ArrayFire.AFArray{Float32,1} = ashift.*bshift - ashift2.*bshift2;
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-25
      相关资源
      最近更新 更多