從原始碼看DL4J中Native BLAS的載入,以及配置

oncealong發表於2016-11-24

最近在用DeepLearning4J(DL4J)嘗試語音識別的深度學習,Git DL4J的程式碼,用IntelliJ IDEA開啟,配置好相關依賴後,執行包org.deeplearning4j.examples.test.Test的main,可以正常執行,但是有警告提示如下:

提示無法載入com.github.fommil.netlib.NativeSystemBLAS,和無法載入native system blas,DN4J的效能會受到影響.

查了github,stackoverflow,quora等,找到了如下網頁.github的是一個遇到類似問題的人抱怨native blas難以配置,害的自己在原始碼中才找到解決方法,而nd4j的程式設計師回答所有的深度學習框架中的native blas都是難配置的,我在搜尋的時候也發現了MLib等庫確實也會報這個警告.第二個部落格是一篇講述如何配置blas的文章.

這篇文章中,我想說明一下幾個問題:

1. native blas 是本地庫,用C/C++寫成,因而運算速度較快.

2. Java如果要呼叫C/C++的dll,一定要用JNI技術來呼叫對應的dll,那麼dll的路徑和名稱分別是什麼?

3. 如果找到需要的dll,假設叫a.dll,如果a.dll又依賴於b.dll和c.dll,那麼把a.dll,b.dll,c.dll都放在Java識別的路徑下,是不是就可以解決這個問題了.

1.dll的存放路徑和名稱

先看DL4J的原始碼,錯誤首先出現在如下程式碼中

進入Nd4j的類,加斷點,單步除錯,經過如下的函式呼叫棧後,進入NativeSystemBLAS這個類.

20151127141526754

我們看下NativeSystemBLAS類的內容,在static靜態塊中找到如下用於載入dll的程式碼:

先加斷點單步執行,看看jnilib的內容,執行後得到的是”netlib-native_system-win-x86_64.dll”,為什麼是這個,我的電腦是64位,如果32位系統又會需要哪個dll庫呢?

我們進入getJniName函式,看下其程式碼,這裡arch用於獲得架構,os用於獲得系統版本,extension獲得字尾,然後拼出dll的名稱:

arch程式碼如下:

abi程式碼如下:

os程式碼如下:

extension程式碼如下:

這樣,我就知道了dll的具體名字為什麼是netlib-native_system-win-x86_64.dll了.

接下來,我還需要知道這個dll要放在哪裡,才能被nd4j程式碼找到!

接下來,我們跳進JniLoader.load(natives.split(“,”)),看看load是如何執行的:

其實這段程式碼本來我沒有看太懂,但是架不住除錯功能強大,執行一次,加斷點,看看內容怎麼變化,就知道是什麼意思了.

這裡假設我的windows下Path環境變數設定為:”D:\Python\Python35\Scripts\;D:\Program Files\Java\jdk1.7.0_15\bin;C:\WINDOWS;D:\BLAS;”,那麼javaLibPath的內容就會是這四個組成的字串陣列.接下來取出來第一個,和dll名稱(netlib-native_system-win-x86_64.dll)一起拼成一個檔案路徑”D:\Python\Python35\Scripts\netlib-native_system-win-x86_64.dll”,接下來檢查這個路徑是否是檔案,如果不是,就會繼續拼下一個,直到拼出”D:\BLAS\netlib-native_system-win-x86_64.dll”,然後我的dll檔案確實放在這裡,程式就會載入.

現在我們找到對應的dll檔案,這裡為netlib-native_system-win-x86_64.dll,然後放在D:\BLAS\這個位置,把D:\BLAS加入path變數,然後重啟Intellij(這一步不一定需要,大家自己嘗試),讓它重新讀取path值.

重新執行下Test裡的main函式,然後執行結果竟然還是如上的錯誤,額,是我們剛才的分析都是錯誤了麼?

2.dll庫的依賴和依賴查詢

我們在跳進載入dll的地方,看看究竟是哪裡錯了:

這裡我們捕獲到一個異常,說 D:\BLAS\netlib-native_system-win-x86_64.dll: Can’t find dependent libraries.

原來如此我們的庫還需要一些依賴庫,這些依賴庫沒有找到.但是我們怎麼知道這個庫依賴於哪些庫呢?哪些是已經有的,哪些是沒有的?這裡推薦一個工具,叫PEStudio,可以檢視dll檔案或exe檔案依賴於哪些庫:

20151127141207097

這裡顯示了netlib-native_system-win-x86_64.dll依賴於哪些庫,其中liblapack3.dll和libblas3.dll是我們需要找到了.其實到這一步,問題就算解決了,參見OpenBlas的官網,這些檔案都可以很輕鬆的下載到,就是要注意首先需要知道你要的是32位還是64位,其次所有dll需要是統一的,不能部分32,部分64. 謝謝曲奇餅的提醒, 這裡需要注意的還有jdk的版本, 在64位系統下, 應該使用64的jdk, 大家注意嘗試.

這裡是我用PEStudio找到的依賴關係:

20151127141238515

至此,問題圓滿解決.

=========================

最後,把在win10 64位系統下成功執行的庫檔案放在這:

csdn:http://download.csdn.net/detail/u201011221/9355487

baiduyun: http://pan.baidu.com/s/1jGO5waE

相關文章