用于 Julia 的类 PETSc 库

计算科学 有限元 线性代数 宠物 显卡 朱莉娅
2021-12-04 18:12:44

我想在 Julia 中为 Material Point Method(可能还有其他无网格方法)构建一个应用程序,并且我正在寻找可以帮助我解决它的直接和迭代求解器的库。用于此类应用程序的最常用库之一是 PETSc,我知道它与 Julia 绑定。但由于缺乏文档,我也在寻找替代方案。

我发现的一些替代方案包括:Elemental.jl(同样,没有文档)、ArrayFire(似乎特别适用于 GPU 计算)。
另一种选择是使用 CUDA.jl 为 GPU 计算编写相关内核,并使用 PETSc 支持多 CPU,但这意味着该应用程序将不支持其他供应商。老实说,这是我倾向于的堆栈。那么,任何人都可以为 Julia 推荐像 PETSc 这样的库,这些库有足够的文档可以与 GPU 和 CPU 一起使用吗?

1个回答

Julia 的构建方式使您永远看不到完整的类似 PETSc 的库,这是故意的。PETSc 不是一个单一的东西:它是一个 HPC 库,具有一些实用函数、线性求解器、非线性求解器……一整罐在它自己的世界内工作但不在其外的汤。

Julia 的包生态系统建立在泛型和可组合性之上。对于这种情况,最好用一个例子来解释它。CUDA.jl为基于 CUDA 的数组操作提供CuArray类型。如果您x .+ y .* z使用 CuArray,它会使用 .ptx JIT 编译器按(x,y,z) -> x + y * z元素生成函数并通过 CUDA 应用映射。它具有高级操作,因此A*x在 GPU 上,并且A\x在 GPU 上。

但是与 PETSc 相比,CUDA.jl 是不完整的吗?像 GMRES 这样的迭代求解器在哪里?好吧,如果有人为也使用泛型的迭代求解器编写 Julia 库,那么它就是 CUDA.jl 的“最”迭代求解器。例如Krylov.jl有这样的 CG/GMRES/等。实施。对于 ODE 求解器,DifferentialEquations.jl非线性求解器NonlinearSolve.jl等等。泛型都足够好,如果你使用 GPU 数组,包中的所有计算都重新编译到 GPU 上,如果它是分布式的,它不会在没有你要求的情况下进行内存传输等。

所以这将问题改变为以下问题:什么是好的数组类型以及它们可以与什么一起使用?SciML生态系统通常与通用数组类型兼容,因此您可以在那里找到额外的功能(由于劳动力更大、关注点分离等原因,它比 PETSc 做得更多)。所以真正的过剩是数组类型。有很多好的,但对于分布式来说,它不太完整。这是一般摘要:

  • CUDA.jl - 基于 CUDA 的数组。非常好,非常完整,使用 codegen 可以轻松生成新内核,因此它支持大多数操作。以多种方式与多 GPU 配合使用。仅限英伟达 GPU。
  • ROCArrays.jl - 类似于 CUDA.jl,但基于 ROC 的支持(AMD GPU)。不如 CUDA.jl 完整,往往会遗漏更多的线性代数,但相当可用。
  • ArrayFire.jl - 基于 ArrayFire 的“通用 GPU”。与其他两个相比,它会损失性能,因为它不包括用于融合 GPU 调用的内核生成,但它仍然是一个不错的选择。比其他两个用得少得多。
  • DistributedArrays.jl - 用于分布式 HPC 的东西,但它很慢并且缺少很多线性代数。对于大多数线性代数运算,它将依赖 Elemental.jl。
  • MPIArrays.jl - 基于 MPI 的数组类型的一个很好的原型,遗憾的是它不再维护太多。
  • PETSc.jl - 正在处理一个包装器,主要是为了让数组类型Mat足够完整,以完成我提到的通用包用法。

如您所见,分布式数组类型需要做更多的工作,但这正是您要寻找的。不一定是类似 PETSc 的东西,而只是提供了一个可靠的分布式阵列以与下游功能一起使用。