いわて駐在研究日誌

OpenCAE、電子工作、R/C等、徒然なるままに

平成28年度開始しました。

年度初めのドタバタを終了し、なんとか毎日のリズムが出てきた。

昨年度は練習問題を一生懸命やっていたなぁというのが正直な所で、今年度はちゃんとアウトプットしていきたい。

研究リハビリ第1段として、昨秋にやっていたDakotaのRosenbrock関数(2D)の最適化で(min = 0 at (x1,x2)=(1,1))、ちょっとパラメータの追い込みをしてみる。長岡のY先生曰く、モデル関数でパラメータセットを指定したら、CFDでの本番ではあまりいじらないそうなので、その言にしたがってみる。

 

設定すべきパラメータはいくつかあるが、まずはMOGAのパラメータセットは共通として、Kriging近似曲面でのSURROGATE でのサンプル数samples = 50/100/200/300/400と変えてやってみる(surrogate_based_global)。ただし、最小値が3つあるので、最後の値になるようにx1,x2の配位を狭めてやってみる。

        initial_point             -3  -3   
        lower_bounds       -5   -5    
        upper_bounds      10   10   
        descriptors      'x1'  'x2' 

結果は、以下のとおりで、samples=100がなんか怪しいが200以上であれば良さそう。

samples, x1, x2, fmin, CPUs
 50, 1.0585147380, 1.1213159660,  3.4983678384e-3, 2.86341
100, 3.0855104598, 9.5452386907, 4.4111751971, 5.580
200, 0.96201007998, 0.92113517035, 3.3165860016e-3, 7.68196
300, 1.0214072634, 1.0472875769, 2.0701161290e-3, 10.9975
400, 1.0585147380, 1.1213159660, 3.4983678384e-3, 14.3596
moga, 1.0585147380,  1.1213159660, 3.4983678384e-3, 41.47

 

 

 

 

 

OpenCV3.1.0+VS2015+Win10Pro

前から気になっていたOpenCVをいじってみようということで、とりあえずWebカメラのついている家PC(Win10Pro x86_64)に環境構築をトライしてみる。OpenCV3.1.0が年末に公開され、VS2015にも対応したとのことなので、C++の勉強もかねてVS2015 C++での開発を考えよう。

1.VS2015のダウンロード・インストール

MSから無償公開されているVS2015 Community版をダウンロード・インストール(vs

_community_JPN.exeを落としてきてダブルクリックし、ネットインストールすることになる。カスタムでインストールすると26GBくらい必要と表示された)。なお、インストール時に標準ではC#しか選択されないようなので、カスタムインストールでC++も選択しておく。2016/1現在で、VS2015 Update1が導入される。導入後はPCを再起動しておく。

f:id:waku2005:20160109133434p:plain

f:id:waku2005:20160109133439p:plain

 f:id:waku2005:20160109075659p:plain

 2.OpenCV 3.1.0のダウンロード・インストール

 ここからWindows用のOpenCV for Windows (opencv-3.1.0.exe)をダウンロードする。Githubから落としてくると早いかも。SFはミラーサイトにいきわたっていない?

http://opencv.org/downloads.html

自己解凍ファイル(exe)形式になっているので、ダブルクリックすると、opencvフォルダに展開されるので、フォルダごと適当な場所に置いておく。

今回は、バージョンがわかるようにopencv-3.1.0にリネームして、C:\Users\waku\opencv-3.1.0としておいておく。

なお、OpenCV3.0からAll-in-oneのライブラリ(C:\Users\waku\opencv-3.1.0\build\x64\vc14\lib\opencv_world310(d).lib)になったので、個別のlibが欲しい場合(2系列のように)やstaticライブラリが欲しい場合は、cmakeをつかってrebuildする必要があるとのこと。

3.Windows環境変数の設定

VS2015用動的ライブラリが置かれている場所は「C:\Users\Waku\opencv-3.1.0\build\x64\vc14\bin」であるので、これをWindowsのシステム環境変数PATHに追記する。環境変数は、システムのプロパティから設定できる。

4.VS2015での環境設定

 VS2015では、プロジェクトがOpenCVを認識できるようにOpenCVの「includeフォルダ」と「libraryフォルダ」を以下のようにして設定する必要がある。

  • まず、ファイル>新規作成>プロジェクトをクリックして、Win32コンソールアプリケーションの新しいプロジェクト(ここではプロジェクト名をOpenCV_Testとし、場所はc:\users\waku\documents\visual studio 2015\Projects)を作成する。
  •  次に、ビルド>構成マネージャーをクリックして、アクティブソリューションプラットフォームを「x86」から「x64」に変更する。debug/releaseはdebugのままとする。
  • ソリューション名”OpenCV_test”を右クリック>プロパティ>構成プロパティ>C/C++>全般を選択し、右側に出てくる設定画面に「追加のインクルードディレクトリ」が一番上にあるので、C:\Users\waku\opencv-3.1.0\build\includeを設定する(その下のopencv/opencv2までは不要)。
  • 同様にソリューション名”OpenCV_test”を右クリック>プロパティ>構成プロパティ>リンカ―>全般を選択し、右側の設定画面の中ほどにある追加のライブラリディレクトリにC:\Users\waku\opencv-3.1.0\build\x64\vc14\libを設定する。
  • 同様にソリューション名”OpenCV_test”を右クリック>プロパティ>構成プロパティ>リンカ―>入力を選択し、一番側の設定画面の中ほどにある追 加のライブラリディレクトリにopencv_world310(d).libを追記する。
  • http://chichimotsu.hateblo.jp/entry/2014/11/28/212432を参考に、opencv_libs.hppを作成し、上記のincludeフォルダに入れておく。

5.テストCoding

http://www.arubeh.com/archives/1102

にあったサンプルコードを以下のようにしてみた。

なお、各プロジェクトのプロパティから、構成プロパティ>C/C++>コード生成>「ランタイムライブラリ」をdebug/releaseに応じて変更する必要があるそうな。

Static Link

  • debugモードの場合:「マルチスレッドdebug(/MTd)」
  • releaseモードの場合:「マルチスレッド(/MT)」

Dynamic Link

  • debugモードの場合:「マルチスレッドdebugDLL(/MTd)」
  • releaseモードの場合:「マルチスレッドDLL(/MT)」

#include "stdafx.h"

// Dynamic Linkの場合
#include <opencv2/opencv.hpp> // インクルードファイル指定
//#include <opencv_libs.hpp> // 静的リンクライブラリの指定 (不要)

// Static Linkの場合
//#include <opencv2/opencv.hpp>
//#define _OPENCV_BUILD_STATIC_
//#include "opencv_libs.hpp"

using namespace cv; // 名前空間の指定

int main()
{
    //width220, height150の画像を作成
    Mat src = Mat::zeros(150, 220, CV_8UC3);

    //赤色で画像にHello Worldを描く
    putText(src, "Hello World", Point(5, 50), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 200), 2, CV_AA);

    //緑色で画像に線を描く
    line(src, Point(190, 25), Point(190, 45), Scalar(0, 200, 0), 3);

    //要素を直接操作し画像に点を描く
    for (int x = 188; x < 192; x++) {
        for (int y = 53; y < 57; y++) { // y座標
            for (int i = 0; i < 2; i++) { // i < 3にするとBGRすべての要素を200にする
                src.at<uchar>(Point(x * 3 + i, y)) = saturate_cast<uchar>(200);
            }
        }
    }

    //画像を表示
    imshow("", src);

    //ウインドウの表示時間(0はキーが押されるまで閉じない)
    waitKey(0);

    return 0;
}

 LINK : fatal error LNK1104: ファイル 'opencv_ts310d.lib' を開くことができません。となりエラーになる?

(以上、STOPです。Cmakeでビルドしなおせということか?)

 

(01/10追記)

いろいろ調べたところ、OpenCV3.1.0には個別のライブラリではなく、全部入りのopencv_world310(d).libだけがついてくるそうで、リンカの入力にこのライブラリを指定すればOK。また、

#include <opencv_libs.hpp>

のようなstatic libraryの指定も不要らしい..というか、そもそもstatic libraryがついてこないので、camekを使って自前でbuildしなければいけないらしい。

f:id:waku2005:20160110201223p:plain

blockMeshのmultiGrading 機能(2.3.x~)

blockMeshDGなんていうツールもあるが、ちょっと調べたら2.3.xから本家のblockMeshコマンドにmultiGrading機能が追加されていたとのことで調べてみた。

従来のblockMeshでは例えば矩形ダクト流れを計算するときに壁面にメッシュを寄せたい場合は、ブロックを分割して壁面側にgradingを近づける必要があったが、新しい機能では、その必要がないということらしい。

 

1)一様メッシュ

blocks
(
    hex (0 1 2 3 4 5 6 7) (100 40 40)
    simpleGrading (

                             1
                             1
                             1
                             )
);

f:id:waku2005:20151029201029p:plain

 

 

 

2)multiGrading

blocks
(
hex (0 1 2 3 4 5 6 7) (100 40 40)
    simpleGrading (

       1

       // (fraction of the block, fraction of the divisions, grading ratio)
        ( (0.2 0.3 10) (0.6 0.4 1) (0.2 0.3 0.1) )
        ( (0.2 0.3 10) (0.6 0.4 1) (0.2 0.3 0.1) )
      )
);

f:id:waku2005:20151029201239p:plain

上記の例だと、x方向は一様分割で、yおよびz方向は、3つのグレーディングセクションに分かれており(3つの括弧が対応)、それぞれの括弧内は以下のように指定する。

(ブロック全体に占める割合  セクションが占める分割数の割合 グレーディング比)

具体的には、

(0.2 0.3 10)・・・ブロックの2割をセクション化し、分割数40分割の3割を割り当てるとする。比率は10なのでだんだん大きくなるようにする

(0.6 0.4 1)・・・ブロックの6割部分(真ん中のセクション)は一様分割

(0.2 0.3 0.1)・・・ブロックの2割をセクション化し、分割数40の3割を割り当てる。比率は0.1なのでだんだん小さくなるようにする

※ なお、0.2とか0.3というのは割合を指定できればよく、内部で規格化されるので、必ずしも和が1でなくてもよい。

Dakotaの並列計算機能について(その4)

ちょっと時間が開いてしまった。

4ノードの「なんちゃってクラスタ」でdakota+OF並列計算したいときのやり方をまとめておく。

クラスタでの利用にはいくつか(計算したい内容に応じて)方法があるが、ここでは、

  • 個々の目的関数の評価はOpenFOAMの並列計算結果を用いる(したがって1個1個の目的関数の評価は計算負荷が大きい)
  • OFの計算は1個1個のノード内で実行する
  • とくにTorqueやSLURMなどのリソースマネージャー(job scheduler)は利用しない

という条件で考える。

①dakotaの設定(dakota input file)

dakotaのプロセス自体はserialで実行し、evaluation_concurrencyを実行したいノード数に合わせる。

ポイントは   local_evaluation_scheduling staticで、この設定により例えばjob 2の次はjob 6、job10、.....という風にjobの順番が固定で回ってくるようにできる。

[snip]

interface,  
###############
  fork
    asynchronous
    evaluation_concurrency = 4
    local_evaluation_scheduling static

[snip]

②dakotaの設定(OFのドライバーファイルrun_openfoam.sh)

OFのジョブを起動するためのドライバスクリプト中で(shスクリプト)、どのjobがどのノードにmpirunで投入されるかを決める。こんな感じです。

 

# Cuurent Job number
num=$(pwd | awk -F. '{print $NF}')     ←workdir名からjob番号を取得
#echo $num
# Dakota concurrency (be same setting in dakota input file)
CONCURRENCY=4
# Num. of Procs per node
PPN=4
# number of processors per application job
APPLIC_PROCS=4
# relative node on which the job should schedule (floor)
# this is the first of the node block for this job
relative_node=$*1 ←剰余演算でjob番号と、OFで利用するcore数などからホスト番号を計算
#echo $relative_node
# build a node list ←ホスト番号からノード名を設定
if   [ $relative_node -eq 0 ]; then  
   node_list="ensis10"
elif [ $relative_node -eq 1 ]; then  
   node_list="ensis12"
elif [ $relative_node -eq 2 ]; then   
   node_list="ensis13"
else
   node_list="ensis14"
fi
echo "Evaluation on" $node_list
#for node_increment in `seq 1 $*2`; do
#  node_list="$node_list,+n$*3"
#done


./Allrun $node_list $APPLIC_PROCS ←OFの起動スクリプトにノード名とcore数を引き渡す

※ OpenMPIのrelative host indexingの機能を使えば、ノード名を設定しなくてもよさそうだが、なぜかうまくいかないので力技で指定しています。

→OpenMPIのMLに投げたところどうもバグらしい。OpenMPI2.0になるまで待てということらしい。

※ Allrunもちゃんと書き換えて、sHMとかも投入ノードで実行するようにしたほうがよさそうです。今は、master兼computeノード(具体的にはensis10)で実行してしまってるので...。

※ mpirunはsshで実行できるようにしてあります。ここらへんの設定は前にも書きました。

*1: (num - 1) % CONCURRENCY * APPLIC_PROCS / PPN

*2:applic_nodes - 1

*3:relative_node + node_increment

Dakotaの並列計算機能について(その3)

MOGAがやっぱり時間がかかるので、近似応答局面を導入した計算(Surrogate based optimization)の効率化を図ってみる。

テスト問題はBranin function(2D)で、3つの最小点がある。

f(-pi, 12.275)=f(pi,2.275)=f(9.42478,2.475)=0.397887

moga部分は共通で、以下のようなsettingとする。また、Surrogate作成のsamplingはLHS(samples=100)とした。

method
    id_method = 'MOGA'
    output silent
    max_function_evaluations = 5000
    moga
      fitness_type domination_count
      replacement_type below_limit = 6
        shrinkage_percentage = 0.9
      niching_type distance 0.05 0.05
      convergence_type metric_tracker
        percent_change = 0.05
        num_generations = 10
      postprocessor_type
        orthogonal_distance 0.05 0.05
      population_size = 300
      initialization_type unique_random
      crossover_type shuffle_random
        num_offspring = 2 num_parents = 2
        crossover_rate = 0.8
      mutation_type replace_uniform
        mutation_rate = 0.1
      seed = 531

① MOGAのみ(evaluation_concurrency = 4)

<<<<< Function evaluation summary: 1264 total (1264 new, 0 duplicate)
<<<<< Best parameters          =
                      9.4287956783e+00 x1
                      2.4366909952e+00 x2
<<<<< Best objective function  =
                      3.9970375654e-01
<<<<< Best data captured at function evaluation 1194


<<<<< Iterator moga completed.
<<<<< Environment execution completed.
DAKOTA execution time in seconds:
  Total CPU        =        0.9 [parent =   0.891864, child =   0.008136]
  Total wall clock =    70.9963

 

② MOGA+Surrogate(Kriging)(evaluation_concurrency = 4)

<<<<< Function evaluation summary (APPROX_INTERFACE): 6328 total (6328 new, 0 duplicate)
         obj_fn: 6328 val (6328 n, 0 d), 0 grad (0 n, 0 d), 0 Hess (0 n, 0 d)
<<<<< Function evaluation summary: 105 total (105 new, 0 duplicate)
         obj_fn: 105 val (105 n, 0 d), 0 grad (0 n, 0 d), 0 Hess (0 n, 0 d)
<<<<< Best parameters          =
                      9.3747568430e+00 x1
                      2.4445742729e+00 x2
<<<<< Best objective function  =
                      4.1002862086e-01
<<<<< Best data captured at function evaluation 105


<<<<< Iterator surrogate_based_global completed.
<<<<< Environment execution completed.
DAKOTA execution time in seconds:
  Total CPU        =       1.22 [parent =    1.22181, child =  -0.001814]
  Total wall clock =     8.5127

なんか精度がいまいちなので、LHS(samples=200)としてみる。

<<<<< Function evaluation summary (APPROX_INTERFACE): 6288 total (6288 new, 0 duplicate)
         obj_fn: 6288 val (6288 n, 0 d), 0 grad (0 n, 0 d), 0 Hess (0 n, 0 d)
<<<<< Function evaluation summary: 205 total (203 new, 2 duplicate)
         obj_fn: 205 val (203 n, 2 d), 0 grad (0 n, 0 d), 0 Hess (0 n, 0 d)
<<<<< Best parameters          =
                      9.4443335614e+00 x1
                      2.5037465699e+00 x2
<<<<< Best objective function  =
                      3.9987220558e-01
<<<<< Best data captured at function evaluation 205


<<<<< Iterator surrogate_based_global completed.
<<<<< Environment execution completed.
DAKOTA execution time in seconds:
  Total CPU        =       0.97 [parent =   0.963853, child =   0.006147]
  Total wall clock =    14.1147

 サンプル数が倍になったので、計算時間も倍になったが、精度はおおむねMOGAと同等になった。使ったinputファイルを上げておく。

branin_opt_sbo.in

# Dakota Input File: branin_opt_sbo.in
# moga + surrogate(kriging)

environment
    tabular_graphics_data
      tabular_graphics_file = 'branin_opt_sbo.dat'
    top_method_pointer = 'SBGO'

method
    id_method = 'SBGO'
    surrogate_based_global        
      model_pointer = 'SURROGATE'
      method_pointer = 'MOGA'
      replace_points
    max_iterations = 5
    output verbose

method
    id_method = 'MOGA'
    output silent
    max_function_evaluations = 5000
    moga
      fitness_type domination_count
      replacement_type below_limit = 6
        shrinkage_percentage = 0.9
      niching_type distance 0.05 0.05
      convergence_type metric_tracker
        percent_change = 0.05
        num_generations = 10
      postprocessor_type
        orthogonal_distance 0.05 0.05
      population_size = 300
      initialization_type unique_random
      crossover_type shuffle_random
        num_offspring = 2 num_parents = 2
        crossover_rate = 0.8
      mutation_type replace_uniform
        mutation_rate = 0.1
      seed = 531

model
    id_model = 'SURROGATE'
    surrogate global
      dace_method_pointer = 'SAMPLING'
      gaussian_process
        dakota

method
    id_method = 'SAMPLING'
    model_pointer = 'TRUTH'
    sampling
      sample_type lhs
      samples = 200
      seed = 12345

model
    id_model = 'TRUTH'
    single

variables
    continuous_design = 2
        initial_point      0     2    
        lower_bounds      -5     0     
        upper_bounds      10    15    
        descriptors      'x1'  'x2'  

interface
  fork
    asynchronous evaluation_concurrency = 4
  analysis_driver = 'simulator_script'
  parameters_file = 'params.in'
  results_file = 'results.out'
  work_directory directory_tag
    copy_files = 'templatedir/*'
  named 'workdir' file_save  directory_save
    aprepro

responses
    objective_functions = 1
    no_gradients
    no_hessians

 

Dakotaの並列計算機能について(その2)

以下のような簡単な問題(Beale's function)を最適化で解いてみる。設計変数がx1, x2で、目的関数(単一)がf、制約条件(単一)がc>=0である。最小値の答えはf(3, 0.5)=0。

See: Test functions for optimization - Wikipedia, the free encyclopedia

#!/bin/python
from sys import argv
from math import *
import numpy as np

def f(x1, x2):
    return (1.5-x1+x1*x2)**2+(2.25-x1+x1*x2**2)**2+(2.625-x1+x1*x2**3)**2

def c(x1, x2):
    return x1**2-x2

if __name__ == '__main__':
    x1 = float(argv[1])
    x2 = float(argv[2])
    print f(x1,x2)
    print c(x1,x2)

これの最適解は、

 

①Gradientベースの最適化(conmin_mfd method)

勾配を用いる最適化の場合は、逐次的に最適値を探索する。勾配には、あらかじめ数式などで求まっている場合と数値的な微分を用いる場合があるが、後者が一般的。

Dakotaで実装されている一番一般的な勾配法として、conmin_mfdやconmin_frcg ( conjugate gradient optimization method)がある。ここでは前者を利用する。勾配はNumerical gradientである。初期値は(1,0)とする。

1)シリアル計算で実行した場合

<<<<< Function evaluation summary: 10 total (8 new, 2 duplicate)
<<<<< Best parameters          =
                      5.0524767374e-01 x1
                      2.5527521182e-01 x2
<<<<< Best objective function  =
                      8.9519566068e+00
<<<<< Best constraint values   =
                     -1.2678746941e-13
<<<<< Best data captured at function evaluation 6


<<<<< Iterator conmin_mfd completed.
<<<<< Environment execution completed.
DAKOTA execution time in seconds:
  Total CPU        =       0.02 [parent =   0.010999, child =   0.009001]
  Total wall clock =    1.26761

real    0m1.362s
user    0m1.528s
sys    0m0.221s

 2)evaluation_concurrency=4を指定した場合

<<<<< Function evaluation summary: 10 total (8 new, 2 duplicate)
<<<<< Best parameters          =
                      5.0524767374e-01 x1
                      2.5527521182e-01 x2
<<<<< Best objective function  =
                      8.9519566068e+00
<<<<< Best constraint values   =
                     -1.2678746941e-13
<<<<< Best data captured at function evaluation 6


<<<<< Iterator conmin_mfd completed.
<<<<< Environment execution completed.
DAKOTA execution time in seconds:
  Total CPU        =       0.02 [parent =   0.011998, child =   0.008002]
  Total wall clock =    1.26666

real    0m1.367s
user    0m1.534s
sys    0m0.234s

 3)mpirun -np 4で起動した場合(evaluation_concurrency指定なし)

<<<<< Function evaluation summary: 10 total (8 new, 2 duplicate)
<<<<< Best parameters          =
                      5.0524767374e-01 x1
                      2.5527521182e-01 x2
<<<<< Best objective function  =
                      8.9519566068e+00
<<<<< Best constraint values   =
                     -1.2678746941e-13
<<<<< Best data captured at function evaluation 6


<<<<< Iterator conmin_mfd completed.
<<<<< Environment execution completed.
DAKOTA master processor execution time in seconds:
  Total CPU        =       0.02 [parent   =   0.018997, child =   0.001003]
  Total wall clock =    1.42358 [MPI_Init = 1.69277e-05, run   =    1.42357]

 

という結果になった(3つとも当然ながら計算結果は一致し、勾配ベースはやはり計算が速い!)が、正解には到達していない。

 原理的に逐次計算を必要とする(数値的勾配を用いる場合)は、並列計算の意味があまりなさそうである(もしかしたらもっと良い方法があるのかもしれないが....)。

※ 勾配ベースの最適化は、実際には滑らかな応答局面でないと収束しなかったり、

局所最適解に落ちつくなどがあるので、流体計算などで適用できる場合は限られるかもしれない。

 

②Non-Gradientベースの最適化(moga method)

MOGA(Multi Objective GA)で確認してみる。mogaの設定は以下の通りで、最適解の可能性のあるものを1つ出力する。このあたりのパラメーターの設定をどうすればよいか、指針が欲しいところ(現状は、ネットで調べた設定をそのまま利用)。

method
  moga
  output silent
    seed = 10983
    final_solutions = 1
  max_function_evaluations = 5000
  initialization_type unique_random
  crossover_type shuffle_random
    num_offspring = 2 num_parents = 2
    crossover_rate = 0.8
  mutation_type replace_uniform
    mutation_rate = 0.1
  fitness_type domination_count
  replacement_type below_limit = 6
    shrinkage_percentage = 0.9
  convergence_type metric_tracker
    percent_change = 0.05 num_generations = 50

1)シリアル計算で実行した場合

<<<<< Function evaluation summary: 257 total (257 new, 0 duplicate)
<<<<< Best parameters          =
                     -9.7989947697e-01 x1
                      9.9330955813e-01 x2
<<<<< Best objective function  =
                      1.4384761666e+01
<<<<< Best constraint values   =
                     -3.3106573164e-02
<<<<< Best data captured at function evaluation 115


<<<<< Iterator moga completed.
<<<<< Environment execution completed.
DAKOTA execution time in seconds:
  Total CPU        =        0.2 [parent =    0.19597, child =    0.00403]
  Total wall clock =    47.6183

real    0m47.714s
user    0m41.059s
sys    0m5.870s

2)evaluation_concurrency=4を指定した場合

<<<<< Function evaluation summary: 257 total (257 new, 0 duplicate)
<<<<< Best parameters          =
                     -9.7989947697e-01 x1
                      9.9330955813e-01 x2
<<<<< Best objective function  =
                      1.4384761666e+01
<<<<< Best constraint values   =
                     -3.3106573164e-02
<<<<< Best data captured at function evaluation 115


<<<<< Iterator moga completed.
<<<<< Environment execution completed.
DAKOTA execution time in seconds:
  Total CPU        =       0.18 [parent =   0.187972, child =  -0.007972]
  Total wall clock =     22.097

real    0m22.193s
user    0m43.546s
sys    0m6.179s

3)mpirun -np 4で起動した場合(evaluation_concurrency指定なし)

<<<<< Function evaluation summary: 257 total (257 new, 0 duplicate)
<<<<< Best parameters          =
                     -9.7989947697e-01 x1
                      9.9330955813e-01 x2
<<<<< Best objective function  =
                      1.4384761666e+01
<<<<< Best constraint values   =
                     -3.3106573164e-02
<<<<< Best data captured at function evaluation 115


<<<<< Iterator moga completed.
<<<<< Environment execution completed.
DAKOTA master processor execution time in seconds:
  Total CPU        =       0.58 [parent   =   0.588911, child =  -0.008911]
  Total wall clock =    27.0884 [MPI_Init = 9.77516e-06, run   =    27.0884]

real    0m27.302s
user    1m20.837s
sys    0m7.109s

ということで、並列計算では計算時間は約半分になる....がやはり正解にたどり着かない!

 

(追記)

nonlinear constraintをなしにするとどちらも正解に近い値を出すことを確認できた。

Dakotaの並列計算機能について

ようやく復帰。Dakotaの並列計算機能について調べたのでまとめてみる。

概観と簡単なサマリー

Dakota自体から起動する"simulator"はシリアル計算でも並列計算でももちろん構わない(たとえばOFの並列計算など)ので、ここではDakota本体の並列計算について調べてみた。

 

ユーザーマニュアルのChapter 17 Parallel Computingを読んで理解した限りでは、Dakota本体としては、

  1. dakotaプロセス内からの複数のsimulation起動(応答関数の複数同時evaluation)
  2. MPIによる複数のdakotaプロセスの起動(multi node用?)

の機能があり、何をどう並列計算したいかにより、並列度を変えて使い分けることができる。とりあえず一番わかりやすいSingle-Level Parallelでは、

①asynchronous local

単一ノード内で、独立した設計変数による応答関数評価を同時に起動して計算効率化

②message passing with single simulation per node

MPIにより多ノードでdakotaを起動し、それぞれのdakotaプロセスで応答関数評価simlationを1つ起動する。masterノードがそれらの結果を取りまとめする

③Hybrid

①と②の組み合わせ

 となっている。

 

この中で、おそらく個々のsimlation負荷が小さいのであれば、①か③がよく、OF計算のような計算負荷が1つ1つ大きい場合には、②もしくは③がよいのかもしれない。

なお、並列プロセス実行にはforkを推奨とのこと。

 

【DACEでの例】

一番わかりやすいと思われる設計変数に対する応答関数の評価を独立に行うDACEでの並列計算の例を調べてみる。

具体例①:ラテン超方格を使ったDACEチュートリアル(ascynchronous evaluation_concurrency)

問題:Pythonを使った2設計変数2目的関数(objective.py)の最適評価

objective.py

#!/bin/python
from sys import argv
from math import *
import numpy as np

def f1(x1, x2):
    return 2.0*sqrt(x1)

def f2(x1, x2):
    return x1-x1*x2+5.0

if __name__ == '__main__':
    x1 = float(argv[1])
    x2 = float(argv[2])
    print f1(x1,x2), f2(x1,x2)

dakota_lhs_par.in

# Dakota Input File: dakota.in

environment
#  graphics
  tabular_graphics_data
    tabular_graphics_file = 'objective.dat'

method
  dace oa_lhs
     seed = 5  
     samples = 121
model
  single

variables
  continuous_design = 2
    initial_point     2.0      1.5
    lower_bounds      1.0      1.0
    upper_bounds      4.0      2.0
    descriptors       'x1'     "x2"

interface
  fork
    asynchronous evaluation_concurrency = 4
  analysis_driver = 'simulator_script'
  parameters_file = 'params.in'
  results_file = 'results.out'
  work_directory directory_tag
    copy_files = 'templatedir/*'
  named 'workdir' file_save  directory_save
    aprepro

responses
  response_functions = 2
  no_gradients
  no_hessians

赤字の部分のようにevaluation_concurencyを指定すると同時に評価サンプルを複数実行してくれる。この場合、シングルで24.2s, evaluation_concurrency = 4 で7.5sとなった。

$ dakota dakota_lhs_par.in

[snip]

<<<<< Function evaluation summary: 121 total (121 new, 0 duplicate)

Simple Correlation Matrix among all inputs and outputs:
                       x1           x2 response_fn_1 response_fn_2
          x1  1.00000e+00
          x2  1.37441e-02  1.00000e+00
response_fn_1  9.96397e-01  1.52353e-02  1.00000e+00
response_fn_2 -4.95228e-01 -8.29560e-01 -4.94665e-01  1.00000e+00

Partial Correlation Matrix between input and output:
             response_fn_1 response_fn_2
          x1  9.96398e-01 -8.66506e-01
          x2  1.81689e-02 -9.47129e-01

Simple Rank Correlation Matrix among all inputs and outputs:
                       x1           x2 response_fn_1 response_fn_2
          x1  1.00000e+00
          x2  1.41173e-02  1.00000e+00
response_fn_1  1.00000e+00  1.41173e-02  1.00000e+00
response_fn_2 -4.56767e-01 -8.63711e-01 -4.56767e-01  1.00000e+00

Partial Rank Correlation Matrix between input and output:
             response_fn_1 response_fn_2
          x1  1.00000e+00 -8.82201e-01
          x2  1.16427e-10 -9.63760e-01


<<<<< Iterator dace completed.
<<<<< Environment execution completed.
DAKOTA execution time in seconds:
  Total CPU        =       0.09 [parent =   0.095986, child =  -0.005986]
  Total wall clock =    7.45185

※ analysis_concurrencyというキーワードもあるが、これを指定すると同時に評価する最大数を制限できる。

When asynchronous execution is enabled and each evaluation involves multiple analysis drivers, then the default behavior is to launch all drivers simultaneously. The analysis_concurrency keyword can be used to limit the number of concurrently run drivers.

 

具体例②:ラテン超方格を使ったDACEチュートリアル(mpirun on single node)

問題:Pythonを使った2設計変数2目的関数(objective.py)の最適評価(上記と同じ)

dakota_lhs.in (evaluation concurrencyの指定なしに注意)

# Dakota Input File: dakota.in
environment
#  graphics
  tabular_graphics_data
    tabular_graphics_file = 'objective.dat'

method
  dace oa_lhs
     seed = 5  
     samples = 100

model
  single

variables
  continuous_design = 2
    initial_point     2.0      1.5
    lower_bounds      1.0      1.0
    upper_bounds      4.0      2.0
    descriptors       'x1'     "x2"

interface
  fork

###    asynchronous evaluation_concurrency = 4
  analysis_driver = 'simulator_script'
  parameters_file = 'params.in'
  results_file = 'results.out'
  work_directory directory_tag
    copy_files = 'templatedir/*'
  named 'workdir' file_save  directory_save
    aprepro

responses
  response_functions = 2
  no_gradients
  no_hessians

$ mpirun -np 4 dakota dakota_lhs.in  > dakota_lhs_openmpi.out

→ dakotaプロセスが4つ起動する。前例では1つだけである。

[snip]

<<<<< Function evaluation summary: 121 total (121 new, 0 duplicate)

Simple Correlation Matrix among all inputs and outputs:
                       x1           x2 response_fn_1 response_fn_2
          x1  1.00000e+00
          x2  1.37441e-02  1.00000e+00
response_fn_1  9.96397e-01  1.52353e-02  1.00000e+00
response_fn_2 -4.95228e-01 -8.29560e-01 -4.94665e-01  1.00000e+00

Partial Correlation Matrix between input and output:
             response_fn_1 response_fn_2
          x1  9.96398e-01 -8.66506e-01
          x2  1.81689e-02 -9.47129e-01

Simple Rank Correlation Matrix among all inputs and outputs:
                       x1           x2 response_fn_1 response_fn_2
          x1  1.00000e+00
          x2  1.41173e-02  1.00000e+00
response_fn_1  1.00000e+00  1.41173e-02  1.00000e+00
response_fn_2 -4.56767e-01 -8.63711e-01 -4.56767e-01  1.00000e+00

Partial Rank Correlation Matrix between input and output:
             response_fn_1 response_fn_2
          x1  1.00000e+00 -8.82201e-01
          x2  1.16427e-10 -9.63760e-01

 

<<<<< Iterator dace completed.
<<<<< Environment execution completed.
DAKOTA master processor execution time in seconds:
  Total CPU        =       0.21 [parent   =   0.206969, child =   0.003031]
  Total wall clock =    7.38266 [MPI_Init = 9.05991e-06, run   =    7.38266]

※ 計算時間はevaluation_concurrency指定の場合とほぼ変わらず7.4s。

 ということで、マルチノードならmpi、シングルノードならevaluation concurrency指定でよさそうである。

 

→ 次は、gradien base, Non-gradient baseの最適化の例について調査すべし。