82

几天以来,我在使用 MATLAB 时经常收到相同的错误,这在dlopen. 我对 MATLAB 很陌生,这就是为什么我不知道该怎么做。谷歌似乎也没有帮助我。当我尝试制作一个特征向量时,我得到了这个:

Error using eig
LAPACK loading error:
dlopen: cannot load any more object with static TLS

我在做乘法时也得到了这个:

Error using  * 
BLAS loading error:
dlopen: cannot load any more object with static TLS

我当然确实在寻找这个问题的解决方案,但是我不太了解,也不知道该怎么办。这些是我发现的线程:

  1. 如何使用 MATLAB 提供的 BLAS 库?
  2. http://www.mathworks.de/de/help/matlab/matlab_external/calling-lapack-and-blas-functions-from-mex-files.html

有人能帮助我吗?

演示此错误的函数调用示例

>> randn(3,3)

ans =

 2.7694    0.7254   -0.2050             
-1.3499   -0.0631   -0.1241             
 3.0349    0.7147    1.4897            

>> eig(ans)

Error using eig
LAPACK loading error:
dlopen: cannot load any more object with static TLS
4

10 回答 10

106

这是自 R2012b (8.0) 以来已知的 MATLAB 的错误号 961964。MATLAB 使用静态 TLS 动态加载一些库(线程本地存储,例如参见 gcc 编译器标志 -ftls-model)。加载太多这样的库 => 没有剩余空间。

到目前为止,mathwork 唯一的解决方法是先加载重要的(!)库,并尽早使用它们(他们建议在 startup.m 中放入“ones(10)*ones(10);”)。我最好不要评论这个“解决策略”。

自 R2013b (8.2.0.701) 与 Linux x86_64 以来,我的经验是:不要使用“doc”(图形帮助系统)!我认为这个文档实用程序(libxul 等)正在使用大量静态 TLS 内存。

这是一个更新 (2013/12/31)

以下所有测试均使用 Fedora 20(带有 glibc-2.18-11.fc20)和 Matlab 8.3.0.73043(R2014a 预发行版)完成。

有关 TLS 的更多信息,请参阅 Ulrich Drepper,线程本地存储的 ELF 处理,版本 0.21,2013,目前可在AkkadiaRedhat获得。

究竟会发生什么?

MATLAB 动态(使用 dlopen)加载几个需要 tls 初始化的库。所有这些库都需要 dtv(动态线程向量)中的一个插槽。因为 MATLAB 在编译/链接时在运行时动态加载其中几个库,所以链接器(在 mathworks 中)没有机会计算所需的插槽(这是重要的部分)。现在动态库加载器的任务是在运行时处理这种情况。但这并不容易。引用 dl-open.c:

对于静态 TLS,我们必须在此时此地分配内存。这包括在 DTV 中分配内存。但是我们不能改变除我们自己的数字电视以外的任何数字电视。因此,如果我们不能保证 DTV 中有空间,我们甚至不会尝试并导致负载失败。

在 glibc 的动态库加载器中有一个编译时间常数(称为 DTV_SURPLUS,参见 glibc-source/sysdeps/generic/ldsodefs.h),用于为这种混乱保留一些额外的插槽(在多线程中动态加载具有静态 TLS 的库)程序)。在 Fedora 20 的 glibc 版本中,该值为 14。

在我的例子中,这是第一个需要 dtv 插槽的库(运行 MATLAB):

matlabroot/bin/glnxa64/libut.so
/lib64/libstdc++.so.6
/lib64/libpthread.so.0
matlabroot/bin/glnxa64/libunwind.so.8
/lib64/libuuid.so.1
matlabroot/sys/java/jre/glnxa64/jre/lib/amd64/server/libjvm.so
matlabroot/sys/java/jre/glnxa64/jre/lib/amd64/libfontmanager.so
matlabroot/sys/java/jre/glnxa64/jre/lib/amd64/libt2k.so
matlabroot/bin/glnxa64/mkl.so
matlabroot/sys/os/glnxa64/libiomp5.so
/lib64/libasound.so.2
matlabroot/sys/jxbrowser/glnxa64/xulrunner/xulrunner-linux-64/libxul.so
/lib64/libselinux.so.1
/lib64/libpixman-1.so.0
/lib64/libEGL.so.1
/lib64/libGL.so.1
/lib64/libglapi.so.0

是的,超过 14 个 => 太多 => dtv 中没有剩余插槽。这就是错误消息试图告诉我们的内容,尤其是 mathworks。

备案:为了不违反 MATLAB 的许可,我没有调试、反编译或反汇编 MATLAB 随附的二进制文件的任何部分。我只调试了 MATLAB 用来动态加载库的 Fedora 20 的免费和开放的 glibc 二进制文件。

可以做些什么来解决这个问题?

有 3 个选项:

(a) 重建 MATLAB 并且不动态加载这些库(使用 initial-exec tls 模型)而是链接它们(然后链接器可以计算所需的插槽!)

(b) 重建这些库并确保它们没有使用 initial-exec tls 模型。

(c) 重建 glibc 并在 glibc/sysdeps/generic/ldsodefs.h 中增加 DTV_SURPLUS

显然选项 (a) 和 (b) 只能由 mathworks 完成。

对于选项 (c),不需要 MATLAB 的源代码,因此可以在没有 mathworks 的情况下完成。

mathworks 的现状如何?

我真的试图向“MathWorks 技术支持部门”解释这一点。但我的印象是:他们不理解我。他们关闭了我的支持票,并建议在 2014 年 1 月与技术支持经理进行电话(!)对话。

我会尽力解释这一点,但说实话:我不是很自信。

更新 (2014/01/10):目前 mathworks 正在尝试选项 (b)。

更新 (2014/03/19):对于文件 libiomp5.so,您可以在 mathworks 下载新编译的版本(没有静态 TLS),错误报告 961964。和其他库?那里没有改善。所以不要惊讶于“dlopen: cannot load any more object with static TLS”和“doc”,例如参见错误报告 1003952

于 2013-10-19T16:34:35.637 回答
27

重新启动 Matlab 为我解决了这个问题。

于 2014-01-13T13:50:51.403 回答
6

长话短说:在您启动 matlab 的目录中,创建一个包含内容的文件 startup.m ones(10)*ones(10);。重新启动matlab,它将被处理。

于 2014-07-02T18:28:29.440 回答
5

我发现这是 MathWorks 尚未解决的一个古老问题。

这是我的两分钱,对我有用(当我想要 IT++ 外部库时,使用 MEX)。


让您发现导致问题的库为“libXYZ.so”,并且您知道它在系统上的位置。

解决方案是通知 MATLAB 在其启动最早的时候加载特定的库。此错误的原因显然是由于缺少用于此目的的插槽thread local storagetls由于它们已被填满)。

由于最新的编译突然需要一个在其启动期间未加载的新库,因此 MATLAB 会抛出此错误。

可惜 MATLAB 从来没有关心过这么久来解决这个问题。

幸运的是,解决方案是一个非常简单的终端命令。


linux机器上的典型步骤应该如下:

  1. 打开命令提示符(Ctrl+Alt+T在 Ubuntu 中)
  2. 发出以下命令

    导出 LD_PRELOAD=<PATH-TO-libxyz.so>

例如:export LD_PRELOAD=/usr/local/lib/libitpp.so

  1. 从同一个终端启动 matlab

    MATLAB &

现在运行您的程序应该可以解决问题,就像我的情况一样。

祝你好运!


参考:

[1] http://au.mathworks.com/matlabcentral/answers/125117-openmp-mex-files-static-tls-problem

于 2016-04-21T12:05:07.733 回答
4

http://www.mathworks.de/support/bugreports/961964已于 2014 年 1 月 30 日更新。libiomp5 附带了一个 zip 文件,所以我使用 Matlab R2013b 在 Mageia 4 x86_64 上对其进行了测试。我现在可以毫无问题地使用 Matlab 的文档打开演示。

于 2014-02-11T09:27:11.973 回答
3

Matlab 2013b 和 Matlab 2014a 都有同样的问题。mathworks 为 libiomp5.so 提供的修复仅消除了 LAPACK 无法正常工作的问题。但是,我无法使用正在使用 OpenMp 的外部库(例如 VL_FEAT):我仍然收到错误“dlopen:无法使用静态 TLS 加载更多对象”。

唯一对我有用的是降级到 Matlab 2012b。

于 2014-04-24T10:37:58.403 回答
3

我有同样的问题,我想我刚刚解决了它。

安装 matlab 时使用自定义安装(我第一次没有这样做)。选择在预定义文件夹 (/usr/local/bin) 中创建指向 matlab 脚本的符号链接。这对我有用!

于 2013-10-16T19:41:30.947 回答
2

在带有数组的“条形图”(用于条形图)给我一个蓝色块后,我遇到了这个问题,没有抛出任何错误。重启首先解决了问题。但是在内存错误(处理一个非常大的文件之后)之后,我无法解决这个蓝块问题。

在矩阵输入上使用“hist”会给我“BLAS 加载错误”问题,并导致我进入这个线程。Mathwork 解决方法修复了 hist 和 bar 问题。

只是想让人们认识到这个错误的影响程度。

于 2014-05-08T00:51:09.833 回答
0

在 R2013b/Ubuntu 12.04 上增加 Java 堆内存(到 512 mb)也对我有用。“BLAS 加载错误”在我处理 11 GB 文件(具有 16 GB RAM)时开始,并且在增加 java 堆内存并重新启动 matlab 后没有再次出现。

于 2014-05-22T16:06:22.627 回答
0

我遇到了同样的问题,并通过增加我的 Java 堆内存来解决它。转到 Preferences > General > Java-Heap Memory,并增加分配的内存。

于 2013-11-13T21:19:49.370 回答