2016-08-24 1 views
0

Ich verwende NRELs DAKOTA_driver openmdao Plugin für parallelisierte Monte Carlo Sampling eines Modells. In 0.X war ich in der Lage, Assemblys zu verschachteln, sodass ein externer Optimierungstreiber die DAKOTA_driver-Sampling-Evaluierungen steuern konnte. Ist es möglich, dass ich dieses Setup in einem äußeren Optimierer verschachteln kann? Ich möchte, dass der Workflow des äußeren Optimierers die DAKOTA_driver-Assembly und dann die get_dakota_output-Komponente aufruft.nesting openmdao "Assemblys"/Treiber - Arbeiten von einer 0,13 Analogie, ist dies in 1.X zu implementieren?

import pandas as pd 
import subprocess 
from subprocess import call 
import os 
import numpy as np 
from dakota_driver.driver import pydakdriver 
from openmdao.api import IndepVarComp, Component, Problem, Group 

from mpi4py import MPI 
import sys 
from itertools import takewhile 
sigm = .005 
n_samps = 20 
X_bar=[0.065 , sigm] #2.505463e+03*.05] 
dacout = 'dak.sout' 


class get_dak_output(Component): 
    mean_coe = 0 

    def execute(self): 
     comm = MPI.COMM_WORLD 
     rank = comm.Get_rank() 
     nam ='ape.net_aep' 
     csize = 10000 
     with open(dacout) as f: 
      for i,l in enumerate(f): 
       pass 
     numlines = i 
     dakchunks = pd.read_csv(dacout, skiprows=0, chunksize = csize, sep='there_are_no_seperators') 
     linespassed = 0 
     vals = [] 
     for dchunk in dakchunks: 
      for line in dchunk.values: 
       linespassed += 1 
       if linespassed < 49 or linespassed > numlines - 50: continue 
       else: 
        split_line = ''.join(str(s) for s in line).split() 
       if len(split_line)==2: 
        if (len(split_line) != 2 or 
         split_line[0] in ('nan', '-nan') or 
         split_line[1] != nam): 
          continue 
        else:vals.append(float(split_line[0])) 
     self.coe_vals = sorted(vals) 
     self.mean_coe = np.mean(self.coe_vals) 


class ape(Component): 
    def __init__(self): 
     super(ape, self).__init__() 
     self.add_param('x', val=0.0) 
     self.add_output('net_aep', val=0.0) 

    def solve_nonlinear(self, params, unknowns, resids): 
     print 'hello' 
     x = params['x'] 
     comm = MPI.COMM_WORLD 
     rank = comm.Get_rank() 
     outp = subprocess.check_output("python test/exampleCall.py %f"%(float(x)), 
     shell=True) 

     unknowns['net_aep'] = float(outp.split()[-1]) 


top = Problem() 

root = top.root = Group() 

root.add('ape', ape()) 
root.add('p1', IndepVarComp('x', 13.0)) 
root.connect('p1.x', 'ape.x') 

drives = pydakdriver(name = 'top.driver') 
drives.UQ('sampling', use_seed=False) 
#drives.UQ() 
top.driver = drives 
#top.driver = ScipyOptimizer() 
#top.driver.options['optimizer'] = 'SLSQP' 

top.driver.add_special_distribution('p1.x','normal', mean=0.065, std_dev=0.01, lower_bounds=-50, upper_bounds=50) 
top.driver.samples = n_samps 
top.driver.stdout = dacout 
#top.driver.add_desvar('p2.y', lower=-50, upper=50) 
#top.driver.add_objective('ape.f_xy') 
top.driver.add_objective('ape.net_aep') 

top.setup() 


top.run() 
bak = get_dak_output() 
bak.execute() 

print('\n') 
print('E(aep) is %f'%bak.mean_coe) 
+1

Ihr Code-Beispiel ist ein wenig seltsam. Es enthält sowohl eine openmdao 1.x als auch eine openmdao 0.x Komponente. Ist das absichtlich? –

+0

Dies läuft in openmdao 1.X ... Nein, es war nicht beabsichtigt - ich bin gespannt, welchen Teil des Codes Sie referenzieren. Ich konvertiere von 0.X. Ich habe die Frage bearbeitet, um den kommentierten 0.X-Code zu entfernen. – kilojoules

Antwort

1

Es gibt zwei verschiedene Möglichkeiten für diese Situation. Beide werden parallel arbeiten, und beide können derzeit unterstützt werden. Aber nur einer von ihnen funktioniert, wenn Sie analytische Derivate verwenden möchten:

1) Verschachtelte Probleme: Sie erstellen eine Problemklasse, die einen DOE-Treiber enthält. Sie übergeben die Liste der Fälle, die in diesem Treiber ausgeführt werden sollen, und es führt sie parallel aus. Dann fügen Sie dieses Problem als Komponente in ein Elternproblem ein.

Das Elternproblem weiß nicht, dass es ein Unterproblem hat. Es denkt nur, dass es eine einzelne Komponente gibt, die mehrere Prozessoren verwendet.

Dies ist der ähnlichste Weg, wie Sie es in 0.x getan hätten. Allerdings empfehle ich diesen Weg nicht, weil es nicht funktioniert, wenn Sie immer analytische Derivate verwenden möchten.

Wenn Sie auf diese Weise arbeiten, kann der Dakota-Treiber so bleiben, wie er ist. Aber Sie müssen eine spezielle Unterproblemklasse verwenden. Dies ist noch kein offiziell unterstütztes Feature, aber es ist sehr machbar.

2) Mit einem Mehrpunktansatz erstellen Sie eine Gruppenklasse, die Ihr Modell darstellt. Sie würden dann eine Instanz dieser Gruppe für jeden Monte-Carlo-Lauf erstellen, den Sie ausführen möchten. Sie fügen alle diese Instanzen in eine parallele Gruppe innerhalb Ihres Gesamtproblems ein.

Dieser Ansatz vermeidet die Unterproblematik. Es ist auch viel effizienter für die tatsächliche Ausführung. Es wird eine etwas höhere Setup-Kosten als die erste Methode haben. Aber meiner Meinung nach lohnt es sich, die einmaligen Setup-Kosten zu nutzen, um den Vorteil analytischer Derivate zu bekommen. Das einzige Problem ist, dass es wahrscheinlich einige Änderungen an der Funktionsweise von dakota_driver erfordern würde. Sie möchten eine Liste der Bewertungen vom Fahrer erhalten und diese dann an die einzelnen Kindergruppen verteilen.

+0

Leicht tangentiale Frage: Können die DOE-Treiber von OpenMDAO die Antworten zusammenfassen? Im DOE-Tutorial erwartete ich, dass eine Liste von Antworten (und möglicherweise die zugehörigen Gradienteninformationen) zugänglich werden. https://openmdao.readthedocs.io/en/latest/usr-guide/tutorials/doe-drivers.html – kilojoules

+0

Das wäre nicht schwierig zu implementieren, würde aber einige Änderungen am Treiber erfordern. Vor allem, wenn Sie auch Gradienteninformationen wollten. Derzeit berechnet der DOE-Treiber die Derivate nicht so wie sie sind. In der Regel wäre dies sehr ineffizient, da Sie bei einem Funktionsaufruf nicht immer Derivate benötigen. Zeilensuchen oder Vertrauensbereichsmethoden werden oft ausgewertet, ohne dass Derivate benötigt werden. –

+0

Das macht Sinn. Es wäre interessant, einen "robusten Optimierungs" -Treiber zu erforschen. – kilojoules

Verwandte Themen