【发布时间】:2015-06-26 13:03:16
【问题描述】:
我有两个矩阵
#define MATRIX_SIZE 20
#define BLOCK_SIZE 2
#define TILE_SIZE 2
double** A
double** B
矩阵 A 是稠密的,矩阵 B 是三对角的。我创建了 A 的矢量化表示
/* sz = A.rowlen = B.rowlen = A.collen = B.collen */
double* A1d = matrix_to_vector(sz, A);
我还使用以下函数创建了 B 的压缩表示
double* l_array = new double(sz - 1);
double* m_array = new double(sz);
double* r_array = new double(sz-1);
int current_l_idx = 0;
int current_m_idx = 0;
int current_r_idx = 0;
for (int i = 0; i < sz; i++) {
for (int j = 0; j < sz; j++) {
if ((i == j+1) || (i-1 == j)) {
l_array[current_l_idx] = B[i][j];
current_l_idx++;
}
else if ((i == j-1) || (i+1 == j)) {
r_array[current_r_idx] = B[i][j];
current_r_idx++;
}
else if (i == j) {
m_array[current_m_idx] = B[i][j];
current_m_idx++;
}
}
}
然后,我为CUDA 创建一个空的二维向量化矩阵 E 以及我的所有对象
double* E1d = matrix_to_vector(sz, E);
double* d_A
double* d_B_l;
double* d_B_m;
double* d_B_r;
double* d_E;
size_t sizeA = sz * sz * sizeof(double);
size_t sizeB_lr = (sz - 1) * sizeof(double);
size_t sizeB_m = sz * sizeof(double);
cudaMalloc(&d_A, sizeA);
cudaMalloc(&d_B_l. sizeB_lr);
cudaMalloc(&d_B_m, sizeB_m);
cudaMalloc(&d_B_r, sizeB_lr);
cudaMalloc(&d_E, sizeA);
cudaMemcpy(d_A, A1d, sizeA, cudaMemcpyHostToDevice);
cudaMemcpy(d_B_l, l_array, sizeB_lr, cudaMemcpyHostToDevice);
cudaMemcpy(d_B_m, m_array, sizeB_m, cudaMemcpyHostToDevice);
cudaMemcpy(d_B_r, r_array, sizeB_lr, cudaMemcpyHostToDevice);
cudaMemcpy(d_E, E1d, sizeA, cudaMemcpyHostToDevice);
dim3 threads(BLOCK_SIZE, BLOCK_SIZE);
dim3 grid(MATRIX_SIZE / threads.x, MATRIX_SIZE / threads.y);
cudakernel<<<grid, threads>>>(sz, d_A, d_B_l, d_B_m, d_B_r, d_E);
我可以连续执行这个乘法,但不幸的是,我不知道如何在 CUDA 设备上实现它
假设
- A 和 B 总是正方形的
- sz 总是能被 BLOCK_SIZE 和 TILE_SIZE 整除
- BLOCK_SIZE 将始终等于 TILE_SIZE
【问题讨论】:
-
如果你愿意将你的三对角矩阵转换为 CSR 存储,你可以使用 CUSPARSE csrmm 因为你的矩阵是正方形的,你想要的操作(密集 x 稀疏)可以通过转置来实现操作并反转 csrmm 的顺序(稀疏 x 密集)。
-
@Robert CSR 是可以接受的,但不幸的是我不能使用库。 :(
-
矩阵乘法计算输出矩阵 (C) 中每个点的行 (A) 乘以 (B) 列的总和。由于 B 是您的三对角矩阵,这意味着您在 B 的列中对于每个输出元素只有 3 个元素(或者对于边缘情况为 2 个)。一个简单的方法可能是适当地限制 for 循环(只做 3 次乘法)并提出适当的索引来索引到您的 B 向量中。
-
@Robert 我同意。这就是向我建议的方法。我只是不太擅长设备上的矩阵迭代。 :( 你能提供如何使用这种方法编写这个内核吗?
-
这是做作业的吗?如果您了解如何进行密集矩阵-矩阵乘法,您应该能够弄清楚在三对角情况下每个元素需要哪些 3 个乘积项。弄清楚这一点(C 中的每个结果都需要 A 和 B 的 3 个乘积项)实际上与 GPU 无关。
标签: c++ matrix cuda sparse-matrix matrix-multiplication