2009年5月10日 星期日

實現 brook+ 與 cuda 於 VS2008 下的混合開發.

會寫這篇文是因為原本想把 brook+ 跟 cuda 的專案整在一個 project 裡面, 但這樣會碰上資料格式重覆定義的錯誤, 才嘗試將這兩種語言分別以兩個不同的 project 去做成個別的 DLL, 這樣一來也比較方便管理各別的 code.

首先遇上的就是做成 DLL 時 brook+ 與 cuda 各有各要注意的事項, 而在講建立 DLL 之前我要先提怎麼建一個 custom build rules, 以下以 cuda 的為例.

[build rules]
建立 cuda 的 build rules 其實很簡單, 只是設定而已. 先將 C:\Documents and Settings\All Users\Application Data\NVIDIA Corporation\NVIDIA CUDA SDK\common\Cuda.rules 這個檔案 copy 到 VS 安裝目錄的 VC\VCProjectDefaults 下 (這兩個目錄都可以用 "搜尋.rules檔案" 找的到). 
檔案丟進去之後, 在 VS 底下隨便選一個 project 名按右鍵選 custom build rules 如圖

尋找一個已經存在的 rules

指到剛剛 cuda.rules copy 到的目錄

選到 cuda.rules

後, 會跟第一個畫面一樣上面會多出現一個 cuda build rules, 而在 cuda 的 project 上請把那設定畫面中 "CUDA build rules" 勾起來, 這樣你這個 project 以後加 .cu 的檔案就會自動套用這個 build rule, 以後加檔案會方便很多!
引用成功後可以在 configuration properties 裡看到有 CUDA build rules, 但 include 的設定是空的! 請在 debug 與 release 兩個 configuration 裡都加進去這行 
"$(CUDA_INC_PATH)"; "$(NVSDKCUDA_ROOT)/common/inc"
Linker 裡 Input->Additional Dependencies 裡加上 cudart.lib cutil32.lib 這兩個.

而 brook+ 沒有 .rules 可用, AMD 官方以 "你可以自己建" 一句話輕鬆帶過. 要建一個簡單可用的 brook+ rules 不難, 但我不知道怎麼自動區分 debug 還 release build, 我目前用的還是舊的筆記 .

[cuda project]
cuda 的檔案因為都是 reference 自 .cu 運作, 但如果給一般 .cpp 裡 include 這些 .cu 檔時, VC9 會出現一堆錯誤 (不知道 threadIdx 是啥, 看不懂 <<<>>> 等等..), 而解法其實也很簡單, 就是再建一個 header 檔裡面說明你要引用的 .cu 檔案裡有哪些 function, 然後再給其它 .cpp 檔案引用這個 header 檔, 就可以正常編譯.
cuda 的 DLL 可以直接用 MFC DLL 的框架, 也可以全部自訂.

[brook project]
brook+ 要建 DLL 時最好不要用 VS 裡的 project wizard 去建, 因為那個會用到 precompile header (stdafx.cpp, stdafx.h) 的關係, 底下每一個 .cpp 檔都要去 include stdafx.h 才可以正常編譯, 但 .br 編譯時是以 "產生" 的方式輸出 .cpp 檔跟兩個 header 檔, 即使在 .br 檔裡加入 #include "stdafx.h" 這行, 最後在輸出的 .cpp 檔裡 stdafx.h 這行也會被排到前三個一定會 include 的 header 檔下面, 然後編譯會有一堆問題.

我的解法是, 開一個空的 project, 裡面啥都沒有, 然後把 brook+ 所有的檔案移過來這個 project 裡, 也要設定好相關的編譯環境 , configuration type 改為 DLL 即可. 

而 project 的 properties 中, linker -> input -> Additional Dependencies 加上該有的 .lib, release mode 是 brook.lib aticalrt.lib, debug mode 是 brook_d.lib aticalrt.lib

沒意外的話都可以編譯的起來了.

沒有留言: