1. 程式人生 > >無法解析的外部符號 [email protected],

無法解析的外部符號 [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.0
CUDA_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.exedeviceQuery.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 依賴項

    1. 配置屬性–>聯結器–>輸入–>附加依賴項
    1. 新增庫檔案: 
      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;
}

執行結構貼上,錯誤已解決,不容易啊,