Theano如何禁用-march=native编译选项?
问题现象
当你把在新款CPU上编译好的Theano项目拿到旧款CPU上运行时,大概率会碰到这类错误:
PROGRAM DEFECTIVE (TERMINATED BY SIGNAL): Illegal instruction
创建堆栈跟踪(最内层优先):
#2 /lib/x86_64-linux-gnu/libc.so.6(+0x354b0) [0x2b0304efc4b0]
#3 /u/bozheniuk/.theano/compiledir_Linux-4.4--generic-x86_64-with-Ubuntu-16.04-xenial-x86_64-2.7.12-64/lazylinker_ext/lazylinker_ext.so(+0x4d2a) [0x2b030fe44d2a]
#4 /usr/l...
问题根源
根据Theano官方FAQ的说明,Theano默认会自动给编译器加上-march=native选项。这个选项的作用是让编译器针对当前编译环境的CPU生成最适配的机器指令,性能拉满,但弊端也很明显:如果编译缓存是在新款CPU上生成的,里面包含了旧CPU不支持的新指令,旧CPU执行时就会触发非法指令错误,直接导致缓存的编译模块失效。
解决方法
要搞定这个问题,核心就是让Theano生成兼容旧CPU的编译代码,具体步骤如下:
1. 修改Theano配置文件
在你的用户主目录下找到.theanorc文件(如果没有就新建一个),添加以下内容:
[gcc] cxxflags = -march=core2
-march=core2是个兼容性很强的选项,能适配绝大多数旧款x86_64 CPU。如果你的CPU型号更老,也可以换成-march=pentium4这类更针对性的参数。
2. 清理旧编译缓存
删除Theano自动生成的编译缓存目录,默认路径是~/.theano/compiledir_*,这样Theano下次运行时会用新的编译选项重新生成兼容的模块。
3. 临时设置(无需修改配置文件)
如果只是临时在旧CPU上运行,不想改配置文件,可以在启动脚本前先设置环境变量:
export THEANO_FLAGS='gcc.cxxflags=-march=core2'
内容的提问来源于stack exchange,提问作者Albert

