MPI - масштабирование для параллельных драйверов DOEDriver
Были ли параллельные драйверы протестированы с точки зрения масштабирования любым разработчиком / пользователем? Каково ожидаемое масштабирование для них?
У меня есть установка с openmpi и я использовал параллельный пример DOEDriver из руководства, но с UniformGenerator.
Испытано в 2,4,8,16 ядрах. Производительность масштабирования довольно плохая. Это из-за узкого места, о котором я не знаю в этом примере.
У вас есть лучший пример предложения по тестированию масштабирования?
1 ответ
Ваш вопрос немного расплывчатый, потому что вы не дали нам никакой конкретной информации о том, как вы справляетесь с примерами проблем. Я предполагаю, что вы только что изменили базовый пример. Если предположить, что вы пытаетесь запустить множество случаев модели Paraboloid, основываясь на этом конкретном примере, то проблема, с которой вы сталкиваетесь при масштабировании, вероятно, связана с тем, что модель Paraboloid не имеет значительных вычислительных затрат, чтобы сделать параллелизацию стоящей,
Каждый раз, когда вы переходите от любого алгоритма или кода от последовательного к параллельному, вы всегда подвергаетесь некоторому количеству новых издержек. Так как 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)
В итоге: ваши модели / компоненты должны быть достаточно дорогими, чтобы сделать распараллеливание стоящим. Если вы используете обернутые в файл компоненты, вам нужно быть особенно осторожным, потому что весь файловый ввод-вывод станет огромным препятствием для параллельного выполнения.