前段時間,在TX2上裝了OpenCV3.4,TX2更新源失敗的問題,OpenCV內部很多函數都已經實現了GPU加速,但是我們手動寫的函數,想要通過GPU加速就需要手動調用CUDA進行加速。下面介紹Windows平台的環境配置和編譯。
Windows下VS2013 + CUDA配置
1.1 確認安裝
命令行下輸入
nvcc
如果出現下面的打印,說明安裝完成
1.2 創建CUDA項目
然后打開vs2013,新建一個空項目
然后在項目中添加CUDA依賴,解決方案右擊:生成依賴項->生成自定義,添加CUDA
添加依賴項之后,可以新建一個.cu文件,然后右擊該文件:屬性->配置屬性->常規->項類型->CUDA C/C++。
1.3 配置x64環境
工具欄點擊解決方案配置->配置管理器->活動解決方案平台->新建->
1.4 配置CUDA屬性
准備工作做完了,接下來配置CUDA的相關屬性(包含路徑,庫目錄等),為了方便以后使用,創建一個配置文件,在這個配置文件中配置CUDA的相關屬性。
點擊屬性管理器(找不到屬性管理器的可以按照這個順序:視圖->其他窗口->屬性管理器)-> Debug | x64 -> 添加新項目屬性表,填入屬性表名字 CUDA_Dubeg_x64_Config.props,創建完成后雙擊新建的屬性表->通用屬性->VC++目錄,在包含目錄和庫目錄這兩個選項下面添加:
包含目錄:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include C:\ProgramData\NVIDIA Corporation\CUDA Samples\v8.0\common\inc
庫目錄:
C:\ProgramData\NVIDIA Corporation\CUDA Samples\v8.0\common\lib\x64 C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\lib\x64
然后:鏈接器->輸入->附加依賴項目,添加下面這些庫文件
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
保存退出。
1.5 編譯測試
配置完成后,編譯一個小程序測試配置是否成功
/*hello.cu*/
// CUDA runtime 庫 + CUBLAS 庫 #include <cuda_runtime.h> #include <cublas_v2.h> #include <device_launch_parameters.h> #include <time.h> #include <iostream> # pragma warning (disable:4819) using namespace std; bool initDevice(void) { int cnt, i; cudaGetDeviceCount(&cnt); if (cnt < 0){ cout << "Can not find CUDA device" << endl; return false; } for (i = 0; i < cnt; i++){ cudaDeviceProp porp; if (cudaGetDeviceProperties(&porp, i) == cudaSuccess){ if (porp.major >= 1) { break; } } } if (i == cnt){ cout << "< 1.0" << endl; } return true; } __global__ void kernel_compute(float *model, float *input, float *output) { int idx_x, idx_y; idx_y = blockIdx.x; idx_x = idx_y * blockDim.x + threadIdx.x; float sum = 0; for (int i = 0; i < 9; i++){ sum += input[idx_x] * model[i]; } //printf("%3d %d %2.6f %2.6f\n", idx_x, idx_y, sum, input[idx_x]); output[idx_x] = sum; } /*block ---> row*/ int buildMaps(float *model, float *input, float *output, int height, int width) { initDevice(); float *dev_m = NULL, *dev_i = NULL, *dev_o = NULL; int size = height * width; cudaMalloc((void **)&dev_m, 9 * sizeof(float)); cudaMalloc((void **)&dev_i, size * sizeof(float)); cudaMalloc((void **)&dev_o, size * sizeof(float)); cudaMemcpy(dev_m, model, 9 * sizeof(float), cudaMemcpyHostToDevice); cudaMemcpy(dev_i, input, size * sizeof(float), cudaMemcpyHostToDevice); dim3 grid(height, 1, 1); dim3 block(width, 1, 1); kernel_compute <<<grid, block>>> (dev_m, dev_i, dev_o); cudaMemcpy(output, dev_o, size * sizeof(float), cudaMemcpyDeviceToHost); return 0; }
/*main.cpp*/
#include <iostream> #include <Windows.h> #include <stdlib.h> #include <time.h> using namespace std; extern int buildMaps(float *model, float *input, float *output, int height, int width); void show(float *ptr, int height, int width, char *str) { cout << str << " : " << endl; for (int h = 0; h < height; h++){ for (int w = 0; w < width; w++){ int cnt = h * width + w; printf("%5.5f ", ptr[cnt]); } cout << endl; } } #define width 5 #define size (width * width) int main() { float *model = (float *)malloc(9 * sizeof(float)); float *input = (float *)malloc(size * sizeof(float)); float *output = (float *)malloc(size * sizeof(float)); if (!model || !input || !output){ std::cout << "Malloc Error" << endl; exit(-1); } for (int i = 0; i < 9; i++){ model[i] = (float)(i); } srand((unsigned)time(0)); for (long long int i = 0; i < size; i++){ input[i] = ((rand() % 100) * 1.f) / (rand() % 100 + 1); } buildMaps((float *)model, (float *)input, output, width, width); show(model, 3, 3, "model"); show(input, width, width, "input"); show(output, width, width, "output"); int a; cin >> a; }
這是一個矩陣相關運算的代碼,執行結果如下: