【发布时间】:2015-05-31 13:00:44
【问题描述】:
我想要做的是输入我的 m x n 矩阵,并并行地为矩阵的每一列构造 n 个方对角矩阵,对每个方对角矩阵执行操作,然后重新组合结果。我该怎么做呢?
到目前为止,我从一个 m x n 矩阵开始;先前矩阵计算的结果,其中每个元素都是使用函数 y = f(g(x)) 计算的。
这给了我一个包含 n 列元素 [f1, f2...fn] 的矩阵,其中每个 fn 代表一个高度为 m 的列向量。
从这里开始,我想区分矩阵的每一列关于 g(x)。区分 fn(x) w.r.t. g(x) 产生一个包含元素 f'(x) 的方阵。在约束条件下,该方阵简化为雅可比行列式,每行的元素沿方阵的对角线,且等于 fn',所有其他元素均为零。
这就是为什么需要为每个向量行 fn 构造对角线的原因。
为此,我采用定义为 A(hA x 1) 的目标向量,该向量是从较大的 A(m x n) 矩阵中提取的。然后我准备了一个定义为 C(hA x hA) 的归零矩阵,用于保存对角线。
目的是将向量 A 对角化为一个方阵,其中 A 的每个元素都位于 C 的对角线上,其他所有元素都为零。
可能有更有效的方法可以使用一些预先构建的例程来完成此任务,而无需构建全新的内核,但请注意,出于这些目的,此方法是必要的。
完成此操作的内核代码(有效)如下所示:
_cudaDiagonalizeTest << <5, 1 >> >(d_A, matrix_size.uiWA, matrix_size.uiHA, d_C, matrix_size.uiWC, matrix_size.uiHC);
__global__ void _cudaDiagonalizeTest(float *A, int wA, int hA, float *C, int wC, int hC)
{
int ix, iy, idx;
ix = blockIdx.x * blockDim.x + threadIdx.x;
iy = blockIdx.y * blockDim.y + threadIdx.y;
idx = iy * wA + ix;
C[idx * (wC + 1)] = A[idx];
}
我有点怀疑这是一种非常幼稚的解决方案,并且想知道是否有人可以举例说明我如何使用
a) 减少
b) 推力
对于大行大小的向量,我希望能够使用 GPU 的多线程功能将任务分成小作业,并在最后将每个结果与 __syncthreads() 组合。
下图显示了想要的结果。
我已阅读NVIDIA's article on reduction,但未能达到预期的效果。
非常欢迎任何帮助或解释。
谢谢。
矩阵 A 是具有 4 列的目标。我想获取每一列,并将其元素作为对角线复制到矩阵 B 中,遍历每一列。
【问题讨论】:
-
我不确定我是否完全符合您的要求。您能否包括一个示例输入和所需的输出?我不明白减少如何适用于这个问题。
-
你真的确定你需要这样做吗?如果您有一个纯对角矩阵,那么存储和使用它的最佳方式就是您已经拥有它 - 作为对角数组。您将使用大量内存、大量内存带宽和大量失败,只是加载和存储零,通常没有充分的理由
-
上述向量行的对角化只是较大操作中的一小步。我正在尝试将 m x n 矩阵的每一行并行对角化,使用这些 n 个对角化方阵执行计算(m x n 矩阵中有 n 行,因此在对每个对角化后有 n 个对角化方阵),然后对结果求和的计算重新组合在一起。所有这些都必须在内核中完成。有没有一种有效的方法来做到这一点?
-
你确定你的示例内核真的这样做了吗?不管怎样,让我再猜一下你的意思:你想将
A(x,y)复制到C(x,x+y),其中M(x,y)表示M在x-th行和y-th列中的条目? (使用基于 0 的索引)并且...可能用零填充C的其余部分?或者你的意思是将A(x,y)复制到C(x, (x+y) mod N),其中N是C的列数? -
请参考第二张图片以获得更清晰的图片。矩阵 A 是一个较小的 5 x 4 矩阵(5 行,4 列)。矩阵 B 是一个更大的 5 x 20 矩阵(5 行,20 列)。我想取矩阵 A 的 4 列中的每一列(每一列都是高度为 5 的向量)并将其元素布置成对角线。每个对角线结构都会产生一个 5 x 5 矩阵,然后将其放入更大的 5 x 20 矩阵 B。我想使用 CUDA 并行执行此操作。请参考原帖底部张贴的图片。