内核看起来不会执行

问题描述:

对于CUDA编程,我是初学者,但这种情况看起来并不复杂,但它不起作用。内核看起来不会执行

#include <cuda.h> 
#include <cuda_runtime.h> 

#include <iostream> 

__global__ void add(int *t) 
{ 
    t[2] = t[0] + t[1]; 
} 

int main(int argc, char **argv) 
{ 
    int sum_cpu[3], *sum_gpu; 

    sum_cpu[0] = 1; 
    sum_cpu[1] = 2; 
    sum_cpu[2] = 0; 

    cudaMalloc((void**)&sum_gpu, 3 * sizeof(int)); 

    cudaMemcpy(sum_gpu, sum_cpu, 3 * sizeof(int), cudaMemcpyHostToDevice); 

    add<<<1, 1>>>(sum_gpu); 

    cudaMemcpy(sum_cpu, sum_gpu, 3 * sizeof(int), cudaMemcpyDeviceToHost); 

    std::cout << sum_cpu[2]; 

    cudaFree(sum_gpu); 

    return 0; 
} 

我编译它像这样

nvcc main.cu 

它编译,但返回的值是0。我试图从内核中进行打印,也不会打印,所以我认为我没有按”执行。你能解释为什么吗?

+3

添加[适当的cuda错误检查](http://stackoverflow.com/questions/14038589/what-is-the-canonical-way-to-check-for-errors-using-the-cuda-runtime-api )到您的代码。你也可以尝试用'cuda-memcheck'运行你的代码。 – 2015-02-07 17:23:02

+0

谢谢你的提示。在第一个cudaMalloc上检查报告“未知错误”时出错。 'cuda-memcheck'检测到0个错误。 – wiktus239 2015-02-07 17:34:57

+2

您有机器配置问题。 CUDA在该机器上无法正常工作,因为它没有正确安装,或者因为其他机器问题。您可能要仔细按照[适用于您的操作系统的入门指南](http://docs.nvidia.com/cuda/index.html#getting-started-guides)中的说明进行操作,包括验证步骤。 – 2015-02-07 17:42:41

我检查了你的代码,一切都很好。在我看来,你编译错了(假设你正确安装了CUDA SDK)。也许你错过了一些标志......在我看来,这有点复杂。只要检查你的GPU有哪些计算能力。

作为最佳实践,我为每个CUDA项目都使用了Makefile。当您第一次正确设置您的路径时,它非常容易使用。一个简化的版本是这样的:

NAME=base 
# Compilers 
NVCC = nvcc 
CC = gcc 
LINK = nvcc 
CUDA_INCLUDE=/opt/cuda 
CUDA_LIBS= -lcuda -lcudart 
SDK_INCLUDE=/opt/cuda/include 
# Flags 
COMMONFLAGS =-O2 -m64 
NVCCFLAGS =-gencode arch=compute_20,code=sm_20 -m64 -O2 
CXXFLAGS = 
CFLAGS = 
INCLUDES = -I$(CUDA_INCLUDE) 
LIBS = $(CUDA_LIBS) 
ALL_CCFLAGS := 
ALL_CCFLAGS += $(NVCCFLAGS) 
ALL_CCFLAGS += $(addprefix -Xcompiler ,$(COMMONFLAGS)) 
OBJS = cuda_base.o 
# Build rules 
.DEFAULT: all 

all: $(OBJS) 
    $(LINK) -o $(NAME) $(LIBS) $(OBJS) 
%.o: %.cu 
    $(NVCC) -c $(ALL_CCFLAGS) $(INCLUDES) $< 
%.o: %.c 
    $(NVCC) -ccbin $(CC) -c $(ALL_CCFLAGS) $(INCLUDES) $< 
%.o: %.cpp 
    $(NVCC) -ccbin $(CXX) -c $(ALL_CCFLAGS) $(INCLUDES) $< 
clean: 
    rm $(OBJS) $(NAME) 

说明

我使用的Arch Linux的x64

  • 的代码存储在一个名为cuda_base.cu
  • 的路径,我的CUDA SDK是/opt/cuda(也许你有不同的路径)
  • 最重要的是:你的卡有哪些计算能力?我的GTX 580具有最高的计算能力2.0。所以,我必须设置为NVCC标志arch=compute_20,code=sm_20,代表计算能力2.0

Makefile文件需要存储之外cuda_base.cu。我只是复制粘贴&你的代码到这个文件,然后在外壳

$ make 
nvcc -c -gencode arch=compute_20,code=sm_20 -m64 -O2 -Xcompiler -O2 -Xcompiler -m64 -I/opt/cuda cuda_base.cu 
nvcc -o base -lcuda -lcudart cuda_base.o 
$ ./base 
3 

类型,并得到你的结果。

我和我的一个朋友创建了一个用于编写CUDA代码的基本模板。 You can find it here if you like.

希望这有助于;-)

+0

这听起来会很好,人们为什么会低估我的答案。我真的专注于这个问题,检查了代码,在我的机器上执行了它,发现在某些情况下为nvcc设置正确的标志是非常重要的。 由于我使用Linux,所以使用Makefile编译它很方便。这是编写CUDA代码并在终端上编译的干净解决方案。 – n2o 2015-02-16 10:09:04

我有完全相同的问题。我尝试了'CUDA by example'的矢量和示例,Sanders & Kandrot。我输入了代码,将这些向量加在一起,出来了零。

CUDA不会向控制台输出错误消息,而只会从CUDAMalloc和CUDAMemcpy等函数返回错误代码。在我想要得到一个工作示例的愿望中,我没有检查错误代码。一个基本的错误。所以,当我运行加载的版本,当我在Visual Studio中启动一个新的CUDA项目时,它会执行错误检查,宾果!一个错误。错误消息是'无效的设备功能'。

检查出我的卡的计算能力,在书或等同的使用程序,表明它是...

...等待...

1.1

所以,我改变了编译选项。在Visual Studio 13中,项目 - >属性 - >配置属性 - > CUDA C/C++ - >设备 - >代码生成。

我将项目从compute_20,sm_20更改为compute_11,sm_11。这表明计算能力是1.1而不是假设的2.0。

现在,重建的代码按预期工作。

我希望这很有用。