前言 本文講解如何在VS 2010開發(fā)平臺中搭建CUDA開發(fā)環(huán)境 當(dāng)前配置: 系統(tǒng):WIN7 64位 開發(fā)平臺:VS 2010 顯卡:英偉達(dá)G卡 CUDA版本:6.0 若配置不一樣,請勿參閱本文。 第一步 點擊這里下載 cuda最新版,目前最高版本是6.0。下載完畢后得到 cuda_6.0.37_winvista_win7_win8.1_general_64.exe 文件。 第二步 運行安裝程序,彈出安裝過程中轉(zhuǎn)文件路徑設(shè)定框: 這個路徑隨便填無所謂,安裝完后就會自動刪除的,我就直接設(shè)置為默認(rèn)的。 第三步 等待系統(tǒng)幫你檢測當(dāng)前平臺是否適合搭建CUDA: 第四步 檢測完畢后,正式進(jìn)入CUDA安裝界面: 同意并繼續(xù) 第五步 然后選擇安裝模式: 為了完全安裝所有功能,選擇自定義模式安裝。 第六步 接下來勾選要安裝的組件: 全部勾上 第七步 接下來要設(shè)置三個安裝路徑: 這三個路徑安裝的是什么在日后的文章中將會解釋,目前先不理會,直接安裝到默認(rèn)路徑。點擊下一步之后開始正式安裝。 第八步 安裝完畢后,可以看到系統(tǒng)中多了CUDA_PATH和CUDA_PATH_V6_0兩個環(huán)境變量,接下來,還要在系統(tǒng)中添加以下幾個環(huán)境變量: CUDA_SDK_PATH = C:\ProgramData\NVIDIA Corporation\CUDA Samples\v6.0 CUDA_LIB_PATH = %CUDA_PATH%\lib\x64 CUDA_BIN_PATH = %CUDA_PATH%\bin CUDA_SDK_BIN_PATH = %CUDA_SDK_PATH%\bin\x64 CUDA_SDK_LIB_PATH = %CUDA_SDK_PATH%\common\lib\x64 然后,在系統(tǒng)變量 PATH 的末尾添加: ;%CUDA_LIB_PATH%;%CUDA_BIN_PATH%;%CUDA_SDK_LIB_PATH%;%CUDA_SDK_BIN_PATH%; 第九步 重新啟動計算機(jī)以使環(huán)境變量生效 第十步 打開VS2010并建立一個空的win32控制臺項目: 附加選項那里請把“空項目”打鉤: 第十一步 右鍵源文件 -> 添加 -> 新建項 如下圖所示: 在打開的對話框中選擇新建一個CUDA格式的源文件 (如果你只是要調(diào)用 CUDA 庫編寫程序而不需要自行調(diào)用核函數(shù)分配塊,線程的話也可以就建立 .cpp 的源文件): 第十二步 右鍵工程 -> 生成自定義 如下圖所示: 在彈出的對話框中勾選“CUDA 6.0 *****"選項: 第十三步 右鍵項目 -> 屬性 -> 配置屬性 -> VC++目錄,添加以下兩個包含目錄: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.0\include C:\ProgramData\NVIDIA Corporation\CUDA Samples\v6.0\common\inc 再添加以下兩個庫目錄: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.0\lib\x64 C:\ProgramData\NVIDIA Corporation\CUDA Samples\v6.0\common\lib\x64 第十四步 右鍵項目 -> 屬性 -> 配置屬性 ->連接器 -> 常規(guī) -> 附加庫目錄,添加以下目錄: $(CUDA_PATH_V6_0)\lib\$(Platform) 如下圖所示: 第十五步 右鍵項目 -> 屬性 -> 配置屬性 ->連接器 -> 輸入 -> 附加依賴項,添加以下庫: cublas.lib 如下圖所示: 第十六步 右鍵項目 -> 屬性,如下圖所示: 將項類型設(shè)置為 CUDA C/C++: 第十七步 打開配置管理器,如下圖所示: 點擊 新建,如下圖所示: 選擇 X64 平臺: 好了,至此平臺已經(jīng)完全搭建完畢,可用以下代碼進(jìn)行測試: 1 // CUDA runtime 庫 + CUBLAS 庫 2 #include "cuda_runtime.h" 3 #include "cublas_v2.h" 4 5 #include <time.h> 6 #include <iostream> 7 8 using namespace std; 9 10 // 定義測試矩陣的維度 11 int const M = 5; 12 int const N = 10; 13 14 int main() 15 { 16 // 定義狀態(tài)變量 17 cublasStatus_t status; 18 19 // 在 內(nèi)存 中為將要計算的矩陣開辟空間 20 float *h_A = (float*)malloc (N*M*sizeof(float)); 21 float *h_B = (float*)malloc (N*M*sizeof(float)); 22 23 // 在 內(nèi)存 中為將要存放運算結(jié)果的矩陣開辟空間 24 float *h_C = (float*)malloc (M*M*sizeof(float)); 25 26 // 為待運算矩陣的元素賦予 0-10 范圍內(nèi)的隨機(jī)數(shù) 27 for (int i=0; i<N*M; i++) { 28 h_A[i] = (float)(rand()%10+1); 29 h_B[i] = (float)(rand()%10+1); 30 31 } 32 33 // 打印待測試的矩陣 34 cout << "矩陣 A :" << endl; 35 for (int i=0; i<N*M; i++){ 36 cout << h_A[i] << " "; 37 if ((i+1)%N == 0) cout << endl; 38 } 39 cout << endl; 40 cout << "矩陣 B :" << endl; 41 for (int i=0; i<N*M; i++){ 42 cout << h_B[i] << " "; 43 if ((i+1)%M == 0) cout << endl; 44 } 45 cout << endl; 46 47 /* 48 ** GPU 計算矩陣相乘 49 */ 50 51 // 創(chuàng)建并初始化 CUBLAS 庫對象 52 cublasHandle_t handle; 53 status = cublasCreate(&handle); 54 55 if (status != CUBLAS_STATUS_SUCCESS) 56 { 57 if (status == CUBLAS_STATUS_NOT_INITIALIZED) { 58 cout << "CUBLAS 對象實例化出錯" << endl; 59 } 60 getchar (); 61 return EXIT_FAILURE; 62 } 63 64 float *d_A, *d_B, *d_C; 65 // 在 顯存 中為將要計算的矩陣開辟空間 66 cudaMalloc ( 67 (void**)&d_A, // 指向開辟的空間的指針 68 N*M * sizeof(float) // 需要開辟空間的字節(jié)數(shù) 69 ); 70 cudaMalloc ( 71 (void**)&d_B, 72 N*M * sizeof(float) 73 ); 74 75 // 在 顯存 中為將要存放運算結(jié)果的矩陣開辟空間 76 cudaMalloc ( 77 (void**)&d_C, 78 M*M * sizeof(float) 79 ); 80 81 // 將矩陣數(shù)據(jù)傳遞進(jìn) 顯存 中已經(jīng)開辟好了的空間 82 cublasSetVector ( 83 N*M, // 要存入顯存的元素個數(shù) 84 sizeof(float), // 每個元素大小 85 h_A, // 主機(jī)端起始地址 86 1, // 連續(xù)元素之間的存儲間隔 87 d_A, // GPU 端起始地址 88 1 // 連續(xù)元素之間的存儲間隔 89 ); 90 cublasSetVector ( 91 N*M, 92 sizeof(float), 93 h_B, 94 1, 95 d_B, 96 1 97 ); 98 99 // 同步函數(shù) 100 cudaThreadSynchronize(); 101 102 // 傳遞進(jìn)矩陣相乘函數(shù)中的參數(shù),具體含義請參考函數(shù)手冊。 103 float a=1; float b=0; 104 // 矩陣相乘。該函數(shù)必然將數(shù)組解析成列優(yōu)先數(shù)組 105 cublasSgemm ( 106 handle, // blas 庫對象 107 CUBLAS_OP_T, // 矩陣 A 屬性參數(shù) 108 CUBLAS_OP_T, // 矩陣 B 屬性參數(shù) 109 M, // A, C 的行數(shù) 110 M, // B, C 的列數(shù) 111 N, // A 的列數(shù)和 B 的行數(shù) 112 &a, // 運算式的 α 值 113 d_A, // A 在顯存中的地址 114 N, // lda 115 d_B, // B 在顯存中的地址 116 M, // ldb 117 &b, // 運算式的 β 值 118 d_C, // C 在顯存中的地址(結(jié)果矩陣) 119 M // ldc 120 ); 121 122 // 同步函數(shù) 123 cudaThreadSynchronize(); 124 125 // 從 顯存 中取出運算結(jié)果至 內(nèi)存中去 126 cublasGetVector ( 127 M*M, // 要取出元素的個數(shù) 128 sizeof(float), // 每個元素大小 129 d_C, // GPU 端起始地址 130 1, // 連續(xù)元素之間的存儲間隔 131 h_C, // 主機(jī)端起始地址 132 1 // 連續(xù)元素之間的存儲間隔 133 ); 134 135 // 打印運算結(jié)果 136 cout << "計算結(jié)果的轉(zhuǎn)置 ( (A*B)的轉(zhuǎn)置 ):" << endl; 137 138 for (int i=0;i<M*M; i++){ 139 cout << h_C[i] << " "; 140 if ((i+1)%M == 0) cout << endl; 141 } 142 143 // 清理掉使用過的內(nèi)存 144 free (h_A); 145 free (h_B); 146 free (h_C); 147 cudaFree (d_A); 148 cudaFree (d_B); 149 cudaFree (d_C); 150 151 // 釋放 CUBLAS 庫對象 152 cublasDestroy (handle); 153 154 getchar(); 155 156 return 0; 157 } 運行結(jié)果 PS: 矩陣元素是隨機(jī)生成的 小結(jié) 不論什么開發(fā)環(huán)境的搭建,都應(yīng)該確保自己電腦的硬件配置,軟件版本和參考文檔的一致,這樣才能確保最短的時間內(nèi)完成搭建,進(jìn)入到具體的開發(fā)環(huán)節(jié)。
|
|