从源码看DL4J中Native BLAS的加载,以及配置

最近在用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

1 收藏 评论

关于作者:万斯阿隆

熟悉Android,Java,React Native,Linux,C++等的拼写 个人主页 · 我的文章 · 5

可能感兴趣的话题



直接登录
跳到底部
返回顶部