CudamAllocManager适用于二维和三维阵列
如果要将阵列从主机复制到设备,则需要执行cudamaloc和cudaMemcpy。但是为了减少麻烦,我们只需要在没有前两件事的情况下处理Cudamalloc,生活从来没有像现在这样简单过。 代码看起来像这样(或多或少)CudamAllocManager适用于二维和三维阵列,cuda,Cuda,如果要将阵列从主机复制到设备,则需要执行cudamaloc和cudaMemcpy。但是为了减少麻烦,我们只需要在没有前两件事的情况下处理Cudamalloc,生活从来没有像现在这样简单过。 代码看起来像这样(或多或少) 非常感谢您的帮助。您在尝试中犯了很多错误,因此编写工作版本比列出问题代码中的所有单个问题要快得多。下面是一个工作版本,它显示了您试图做的事情: #include <algorithm> #include <iostream> const int N =
非常感谢您的帮助。您在尝试中犯了很多错误,因此编写工作版本比列出问题代码中的所有单个问题要快得多。下面是一个工作版本,它显示了您试图做的事情:
#include <algorithm>
#include <iostream>
const int N = 3;
__global__ void MatAdd(float A[][N], float B[][N], float C[][N])
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
if (i < N && j < N)
C[i][j] = A[i][j] + B[i][j];
}
int main()
{
float* A; cudaMallocManaged(&A, N*N*sizeof(float));
float* B; cudaMallocManaged(&B, N*N*sizeof(float));
float* C; cudaMallocManaged(&C, N*N*sizeof(float));
const float A_vals[N][N]={{1,0,0},{0,1,0},{0,0,1}};
const float B_vals[N][N]={{1,0,0},{0,1,0},{0,0,1}};
float (*C_vals)[N] = reinterpret_cast<float (*)[N]>(C);
std::copy(&A_vals[0][0], &A_vals[0][0] + N*N, A);
std::copy(&B_vals[0][0], &B_vals[0][0] + N*N, B);
dim3 threadsPerBlock(16, 16);
dim3 numBlocks(1, 1);
MatAdd<<<numBlocks, threadsPerBlock>>>( reinterpret_cast<float (*)[N]>(A),
reinterpret_cast<float (*)[N]>(B),
C_vals );
cudaDeviceSynchronize();
for(int i=0; i<N; i++) {
for(int j=0; j<N; j++) {
std::cout << C_vals[i][j] << " ";
}
std::cout << std::endl;
}
return 0;
}
#包括以获取更多详细信息
您可以(并且需要)强制转换,以便在运行时动态分配的线性内存上使用[][]
访问语法(这适用于malloc
、new
或任何CUDA主机内存分配API。有关更多详细信息,请参阅)
数组的初始化语法和赋值语法不能互换
我所能建议的是,你要彻底研究它,直到你理解它是如何工作的。“2D数组”不能作为指向指针的指针传递。为什么所有东西都分配了两次?@Talonmes,因为我在CPU中分配了内存,所以我也必须在cuda设备中分配内存。在这里,cudaMallocManaged在GPU中分配相同的内存。至少我认为你想错了。malloc调用是不必要和不正确的,就像代码中的所有其他调用一样。我建议您重新阅读上一个问题的答案中的所有内容,因为您显然不理解那里告诉您的内容。先生,感谢您对这个问题的详细回答。对于程序的内存分配部分,我当然不太了解。我是一名物理专业的学生,也是一名python程序员,所以我的路径不会与内存元素交叉。今年夏天,我为我的模拟项目选择了CUDA,并在这一过程中犯了一些重大错误。然而,总有一条学习曲线。
__global__ void MatAdd(float A[N][N], float B[N][N], float C[N][N])
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
if (i < N && j < N)
C[i][j] = A[i][j] + B[i][j];
}
int main()
{ // I thonk, 2D arrays can be passed as pointer to pointers
float **A = (float **)malloc(N*N*sizeof(float));
float **B = (float **)malloc(N*N*sizeof(float));
float **C = (float **)malloc(N*N*sizeof(float));
cudaMallocManaged(&A, N*N*sizeof(float));
cudaMallocManaged(&B, N*N*sizeof(float));
cudaMallocManaged(&C, N*N*sizeof(float));
A[N][N]={{1,0,0},{0,1,0},{0,0,1}};
B[N][N]={{1,0,0},{0,1,0},{0,0,1}};
dim3 threadsPerBlock(16, 16);
dim3 numBlocks(N / threadsPerBlock.x, N / threadsPerBlock.y);
MatAdd<<<numBlocks, threadsPerBlock>>>(A, B, C);
//outputs and all
}
matrix_add.cu(22): error: too many initializer values
matrix_add.cu(25): error: argument of type "float **" is incompatible with parameter of type "float (*)[3]"
#include <algorithm>
#include <iostream>
const int N = 3;
__global__ void MatAdd(float A[][N], float B[][N], float C[][N])
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
if (i < N && j < N)
C[i][j] = A[i][j] + B[i][j];
}
int main()
{
float* A; cudaMallocManaged(&A, N*N*sizeof(float));
float* B; cudaMallocManaged(&B, N*N*sizeof(float));
float* C; cudaMallocManaged(&C, N*N*sizeof(float));
const float A_vals[N][N]={{1,0,0},{0,1,0},{0,0,1}};
const float B_vals[N][N]={{1,0,0},{0,1,0},{0,0,1}};
float (*C_vals)[N] = reinterpret_cast<float (*)[N]>(C);
std::copy(&A_vals[0][0], &A_vals[0][0] + N*N, A);
std::copy(&B_vals[0][0], &B_vals[0][0] + N*N, B);
dim3 threadsPerBlock(16, 16);
dim3 numBlocks(1, 1);
MatAdd<<<numBlocks, threadsPerBlock>>>( reinterpret_cast<float (*)[N]>(A),
reinterpret_cast<float (*)[N]>(B),
C_vals );
cudaDeviceSynchronize();
for(int i=0; i<N; i++) {
for(int j=0; j<N; j++) {
std::cout << C_vals[i][j] << " ";
}
std::cout << std::endl;
}
return 0;
}