为啥用Visual Studio给CUDA编程,却显示"undeclared identifier"呢
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥用Visual Studio给CUDA编程,却显示"undeclared identifier"呢相关的知识,希望对你有一定的参考价值。
为什么用Visual Studio给CUDA编程,却显示"undeclared identifier",我已经包含了cuda.h,为什么他还是不能识别命令?(注意我不是在问那段英文什么意思),以下是我的代码
include<cuda.h>
int main()
float *a = new float[N*N];
float *b = new float[N*N];
float *c = new float[N*N];
for ( int i = 0; i < N*N; ++i )
a[i] = 1.0f; b[i] = 3.5f;
float *ad, *bd, *cd;
const int size = N*N*sizeof(float);
cudaMalloc( (void**)&ad, size );
cudaMalloc( (void**)&bd, size );
cudaMalloc( (void**)&cd, size );
cudaMemcpy( ad, a, size, cudaMemcpyHostToDevice );
cudaMemcpy( bd, b, size, cudaMemcpyHostToDevice );
dim3 dimBlock( blocksize, blocksize );
dim3 dimGrid( N/dimBlock.x, N/dimBlock.y );
add_matrix<<<dimGrid, dimBlock>>>( ad, bd, cd, N );
cudaMemcpy( c, cd, size, cudaMemcpyDeviceToHost );
cudaFree( ad ); cudaFree( bd ); cudaFree( cd );
delete[] a; delete[] b; delete[] c;
return EXIT_SUCCESS;
const int N = 1024;
const int blocksize = 16;
__global__
void add_matrix( float* a, float *b, float *c, int N )
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
int index = i + j*N;
if ( i < N && j < N )
c[index] = a[index] + b[index];
少了个“#”,另外,最好使用双引号,应该是:
#include "cuda.h"追问
加上了,还是不行
追答const int N = 1024;
const int blocksize = 16;
这两个应该放在main函数前面
如果还有错误,你把错误发出来,看看是哪一行出错的
还是不行,每一行都有错,dudaMalloc,cudaMemcpy,dudafree等等,常用的命令都不能识别,另外,build rule用的是runtime API 4.0.
追答#include "cuda_runtime.h"
追问还是不行
为 CUDA 内核调用设置 Visual Studio Intellisense
【中文标题】为 CUDA 内核调用设置 Visual Studio Intellisense【英文标题】:Setting up Visual Studio Intellisense for CUDA kernel calls 【发布时间】:2011-08-29 00:39:49 【问题描述】:我刚刚开始进行 CUDA 编程,一切顺利,我的 GPU 已被识别,一切正常。我已经使用这个非常有用的指南在 Visual Studio 中部分设置了 Intellisense:
http://www.ademiller.com/blogs/tech/2010/10/visual-studio-2010-adding-intellisense-support-for-cuda-c/
这里:
http://www.ademiller.com/blogs/tech/2011/05/visual-studio-2010-and-cuda-easier-with-rc2/
但是,Intellisense 仍然无法接收这样的内核调用:
// KernelCall.cu
#include <iostream>
#include "cuda.h"
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
__global__ void kernel(void)
int main()
kernel<<<1,1>>>();
system("pause");
return 0;
行 kernel>>() 带有红色下划线,特别是第一个箭头左侧的一个箭头,错误为“错误:预期和表达式”。但是,如果我将鼠标悬停在函数上,它的返回类型和参数会正确显示。它仍然编译得很好,我只是想知道如何摆脱这个小烦恼。
【问题讨论】:
【参考方案1】:哇,这个线程上有很多灰尘。我想出了一个宏修复(好吧,更像是解决方法......),我想我会分享:
// nvcc does not seem to like variadic macros, so we have to define
// one for each kernel parameter list:
#ifdef __CUDACC__
#define KERNEL_ARGS2(grid, block) <<< grid, block >>>
#define KERNEL_ARGS3(grid, block, sh_mem) <<< grid, block, sh_mem >>>
#define KERNEL_ARGS4(grid, block, sh_mem, stream) <<< grid, block, sh_mem, stream >>>
#else
#define KERNEL_ARGS2(grid, block)
#define KERNEL_ARGS3(grid, block, sh_mem)
#define KERNEL_ARGS4(grid, block, sh_mem, stream)
#endif
// Now launch your kernel using the appropriate macro:
kernel KERNEL_ARGS2(dim3(nBlockCount), dim3(nThreadCount)) (param1);
我更喜欢这种方法,因为由于某种原因,我的代码中总是丢失 '
【讨论】:
感谢您的出色解决方案。此外,不是“#end”而是“#endif”是对的。对小事感到抱歉。 似乎__INTELLISENSE__
比__CUDACC__
更安全,检查***.com/a/6182137/8037585 和devtalk.nvidia.com/default/topic/513485/…
这是一个有用的解决方案,但非常难看。希望微软修改 Intellisense,以便不再需要像这样的解决方案【参考方案2】:
Visual Studio 为 C++ 提供 IntelliSense,火箭科学家博客中的技巧基本上是依靠 CUDA-C 与 C++ 的相似性,仅此而已。
在 C++ 语言中,正确解析尖括号是很麻烦的。 <
是 less than 和 for 模板,<<
是 shift,记得不久前我们不得不在嵌套模板声明之间放置一个空格。
所以事实证明,提出这种语法的 NVIDIA 人并不是语言专家,并且碰巧选择了最糟糕的分隔符,然后将它翻了三倍,好吧,你会遇到麻烦的。令人惊奇的是,Intellisense 在看到这一点时完全可以工作。
我知道在 CUDA 中获得完整 IntelliSense 的唯一方法是从运行时 API 切换到驱动程序 API。 C++ 只是 C++,而 CUDA 仍然是(有点)C++,语言解析没有 <<<>>>
不好的地方。
【讨论】:
我必须说,你比 NVIDIA 论坛上的任何人都更有道理......那我该怎么做你刚才说的呢? 看看matrixMul和matrixMulDrv的区别。 >> 语法由编译器处理,本质上只是吐出调用驱动程序 API 调用的代码。您将链接到 cuda.lib 而不是 cudart.lib,如果您仅使用 CUDA-RT 库,则可能必须处理“混合模式”程序。 在我的博客上查看我对您问题的回复。蜘蛛是正确的。这不太可能正常工作。 感谢您的帮助,我最想知道这是否是预期的行为,这基本上让我放心。再次感谢。 更新:2021。如果您 #include "cuda_runtime.h" 并将 CUDA 包含添加到您的包含路径中,Visual Studio 2019 的表现相当不错。在我的机器上它是 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2\include【参考方案3】:从 VS 2015 和 CUDA 7 开始,您可以在任何其他包含之前添加这两个包含,前提是您的文件具有 .cu
扩展名:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
不需要宏或任何东西。之后一切都会完美运行。
【讨论】:
在错误列表中选择“仅构建”以消除“预期表达式”错误 在 VS 2019 上为我工作。我唯一的问题:需要#include "cuda_runtime.h"
吗?只需#include "device_launch_parameters.h"
,我的简单测试看起来就很好。
错误?你是说红线?能举个例子吗?
在 VS2019 社区上添加这些行似乎对我也不起作用。 @BartDeBoeck 这只是过滤错误列表,而不是突出显示。
是的,这并不能解决我在 VS2017 中的 Intellisense 问题【参考方案4】:
我喜欢Randy 的solution。我将使用 C 预处理器可变参数宏进行匹配和提升:
#ifdef __INTELLISENSE__
#define CUDA_KERNEL(...)
#else
#define CUDA_KERNEL(...) <<< __VA_ARGS__ >>>
#endif
用法示例:
my_kernel1 CUDA_KERNEL(NUM_BLOCKS, BLOCK_WIDTH)();
my_kernel2 CUDA_KERNEL(NUM_BLOCKS, BLOCK_WIDTH, SHMEM, STREAM)(param1, param2);
【讨论】:
【参考方案5】:我一直在学习 CUDA 并遇到了这个确切的问题。正如其他人所说,这只是 Intellisense 问题,可以忽略,但我找到了一个干净的解决方案,实际上将其删除。
如果 >> 在模板函数中,它似乎被解释为正确的代码。
当我想为内核创建包装器以便能够从常规 cpp 代码中调用它们时,我偶然发现了它。它既是一个很好的抽象,又消除了语法错误。
内核头文件(例如kernel.cuh)
const size_t THREADS_IN_BLOCK = 1024;
typedef double numeric_t;
// sample kernel function headers
__global__ void sumKernel(numeric_t* out, numeric_t* f, numeric_t* blockSum, size_t N);
__global__ void expKernel(numeric_t* out, numeric_t* in, size_t N);
// ..
// strong-typed wrapper for a kernel with 4 arguments
template <typename T1, typename T2, typename T3, typename T4>
void runKernel(void (*fun)(T1, T2, T3, T4), int Blocks, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
fun <<<Blocks, THREADS_IN_BLOCK >>> (arg1, arg2, arg3, arg4);
// strong-typed wrapper for a kernel with 3 arguments
template <typename T1, typename T2, typename T3>
void runKernel(void (*fun)(T1, T2, T3), int Blocks, T1 arg1, T2 arg2, T3 arg3)
fun <<<Blocks, THREADS_IN_BLOCK >>> (arg1, arg2, arg3);
// ...
// the one-argument fun cannot have implementation here
void runKernel(void (*fun)(), int Blocks);
在 .cu 文件中(您会在此处遇到语法错误,但您是否需要无参数内核函数?如果不需要,可以删除此文件和相应的头文件):
void runKernel(void (*fun)(), int Blocks)
fun <<<Blocks, THREADS_IN_BLOCK >>> ();
.cpp 文件中的用法:
runKernel(kernelFunctionName, arg1, arg2, arg3);
// for example runKernel(expKernel, B, output, input, size);
【讨论】:
以上是关于为啥用Visual Studio给CUDA编程,却显示"undeclared identifier"呢的主要内容,如果未能解决你的问题,请参考以下文章
基于Visual Studio 2015的CUDA编程:基本配置
基于Visual Studio 2015的CUDA编程:基本配置
为啥用visual studio2012编程时输入汉字显示为问号
Visual Studio 是不是使用 nvcc 编译 cuda 代码?