1

我遇到了一个我不明白的问题。我正在尝试在设备中设置数组的值。使用 int 数组,我这样做:

#define VECTOR_SIZE 8
int main()
{
    printf("Start\n");
    int *input_d;
    int *output_d;
    int output_h[VECTOR_SIZE];
    int input_h[VECTOR_SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    int size = VECTOR_SIZE*sizeof(int);
    cudaMalloc(&input_d,size);
    cudaMalloc(&output_d,size);
    cudaMemcpy(input_d,input_h,size,cudaMemcpyHostToDevice);
    kernel<<<1,VECTOR_SIZE>>>(input_d,output_d);
    cudaMemcpy(output_h,output_d,size, cudaMemcpyDeviceToHost);
    cudaFree(input_d);
    cudaFree(output_d);
    return 0;
}

内核看起来像:

__global__ void kernel(int* input, int* output)
{
    int dx = threadIdx.x + (blockDim.x * blockIdx.x);
    output[dx] = dx;
}

输出 (output_h) 就像我预期的 {0, 1, 2, 3, 4, 5, 6, 7}。现在,当我尝试对浮点数组执行相同操作时:

#define VECTOR_SIZE 8
int main()
{
    printf("Start\n");
    float *input_d;
    float *output_d;
    float output_h[VECTOR_SIZE];
    float input_h[VECTOR_SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8 };
    int size = VECTOR_SIZE*sizeof(float);
    cudaMalloc(&input_d,size);
    cudaMalloc(&output_d,size);
    cudaMemcpy(input_d,input_h,size,cudaMemcpyHostToDevice);
    kernel<<<1,VECTOR_SIZE>>>(input_d,output_d);
    cudaMemcpy(output_h,output_d,size, cudaMemcpyDeviceToHost);
    cudaFree(input_d);
    cudaFree(output_d);
    return 0;
}

带内核:

__global__ void kernel(float* input, float* output)
{
    int dx = threadIdx.x + (blockDim.x * blockIdx.x);
    output[dx] = dx;
}

我在 output_h 变量中的设备上接收到零数组。

处理浮点数组的完整代码:

#include "cuda_runtime.h"
#include <stdio.h>

#define VECTOR_SIZE 8

__global__ void kernel(float* input, float* output)//, int halfSize)
{
    int dx = threadIdx.x + (blockDim.x * blockIdx.x);
    output[dx] = dx;
} 

int main()
{
    printf("Start\n");
    float *input_d;
    float *output_d;
    float output_h[VECTOR_SIZE];
    float input_h[VECTOR_SIZE] = { 1, 2, 3, 4, 5, 6, 7, 8 }; 
    int size = VECTOR_SIZE*sizeof(float);
    cudaMalloc(&input_d,size);
    cudaMalloc(&output_d,size);
    cudaMemcpy(input_d,input_h,size,cudaMemcpyHostToDevice);
    kernel<<<1,VECTOR_SIZE>>>(input_d,output_d);
    cudaMemcpy(output_h,output_d,size, cudaMemcpyDeviceToHost);
    cudaFree(input_d);
    cudaFree(output_d);
    int i;
    for (i=1; i<=VECTOR_SIZE; i++)
    {
        printf("%d, ", output_h[i-1]);
    }
    getchar();
    return 0;
}
4

1 回答 1

4

您发布的 CUDA 代码的整数和浮点版本都可以完美运行。唯一的错误是在浮点代码的情况下如何打印内核返回的值:

int i;
for (i=1; i<=VECTOR_SIZE; i++)
{
    printf("%d, ", output_h[i-1]);
}

应该改为

int i;
for (i=0; i<VECTOR_SIZE; i++)
{
    printf("%f, ", output_h[i]);
}

(请注意,%f打印浮点数需要格式)。

鉴于默认情况下 CUDA 使用 C++ 编译器来编译主机代码,您可能应该更喜欢iostream-printf无论输出的类型如何,它都可以工作,并且不会导致您看到的错误。如果我要编写您示例的“通用”版本,它将如下所示:

#include <iostream>

template<typename T>
__global__ void kernel(T* output)
{
    int dx = threadIdx.x + (blockDim.x * blockIdx.x);
    output[dx] = dx;
}

template<typename T, int VECTOR_SIZE>
void do_run(void)
{
    T *output_d;
    T output_h[VECTOR_SIZE] = { 999 };
    size_t size = sizeof(output_h);
    cudaMalloc(&output_d,size);
    kernel<T><<<1,VECTOR_SIZE>>>(output_d);
    cudaMemcpy(output_h, output_d, size, cudaMemcpyDeviceToHost);
    for(int i=0; i<VECTOR_SIZE; i++)
        std::cout << output_h[i] << std::endl;

    cudaFree(output_d);
}

int main()
{
    std::cout << "Integer version" << std::endl;
    do_run<int, 8>();

    std::cout << "floating point version" << std::endl;
    do_run<float, 8>();

    return 0;
}

请注意,输出代码可以不变地用于intfloat版本,从而消除您在此处犯错误的可能性。

于 2013-09-15T10:45:43.453 回答