无法打印从 CUDA 内核返回的值 [关闭]

Posted

技术标签:

【中文标题】无法打印从 CUDA 内核返回的值 [关闭]【英文标题】:Cannot print values returned from CUDA kernel [closed] 【发布时间】:2021-04-08 00:59:00 【问题描述】:

我正致力于在同一个节点交换 V1 和 V3 的变量。但是,我无法将值 16 和 31 初始化为数组。这可能是我犯的一个愚蠢的错误,但我花了一个小时调试我的代码。它只在printf 输出处打印每个数组的“0”。

谁能发现我的代码中的错误?这是我的代码:

 #include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <cuda.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>


#define threads 1024  //define the number of thread to use
#define blocks 4 //define the number of blocks to use


//Kernal Function
__global__ void Initial(double* V1, double* V3, int NX, int NY)

    unsigned int idx = threadIdx.x + blockIdx.x * blockDim.x;

    if (idx <= NX * NY)
    
        V1[idx] = 16;
        V3[idx] = 31;
    




__global__ void Add2D(double* V1 , double* V3, int NX, int NY)

    unsigned int idx = threadIdx.x + blockIdx.x * blockDim.x;
    

    if (idx <= NX * NY)
    
        double tmp = V1[idx] ;
        V1[idx] = V3[idx + NX];
        V3[idx + NX] = tmp;

    



int main(void) 

    //number of nodes 
    int NX = 5;
    int NY = 5;
    int N = NY * NX;

    size_t bytes =  NX * NY * sizeof(double);  // define the memory size which needs to use in this application

    //declare V1 in host
    double* hos_V1 ;
    double* hos_V3 ;

    double* dev_V1 ;
    double* dev_V3 ;

//  hos_V1 = new double[N];     // allocate storage for VL array
//  hos_V3 = new double[N];

    hos_V1 = (double*)malloc(bytes);
    hos_V3 = (double*)malloc(bytes);

//  dev_V1 = new double[N];     // allocate storage for VL array
//  dev_V3 = new double[N];


    cudaMalloc((void**)&dev_V1, bytes);
    cudaMalloc((void**)&dev_V3, bytes);


    Initial <<< blocks , threads >>> (dev_V1, dev_V3, NX, NY);

    cudaMemcpy(hos_V1, dev_V1, bytes, cudaMemcpyDeviceToHost);
    cudaMemcpy(hos_V3, dev_V3, bytes, cudaMemcpyDeviceToHost);

    cudaThreadSynchronize();

    for (int x = 0; x <= NX * NY; x++)
    

        printf("V1[%d] = %f  \n", x, &hos_V1[x]);
        printf("V3[%d] = %f  \n", x, &hos_V3[x]);

    
    printf("-----------------------------\n");

    Add2D <<< blocks, threads >> > (dev_V1, dev_V3, NX, NY);

    cudaThreadSynchronize(); //Sync CPU and GPU to start the timer  
    cudaMemcpy(hos_V1, dev_V1, bytes, cudaMemcpyDeviceToHost);
    cudaMemcpy(hos_V3, dev_V3, bytes, cudaMemcpyDeviceToHost);

    for (int x = 0; x <= NX*NY; x++)
    
        
            printf("V1[%d] = %f  \n", x, &hos_V1[x]);
            printf("V3[%d] = %f  \n", x, &hos_V3[x]);
        
    

    // free the memory allocated on the GPU
    cudaFree(dev_V1);
    cudaFree(dev_V3);


    return 0;

【问题讨论】:

为什么要打印 &hos_V1[x] 而不是 hos_V1[x]?! 我将重复你上一个问题的建议——“注释掉所有的 CUDA 代码并运行你的程序,看着它爆炸或打印废话,然后问自己为什么”。如果您不了解它所依赖的底层 C 风格语言的基础知识,那么尝试使用 CUDA 就是浪费时间。您的两个问题在主机代码中都有基本错误,与 CUDA 无关。 Stack Overflow不是免费的基础查错服务,请不要当真 【参考方案1】:

您正在打印 &hos_V1[x] 和 &hos_V3[x],而不是 hos_V1[x] 和 hos_V3[x]。我确定您想实际打印数组的内容。

for (int x = 0; x <= NX * NY; x++)


    printf("V1[%d] = %f  \n", x, hos_V1[x]);
    printf("V3[%d] = %f  \n", x, hos_V3[x]);


在编译时启用警告可能对您很有用。 NVCC(或 gcc,因为那是主机代码)向我建议您可能打印了错误的东西。 编辑:正如其他人所指出的,您提供的代码还有更多“系统性”问题。

【讨论】:

非常感谢!我使用 & 因为一开始它正在打印一些地址,所以我想知道是否应该使用 &。现在,没事了!!谢谢你的回答,新年快乐!!!! 代码中还有其他缺陷,例如Add2D内核将索引到V3数组越界。两个内核的边界检查 if-test 也被破坏了。使用cuda-memcheck 很容易发现此问题。 您基本上试图打印取消引用指针的地址。您尝试打印 &(*(hosV1 + x)) 而不是打印 *(hosV1 + x),但采用浮点格式,这就是输出 0 的原因。

以上是关于无法打印从 CUDA 内核返回的值 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Cuda 内核返回向量

如何从 WCF 打印数组的值以形成标签?

无法从 Objective C 插件返回到 Ionic/Cordova 应用程序时出错

为啥我的 Python 函数打印一个值但返回 None? [关闭]

无法使用存储过程获得确切的结果,因为它返回带有增量的值[关闭]

torch.cuda.is_available() 返回 true,但火炬模型继续在 CPU 上进行训练 [关闭]