gpt4 book ai didi

c++ - 复制跨步数据(进出 CUDA 设备)的有效方法?

转载 作者:太空狗 更新时间:2023-10-29 21:46:30 25 4
gpt4 key购买 nike

是否有可能有效地向 CUDA 设备或从 CUDA 设备复制以恒定(甚至非常量)值跨越的数据?

我想对角化一个大的对称矩阵。

使用 jacobi 算法,在每次迭代中有一堆使用两行和两列的操作。

由于 Matrix 本身太大而无法完全复制到设备,我正在寻找一种将两行和两列复制到设备的方法。

如果使用三角矩阵形式来存储数据会很好,但还有其他缺点,例如

  • 非常量行长 [不是那种问题]
  • 列值的非恒定步幅[每行步幅增加 1。]

起来。[编辑:即使使用三角形形式,仍然不可能将整个矩阵存储在 GPU 上。]

我查看了一些时间并认识到一个一个地复制跨步值非常慢(同步和异步)。

//编辑:删除解决方案 - 添加答案

最佳答案

感谢 Robert Crovella 给出了使用 cudamemcpy2d 的正确提示。我会附上我的测试代码,让每个人都有可能理解......

如果有人提出使用行优先有序三角矩阵解决复制问题的建议 - 请随时写下另一个答案。

__global__ void setValues (double *arr, double value)
{
arr[blockIdx.x] = value;
}

int main( void )
{
// define consts
static size_t const R = 10, C = 10, RC = R*C;

// create matrices and initialize
double * matrix = (double*) malloc(RC*sizeof(double)),
*final_matrix = (double*) malloc(RC*sizeof(double));
for (size_t i=0; i<RC; ++i) matrix[i] = rand()%R+10;
memcpy(final_matrix, matrix, RC*sizeof(double));

// create vectors on the device
double *dev_col, *dev_row,
*h_row = (double*) malloc(C*sizeof(double)),
*h_col = (double*) malloc(R*sizeof(double));
cudaMalloc((void**)&dev_row, C * sizeof(double));
cudaMalloc((void**)&dev_col, R * sizeof(double));

// choose row / col to copy
size_t selected_row = 7, selected_col = 3;

// since we are in row-major order we can copy the row at once
cudaMemcpy(dev_row, &matrix[selected_row*C],
C * sizeof(double), cudaMemcpyHostToDevice);
// the colum needs to be copied using cudaMemcpy2D
// with Columnsize*sizeof(type) as source pitch
cudaMemcpy2D(dev_col, sizeof(double), &matrix[selected_col],
C*sizeof(double), sizeof(double), R, cudaMemcpyHostToDevice);

// copy back to host to check whether we got the right column and row
cudaMemcpy(h_row, dev_row, C * sizeof(double), cudaMemcpyDeviceToHost);
cudaMemcpy(h_col, dev_col, R * sizeof(double), cudaMemcpyDeviceToHost);
// change values to evaluate backcopy
setValues<<<R, 1>>>(dev_col, 88.0); // column should be 88
setValues<<<C, 1>>>(dev_row, 99.0); // row should be 99
// backcopy
cudaMemcpy(&final_matrix[selected_row*C], dev_row,
C * sizeof(double), cudaMemcpyDeviceToHost);
cudaMemcpy2D(&final_matrix[selected_col], C*sizeof(double), dev_col,
sizeof(double), sizeof(double), R, cudaMemcpyDeviceToHost);

cudaDeviceSynchronize();
// output for checking functionality

printf("Initial Matrix:\n");
for (size_t i=0; i<R; ++i)
{
for (size_t j=0; j<C; ++j) printf(" %lf", matrix[i*C+j]);
printf("\n");
}
printf("\nRow %u values: ", selected_row);
for (size_t i=0; i<C; ++i) printf(" %lf", h_row[i]);
printf("\nCol %u values: ", selected_col);
for (size_t i=0; i<R; ++i) printf(" %lf", h_col[i]);
printf("\n\n");

printf("Final Matrix:\n");
for (size_t i=0; i<R; ++i)
{
for (size_t j=0; j<C; ++j) printf(" %lf", final_matrix[i*C+j]);
printf("\n");
}

cudaFree(dev_col);
cudaFree(dev_row);
free(matrix);
free(final_matrix);
free(h_row);
free(h_col);
cudaDeviceReset();
return 0;

}

关于c++ - 复制跨步数据(进出 CUDA 设备)的有效方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14985667/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com