2016-11-16 17 views
5

進化的アルゴリズム(CMAES)を使用して関数の最適化を行っています。高速に実行するには、マルチプロセッシングモジュールを使用しています。私が最適化する必要がある関数は、以下のコードで大きな行列を入力として受け取ります。(input_A_Opt, and input_B_Opt)マルチプロセッシングの使用中にメモリの制約を克服する

サイズは数GBです。マルチプロセッシングなしで関数を実行すると、うまく機能します。私がマルチプロセッシングを使用するとき、メモリに問題があるようです。私は、小さな入力でそれを実行した場合、それはうまく動作しますが、私は完全な入力を実行したとき、私は次のエラーを取得する:私はそれを実行した場合

File "<ipython-input-2-bdbae5b82d3c>", line 1, in <module> 
opt.myFuncOptimization() 

File "/home/joe/Desktop/optimization_folder/Python/Optimization.py", line 45, in myFuncOptimization 
**f_values = pool.map_async(partial_function_to_optmize, solutions).get()** 
File "/usr/lib/python3.5/multiprocessing/pool.py", line 608, in get 
raise self._value 
    File "/usr/lib/python3.5/multiprocessing/pool.py", line 385, in _handle_tasks 
put(task) 
File "/usr/lib/python3.5/multiprocessing/connection.py", line 206, in send 
self._send_bytes(ForkingPickler.dumps(obj)) 

File "/usr/lib/python3.5/multiprocessing/connection.py", line 393, in _send_bytes 
header = struct.pack("!i", n) 

error: 'i' format requires -2147483648 <= number <= 2147483647 

そしてここでは、コードの簡易版は、再び(です入力は10倍小さく、すべて正常に動作します):

import numpy as np 
import cma 
import multiprocessing as mp 
import functools 
import myFuncs 
import hdf5storage 



def myFuncOptimization(): 

    temp = hdf5storage.loadmat('/home/joe/Desktop/optimization_folder/matlab_workspace_for_optimization')  

    input_A_Opt = temp["input_A"] 
    input_B_Opt = temp["input_B"] 

    del temp 

    numCores = 20 

    # Inputs 
    #________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________ 
    P0 = np.array([   4.66666667, 2.5, 2.66666667, 4.16666667, 0.96969697,  1.95959596,  0.44088176,  0.04040404,  6.05210421,  0.58585859,  0.46464646,   8.75751503,   0.16161616,    1.24248497,   1.61616162,     1.56312625,   5.85858586,     0.01400841, 1.0,   2.4137931,  0.38076152, 2.5, 1.99679872  ]) 
    LBOpt = np.array([   0.0,  0.0, 0.0,  0.0,  0.0,   0.0,   0.0,   0.0,   0.0,   0.0,   0.0,    0.0,    0.0,     0.0,    0.0,      0.0,    0.0,      0.0,  0.0,   0.0,   0.0,  0.0, 0.0,   ]) 
    UBOpt = np.array([   10.0,  10.0, 10.0,  10.0,  10.0,   10.0,   10.0,   10.0,   10.0,   10.0,   10.0,    10.0,    10.0,     10.0,    10.0,      10.0,    10.0,      10.0,  10.0,   10.0,   10.0,  10.0, 10.0,   ]) 
    initialStdsOpt = np.array([2.0,  2.0, 2.0,  2.0,  2.0,   2.0,   2.0,   2.0,   2.0,   2.0,   2.0,    2.0,    2.0,     2.0,    2.0,      2.0,    2.0,      2.0,  2.0,   2.0,   2.0,  2.0, 2.0,   ]) 
    minStdsOpt = np.array([ 0.030,  0.40, 0.030,  0.40,  0.020,   0.020,   0.020,   0.020,   0.020,   0.020,   0.020,    0.020,    0.020,     0.020,    0.020,      0.020,    0.020,      0.020,  0.050,   0.050,   0.020,  0.40, 0.020,   ]) 

    options = {'bounds':[LBOpt,UBOpt], 'CMA_stds':initialStdsOpt, 'minstd':minStdsOpt, 'popsize':numCores} 
    es = cma.CMAEvolutionStrategy(P0, 1, options) 

    pool = mp.Pool(numCores) 

    partial_function_to_optmize = functools.partial(myFuncs.func1, input_A=input_A_Opt, input_B=input_B_Opt) 

    while not es.stop(): 
     solutions = es.ask(es.popsize)    
     f_values = pool.map_async(partial_function_to_optmize, solutions).get() 
     es.tell(solutions, f_values) 
     es.disp(1) 
     es.logger.add() 

    return es.result_pretty() 

この問題の解決方法についてのご意見はありますか?私は適切にコーディングしていないのですか(pythonの初心者)、またはscoopのような他のマルチプロセッシングパッケージを使うべきですか?

+0

あなたはあまりにも多くのメモリを使用しています!共用メモリにコピーする必要のない値を探します(https://docs.python.org/2/library/multiprocessing.html#sharing-state- between-processes)。 – tcooc

+0

関連:[マルチプロセッシングのために共有メモリにnumpy配列を使用する](https://stackoverflow.com/questions/7894791/use-numpy-array-in-shared-memory-for-multiprocessing) – robyschek

答えて

0

オブジェクトが大きすぎてプロセス間を通過できません。あなたは2147483647バイト以上を渡しています - それは2GB以上です!このためのプロトコルは作成されておらず、そのような大きなチャンクをシリアライズしてデシリアライズすれば、パフォーマンス上の重大なオーバーヘッドになる可能性があります。

各プロセスに渡されるデータのサイズを減らします。ワークフローで許可されている場合は、別のプロセスのデータを読み込み、結果のみを渡します。

+0

Thanks MisterMiyagi。はい、私が渡す各マトリックスは2GB以上あります。しかし、このデータは必要です。それぞれのプロセスでデータを読むことをお勧めします。実際に実行できます。プロセスの開始時に1つの読みを読み込むのではなく、1回の評価(何千回も)を行うたびに読む必要があるため、各反復に必要な時間が増えます。おそらく増加した時間は許容可能な種類の約25%です。 – Joe

+0

btw、この量のデータ(たとえばスクープ)で動作する他の並列処理フレームワークがあるかどうかは分かりますか? – Joe

+0

フォローアップの質問 - 同じファイルを同時に読む20の並列プロセスが問題になることはありますか? – Joe

関連する問題