生活随笔
收集整理的這篇文章主要介紹了
在.c文件中调用cuda函数
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在.c文件中調用cuda函數
2014-04-19 17:17 446人閱讀 收藏 舉報
分類: cuda編程(1)
版權聲明:本文為博主原創文章,未經博主允許不得轉載。
問題描述:假設在Ubuntu的一個用戶目錄下有2個文件,main.c, VectorAdd.cu,其中?VectorAdd.cu有vectorAdd函數,main.c提供程序的入口main函數。現在為了在main.c中實現兩個向量相加的操作,就需要調用?VectorAdd.cu中的vectorAdd函數
首先列出兩個文件中的內容
[cpp] view plaincopy
??#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);??}??????#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 plaincopy
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 plaincopy
-L$(CUDA_DIR)/lib64?-lcudart?libVectorAddCu.a?? ? ? ? ? ?通過測試,如果不要這句話就會出現下面這樣的錯誤:
[cpp] view plaincopy
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 plaincopy
<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不是太了解,目前對這種順序還不是太了解,希望知道的能給我留言,謝謝!
總結
以上是生活随笔為你收集整理的在.c文件中调用cuda函数的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。