在.c文件中调用cuda函数

在.c文件中调用cuda函数

446人阅读 评论(0) 收藏 举报
分类:

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

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

  1. //VectorAdd.cu  
  2. #include <cutil.h>  
  3. extern "C" void VectAdd(int *a, int *b, int *c, int length);  
  4.   
  5. __global__ void Add(int *d_a, int *d_b, int *d_c, int length)  
  6. {  
  7.     int id = threadIdx.x;  
  8.     if(id < length)  
  9.         d_c[id] = d_a[id] + d_b[id];  
  10. }  
  11.   
  12. void VectAdd(int *a, int *b, int *c, int length)  
  13. {     
  14.     unsigned int size = sizeof(int) * length;   
  15.     int *d_a;  
  16.     cudaMalloc((void**)&d_a,size);  
  17.     int *d_b;  
  18.     cudaMalloc((void**)&d_b,size);  
  19.     int *d_c;  
  20.     cudaMalloc((void**)&d_c,size);  
  21.   
  22.     cudaMemcpy(d_a, a, size, cudaMemcpyHostToDevice);  
  23.     cudaMemcpy(d_b, b, size, cudaMemcpyHostToDevice);  
  24.       
  25.     Add<<<1, length>>>(d_a, d_b, d_c, length);  
  26.   
  27.     cudaMemcpy(c, d_c, size, cudaMemcpyDeviceToHost);  
  28.   
  29.     cudaFree(d_a);  
  30.     cudaFree(d_b);  
  31.     cudaFree(d_c);  
  32. }  
  33.   
  34. //main.c文件  
  35. #include <stdio.h>  
  36. #include <malloc.h>  
  37. int main()  
  38. {  
  39.     int *a, *b, *c;  
  40.     int length = 32;  
  41.     int i;  
  42.   
  43.     a = (int*)malloc(sizeof(int) * length);  
  44.     b = (int*)malloc(sizeof(int) * length);  
  45.     c = (int*)malloc(sizeof(int) * length);  
  46.   
  47.     for(i = 0; i < length; ++i)  
  48.     {  
  49.         a[i] = i;  
  50.         b[i] = i;  
  51.     }  
  52.   
  53.     VectAdd(a,b,c,length);  
  54.   
  55.     for(i = 0; i < length; i++)  
  56.     {  
  57.         printf("%d ",c[i]);  
  58.     }  
  59.     printf("\n");  
  60.         return 0;  
  61. }  
.cu文件实际上是按c++的语法规则来编译的,因此上述问题的实质也是如何在.c文件中调用.cpp,为方便讨论,假设在.c文件中调用.cu中的函数,为.cu文件使用nvcc编译,对.c文件使用gcc编译,具体的编译命令如在makefile文件所示:
  1. default: libcuda run  
  2. CUDA_DIR=/usr/local/cuda  
  3. SDK_DIR=/home/NVIDIA_GPU_Computing_SDK/C  
  4.   
  5. CC=nvcc  
  6. C = gcc  
  7. CPP = g++  
  8.   
  9. SOURCE = main.c  
  10.   
  11. DEST = main  
  12.   
  13. libcuda:  
  14.      $(CC) $(INC) $(LIB) -c VectorAdd.cu -o VectorAddCu.o  
  15.      ar cr libVectorAddCu.a VectorAddCu.o  
  16.   
  17. run:  
  18.      <span style="color:#ff6666;">$(C) $(SOURCE) -lstdc++ -o $(DEST) -L$(CUDA_DIR)/lib64 -lcudart libVectorAddCu.a  
  19.      $(CPP) $(SOURCE) -o $(DEST) -L$(CUDA_DIR)/lib64 -lcudart libVectorAddCu.a</span>  


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

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

  1. -L$(CUDA_DIR)/lib64 -lcudart libVectorAddCu.a  
         通过测试,如果不要这句话就会出现下面这样的错误:
  1. libVectAddCu.a(VectAddCu.o): In function `__sti____cudaRegisterAll_42_tmpxft_00004317_00000000_4_VectAdd_cpp1_ii_e5583c85()':  
  2. tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0xe): undefined reference to `__cudaRegisterFatBinary'  
  3. tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x69): undefined reference to `__cudaRegisterFunction'  
  4. libVectAddCu.a(VectAddCu.o): In function `__cudaUnregisterBinaryUtil()':  
  5. tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x88): undefined reference to `__cudaUnregisterFatBinary'  
  6. libVectAddCu.a(VectAddCu.o): In function `__device_stub__Z3AddPiS_S_i(int*, int*, int*, int)':  
  7. tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0xb4): undefined reference to `cudaSetupArgument'  
  8. tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0xd0): undefined reference to `cudaSetupArgument'  
  9. tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0xec): undefined reference to `cudaSetupArgument'  
  10. tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x108): undefined reference to `cudaSetupArgument'  
  11. libVectAddCu.a(VectAddCu.o): In function `VectAdd':  
  12. tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x187): undefined reference to `cudaMalloc'  
  13. tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x193): undefined reference to `cudaMalloc'  
  14. tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x19f): undefined reference to `cudaMalloc'  
  15. tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x1b4): undefined reference to `cudaMemcpy'  
  16. tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x1c9): undefined reference to `cudaMemcpy'  
  17. tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x216): undefined reference to `cudaConfigureCall'  
  18. tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x243): undefined reference to `cudaMemcpy'  
  19. tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x24c): undefined reference to `cudaFree'  
  20. tmpxft_00004317_00000000-1_VectAdd.cudafe1.cpp:(.text+0x255): undefined reference to `cudaFree'  
  21. 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是我自己生成的一个库文件,这个库文件好像必须要放在最后面才行

  1. <span style="color:#ff6666;">$(C) $(SOURCE) -lstdc++ -o $(DEST) -L$(CUDA_DIR)/lib64 -lcudart libVectorAddCu.a  
  2. $(CPP) $(SOURCE) -o $(DEST) -L$(CUDA_DIR)/lib64 -lcudart libVectorAddCu.a</span>  
这两行的代码中的内容是有一定的顺序的,由于我对linux不是太了解,目前对这种顺序还不是太了解,希望知道的能给我留言,谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值