是否有像 IPOPT 这样在 GPU 上运行的受限非线性优化库?

计算科学 非线性规划 显卡
2021-12-05 07:07:58

我团队中的某个人想要并行化 IPOPT。(至少它的一些功能)。我一直无法找到它的 GPU 实现或类似的包。我也没有在他们的文档上找到任何东西。

所以问题是,是否已经在 GPU 上实现了替代方案?或者至少有人致力于将它移植到 GPU 上以便我们可以一起工作?

3个回答

tl; dr:我对文献的总体印象是加速是适度的(如果存在的话)。您将在这些方法中看到的主要内核是稀疏直接方法(例如,稀疏 LU、稀疏 LDLT),并且内存访问是不规则的;这些特性不利于使用 GPU。此外,并行 IPM 还处于起步阶段。我仍然怀疑人们会致力于 GPU 实现,但我很怀疑他们是否会出现。(然而,分布式内存 IPM 似乎更有希望和有用。)


一些人研究过用于 GPU 的内点方法 (IPM):

  • Smith、Gondzio 和 Hall开发了一种用于线性程序 (LP) 的 IPM,实现了 4-10 倍的加速
  • Jung 和 O'Leary研究了用于 LP 的 IPM 中的一些线性代数内核,并看到 GPU 在其测试集中的较大问题上的适度加速

一般来说,这些论文没有将他们的工作与高度调整的 LP 求解器进行比较。Jung 和 O'Leary 将 linprog 与大多数从业者的选择相比较,而我通过浏览 Smith 等人的论文得到的印象是,串行内点法是从头开始编写的。鉴于 Hall 对开源 LP 求解器的参与度很高,因此我对这项工作的重视程度更高。最好的开源 LP 求解器之一是 Hall 维护的 Clp,如果他们使用了该代码,则会按名称提及。因此,如果这些代码正在加速已经高度调整的求解器,而不是不是最先进的一次性串行比较,我会更加关注。

也就是说,现有的工作是针对 LP 的,您可能需要非线性规划 (NLP) 求解器,因为这就是 IPOPT。以下是我对 NLP 求解器案例的了解:

  • 并行化 IPM 通常具有挑战性(对于 LP 和 SOCP 案例,请参阅Elemental;对于一般 IPM,您会使用 SOCP 版本(或 QP 版本)之类的东西
  • 如果您的 NLP 没有明显的结构(例如,不是随机程序,没有明显的边界块角结构,不是 PDE 约束的优化问题,其中 PDE 的预处理器是众所周知的) ,最好的线性代数方法涉及具有不规则内存访问的稀疏直接方法(例如,LU、LDLT),这些访问通常不适合 GPU 架构(如前所述)
  • 如果你的 NLP 确实有明显的结构,你会想要使用不需要惯性显示分解的无惯性线搜索算法(基于Chiang 和 Zavala 最近的工作),所以你可以使用已知的预处理器来帮助求解 Karush-Kuhn-Tucker 系统
  • 我所知道的最好的并行矩阵内点方法是 Gondzio(实现论文, 理论论文)和 Waechter 等人的方法。大规模内点概述论文论文更详细地介绍了大规模内点方法的实现);Petra、Zavala 等人还提出了利用结构的算法(结构化非凸优化论文内点方法的 Schur 补充论文)。

大多数研究似乎都在研究分布式内存案例的并行性(这已经够难了)。对于 LP 和 QP 求解器的共享内存案例有一些工作,因为这些工作使其成为商业代码(例如,Gurobi、CPLEX、Xpress)。现有的工作很有趣,但是对于 GPU 来说似乎还没有什么引人注目的东西,除了特殊应用(例如,机器学习,您可以使用更适合 GPU 的不同算法)。

通常非线性优化很难并行化,因为它的步进算法是非常连续的。GPU 比 CPU 慢,因此只有当您遇到高度并行的问题(即数千个线程)时,您才能获得加速。因此,通过将非线性求解器放在 GPU 上,我不会期望有太多的加速(或任何加速,通常可能会更慢)。这很可能是为什么没有人做得很好,大多数人也不会尝试的原因。

另一方面,如果您的目标和约束函数可以以高度并行(或矢量化)的方式计算,您可以通过在 GPU 上求解目标/约束函数来获得巨大的加速。这是使用具有非线性优化的 GPU 的常用方法,因为它在代码的最难(和最并行)部分使用 GPU 加速,因此可能是最有效的。

我参加聚会有点晚了,但简短的回答是,可以并行化 GPU 的内点方法,但这是否成功取决于问题的结构。就现有软件而言,Optizelle可以做到。抓住开发分支,直到在不久的将来发布新版本。

根据原始问题是否包含等式或不等式,情况略有不同。有多种方法可以做到这一点,但在我看来,对于只有不等式约束的问题,最好的方法是使用不精确的信任域方法牛顿法与原始对偶内点法相结合。

仅对于不等式,基本的不精确信任域 Newton 方法可以在 Nocedal 和 Wright 的数值优化(第 171 页)或 Conn、Gould 和 Toint 的信任域方法(第 205 页)中找到。该算法可以成功地与原始-对偶内点法,主要使用 Byrd、Hribar 和 Nocedal 的论文 An Internal Point Method for Large-Scale Nonlinear Programming 的第 890 页中改进的截断 CG 方法。就个人而言,我不喜欢他们如何设置内点系统,所以我不会使用他们的内点公式,但这是偏好。NITRO 是一个很好的算法。至于内点细节,Optizelle的手册在其手册中解释了如何做到这一点。我可能应该发布更新的手册,

对于同时具有不等式和等式约束的情况,我认为最好的算法是在题为 A Matrix-Free Trust-Region SQP Method for Equality Constrained Optimization 的论文中结合 Heinkenschoss 和 Ridzal 的不精确信任域复合步 SQP 方法。基本上,附加内点法的过程与无约束情况几乎相同,只是还需要保护准正规步骤。

就并行化机会而言,我上面引用的算法运行良好,因为这些算法可以无矩阵地实现。具体来说,Optizelle针对该问题的实现

minxX{f(x):g(x)=0,h(x)0}

要求用户提供实现

  • f(x),f(x),2f(x)x

  • g(x),g(x)x,g(x)y,(g(x)x)y

  • h(x),h(x)x,h(x)y,(h(x)x)y

它不关心这些实现来自哪里或它们是如何并行化的。它们可以在共享内存、分布式内存或 GPU 中完成。没关系。什么对特定问题最有效,取决于结构。此外,它要求用户提供线性代数

  • init: Memory allocation and size setting
  • copy: y <- x (Shallow. No memory allocation.)
  • scal: x <- alpha * x
  • axpy: y <- alpha * x + y
  • innr: innr <- <x,y>
  • zero: x <- 0
  • rand: x <- random
  • prod: Jordan product, z <- x o y
  • id: Identity element, x <- e such that x o e = x
  • linv: Jordan product inverse, z <- inv(L(x)) y where L(x) y = x o y
  • barr: Barrier function, barr <- barr(x) where x o grad barr(x) = e
  • srch: Line search, srch <- argmax {alpha \in Real >= 0 : alpha x + y >= 0} where y > 0
  • symm: Symmetrization, x <- symm(x) such that L(symm(x)) is a symmetric operator

这些操作可以在串行、并行、分布式内存、共享内存或 GPU 上完成。没关系。什么是最好的取决于问题结构。

最后是线性系统,可以提供三个:

  • 的预条件子2f(x)
  • 的左预条件子g(x)g(x)
  • 的右预条件子g(x)g(x)

这些预处理器中的每一个都可以在串行或并行、分布式内存或共享内存或 GPU 上实现。基本上,第一个预处理器是与最优性系统相关的截断 CG 系统的预处理器。最后两个预处理器用于与复合步骤 SQP 算法相关的增强系统求解。一般来说,这是您将获得最大性能提升的地方。想象一下,如果约束代表某种 PDE。然后,的预条件子对应于前向 PDE 求解,然后是伴随 PDE 求解。注意,如果它们是正方形的,gg(x)g(x)(g(x)g(x))1=g(x)g(x)1. 对于大量 PDE 公式,例如具有显式时间积分器的有限差分方法,这些求解可以在 GPU 上很好地并行化。

最后,Optizelle中的算法确实适用于对称锥问题,包括有界、二阶锥和半定约束。然而,一般来说,线性锥体求解往往会胜过它。基本上,线性锥体求解可以降低对一个真正紧凑的系统进行的可行性和最优求解,该系统可以被 Choleski 因子分解。由于Optizelle与非线性系统一起工作,它不能真正做到这一点。至少,我不知道怎么做。最重要的是,Optizelle可以处理的 SDP 块的大小受到限制。运营商linv上面需要 SDP 矩阵的逆矩阵,而逆矩阵对于大块来说确实很昂贵。此外,还有一个需要 Choleski 因式分解的额外安全防护。这些因式分解在 GPU 上并不能很好地并行化。至少,我不知道可以很好地并行化的实现。无论如何,最重要的是,如果它是一个线性圆锥程序,请使用像 CSDP 或 SDPT3 这样的线性圆锥求解器。

TLDR;使用Optizelle它是免费的、开源的和 BSD 许可的。我已经将它缩放到大约十亿个变量,并且效果很好。我已经用 GPU 运行它并且运行良好。它是否适用GPU 取决于上述操作在 GPU 上是否能够很好地并行化。