渐变计算/组合非常慢

问题描述

我正在使用OpenMDAO在Python中实现现有的MATLAB优化代码

openmdao summary中的基本问题结构是:

============== Problem Summary ============
Groups:              14
Components:          70
Max tree depth:       5

Design variables:            7   Total size:      121

Nonlinear Constraints:      12   Total size:      936
    equality:                0                      0
    inequality:             12                    936

Linear Constraints:          0   Total size:        0
    equality:                0                      0
    inequality:              0                      0

Objectives:                  1   Total size:        1

Input variables:           357   Total size:    41451
Output variables:          271   Total size:    31855

Total connections: 357   Total transfer data size: 41451

在顶层,有5-10个组件用于评估约束和目标,其中一个组定义/解析了DOF变量(SplineComp),另一个大组则进行了大量的计算正在完成(包含一组具有两个级别的组,一组具有一个级别的组以及一堆组件)。这基本上与MATLAB代码相同。在MATLAB方面,我正在问题级别上计算解析梯度,但针对该部分的有限差分梯度,将大组调用14次。在Python中,我混合使用了手工计算的渐变和该大型组及其子组内部组件的自动微分工具。

我已经验证了对于一组指定的输入,Python和MATLAB之间的结果匹配,并且check_partials / check_totals在Python中给出了令人满意的结果,现在我对基准测试中的速度比较感到困惑

在MATLAB中,梯度计算所需的时间比独立评估目标/约束的时间要长〜14x ,这在使用有限差分法的情况下是可以预期的。

在Python中,compute_totals比run_model花费的时间〜25-50x 长。这让我感到困惑,因为我期望性能会好得多,因为这里涉及的零差为零。我没想到compute_totals的速度与run_model一样,但是比我预期的慢了一个数量级。

我运行了命令行配置文件(iprof),毫不奇怪的是,大多数时间都花在了solve_linear上,但是使用python profile工具后,它显示dictionary_jacobian中花了将近一半的时间。

我试图研究使用着色功能来缩短计算时间,但似乎并没有找到jacobian的实际稀疏度(报告的〜64%为非零,而实际值为〜6%):

enter image description here

我已经通过clarify_partials的rows / cols选项验证了我所有的自定义组件都在使用稀疏部分定义(某些内置组件不使用会导致这种情况的稀疏定义吗?我在大块内部使用了一些方便起见,我知道黑客马拉松的发现(https://github.com/OpenMDAO/RevHack2020/blob/master/solution_approaches/how_big.md)建议我应该有一个大型组件,而不是多个小型组件,但这在这里很难实现而又不会失去激活所需的大量灵活性该组中的不同功能

解决方法

如果需要灵活性,请保持组件的大小。

Dictionary Jacobian意味着您没有利用DirectSolver的优势,而您需要使用DirectSolver来获得如此大小的模型的真正良好性能。这包括使用组装的雅可比行列式,这对于真正快速的导数也是必需的。

尝试将prob.model.linear_solver = om.DirectSolver()设置为模型顶部的线性求解器,如下所示:

DirectSolver

出于一般性考虑,我不应该这样做:

  • 您只能在序列组上使用DirectSolver(但是该序列组可以是更大的分布式模型的一部分)。
  • 您可以在模型的子组上使用DictionaryJacobian。根据模型结构的不同,此方法可能更快(See section 5.3 of this paper)
  • DirectSolver可与已组装的jacobian配合使用(与有问题的csc相对)。这是杂草丛生的事情,但是在大多数情况下,您需要一个稀疏的组装雅可比树作为直接求解器。有时候,密集的装配会更好。这由system option assembled_jac_type控制,默认为csc(稀疏格式)。您可以尝试进行密集测试,但是<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous"> <link rel="stylesheet" href="/css/style.css"> <title>Hello,world!</title> </head> <body> <header class="header"> <nav class="navbar navbar-expand-lg"> <a class="navbar-brand" href="#">Abdel Pérez</a> <button class="navbar-toggler navbar-dark" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarNav"> <ul class="navbar-nav ml-auto"> <li class="nav-item active"> <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a> </li> <li class="nav-item"> <a class="nav-link" href="#">Features</a> </li> <li class="nav-item"> <a class="nav-link" href="#">Pricing</a> </li> <li class="nav-item"> <a class="nav-link" href="#" tabindex="-1" aria-disabled="true">Disabled</a> </li> </ul> </div> </nav> </header> <section class="site-banner site-banner--dark"> <div class="site-banner__inner anim anim-up anim-fade loaded"> <div class="site-banner__content"> <h1 class="site-banner__title"> My Projects </h1> </div> </div> </section> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script> </body> </html> 很有可能最快。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...