правильный способ определения компонентов для параллельной обработки - PullRequest
0 голосов
/ 05 июня 2019

Я столкнулся с проблемой аэродинамической MDO в OpenMDAO.Задача состоит из 4 связанных дисциплин, представленных явными компонентами и без ограничений.Недавно я добавил параллельную обработку для ускорения кода.В настоящее время, как я определил свои компоненты, я не могу добиться улучшения производительности, когда я вызываю код с помощью mpirun.Вместо этого общее время выполнения увеличивается.У меня есть ощущение, что это может быть из-за того, как я определил явные компоненты для моих дисциплин.Я приложил сценарий, который я называю, а также код для одной из дисциплин.В текущей конфигурации нет четко определенных производных или ограничений, поэтому я думаю, что дисциплины могут быть виновником.Или, может быть, я использовал сочетание заявлений о продвижении и соединении, как показано ниже?Любые предложения приветствуются.

Это сценарий проблемы.

prob = Problem()

model = prob.model  # = SsbjIdf2Mda(nx, ny, y12_initial, y23_initial, y32_initial, y21_initial, y31_initial)

parallel = model.add_subsystem('parallel', ParallelGroup())

model.add_subsystem('z_ini', IndepVarComp('z', .5 * np.ones(nx)))
model.add_subsystem('x1_ini', IndepVarComp('x1', .5 * np.ones(nx)))
model.add_subsystem('x2_ini', IndepVarComp('x2', .5 * np.ones(nx)))
model.add_subsystem('x3_ini', IndepVarComp('x3', .5 * np.ones(nx)))

model.add_subsystem('y31_ini', IndepVarComp('y31', .5 * np.ones(ny)))
model.add_subsystem('y12_ini', IndepVarComp('y12', .5 * np.ones(ny)))
model.add_subsystem('y32_ini', IndepVarComp('y32', .5 * np.ones(ny)))
model.add_subsystem('y23_ini', IndepVarComp('y23', .5 * np.ones(ny)))
model.add_subsystem('y21_ini', IndepVarComp('y21', .5 * np.ones(ny)))

parallel.add_subsystem('Structure', StructureDisc())
parallel.add_subsystem('Aerodynamics', AerodynamicsDisc())
parallel.add_subsystem('Propulsion', PropulsionDisc())
model.add_subsystem('Performance', PerformanceDisc())

# Shared variables z
model.connect('z_ini.z', 'parallel.Structure.z')
model.connect('z_ini.z', 'parallel.Aerodynamics.z')
model.connect('z_ini.z', 'parallel.Propulsion.z')
model.connect('z_ini.z', 'Performance.z')

# Local variables
model.connect('x1_ini.x1', 'parallel.Structure.x1')
model.connect('x2_ini.x2', 'parallel.Aerodynamics.x2')
model.connect('x3_ini.x3', 'parallel.Propulsion.x3')
model.connect('x1_ini.x1', 'Performance.x1')
model.connect('x2_ini.x2', 'Performance.x2')
model.connect('x3_ini.x3', 'Performance.x3')

# Coupling variables
model.connect('y21_ini.y21', 'parallel.Structure.y21')
model.connect('y31_ini.y31', 'parallel.Structure.y31')
model.connect('y32_ini.y32', 'parallel.Aerodynamics.y32')
model.connect('y12_ini.y12', 'parallel.Aerodynamics.y12')
model.connect('y23_ini.y23', 'parallel.Propulsion.y23')

model.add_subsystem('Obj', ExecComp('obj=range'), promotes=['obj'])

# Connections
model.connect('Performance.range', 'Obj.range')
model.connect('parallel.Aerodynamics.y21',  'Performance.y21')
model.connect('parallel.Propulsion.y31',    'Performance.y31')
model.connect('parallel.Propulsion.y32',    'Performance.y32')
model.connect('parallel.Structure.y12',     'Performance.y12')
model.connect('parallel.Aerodynamics.y23',  'Performance.y23')

# create the MDA
# Design variables
model.add_design_var('z_ini.z', lower=np.zeros(nx),   
upper=np.ones(nx))  # shared variables
model.add_design_var('x1_ini.x1', lower=np.zeros(nx), 
upper=np.ones(nx))  # local variable for structural discipline
model.add_design_var('x2_ini.x2', lower=np.zeros(nx), 
upper=np.ones(nx))  # local variable for aerodyn. discipline
model.add_design_var('x3_ini.x3', lower=np.zeros(nx), 
upper=np.ones(nx))  # local variable for propulsion discipline

# # coupling variables
model.add_design_var('y31_ini.y31', lower=np.zeros(ny), 
upper=np.ones(ny))
model.add_design_var('y12_ini.y12', lower=np.zeros(ny), 
upper=np.ones(ny))
model.add_design_var('y32_ini.y32', lower=np.zeros(ny), 
upper=np.ones(ny))
model.add_design_var('y23_ini.y23', lower=np.zeros(ny), 
upper=np.ones(ny))
model.add_design_var('y21_ini.y21', lower=np.zeros(ny), 
upper=np.ones(ny))

# Objective function
model.add_objective('obj')
prob.driver = ScipyOptimizeDriver()
prob.set_solver_print(2)
prob.driver.options['optimizer'] = 'SLSQP'
for tol in [1e-3]:
    prob.driver.options['maxiter'] = 50 # random.randint(40, 50)
    prob.driver.options['tol'] = tol
    prob.driver.add_recorder(SqliteRecorder("cases_idf.sql"))
    # Run optimization
    start_time = time.time()
    prob.setup(mode='fwd')

    # view_model(prob, outfile='n2_mdfgs.html', show_browser=True)
    prob.run_driver()
    prob.run_model()
    # prob.check_partials()
    prob.cleanup()
    end_time = time.time()
    total_time = end_time - start_time
    print("total_time:", total_time, "seconds")

Ниже приводится описание каждой из 4 дисциплин.

class StructureDisc(ExplicitComponent):

def __init__(self):
    super(StructureDisc, self).__init__()
    with open("input_values.p", "rb") as f:
        a = pickle.load(f)
    self.nx = a[0]
    self.ny = a[1]

@staticmethod
def structure():
    structure = Structure()
    return structure

def setup(self):
    # Global Design Variable z
    self.add_input('z', val=np.ones(self.nx) * 0.5)
    # Local Design Variable
    self.add_input('x1', val=np.ones(self.nx) * 0.5)
    # Coupling parameters
    self.add_input('y21', val=np.ones(self.ny) * 0.5)
    self.add_input('y31', val=np.ones(self.ny) * 0.5)
    # Coupling output
    self.add_output('y12', val=np.ones(self.ny) * 0.5)
    self.add_output('y14', val=np.ones(self.ny) * 0.5)
    self.add_output('g1', val=np.ones(self.nx) * 0.5)
    self.declare_partials('*', '*', method='fd')

def compute(self, inputs, outputs):
    t1 = np.concatenate((inputs['x1'], inputs['y21'], inputs['y31'], np.ones(self.nx + 2 * self.ny),
                         np.ones(self.nx + self.ny), inputs['z']))
    x_des = t1
    output_list = ['y12', 'y14', 'g1']
    for i in output_list:
        outputs[i] = np.concatenate(getattr(self.structure(), i)(self.nx, self.ny, x_des), axis=0)
...