MPI - 并行驱动程序 DOEDriver 的缩放
MPI - Scaling for parallel drivers DOEDriver
并行驱动程序是否经过任何 developer/user 的扩展测试?这些的预期缩放比例是多少?
我使用 openmpi 进行了设置,并使用了 DOEDriver 的并行样本 from the manual 但使用了 UniformGenerator。
在 2、4、8、16 核中测试。缩放性能非常糟糕。这是由于
我在这个例子中没有意识到的瓶颈。
你有更好的测试缩放示例建议吗?
你的问题有点含糊,因为你没有给我们任何关于你如何运行解决示例问题的细节。尽管您刚刚修改了基本示例,但我会猜测。假设您正在尝试 运行 很多 Paraboloid model, based on this specific example 的情况,那么您看到的缩放问题很可能是由于抛物面模型没有显着的计算成本来进行并行化值得。
任何时候您将任何算法或代码从串行移动到并行,您总是会产生一些新的开销。由于 OpenMDAO 使用基于 MPI 的并行性,现在需要进行 MPI 通信开销和额外的框架级别设置。此外,如果您保留该示例问题的默认设置,则会有一个连接到驱动程序的记录器。当您并行 运行 一个 DOE 时,您会得到 n 个不同的记录器文件(一个用于您正在使用的每个过程)。因此,将结果写入每个文件都需要时间,除非您有并行文件系统,否则系统会在等待写入磁盘的能力时增加瓶颈。
所以真的,你需要小心并行化,但这里有一个简单的脚本来表明,如果你使组件计算更昂贵,那么你将获得更好的缩放。这不是一个严格的缩放示例,并且 sleep
函数的使用有点作弊,因为没有完成任何实际工作。但它得到了一般观点。
import time
from openmdao.api import Problem, IndepVarComp, ExplicitComponent
from openmdao.api import DOEDriver, FullFactorialGenerator
from openmdao.api import SqliteRecorder, CaseReader
class Paraboloid(ExplicitComponent):
"""
Evaluates the equation f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3.
"""
def setup(self):
self.add_input('x', val=0.0)
self.add_input('y', val=0.0)
self.add_output('f_xy', val=0.0)
# Finite difference all partials.
self.declare_partials('*', '*', method='fd')
def compute(self, inputs, outputs):
"""
f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3
Minimum at: x = 6.6667; y = -7.3333
"""
x = inputs['x']
y = inputs['y']
outputs['f_xy'] = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0
time.sleep(1)
prob = Problem()
model = prob.model
model.add_subsystem('p1', IndepVarComp('x', 0.0), promotes=['x'])
model.add_subsystem('p2', IndepVarComp('y', 0.0), promotes=['y'])
model.add_subsystem('comp', Paraboloid(), promotes=['x', 'y', 'f_xy'])
model.add_design_var('x', lower=0.0, upper=1.0)
model.add_design_var('y', lower=0.0, upper=1.0)
model.add_objective('f_xy')
prob.driver = DOEDriver(FullFactorialGenerator(levels=3))
prob.driver.options['run_parallel'] = True
prob.driver.options['procs_per_model'] = 1
prob.driver.options['debug_print'] = ['desvars', 'objs']
prob.driver.add_recorder(SqliteRecorder("cases.sql"))
prob.setup()
st = time.time()
prob.run_driver()
print('time', time.time() - st)
总结:
您需要 models/components 足够昂贵才能使并行化变得有价值。如果您使用的是文件包装组件,则需要格外小心,因为所有 file-i/o 将成为并行执行的巨大瓶颈。
并行驱动程序是否经过任何 developer/user 的扩展测试?这些的预期缩放比例是多少?
我使用 openmpi 进行了设置,并使用了 DOEDriver 的并行样本 from the manual 但使用了 UniformGenerator。
在 2、4、8、16 核中测试。缩放性能非常糟糕。这是由于 我在这个例子中没有意识到的瓶颈。
你有更好的测试缩放示例建议吗?
你的问题有点含糊,因为你没有给我们任何关于你如何运行解决示例问题的细节。尽管您刚刚修改了基本示例,但我会猜测。假设您正在尝试 运行 很多 Paraboloid model, based on this specific example 的情况,那么您看到的缩放问题很可能是由于抛物面模型没有显着的计算成本来进行并行化值得。
任何时候您将任何算法或代码从串行移动到并行,您总是会产生一些新的开销。由于 OpenMDAO 使用基于 MPI 的并行性,现在需要进行 MPI 通信开销和额外的框架级别设置。此外,如果您保留该示例问题的默认设置,则会有一个连接到驱动程序的记录器。当您并行 运行 一个 DOE 时,您会得到 n 个不同的记录器文件(一个用于您正在使用的每个过程)。因此,将结果写入每个文件都需要时间,除非您有并行文件系统,否则系统会在等待写入磁盘的能力时增加瓶颈。
所以真的,你需要小心并行化,但这里有一个简单的脚本来表明,如果你使组件计算更昂贵,那么你将获得更好的缩放。这不是一个严格的缩放示例,并且 sleep
函数的使用有点作弊,因为没有完成任何实际工作。但它得到了一般观点。
import time
from openmdao.api import Problem, IndepVarComp, ExplicitComponent
from openmdao.api import DOEDriver, FullFactorialGenerator
from openmdao.api import SqliteRecorder, CaseReader
class Paraboloid(ExplicitComponent):
"""
Evaluates the equation f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3.
"""
def setup(self):
self.add_input('x', val=0.0)
self.add_input('y', val=0.0)
self.add_output('f_xy', val=0.0)
# Finite difference all partials.
self.declare_partials('*', '*', method='fd')
def compute(self, inputs, outputs):
"""
f(x,y) = (x-3)^2 + xy + (y+4)^2 - 3
Minimum at: x = 6.6667; y = -7.3333
"""
x = inputs['x']
y = inputs['y']
outputs['f_xy'] = (x-3.0)**2 + x*y + (y+4.0)**2 - 3.0
time.sleep(1)
prob = Problem()
model = prob.model
model.add_subsystem('p1', IndepVarComp('x', 0.0), promotes=['x'])
model.add_subsystem('p2', IndepVarComp('y', 0.0), promotes=['y'])
model.add_subsystem('comp', Paraboloid(), promotes=['x', 'y', 'f_xy'])
model.add_design_var('x', lower=0.0, upper=1.0)
model.add_design_var('y', lower=0.0, upper=1.0)
model.add_objective('f_xy')
prob.driver = DOEDriver(FullFactorialGenerator(levels=3))
prob.driver.options['run_parallel'] = True
prob.driver.options['procs_per_model'] = 1
prob.driver.options['debug_print'] = ['desvars', 'objs']
prob.driver.add_recorder(SqliteRecorder("cases.sql"))
prob.setup()
st = time.time()
prob.run_driver()
print('time', time.time() - st)
总结: 您需要 models/components 足够昂贵才能使并行化变得有价值。如果您使用的是文件包装组件,则需要格外小心,因为所有 file-i/o 将成为并行执行的巨大瓶颈。