通用线性代数包装库

计算科学 线性代数 参考请求 C++
2021-11-30 20:02:25

我目前正在考虑采用我目前使用的代码并从头开始重建它以允许使用更有效的编程和数值技术的想法。

在设计的早期阶段,我决定为矩阵和向量编写一个包装类。这将允许我(希望)换掉 lin。算法。库和求解器,而无需实际接触代码。我会简单地编写一个具有 BLAS 功能的虚函数的类以及一些内部化初始化的方法(允许主代码不必担心并行初始化)。然后,当我想让我的代码与一个新库一起工作时,我只需编写一个新的矩阵类,它使用高效的库函数实现所有这些函数。

我将使用有限体积的代码,因此我将使用具有已知块内存布局的稀疏矩阵。我也在研究大约一百万个未知数,尽管我希望这无关紧要(只要有足够的内存可用)。矩阵包装器还将从配置文件中获取指令以了解要使用的库、内存布局和求解器,因此它不必自己进行任何优化。它只会检查是否安装了请求的库。

对我来说,这似乎是一个相当直接的概念,即使实施并不容易。因此,我的问题分为几个部分。

首先,这之前有没有尝试过/实施过,如果有,在哪里?我宁愿能够抓住一个从零开始的开源库。任何参考或论文将不胜感激。

其次,如果我实施这种系统,我应该期待什么样的问题?我已经可以预见,让它与多个内存模型(共享内存、GPU 或分布式内存)透明地工作会很困难,但我不知道在设计一个相当通用的线性代数接口时要注意哪些其他陷阱。

2个回答

deal.II 为我们自己的线性代数实现、PETSc 和 Trilinos 提供了这样的包装器。因为每个库都提供略有不同的抽象,所以要完成所有这些工作需要做很多工作。就性能而言,deal.II 不使用虚函数,因为调用虚函数来读取矩阵或向量的单个元素的开销可能是不可忽略的。

我的建议是不要走这条路。这简直是​​太多的工作。相反,我的建议是仔细选择要使用的库,然后坚持使用。我不知道你打算用你的代码做什么,但很可能你会想要产生结果,而不是永远花在实现接口上。我之所以这么说是因为在两大巨头(PETSc 和 Trilinos)中,通过使事物通用化并没有太多好处——它们都非常好,而且性能差异远小于通过更改所能获得的差异你的算法。在我看来,你只能通过花费大量时间使一切通用化而失败。

编辑:这个答案的大部分都处理了密集矩阵,我对稀疏矩阵进行了更多的编辑,这更难。据我所知,稀疏性的很多问题是像使用密集矩阵一样利用缓存和内存布局。稀疏矩阵条目的存储和检索更加不规则。

我认为有几个例子。有 Matlab 及其所有开源等效项(正如 HighPerformanceMark 提到的),而 Eigen 是您可能会查看的另一个库。我知道Trilinos也有一些这样的例子——Epetra 为迭代和直接求解器采用抽象的稀疏矩阵。它们通过让您指定每行的估计非零数来处理内存中的存储/检索问题。

关于多种内存模型的想法 - 大多数架构似乎都有 BLAS/LAPACK(Eigen、LAPACK/BLAS 用于串行、ViennaCL、CuBLAS、MAGMA 等用于 GPU 和 OpenMP、Trilinos 分布式等)。可能(虽然很棘手?)编写一个矩阵类/求解器,根据您的架构调用不同的包。