2016-11-16 24 views
5

Evrimsel bir algoritma (CMAES) kullanarak bir işlev optimizasyonu yapıyorum. Daha hızlı çalıştırmak için çoklu işlem modülünü kullanıyorum. Optimize etmem gereken fonksiyon, aşağıdaki kodda büyük matrisleri (input_A_Opt, and input_B_Opt) girişleri olarak alır.Çoklu işlem kullanırken bellek sınırlamalarının üstesinden gelin

Bunlar, birkaç GB boyutundadır. Çok işlem yapmadan işlevi çalıştırdığımda, iyi çalışır. Çoklu işlemeyi kullandığımda bellekte bir sorun var gibi görünüyor. Ben küçük girişler ile çalıştırırsanız iyi çalışıyor, ama tam girişli çalıştırdığınızda, ben şu hatayı alıyorum:

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 

Ve burada onu çalıştırırsanız, tekrar kod (basitleştirilmiş versiyonu 10 kat daha küçük girdi, hepsi) çalışıyor: Bu sorunu çözmek için nasıl

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() 

herhangi bir öneriniz? düzgün kodlamıyorum (python'a yeni) ya da kepçe gibi başka çok işlemcili paket kullanmalı mıyım?

+0

Çok fazla bellek kullanıyorsunuz! Kopyalanması gerekmeyen değerler için paylaşılan belleğe bakın (https://docs.python.org/2/library/multiprocessing.html#sharing-state-between-processes). – tcooc

+0

İlgili: [Çok işlem için paylaşılan bellekte numpy dizisi kullanın] (https://stackoverflow.com/questions/7894791/use-numpy-array-in-shared-memory-for-multiprocessing) – robyschek

cevap

0

Nesneleriniz işlemler arasında geçemeyecek kadar büyük. 2147483647 bayttan fazla geçiyorsunuz - 2GB'ın üzerinde! Protokol bunun için yapılmamıştır ve bu tür büyük veri kümelerinin serileştirilmesi ve serileştirilmesinin aşırı yükü, ciddi bir performans yükü olabilir.

Her işleme verilen veri boyutunu azaltın. İş akışına izin verirseniz, verileri ayrı işlemde okuyun ve yalnızca sonuçları iletin.

+0

Teşekkürler MisterMiyagi. Evet, geçtiğim her matrisin 2GB’dan fazlası var. Bu veriler gerekli olsa da. Her işlemde verileri okuma önerisini deneyecek, aslında yapılabilir. Her iterasyon için gereken süreyi arttıracaktır, bunun yerine sürecin başında bir okuma yaptığım her seferinde bir kez (binlerce kez) yaptığım bir okumaya ihtiyacım olacaktır. Muhtemelen artan zaman ~% 25, ​​kabul edilebilir bir tür. – Joe

+0

btw, bu miktarda veri ile çalışabilen başka bir paralel işlem çerçevesi var mı (örneğin, kepçe) biliyor musunuz? – Joe

+0

izleme sorusu - aynı dosyayı aynı anda okuyan 20 paralel süreçte sorun olabilir mi? – Joe

İlgili konular