我刚刚开始进行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;
}
行内核&lt;&lt;&lt;&lt;&lt;&gt;&gt;&gt;()用红色下划线,特别是第一个箭头左侧的一个箭头,错误显示为“Error:expected and expression”。但是,如果我将鼠标悬停在该函数上,则会正确显示其返回类型和参数。它仍然编译得很好,我只是想知道如何摆脱这个小烦恼。
答案 0 :(得分:25)
// 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)
#end
// Now launch your kernel using the appropriate macro:
kernel KERNEL_ARGS2(dim3(nBlockCount), dim3(nThreadCount)) (param1);
我更喜欢这种方法,因为出于某种原因,我总是失去'&lt;&lt;&lt;&lt;&lt;在我的代码中,但宏通过语法着色获得了一些帮助:)。
答案 1 :(得分:13)
Visual Studio为C ++提供了IntelliSense,来自火箭科学家博客的技巧基本上依赖于CUDA-C对C ++的相似性,仅此而已。
在C ++语言中,正确解析尖括号很麻烦。你有<
小于和{和模板',<<
作为移位,记得不久前我们不得不在嵌套模板声明之间放置一个空格。
事实证明,NVIDIA的那个提出这种语法的人并不是语言专家,碰巧选择了最差的分隔符,然后将它增加了三倍,好吧,你将遇到麻烦。令人惊讶的是Intellisense在看到它时会发挥作用。
我知道在CUDA中获得完整IntelliSense的唯一方法是从Runtime API切换到Driver API。 C ++只是C ++,而CUDA仍然是(有点)C ++,语言解析没有<<<>>>
的不良,需要解决。
答案 2 :(得分:7)
从VS 2015和CUDA 7开始,只要您的文件具有.cu
扩展名,您就可以在其他任何内容之前添加这两个包含:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
不需要MACROS或任何东西。之后一切都会完美无缺。
答案 3 :(得分:0)
我一直在学习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);
答案 4 :(得分:0)