【问题标题】:macro parameter won't take argument passed (nvcc)宏参数不会传递参数(nvcc)
【发布时间】:2018-07-17 15:08:13
【问题描述】:

我刚刚开始在 CUDA 上编写代码,我正在尝试将我的代码管理到一堆不同的文件中,但是我的一个宏由于某种原因不会接受传递的参数。

错误是:

addkernel.cu(19): error: identifier "err" is undefined

所以我的主要代码在../cbe4/addkernel.cu

#include <stdio.h>
#include <stdlib.h>

#include "cbe4.h"
#include "../mycommon/general.h"

#define N 100

int main( int argc, char ** argv ){

        float h_out[N], h_a[N], h_b[N]; 
        float *d_out, *d_a, *d_b; 

        for (int i=0; i<N; i++) {
                h_a[i] = i + 5;
                h_b[i] = i - 10;
        }

        // The error is on the next line
        CUDA_ERROR( cudaMalloc( (void **) &d_out, sizeof(float) * N ) );
        CUDA_ERROR( cudaMalloc( (void **) &d_a, sizeof(float) * N ) ); 
        CUDA_ERROR( cudaMalloc( (void **) &d_b, sizeof(float) * N ) );

        cudaFree(d_a);
        cudaFree(d_b);


        return EXIT_SUCCESS;
}

宏在../mycommon/general.h中定义:

#ifndef __GENERAL_H__
#define __GENERAL_H__

#include <stdio.h>

// error checking 
void CudaErrorCheck (cudaError_t err, const char *file, int line);

#define CUDA_ERROR ( err ) (CudaErrorCheck( err, __FILE__, __LINE__ )) 

#endif

这是../mycommon/general.cu中函数CudaErrorCheck的源代码:

#include <stdio.h>
#include <stdlib.h>

#include "general.h"

void CudaErrorCheck (cudaError_t err,
                        const char *file,
                        int line) {
        if ( err != cudaSuccess ) {
                printf( "%s in %s at line %d \n",
                        cudaGetErrorString( err ),
                        file, line );
                exit( EXIT_FAILURE );
        }
}

../cbe/cbe4.h 是我的头文件,../cbe/cbe4.cu 是内核代码的源文件(以防万一):

在 cbe4.h 中:

__global__
void add( float *, float *, float * ); 

在 cbe4.cu 中:

    #include "cbe4.h"

__global__ void add( float *d_out, float *d_a, float *d_b ) {
        int tid = (blockIdx.x * blockDim.x) + threadIdx.x;
        d_out[tid] = d_a[tid] + d_b[tid]; }

这是我的 makefile(存储在 ../cbe4 中):

NVCC = nvcc
SRCS = addkernel.cu cbe4.cu
HSCS = ../mycommon/general.cu

addkernel:  
        $(NVCC) $(SRCS) $(HSCS) -o $@

另外,顺便说一下,我正在使用 Cuda by Example 一书。关于 common/book.h 中代码的一件事,HandleError 的函数(我将其重命名为 CudaErrorCheck 并将其放置在此处的另一个源代码中)在头文件中定义(等效地,在我的 general.h 中的 CudaErrorCheck 声明中。是这不是不可取的吗?或者我听说了。)

【问题讨论】:

  • 您缺少 cuda 标头。
  • Tangential:请注意,通常不应创建以下划线开头的函数或变量名称。 C11 §7.1.3 Reserved identifiers 说: — 所有以下划线开头的标识符以及大写字母或另一个下划线始终保留供任何使用。 — 所有以下划线开头的标识符始终保留用于在普通名称空间和标记名称空间中用作具有文件范围的标识符。 另请参阅What does double underscore (__const) mean in C?
  • 错误消息来自编译addkernel.cu — 但这是问题中缺少的一大段代码。我们无法帮助您调试我们看不到的代码。
  • @JonathanLeffler 关于下划线,您具体指的是什么? __global__ 是特定于 CUDA 的语法。它不是由 OP 创建的。
  • 请不要将您的解决方案添加到您的问题中。将其发布为答案。

标签: c cuda macros parameter-passing nvcc


【解决方案1】:

间距在宏定义中很重要。你有:

#define CUDA_ERROR ( err ) (CudaErrorCheck( err, __FILE__, __LINE__ )) 

你需要(最小的改变——删除一个空格):

#define CUDA_ERROR( err ) (CudaErrorCheck( err, __FILE__, __LINE__ )) 

对于类似函数的宏,宏名称和宏定义的参数列表的左括号之间不能有空格。在使用宏时,宏名称和参数列表的左括号之间允许有空格。

我会写:

#define CUDA_ERROR(err) CudaErrorCheck(err, __FILE__, __LINE__)

整个展开式周围的额外括号并不是必需的,而且我不太喜欢括号周围的空白。不同的人对此有不同的看法,所以我陈述我的偏好,并没有任何要求你使用它(但显然建议你考虑它)。

由于空间的原因,您的代码正在扩展为:

( err ) (CudaErrorCheck( err, "addkernel.cu", 19 ))( cudaMalloc( (void **) &d_out, sizeof(float) * N ) );

并且err 被诊断为未定义的标识符,使得强制转换无效。

【讨论】:

  • 非常感谢!这就是我要找的。​​span>
猜你喜欢
  • 2020-10-11
  • 1970-01-01
  • 2018-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多