【问题标题】:calling CUDA printf float from kernel returning garbage?从返回垃圾的内核调用 CUDA printf float?
【发布时间】:2013-03-23 07:36:13
【问题描述】:

我正在尝试使用对printf 的调用从内核打印浮点值。我这样做是为了检查我正在处理的另一个程序,该程序需要将浮点数组从主机复制到设备。我编写了一个内核来检查存储在设备中浮点数组中的值,只是为了得到0 作为回报。

所以我写了这段代码来检查:

#include <stdio.h>

#define ARR_LENGTH 3

__global__ void checkArr(float* arr);

int main(void)  
{  
    float* arr = (float*) malloc(sizeof(float) * ARR_LENGTH);

    float cont = 0;
    for(int i = 0 ; i < ARR_LENGTH ; i++) {
        arr[i] = cont;
        cont++;
    }

    for(int i = 0 ; i < ARR_LENGTH ; i++) {
        printf("arr[%d] : %f\n", i , arr[i]);
    }


    float* d_arr;
    cudaMalloc((void**) &d_arr, sizeof(float) * ARR_LENGTH);
    cudaMemcpy(d_arr, arr, sizeof(float) * ARR_LENGTH, cudaMemcpyHostToDevice);

    printf("got here\n");

    checkArr<<<1,1>>>(d_arr);

    printf("got here\n");

    float* check = (float*) malloc(sizeof(float) * ARR_LENGTH);
    cudaMemcpy(check, d_arr, sizeof(float) * ARR_LENGTH, cudaMemcpyDeviceToHost);   
    for(int i = 0 ; i < ARR_LENGTH ; i++) {
        printf("arr[%d] : %f\n", i , check[i]);
    }

}

__global__ void checkArr(float* arr ) 
{
    float check = 5.0;
    printf("float check : %f\n", check);
    printf("float check : %f\n", check + 1.0);
    printf("float check : %f\n", check + 2.0);

    for(int i = 0 ; i < ARR_LENGTH ; i++) {
        printf("arr[%d] : %f\n", i , arr[i]);
    }
}

输出:

arr[0] : 0.000000
arr[1] : 1.000000
arr[2] : 2.000000
got here
float check : 0
float check : 0
float check : 0
arr[0] : 2.4375
arr[1] : 2.4375
arr[2] : 2.4375
got here
arr[0] : 0.000000
arr[1] : 1.000000
arr[2] : 2.000000

如果我在打印数组的值之前没有放置“浮点检查:”,则数组的值将返回0。这有点奇怪..有什么解释吗?这是否意味着我无法检查设备内存中浮点值的值? (如您所见,int 似乎可以正常返回)

我用-arch=sm_20 编译程序。由于我家里没有兼容 CUDA 的设备,所以我使用 GPUOcelot 编译并运行了检查。你能用兼容的设备重现这个错误吗?

干杯, 艾尔劳特

【问题讨论】:

  • 所以这不是在 GPU 上运行或使用 NVIDIA CUDA 运行时库,它只能通过模拟器完成?
  • 是的,我正在使用 GPUOcelot 运行程序,
  • 所以这个问题其实和NVIDIA或者CUDA都没有关系。 Ocelot 使用自己的 PTX 编译器和运行时实现。你应该问问 Ocelot 的作者。

标签: cuda nvidia


【解决方案1】:

当我在实际的 sm_20 gpu (M2090) 上编译并运行您的代码时,我得到以下输出。

$ ./t97
arr[0] : 0.000000
arr[1] : 1.000000
arr[2] : 2.000000
got here
got here
float check : 5.000000
float check : 6.000000
float check : 7.000000
arr[0] : 0.000000
arr[1] : 1.000000
arr[2] : 2.000000
arr[0] : 0.000000
arr[1] : 1.000000
arr[2] : 2.000000
$

请注意,来自真实设备内核的 printf 与来自主机的 printf 队列在某种程度上是异步的,因此输出的顺序可能会有所不同。

我的意思是向您建议 GPU 行为和 Ocelot 行为可能不同。如果您继续发帖“请帮我在真正的 GPU 上检查我的 Ocelot 程序”,我将不会回复这些内容。

【讨论】:

  • 我还没有在真正的 GPU 上测试过代码,所以我认为它不会运行。感谢您的确认
猜你喜欢
  • 2020-09-19
  • 1970-01-01
  • 2014-03-14
  • 2013-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-08
相关资源
最近更新 更多