windows10+cuda7.5+opencv2.4.13+vs2013環境配置

前幾天想把代碼移植到linux下,想用服務器上的GPU來加速處理,結果搞了幾天,頭都大了,環境還沒配好,ffmpeg ,opencv,gstreamer,單獨裝都沒毛病,想讓這些庫關聯起來,而且沒毛病簡直是鬧心,還有各種依賴庫,幾十個,看着都頭大,於是棄坑,還是迴歸到Windows的懷抱。不過配置的過程,也是頭疼,網上各種教程,於是總結一下,加上自己的親身經歷,親測有效,代碼可以運行。

所需的軟件和庫

1.GPU
首先要確定你電腦上的GPU支持cuda嗎,這個可以再英偉達的官網上查看規格參數,我用的是筆記本,配的是GTX950M,cuda核心數:640 ,架構:Maxwell,還算新的架構,這個架構問題後面還是挺蛋疼的。
2.opencv2.4.13
下載地址:http://opencv.org/downloads.html
如果是2.4.9也是可以的
安裝後,就是解壓到一個文件下,
安裝完,需要配置windows的環境變量,在path中加入:D:\application\opencv\build\x64\vc12\bin; D:\application\opencv\build\x86\vc12\bin

3.CUDA ToolKit 7.5
下載地址:https://developer.nvidia.com/cuda-75-downloads-archive
讓它默認安裝,一般在c:programfiles/NVIDIAGPU computing toolkit/下。
沒有用最新的8.0,感覺應該沒差吧
4.cmake3.4.3
下載地址:https://cmake.org/download/
別問爲什麼是3.4.3,網上有人說只能用這個,說其他的報錯,好吧,我信了,且也用了。它的作用就是將opencv和cuda一起編譯,生成一個新的版本。
5.TBB ,據說是編譯opencv_core庫用的,我下的最新的,
下載地址:https://github.com/01org/tbb/releases
可以自定義安裝,好找位置。
將D:\application\tbb2017_20170226oss\bin\intel64\vc12添加到環境變量中。
6.python2.7
下載地址:https://www.python.org/downloads/
這個作用不明,好像有用吧

開始配置

啓動cmake
1.在source code :填入D:/application/opencv/sources(根據自己的目錄定,就是sources文件夾位置)
在where is to build :填入D:/application/opencv/build/cuda。這個cuda文件夾是自己建的,意思是最後編入得目的文件夾。
注意選擇advanced
這裏寫圖片描述

2.然後點configure
會提示你選擇編譯器,選擇visual studio 12 2013 win64
cmake配置:
取消選擇BUILD_DOCS 和‘BUILD_EXAMPLES
確認‘CMAKE_LINKER’, Visual Studio vs2013的路徑
取消‘CUDA_ATTACH_VS_BUILD_RULE_TO_CUDA_FILE’
選擇‘WITH_CUBLAS’, ‘WITH_CUDA’, ‘WITH_OPENGL’, ‘WITH_TBB’ (TBB is optional)
CUDA_GENERATION,只能找到kelper,fermi,auto,還有空白,找不到maxwell,於是就選擇空白,不要選其他的,如果你的可以找到可以直接選擇,下邊這兩項就可以省略了。
由於我的顯卡是maxwell,它的計算能力是5.0,這個你可以官網查到
所以就要設置,CUDA_ARCH_BIN=2.0 2.1(2.0) 3.0 3.5 5.0、CUDA_ARCH_PTX=5.0

再點擊configure
會發現許多紅的消失了
這時候回彈出新的紅色,關於tbb的路徑問題
include path :D:/tbb43_20140724oss\include
再次點擊configure
會彈出配置tbb lib路徑:D:/tbb43_20140724oss/lib/intel64/vc12
再點擊configure,這次應該沒紅色了
3,沒有紅色,就可以點擊generate
如果成功,就可以再目標目錄D:/application/opencv/build/cuda下面找到一個opencv.sln
先管理員權限打開vs2013,然後打開這個opencv.sln
在解決方案管理器下,看到許多的庫,這就是要重新編譯的部分,
首先,先編譯modules下的opencv_core,opencv_gpu,分別,右鍵-僅用於此項目-生成
如果這兩個沒問題,那恭喜你,基本沒問題了,其中opencv_gpu是最慢的。
你就可以ALL_BUILD,如果沒有錯誤,就cmake_target 中INSTALL
先在release下編譯,完成後,再到debug下進行。
一次要兩個小時,這過程,慢慢等吧,而且還要祈禱沒問題發生。
編譯完會有一個重新加載,點擊全部重新加載。
比較開心的就是,我release沒報錯,在debug的時候,報錯了,於是我在debug下先編譯了opencv_gpu,然後再all_build,就成功了,簡直是個玄學。
安裝成功後,就在build/cuda/下生成install文件夾。

4.就是使用和測試了
好多坑,這個搞了一天
先將D:\application\opencv\build\cuda\install\x64\vc12\bin中的dll,拷貝到C:windows/system32目錄下。
將C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\bin加入到系統環境變量中。
D:\application\opencv\build\cuda\install\x64\vc12\bin加入到系統變量中
重啓電腦。

新建一個項目,比如main.cpp,打開視圖-其他窗口-屬性管理器,win32.user-屬性
vc++目錄
包含目錄:
D:\application\opencv\build\cuda\install\include\opencv2
D:\application\opencv\build\cuda\install\include\opencv
D:\application\opencv\build\cuda\install\includ
庫目錄:
D:\application\opencv\build\cuda\install\x64\vc12\lib
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v7.5\lib\Win32
鏈接器-輸入:
debug下
opencv_imgproc2413d.lib
opencv_calib3d2413d.lib
opencv_contrib2413d.lib
opencv_core2413d.lib
opencv_features2d2413d.lib
opencv_flann2413d.lib
opencv_gpu2413d.lib
opencv_highgui2413d.lib
opencv_legacy2413d.lib
opencv_ml2413d.lib
opencv_nonfree2413d.lib
opencv_objdetect2413d.lib
opencv_ocl2413d.lib
opencv_photo2413d.lib
opencv_stitching2413d.lib
opencv_superres2413d.lib
opencv_ts2413d.lib
opencv_video2413d.lib
opencv_videostab2413d.lib
cudart.lib

release下
opencv_imgproc2413.lib
opencv_calib3d2413.lib
opencv_contrib2413.lib
opencv_core2413.lib
opencv_features2d2413.lib
opencv_flann2413.lib
opencv_gpu2413.lib
opencv_highgui2413.lib
opencv_legacy2413.lib
opencv_ml2413.lib
opencv_nonfree2413.lib
opencv_objdetect2413.lib
opencv_ocl2413.lib
opencv_photo2413.lib
opencv_stitching2413.lib
opencv_superres2413.lib
opencv_ts2413.lib
opencv_video2413.lib
opencv_videostab2413.lib
cudart.lib
配置完debug,配置release(感覺沒啥用)
然後調試
報錯:
模塊計算機類型“x64”與目標計算機類型“X86”衝突

因爲庫是x64編譯器編出來的,但是vs默認是win32的編譯配置
這裏寫圖片描述
在配置管理器中選擇平臺x64,沒有就新建一個,選中x64,(默認你的vs是支持編譯x64)
這個時候再去看屬性管理器,發現多了兩個debug/x64,release/x64
安裝上面配的過程,把這兩個也配了,主要是配debug
再源文件中添加,新建項-cuda7.5
這裏寫圖片描述
test.cu文件

#include "cuda_runtime.h"  
#include "device_launch_parameters.h"  

#include <stdio.h>  

//cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size);  
__global__ void addKernel(int *c, const int *a, const int *b)  
{  
    int i = threadIdx.x;  
    c[i] = a[i] + b[i];  
}  
// Helper function for using CUDA to add vectors in parallel.  
extern "C"  
cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size)  
{  
    int *dev_a = 0;  
    int *dev_b = 0;  
    int *dev_c = 0;  
    cudaError_t cudaStatus;  

    // Choose which GPU to run on, change this on a multi-GPU system.  
    cudaStatus = cudaSetDevice(0);  
    if (cudaStatus != cudaSuccess) {  
        fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU installed?");  
        goto Error;  
    }  

    // Allocate GPU buffers for three vectors (two input, one output)    .  
    cudaStatus = cudaMalloc((void**)&dev_c, size * sizeof(int));  
    if (cudaStatus != cudaSuccess) {  
        fprintf(stderr, "cudaMalloc failed!");  
        goto Error;  
    }  

    cudaStatus = cudaMalloc((void**)&dev_a, size * sizeof(int));  
    if (cudaStatus != cudaSuccess) {  
        fprintf(stderr, "cudaMalloc failed!");  
        goto Error;  
    }  

    cudaStatus = cudaMalloc((void**)&dev_b, size * sizeof(int));  
    if (cudaStatus != cudaSuccess) {  
        fprintf(stderr, "cudaMalloc failed!");  
        goto Error;  
    }  

    // Copy input vectors from host memory to GPU buffers.  
    cudaStatus = cudaMemcpy(dev_a, a, size * sizeof(int), cudaMemcpyHostToDevice);  
    if (cudaStatus != cudaSuccess) {  
        fprintf(stderr, "cudaMemcpy failed!");  
        goto Error;  
    }  

    cudaStatus = cudaMemcpy(dev_b, b, size * sizeof(int), cudaMemcpyHostToDevice);  
    if (cudaStatus != cudaSuccess) {  
        fprintf(stderr, "cudaMemcpy failed!");  
        goto Error;  
    }  

    // Launch a kernel on the GPU with one thread for each element.  
    addKernel<<<1, size>>>(dev_c, dev_a, dev_b);  

    // Check for any errors launching the kernel  
    cudaStatus = cudaGetLastError();  
    if (cudaStatus != cudaSuccess) {  
        fprintf(stderr, "addKernel launch failed: %s\n", cudaGetErrorString(cudaStatus));  
        goto Error;  
    }  

    // cudaDeviceSynchronize waits for the kernel to finish, and returns  
    // any errors encountered during the launch.  
    cudaStatus = cudaDeviceSynchronize();  
    if (cudaStatus != cudaSuccess) {  
        fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching addKernel!\n", cudaStatus);  
        goto Error;  
    }  

    // Copy output vector from GPU buffer to host memory.  
    cudaStatus = cudaMemcpy(c, dev_c, size * sizeof(int), cudaMemcpyDeviceToHost);  
    if (cudaStatus != cudaSuccess) {  
        fprintf(stderr, "cudaMemcpy failed!");  
        goto Error;  
    }  

Error:  
    cudaFree(dev_c);  
    cudaFree(dev_a);  
    cudaFree(dev_b);  

    return cudaStatus;  
}  

main.cpp文件

#include <iostream>  
#include "cuda_runtime.h"  
#include "device_launch_parameters.h"  
using namespace std;  

extern "C"  
    cudaError_t addWithCuda(int *c, const int *a, const int *b, unsigned int size);  
int main(int argc,char **argv)  
{  
    const int arraySize = 5;  
    const int a[arraySize] = { 1, 2, 3, 4, 5 };  
    const int b[arraySize] = { 10, 20, 30, 40, 50 };  
    int c[arraySize] = { 0 };  

    // Add vectors in parallel.  
    cudaError_t cudaStatus = addWithCuda(c, a, b, arraySize);  
    if (cudaStatus != cudaSuccess) {  
        fprintf(stderr, "addWithCuda failed!");  
        return 1;  
    }  

    cout<<"{1,2,3,4,5} + {10,20,30,40,50} = {"<<c[0]<<','<<c[1]<<','<<c[2]<<','<<c[3]<<'}'<<endl;  
    printf("cpp工程中調用cu成功!\n");  

    // cudaDeviceReset must be called before exiting in order for profiling and  
    // tracing tools such as Nsight and Visual Profiler to show complete traces.  
    cudaStatus = cudaDeviceReset();  
    if (cudaStatus != cudaSuccess) {  
        fprintf(stderr, "cudaDeviceReset failed!");  
        return 1;  
    }  
    system("pause"); //here we want the console to hold for a while  
    return 0;  
}  

右鍵工程-生成依賴項-生成自定義-選擇cuda7.5
這裏寫圖片描述

右鍵工程-屬性 會發現多了很多東西
選中test.cu-右鍵-屬性-項類型-cuda c/c++
這裏寫圖片描述

工具-選項-文本編輯器-文件擴展名
這裏寫圖片描述
添加cu cuh

致此,終於完成了,調試運行,成功。
你也可以直接測試cuda是否安裝成功
vs2013
新建項目
這裏寫圖片描述
起名爲test
系統會爲你生成一個kernel.cu文件
直接運行,完美,成功!

.cu文件和cpp文件混合編譯,可以先建cpp,在添加.cu。也可以先建.cu,然後將代碼替換掉系統給的kernel.cu,然後再添加cpp

其中自己的代碼也出了很多問題,慢慢改,如果配置沒問題,都是可解決的,再不行就重裝一遍嘛,哈哈。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章