1. 程式人生 > >cuda與Eigen不相容的解決方案

cuda與Eigen不相容的解決方案

cuda提供強大的矩陣計算庫cuBlas,但cuBlas沒法進行特徵值、逆矩陣等高階的運算,要解決這個問題,要麼自己寫演算法(太難),要麼呼叫線性代數運算庫,而線性代數運算庫中Eigen是最簡便易用的一個。

當我想把這兩個庫放在一起編譯的時候,出現了嚴重問題:用VS編譯無法通過!!!

用google查了一下,似乎不少人都遇到過這個問題,對於linux系統,這個問題是可以解決的,gcc4.7 以上是可以解決這個問題的(參看http://eigen.tuxfamily.org/dox-devel/TopicCUDA.html,需翻牆)

但對於windows的vs,這個問題暫時無解。

後來看有人提出一個解決思路,就是把Host部分的程式碼和Device部分的程式碼分開編譯。原因是:eigen庫的語法過於複雜,以至於cuda的編譯器無法解析。分開編譯的話,兩部分程式碼使用不同的編譯器,就解決了這個問題,然後封裝一些介面,解決兩個部分相互呼叫的問題。但文中只是提供了一個思路,沒有講具體實現方法。(參看http://stackoverflow.com/questions/21216359/member-has-already-been-declared-error-with-cuda-and-eigen)

我馬上學習了編譯多個原始檔的知識,進行嘗試,終於解決cuda與Eigen不相容的問題。

我的解決思路是這樣的:

把程式的主體部分(包括Eigen)都放在.cpp下。

把cuda需要用到的程式碼放在.cu下。

在vs中,project->add new item ,將上面那個.cpp檔案新增進去

在.cpp檔案和.cu中都宣告一個名稱空間 cuda_functions,將介面函式的宣告放進去,然後這些函式在.cu檔案中實現,例如:

<cuda_functions.h>

namespace cuda_functions{
void malloc(void ** p, size_t size);//cudaMalloc的介面函式
void free(void * p);//cudaFree的介面函式

};

<test.cu>

#include <cuda_runtime.h>
#include "cublas_v2.h"

#include "cuda_functions.h"

void cuda_functions::malloc(void ** p,size_t s){//實現介面函式cudaMalloc
cudaMalloc(p,s);
};


void cuda_functions::free(void * p){//實現介面函式cudaFree
cudaFree(p);
};

<test.cpp>

#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
#include "cuda_functions.h"

void main(){

float * p;

 cuda_functions::malloc((void **)& p,sizeof(float)*10000);

 cuda_functions::free((void *) p);

while(1);

}


上面這段程式碼實現在.cpp檔案中,開闢和釋放視訊記憶體空間。