您的位置:首页 > 其它

在.c文件中调用cuda函数

2014-04-19 17:17 330 查看

在.c文件中调用cuda函数

2014-04-19 17:17
446人阅读 评论(0)
收藏
举报


分类:
cuda编程(1)


版权声明:本文为博主原创文章,未经博主允许不得转载。

问题描述:假设在Ubuntu的一个用户目录下有2个文件,main.c, VectorAdd.cu,其中 VectorAdd.cu有vectorAdd函数,main.c提供程序的入口main函数。现在为了在main.c中实现两个向量相加的操作,就需要调用 VectorAdd.cu中的vectorAdd函数

首先列出两个文件中的内容

[cpp]
view plain
copy





//VectorAdd.cu  
#include <cutil.h>  
extern "C" void VectAdd(int *a, int *b, int *c, int length);  
  
__global__ void Add(int *d_a, int *d_b, int *d_c, int length)  
{  
    int id = threadIdx.x;  
    if(id < length)  
        d_c[id] = d_a[id] + d_b[id];  
}  
  
void VectAdd(int *a, int *b, int *c, int length)  
{     
    unsigned int size = sizeof(int) * length;   
    int *d_a;  
    cudaMalloc((void**)&d_a,size);  
    int *d_b;  
    cudaMalloc((void**)&d_b,size);  
    int *d_c;  
    cudaMalloc((void**)&d_c,size);  
  
    cudaMemcpy(d_a, a, size, cudaMemcpyHostToDevice);  
    cudaMemcpy(d_b, b, size, cudaMemcpyHostToDevice);  
      
    Add<<<1, length>>>(d_a, d_b, d_c, length);  
  
    cudaMemcpy(c, d_c, size, cudaMemcpyDeviceToHost);  
  
    cudaFree(d_a);  
    cudaFree(d_b);  
    cudaFree(d_c);  
}  
  
//main.c文件  
#include <stdio.h>  
#include <malloc.h>  
int main()  
{  
    int *a, *b, *c;  
    int length = 32;  
    int i;  
  
    a = (int*)malloc(sizeof(int) * length);  
    b = (int*)malloc(sizeof(int) * length);  
    c = (int*)malloc(sizeof(int) * length);  
  
    for(i = 0; i < length; ++i)  
    {  
        a[i] = i;  
        b[i] = i;  
    }  
  
    VectAdd(a,b,c,length);  
  
    for(i = 0; i < length; i++)  
    {  
        printf("%d ",c[i]);  
    }  
    printf("\n");  
        return 0;  
}  

.cu文件实际上是按c++的语法规则来编译的,因此上述问题的实质也是如何在.c文件中调用.cpp,为方便讨论,假设在.c文件中调用.cu中的函数,为.cu文件使用nvcc编译,对.c文件使用gcc编译,具体的编译命令如在makefile文件所示:

[cpp]
view plain
copy





default: libcuda run  
CUDA_DIR=/usr/local/cuda  
SDK_DIR=/home/NVIDIA_GPU_Computing_SDK/C  
  
CC=nvcc  
C = gcc  
CPP = g++  
  
SOURCE = main.c  
  
DEST = main  
  
libcuda:  
     $(CC) $(INC) $(LIB) -c VectorAdd.cu -o VectorAddCu.o  
     ar cr libVectorAddCu.a VectorAddCu.o  
  
run:  
     <span style="color:#ff6666;">$(C) $(SOURCE) -lstdc++ -o $(DEST) -L$(CUDA_DIR)/lib64 -lcudart libVectorAddCu.a  
     $(CPP) $(SOURCE) -o $(DEST) -L$(CUDA_DIR)/lib64 -lcudart libVectorAddCu.a</span>  

          这篇《在.c文件中调用cuda函数》与《在.c文件中调用c++定义的函数》有很多相同的地方,详细的讲解我不再说明,不懂的可以去这里看,在.c文件中调用c++定义的函数,这里我主要说说两者的不同。

         上面的Makefile文件中有这样一句话:

[cpp]
view plain
copy





-L$(CUDA_DIR)/lib64 -lcudart libVectorAddCu.a  

         通过测试,如果不要这句话就会出现下面这样的错误:

[cpp]
view plain
copy





libVectAddCu.a(VectAddCu.o): In function `__sti____cudaRegisterAll_42_tmpxft_00004317_00000000_4_VectAdd_cpp1_ii_e5583c85()':  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0xe): undefined reference to `__cudaRegisterFatBinary'  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x69): undefined reference to `__cudaRegisterFunction'  
libVectAddCu.a(VectAddCu.o): In function `__cudaUnregisterBinaryUtil()':  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x88): undefined reference to `__cudaUnregisterFatBinary'  
libVectAddCu.a(VectAddCu.o): In function `__device_stub__Z3AddPiS_S_i(int*, int*, int*, int)':  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0xb4): undefined reference to `cudaSetupArgument'  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0xd0): undefined reference to `cudaSetupArgument'  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0xec): undefined reference to `cudaSetupArgument'  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x108): undefined reference to `cudaSetupArgument'  
libVectAddCu.a(VectAddCu.o): In function `VectAdd':  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x187): undefined reference to `cudaMalloc'  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x193): undefined reference to `cudaMalloc'  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x19f): undefined reference to `cudaMalloc'  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x1b4): undefined reference to `cudaMemcpy'  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x1c9): undefined reference to `cudaMemcpy'  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x216): undefined reference to `cudaConfigureCall'  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x243): undefined reference to `cudaMemcpy'  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x24c): undefined reference to `cudaFree'  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x255): undefined reference to `cudaFree'  
tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x25e): undefined reference to `cudaFree'  

这些错误是什么东西呢,是说程序在链接的时候找不到上面的这些符号,像'cudaMalloc'、‘cudaFree'等,这些符号对应的函数我没有定义,那么他们来自哪里呢。对,就是这些函数是有系统提供的,是存在于系统的库文件中-L$(CUDA_DIR)/lib64 -lcudart就是让编译器去链接(CUDA_DIR)/lib64中的libcudart.so文件,里面有它想要的东西的。
libVectorAddCu.a是我自己生成的一个库文件,这个库文件好像必须要放在最后面才行

[cpp]
view plain
copy





<span style="color:#ff6666;">$(C) $(SOURCE) -lstdc++ -o $(DEST) -L$(CUDA_DIR)/lib64 -lcudart libVectorAddCu.a  
$(CPP) $(SOURCE) -o $(DEST) -L$(CUDA_DIR)/lib64 -lcudart libVectorAddCu.a</span>  

这两行的代码中的内容是有一定的顺序的,由于我对linux不是太了解,目前对这种顺序还不是太了解,希望知道的能给我留言,谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: