从全局 CUDA 函数返回数据

returning data from a global cuda function?

本文关键字:返回 数据 函数 CUDA 全局      更新时间:2023-10-16

我从 cuda 开始,并尝试一个简单的示例,将两个数组发送到全局函数中,将一个数组复制到另一个数组,然后返回第二个数组。

我有:

__global__
void add(int n, int *tri, int *y)
{
    int index = threadIdx.x;
    int stride = blockDim.x;
    for (int i = index; i < n; i += stride)
        y[i] = tri[i];
}

和:

   //local copy of data
    int *tri2 = tri; // data checked, and is valid
    int *y = new int[width * height]; // same size as `tri`
    int N = width * height;
    // Allocate Unified Memory – accessible from CPU or GPU
    cudaMallocManaged(&tri2, N * sizeof(int));
    cudaMallocManaged(&y, N * sizeof(int));
    // initialize y array on the host
    for (int i = 0; i < N; i++) {
        y[i] = 2;
    }
    // Run kernel on the GPU
    add << <1, 256 >> >(N, tri2, y);
    // Wait for GPU to finish before accessing on host
    cudaDeviceSynchronize();
    //copy back to host
    int i = 0;
    int f = -999.0; /* CPU copy of value */
    cudaMemcpy(&f, &y[i], sizeof(int), cudaMemcpyDeviceToHost);
    std::cout << "back: " << f << std::endl;
    std::cout << "orig: " << tri[i] << std::endl;

orig值为 128,与输入时相同。返回的f值始终为 0。我错过了什么?

数组 tri 的值与数组 tri2 的值不同。

cudaMallocManaged(&tri2, N * sizeof(int));

您在设备上分配新内存,我认为它恰好为零。然后在内核中将这个零数组复制到 y。数组 tri 的值永远不会被复制。

下面是一些如何做到这一点的示例。(未经测试(

int* tri = ....
int* tri_managed;
//allocate new managed memory and save pointer in tri_managed
cudaMallocManaged(&tri_managed, sizeof(int) * N);
//now copy entries of tri to tri_managed
for(int i = 0; i < N; i++)
    tri_managed[i] = tri[i];
int* y;
cudaMallocManaged(&y, N * sizeof(int));
// initialize y array
for (int i = 0; i < N; i++) {
    y[i] = 2;
}
//copy entries of tri_managed to y
add << <1, 256 >> >(N, tri_managed, y);
// Wait for GPU to finish before accessing on host
cudaDeviceSynchronize();
//copy back to host
int i = 0;
int f = -999.0; /* CPU copy of value */
//cudaMemcpy(&f, &y[i], sizeof(int), cudaMemcpyDeviceToHost);
//since managed memory is accessible on host and device, we can just to this
f = y[i];
std::cout << "back: " << f << std::endl;
std::cout << "orig: " << tri[i] << std::endl;
//don't forget to free memory after usage
cudaFree(tri_managed);
cudaFree(y);