無法解析的外部符號 [email protected],
首先貼出我的問題,解決的就是這個問題。要解決這個問題,首先要看你的cuda環境配置的是否正確,那麼就要從頭跟著我們走一遍,再檢查一下您配置的是否正確。
1>1.cu.obj : error LNK2019: 無法解析的外部符號 cublasDestroy_v2,該符號在函式 main 中被引用
1>1.cu.obj : error LNK2019: 無法解析的外部符號 cudaFree,該符號在函式 main 中被引用1>1.cu.obj : error LNK2019: 無法解析的外部符號 cublasGetVector,該符號在函式 main 中被引用
1>1.cu.obj : error LNK2019: 無法解析的外部符號 cublasSgemm_v2,該符號在函式 main 中被引用
1>1.cu.obj : error LNK2019: 無法解析的外部符號 cudaThreadSynchronize,該符號在函式 main 中被引用
1>1.cu.obj : error LNK2019: 無法解析的外部符號 cublasSetVector,該符號在函式 main 中被引用
首先官網下載安裝包,這個就不細說了 ,我下的是這個版本cuda_8.0.61_win10.exe,,注意win7和win10版本要對應,千萬別弄錯了 之後雙擊會出現如下截圖,
解壓完以後一直點下一步如下圖
出現這個等半個小時左右就好了
安裝結束後開始配置系統環境變數
win10可以這麼操作win+s 搜尋環境,自動匹配出系統環境變數
開啟環境變數後如下圖:
如圖中點選環境變數的就是了開啟後,如下圖設定:
CUDA_PATH = C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0
CUDA_PATH_V8_0 = C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0
以上兩個系統我的是安裝上cuda後就有的,沒有的自行新增。
CUDA_SDK_PATH = C:\ProgramData\NVIDIA Corporation\CUDA Samples\v8.0CUDA_LIB_PATH = %CUDA_PATH%\lib\x64
CUDA_BIN_PATH = %CUDA_PATH%\bin
CUDA_SDK_BIN_PATH = %CUDA_SDK_PATH%\bin\win64
CUDA_SDK_LIB_PATH = %CUDA_SDK_PATH%\common\lib\x64
將上面的變數名和變數值依次
比如:
依次填入後,找到path如圖:
依次點選新建,將 %CUDA_LIB_PATH%;%CUDA_BIN_PATH%;%CUDA_SDK_BIN_PATH%;%CUDA_SDK_LIB_PATH%;依次填入,填入後效果如上圖所示。全部安裝好後一定要記得重啟!,這裡就將cuda 在win10中如何配置的完成了
配置完環境變數後
檢驗CUDA環境是否配置成功:
A.開啟cmd視窗,輸入:nvcc -V
,螢幕上會顯示nvcc編譯器的版本資訊。
b.開啟cmd視窗,輸入:
cd C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\extras\demo_suite
bandwidthTest.exe
deviceQuery.exe
如果兩者都是:Rsult=PASS,說明安裝和配置成功啦;否則可能需要重灌。
如果通過前面的編譯通過了,下面的過程可以省去,過程和上面的一樣,直接去看vs2013的配置
編譯CUDA的Samples:
用VS2013開啟:C:\ProgramData\NVIDIA Corporation\CUDA Samples\v8.0\Samples_vs2013.sln分別編譯這兩個檔案,編譯結束後,進入C:\ProgramData\NVIDIA Corporation\CUDA Samples\v8.0\bin\win64\Release
會發現我們剛編譯出的bandwidthTest.exe
和deviceQuery.exe
,在cmd視窗中執行,結果應與上面相同。
如果編譯過程中,未找到CUDA 8.0.props,會出現如下提示:
將C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\extras\visual_studio_integration\MSBuildExtensions\
目錄下的4個檔案,複製到C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\BuildCustomizations
目錄下,然後重新啟動VS2013即可。
接下來需要再配置vs2013了
1.開啟vs2013並建立一個空專案程式,建立一個cuda_samples的解決方案和cuda_test1專案:
2.右鍵原始檔–>新增–>新建項,如下圖所示
3.選擇NIVIDIA CUDA7.5中 CUDA C/C++file,並在名稱那填上cuda_main
- 4.選擇cuda_test1,點選右鍵–>專案依賴項–>自定義生成
- 5.選擇CUDA7.5
- 6.點選cuda_main.cu的屬性
7.在配置屬性–>常規–>項型別–>選擇“CUDA C/C++”
最重要的一步出現啦,就是這一步導致體重無法解析外部符號的問題
接下來進行專案配置
右鍵點選專案屬性–>屬性–>配置管理器–>活動解決方案平臺->新建->鍵入或選擇新平臺->選擇“x64”。
這一步別告訴我你弄不好。如果不行的話,你可以換一下活動解決方案和活動解決平臺,總有一個適合你的專案
x64
1.包含目錄配置
- 1.右鍵點選專案屬性–>屬性–>配置屬性–>VC++目錄–>包含目錄
- 2.新增包含目錄:
$(CUDA_PATH)\include
1.2 庫目錄配置
- 1.VC++目錄–>庫目錄
- 2.新增庫目錄:
$(CUDA_PATH)\lib\x64
1.3 依賴項
- 配置屬性–>聯結器–>輸入–>附加依賴項
- 新增庫檔案:
cublas.lib
cublas_device.lib
cuda.lib
cudadevrt.lib
cudart.lib
cudart_static.lib
cufft.lib
cufftw.lib
curand.lib
cusolver.lib
cusparse.lib
nppc.lib
nppi.lib
nppial.lib
nppicc.lib
nppicom.lib
nppidei.lib
nppif.lib
nppig.lib
nppim.lib
nppist.lib
nppisu.lib
nppitc.lib
npps.lib
nvblas.lib
nvcuvid.lib
nvgraph.lib
nvml.lib
nvrtc.lib
OpenCL.lib
cudnn.lib(選填,當安裝cudnn時)(都新增上是沒有錯的,相信我)
- 新增庫檔案:
注意:新增nvcuvenc.lib庫檔案,編譯時,報找不到該檔案的錯誤。去掉後,程式也能執行
接下來把下面程式拷貝到去
// CUDA runtime 庫 + CUBLAS 庫
#include "cuda_runtime.h"
#include "cublas_v2.h"
#include <time.h>
#include <iostream>
using namespace std;
// 定義測試矩陣的維度
int const M = 5;
int const N = 10;
int main()
{
// 定義狀態變數
cublasStatus_t status;
// 在記憶體中為將要計算的矩陣開闢空間
float *h_A = (float*)malloc(N*M*sizeof(float));
float *h_B = (float*)malloc(N*M*sizeof(float));
// 在 記憶體 中為將要存放運算結果的矩陣開闢空間
float *h_C = (float*)malloc(M*M*sizeof(float));
// 為待運算矩陣的元素賦予 0-10 範圍內的隨機數
for (int i = 0; i<N*M; i++) {
h_A[i] = (float)(rand() % 10 + 1);
h_B[i] = (float)(rand() % 10 + 1);
}
// 列印待測試的矩陣
cout << "矩陣 A :" << endl;
for (int i = 0; i<N*M; i++){
cout << h_A[i] << " ";
if ((i + 1) % N == 0) cout << endl;
}
cout << endl;
cout << "矩陣 B :" << endl;
for (int i = 0; i<N*M; i++){
cout << h_B[i] << " ";
if ((i + 1) % M == 0) cout << endl;
}
cout << endl;
/*
** GPU 計算矩陣相乘
*/
// 建立並初始化 CUBLAS 庫物件
cublasHandle_t handle;
status = cublasCreate(&handle);
if (status != CUBLAS_STATUS_SUCCESS)
{
if (status == CUBLAS_STATUS_NOT_INITIALIZED) {
cout << "CUBLAS 物件例項化出錯" << endl;
}
getchar();
return EXIT_FAILURE;
}
float *d_A, *d_B, *d_C;
// 在 視訊記憶體 中為將要計算的矩陣開闢空間
cudaMalloc(
(void**)&d_A, // 指向開闢的空間的指標
N*M * sizeof(float) // 需要開闢空間的位元組數
);
cudaMalloc(
(void**)&d_B,
N*M * sizeof(float)
);
// 在 視訊記憶體 中為將要存放運算結果的矩陣開闢空間
cudaMalloc(
(void**)&d_C,
M*M * sizeof(float)
);
// 將矩陣資料傳遞進 視訊記憶體 中已經開闢好了的空間
cublasSetVector(
N*M, // 要存入視訊記憶體的元素個數
sizeof(float), // 每個元素大小
h_A, // 主機端起始地址
1, // 連續元素之間的儲存間隔
d_A, // GPU 端起始地址
1 // 連續元素之間的儲存間隔
);
cublasSetVector(
N*M,
sizeof(float),
h_B,
1,
d_B,
1
);
// 同步函式
cudaThreadSynchronize();
// 傳遞進矩陣相乘函式中的引數,具體含義請參考函式手冊。
float a = 1; float b = 0;
// 矩陣相乘。該函式必然將陣列解析成列優先陣列
cublasSgemm(
handle, // blas 庫物件
CUBLAS_OP_T, // 矩陣 A 屬性引數
CUBLAS_OP_T, // 矩陣 B 屬性引數
M, // A, C 的行數
M, // B, C 的列數
N, // A 的列數和 B 的行數
&a, // 運算式的 α 值
d_A, // A 在視訊記憶體中的地址
N, // lda
d_B, // B 在視訊記憶體中的地址
M, // ldb
&b, // 運算式的 β 值
d_C, // C 在視訊記憶體中的地址(結果矩陣)
M //
);
// 同步函式
cudaThreadSynchronize();
// 從 視訊記憶體 中取出運算結果至 記憶體中去
cublasGetVector(M*M, // 要取出元素的個數
sizeof(float), // 每個元素大小
d_C, // GPU 端起始地址
1, // 連續元素之間的儲存間隔
h_C, // 主機端起始地址
1 // 連續元素之間的儲存間隔
);
// 列印運算結果
cout << "計算結果的轉置 ( (A*B)的轉置 ):" << endl;
for (int i = 0; i<M*M; i++){
cout << h_C[i] << " ";
if ((i + 1) % M == 0) cout << endl;
}
// 清理掉使用過的記憶體
free(h_A);
free(h_B);
free(h_C);
cudaFree(d_A);
cudaFree(d_B);
cudaFree(d_C);
// 釋放 CUBLAS 庫物件
cublasDestroy(handle);
getchar();
return 0;
}
執行結構貼上,錯誤已解決,不容易啊,