【发布时间】:2017-12-14 08:02:25
【问题描述】:
我想广播到子数组(即广播到数组切片)。这在 GPU 编程中很有用,例如我想拥有:
X,Y,Z = (rand(3,3,3) for _=1:3)
@.[1,2] X = f(2X^2 + 6X^3 - sqrt(X)) + Y*Z
其中@.[1,2] 表示沿dim 3 广播,即在表达式中将冒号应用于dim 1 和2。
有没有办法支持这种“转播”?
编辑:添加示例
julia> a = reshape(1:8, (2,2,2))
2×2×2 Base.ReshapedArray{Int64,3,UnitRange{Int64},Tuple{}}:
[:, :, 1] =
1 3
2 4
[:, :, 2] =
5 7
6 8
julia> broadcast(*, a, a)
2×2×2 Array{Int64,3}:
[:, :, 1] =
1 9
4 16
[:, :, 2] =
25 49
36 64
julia> broadcast(*, a, a, dim=3) # I would like to broadcast the matrix multiplication (batch mode) instead of elementwise multiplication.
2×2×2 Array{Int64,3}:
[:, :, 1] =
7 15
10 22
[:, :, 2] =
67 91
78 106
编辑 2:我在这里 https://arrayfire.com/introduction-to-vectorization/ 通过 ArrayFire.jl 包(arrayfire 的包装器)尝试不同的矢量化方法,包括矢量化、并行 for 循环、批处理和高级矢量化。 arrayfire 具有 gfor (http://arrayfire.org/docs/page_gfor.htm) 方法来在矩阵切片上运行并行计算,并通过 ArrayFire.jl 中的广播实现。目前,朱莉娅的广播行为元素明智。我只是想知道它是否可以“切片”然后它可以为线性代数函数提供纯 julia 3D 和 4D 支持 (https://github.com/arrayfire/arrayfire/issues/483)。
当然,普通的嵌套 for 循环可以完成工作。我刚刚对广播. 语法感到厌烦,想知道它是否可以扩展。
【问题讨论】:
-
不清楚你的意思,你能举一个预期输出的例子吗?否则,是的,对切片甚至视图使用广播操作并没有什么特别的,例如
X = [1 2 3; 4 5 6]; 3 .+ view(X, :, 2) -
我已经添加了一个例子,请评论。
-
你如何得到这些数字对我来说并不明显;关心显示中间步骤以明确您的意思吗?另外,不要使用
a两次,使用a和b来明确你想在哪里行动。而且仍然不清楚dim将如何应用于“广播”操作本身,而不是它的任何一个论点。除非您的意思是应该将dim应用于两个参数之一(在这种情况下,您需要指定哪个参数;矩阵乘法不是对称的)。想一想,您所说的“广播矩阵乘法”也不清楚。 -
我已经添加了一些参考资料,希望清楚。