LAPACK 例程线程安全吗?
Are the LAPACK routines thread safe?
我是LAPACK例程的新手,对它们了解不深,想在并行循环(openmp)中使用。
我使用 Ubuntu 14.04LTS 并使用我的包管理器安装了 LAPACK。安装的版本是:
liblapack3 3.5.0-2ubuntu1 Library of linear algebra routines 3 - shared version
关联的 BLAS 库是:
libblas3 1.2.20110419-7
所以,我的第一个问题很简单:我可以在使用 OpenMP 并行化的循环中使用 LAPACK 的任何子例程或函数吗?我想,它们是线程安全的吗?
另一个问题是:我可以在我的纯子程序中使用 LAPACK 的任何子程序或函数吗?,id est,在我编写并定义为纯子程序中。
如果这些问题的答案是"not with all LAPACK procedures but with some of them",那么,我可以用下面的子程序来做吗?:
- dgetrs
- dgetrf
- dgetri
- dgecon
最后一个问题:LAPACK 程序是否使用了我所有的核心?据估计,它们是否已经并行?
LAPACK 库应该是线程安全的。它不支持多线程,因此它不会使用(所有)您的系统核心。实际上有一个特定的声明,所有 LAPACK 子例程都是线程安全的,因为 v3.3.
另一方面,LAPACK 旨在广泛使用 BLAS 库子例程。基本的 BLAS 也不使用任何线程。然而,有几种流行的 BLAS 实现(ATLAS、OpenBLAS、MKL)具有大多数 BLAS 子例程的线程版本。如果您的 LAPACK 库正在使用上述 BLAS 库之一,那么它们的子例程很可能会启动自己的线程。当然,在上面的库中,用户可以控制使用的线程数。您可以查阅他们的文档以找出方法。
因此您需要检查您使用的是哪个 BLAS 库的实现,以便清楚地了解 LAPACK 的线程使用情况。
关于纯函数内部的用法,我想指出 BLAS 和 LAPACK 都会在屏幕上打印特定的错误消息(stdout 或 stderr)。这些消息通常与子例程的错误使用有关,而不是数学错误。例如,如果您尝试反转零维矩阵。如果你能做到这一点,那么你可能可以说它是纯净的。
如果我错了请纠正我,但我认为一般的 LAPACK 子程序不是纯粹的,不仅因为打印出消息而且因为使用 return 将结果存储在输入变量中。也就是说,例如,如果您尝试反转矩阵,则子例程类似于 "inv(A)",其中 A 同时是输入和输出 (intent (inout)) 而不是 "inv(A,B)" 其中A只进,B只出
它们不能是纯的,因为修改了它的输入。
我是LAPACK例程的新手,对它们了解不深,想在并行循环(openmp)中使用。
我使用 Ubuntu 14.04LTS 并使用我的包管理器安装了 LAPACK。安装的版本是:
liblapack3 3.5.0-2ubuntu1 Library of linear algebra routines 3 - shared version
关联的 BLAS 库是:
libblas3 1.2.20110419-7
所以,我的第一个问题很简单:我可以在使用 OpenMP 并行化的循环中使用 LAPACK 的任何子例程或函数吗?我想,它们是线程安全的吗?
另一个问题是:我可以在我的纯子程序中使用 LAPACK 的任何子程序或函数吗?,id est,在我编写并定义为纯子程序中。
如果这些问题的答案是"not with all LAPACK procedures but with some of them",那么,我可以用下面的子程序来做吗?:
- dgetrs
- dgetrf
- dgetri
- dgecon
最后一个问题:LAPACK 程序是否使用了我所有的核心?据估计,它们是否已经并行?
LAPACK 库应该是线程安全的。它不支持多线程,因此它不会使用(所有)您的系统核心。实际上有一个特定的声明,所有 LAPACK 子例程都是线程安全的,因为 v3.3.
另一方面,LAPACK 旨在广泛使用 BLAS 库子例程。基本的 BLAS 也不使用任何线程。然而,有几种流行的 BLAS 实现(ATLAS、OpenBLAS、MKL)具有大多数 BLAS 子例程的线程版本。如果您的 LAPACK 库正在使用上述 BLAS 库之一,那么它们的子例程很可能会启动自己的线程。当然,在上面的库中,用户可以控制使用的线程数。您可以查阅他们的文档以找出方法。
因此您需要检查您使用的是哪个 BLAS 库的实现,以便清楚地了解 LAPACK 的线程使用情况。
关于纯函数内部的用法,我想指出 BLAS 和 LAPACK 都会在屏幕上打印特定的错误消息(stdout 或 stderr)。这些消息通常与子例程的错误使用有关,而不是数学错误。例如,如果您尝试反转零维矩阵。如果你能做到这一点,那么你可能可以说它是纯净的。
如果我错了请纠正我,但我认为一般的 LAPACK 子程序不是纯粹的,不仅因为打印出消息而且因为使用 return 将结果存储在输入变量中。也就是说,例如,如果您尝试反转矩阵,则子例程类似于 "inv(A)",其中 A 同时是输入和输出 (intent (inout)) 而不是 "inv(A,B)" 其中A只进,B只出
它们不能是纯的,因为修改了它的输入。