使用 CUDA 进行矩阵操作
Matrix manipulation using CUDA
我正在尝试使用 C/CUDA 编写一个矩阵计算程序。
我有以下程序:
在main.cu
#include <cuda.h>
#include <iostream>
#include "teste.cuh"
using std::cout;
int main(void)
{
const int Ndofs = 2;
const int Nel = 4;
double *Gh = new double[Ndofs*Nel*Ndofs*Nel];
double *Gg;
cudaMalloc((void**)& Gg, sizeof(double)*Ndofs*Nel*Ndofs*Nel);
for (int ii = 0; ii < Ndofs*Nel*Ndofs*Nel; ii++)
Gh[ii] = 0.;
cudaMemcpy(Gh, Gg, sizeof(double)*Ndofs*Nel*Ndofs*Nel, cudaMemcpyHostToDevice);
integraG<<<256, 256>>>(Nel, Gg);
cudaMemcpy(Gg, Gh, sizeof(double)*Ndofs*Nel*Ndofs*Nel, cudaMemcpyDeviceToHost);
for (int ii = 0; ii < Ndofs*Nel*Ndofs*Nel; ii++)
cout << ii + 1 << " " << Gh[ii] << "\n";
return 0;
}
在mtrx.cuh
#ifndef TESTE_CUH_
#define TESTE_CUH_
__global__ void integraG(const int N, double* G)
{
const int szmodel = 2*N;
int idx = threadIdx.x + blockIdx.x*blockDim.x;
int idy = threadIdx.y + blockIdx.y*blockDim.y;
int offset = idx + idy*blockDim.x*gridDim.x;
int posInit = szmodel*offset;
G[posInit + 0] = 1;
G[posInit + 1] = 1;
G[posInit + 2] = 1;
G[posInit + 3] = 1;
}
#endif
结果(应该是一个用 1 填充的矩阵)被复制回主机数组;问题是:没有任何反应!显然,我的程序没有调用 gpu 内核,我仍然得到一个全为零的数组。
我是 CUDA 编程的新手,我正在使用 CUDA 示例 (Jason Sanders) 作为参考书。
我的问题是:
- 我的代码有什么问题?
- 这是使用矩阵向量化形式使用 GPU 处理矩阵的最佳方式吗?
- 是否有其他参考资料可以提供更多关于使用 GPU 的矩阵的示例?
这些是你的问题:
我的代码有什么问题?
这是使用矩阵矢量化形式使用 GPU 处理矩阵的最佳方式吗?
是否有其他参考资料可以提供更多关于使用 GPU 的矩阵的示例?
关于你的第一个问题。首先,您的问题应该明确定义。你想用这段代码做什么?你想在矩阵上做什么样的计算?
尝试正确检查错误 THIS 是一个很好的方法。您的代码中也有一些明显的错误。你的一些错误:
- 您将错误的地址指针传递给 cudaMemcpy,传递给源和目标的指针必须相互交换,检查 here
将它们更改为:
"NdofsNelNdofs*Nel"说明你对数组的前64个数字的值感兴趣,那么为什么要调用256个线程和256个块?
您的这部分代码:
int idx = threadIdx.x + blockIdx.xblockDim.x;
int idy = threadIdx.y + blockIdx.yblockDim.y;
表明你想使用2-Dim线程和块;为此,您需要使用 Dim 类型。
通过进行以下更改:
cudaMemcpy(Gg, Gh, sizeof(double)*Ndofs*Nel*Ndofs*Nel, cudaMemcpyHostToDevice); //HERE
dim3 block(2,2); //HERE
dim3 thread(4,4); //HERE
integraG<<<block, thread>>>(Nel, Gg); //HERE
cudaMemcpy(Gh, Gg, sizeof(double)*Ndofs*Nel*Ndofs*Nel, cudaMemcpyDeviceToHost); //HERE
您将得到如下结果:
1 1
2 1
3 1
4 1
5 0
6 0
7 0
8 0
9 1
10 1
11 1
12 1
.
.
.
57 1
58 1
59 1
60 1
61 0
62 0
63 0
64 0
总之,如果你把你的问题和目标说的更清楚,可以给你更好的建议。
关于你最后两个问题:
在我看来 CUDA C PROGRAMMING GUIDE and CUDA C BEST PRACTICES GUIDE 是开始使用 CUDA 时必须阅读的两个文档,它们还包括矩阵计算的示例。
我正在尝试使用 C/CUDA 编写一个矩阵计算程序。 我有以下程序:
在main.cu
#include <cuda.h>
#include <iostream>
#include "teste.cuh"
using std::cout;
int main(void)
{
const int Ndofs = 2;
const int Nel = 4;
double *Gh = new double[Ndofs*Nel*Ndofs*Nel];
double *Gg;
cudaMalloc((void**)& Gg, sizeof(double)*Ndofs*Nel*Ndofs*Nel);
for (int ii = 0; ii < Ndofs*Nel*Ndofs*Nel; ii++)
Gh[ii] = 0.;
cudaMemcpy(Gh, Gg, sizeof(double)*Ndofs*Nel*Ndofs*Nel, cudaMemcpyHostToDevice);
integraG<<<256, 256>>>(Nel, Gg);
cudaMemcpy(Gg, Gh, sizeof(double)*Ndofs*Nel*Ndofs*Nel, cudaMemcpyDeviceToHost);
for (int ii = 0; ii < Ndofs*Nel*Ndofs*Nel; ii++)
cout << ii + 1 << " " << Gh[ii] << "\n";
return 0;
}
在mtrx.cuh
#ifndef TESTE_CUH_
#define TESTE_CUH_
__global__ void integraG(const int N, double* G)
{
const int szmodel = 2*N;
int idx = threadIdx.x + blockIdx.x*blockDim.x;
int idy = threadIdx.y + blockIdx.y*blockDim.y;
int offset = idx + idy*blockDim.x*gridDim.x;
int posInit = szmodel*offset;
G[posInit + 0] = 1;
G[posInit + 1] = 1;
G[posInit + 2] = 1;
G[posInit + 3] = 1;
}
#endif
结果(应该是一个用 1 填充的矩阵)被复制回主机数组;问题是:没有任何反应!显然,我的程序没有调用 gpu 内核,我仍然得到一个全为零的数组。
我是 CUDA 编程的新手,我正在使用 CUDA 示例 (Jason Sanders) 作为参考书。
我的问题是:
- 我的代码有什么问题?
- 这是使用矩阵向量化形式使用 GPU 处理矩阵的最佳方式吗?
- 是否有其他参考资料可以提供更多关于使用 GPU 的矩阵的示例?
这些是你的问题:
我的代码有什么问题?
这是使用矩阵矢量化形式使用 GPU 处理矩阵的最佳方式吗?
是否有其他参考资料可以提供更多关于使用 GPU 的矩阵的示例?
关于你的第一个问题。首先,您的问题应该明确定义。你想用这段代码做什么?你想在矩阵上做什么样的计算?
尝试正确检查错误 THIS 是一个很好的方法。您的代码中也有一些明显的错误。你的一些错误:
- 您将错误的地址指针传递给 cudaMemcpy,传递给源和目标的指针必须相互交换,检查 here
将它们更改为:
"NdofsNelNdofs*Nel"说明你对数组的前64个数字的值感兴趣,那么为什么要调用256个线程和256个块?
您的这部分代码:
int idx = threadIdx.x + blockIdx.xblockDim.x; int idy = threadIdx.y + blockIdx.yblockDim.y;
表明你想使用2-Dim线程和块;为此,您需要使用 Dim 类型。
通过进行以下更改:
cudaMemcpy(Gg, Gh, sizeof(double)*Ndofs*Nel*Ndofs*Nel, cudaMemcpyHostToDevice); //HERE
dim3 block(2,2); //HERE
dim3 thread(4,4); //HERE
integraG<<<block, thread>>>(Nel, Gg); //HERE
cudaMemcpy(Gh, Gg, sizeof(double)*Ndofs*Nel*Ndofs*Nel, cudaMemcpyDeviceToHost); //HERE
您将得到如下结果:
1 1
2 1
3 1
4 1
5 0
6 0
7 0
8 0
9 1
10 1
11 1
12 1
.
.
.
57 1
58 1
59 1
60 1
61 0
62 0
63 0
64 0
总之,如果你把你的问题和目标说的更清楚,可以给你更好的建议。
关于你最后两个问题:
在我看来 CUDA C PROGRAMMING GUIDE and CUDA C BEST PRACTICES GUIDE 是开始使用 CUDA 时必须阅读的两个文档,它们还包括矩阵计算的示例。