Apakah ada alat dalam Python yang seperti parl Matlab? Saya menemukan utas ini , tetapi sudah berusia empat tahun. Saya pikir mungkin seseorang di sini mungkin memiliki pengalaman yang lebih baru.
Berikut adalah contoh jenis hal yang ingin saya pisahkan:
X = np.random.normal(size=(10, 3))
F = np.zeros((10, ))
for i in range(10):
F[i] = my_function(X[i,:])
di mana my_function
mengambil ndarray
ukuran (1,3)
dan mengembalikan skalar.
Setidaknya, saya ingin menggunakan beberapa core secara bersamaan --- seperti parfor. Dengan kata lain, asumsikan sistem memori bersama dengan 8-ke-16 core.
python
parallel-computing
Paul G. Constantine
sumber
sumber
Jawaban:
Joblib melakukan apa yang Anda inginkan. Pola penggunaan dasar adalah:
di mana
arg_instances
daftar nilai yangmyfun
dihitung secara paralel. Batasan utamanya adalah yangmyfun
harus menjadi fungsi tingkat atas. Thebackend
Parameter dapat berupa"threading"
atau"multiprocessing"
.Anda dapat melewatkan parameter umum tambahan ke fungsi paralel. Tubuh
myfun
juga dapat merujuk pada variabel global yang diinisialisasi, nilai-nilai yang akan tersedia untuk anak-anak.Args dan hasil bisa sangat banyak dengan backend threading tetapi hasilnya harus serializable dengan backend multiprosesing.
Dask juga menawarkan fungsionalitas serupa. Mungkin lebih baik jika Anda bekerja dengan data inti atau Anda mencoba untuk memparalelkan perhitungan yang lebih kompleks.
sumber
threading
backend menderita bottleneck GIL danmultiprocessing
backend membawa overhead yang besar karena serialisasi semua parameter dan nilai pengembalian. Lihat jawaban ini untuk detail level rendah dari pemrosesan paralel dengan Python.map
yang dapat Anda gunakan secara langsung. Juga jika Anda menggunakan mkl kompilasi numpy itu akan memparalelkan operasi vektor secara otomatis tanpa Anda melakukan apa pun. Numpy di Ananconda adalah mkl diaktifkan secara default. Tidak ada solusi universal. Joblib sangat cerewet dan ada sedikit aksi di tahun 2015.Apa yang Anda cari adalah Numba , yang dapat memparalelkan for for loop secara otomatis. Dari dokumentasi mereka
sumber
Tanpa mengasumsikan sesuatu yang istimewa dalam
my_function
memilihmultiprocessing.Pool().map()
adalah tebakan yang baik untuk menyejajarkan loop sederhana tersebut.joblib
,dask
,mpi
Perhitungan ataunumba
seperti yang diusulkan dalam jawaban lainnya terlihat tidak membawa keuntungan apapun untuk kasus-kasus penggunaan tersebut dan menambahkan dependensi tidak berguna (untuk meringkas mereka berlebihan). Menggunakan threading seperti yang diusulkan dalam jawaban lain tidak mungkin menjadi solusi yang baik, karena Anda harus akrab dengan interaksi GIL dari kode Anda atau kode Anda harus melakukan input / output.Yang mengatakan
numba
mungkin ide yang baik untuk mempercepat kode python murni berurutan, tapi saya merasa ini di luar ruang lingkup pertanyaan.Namun ada beberapa peringatan (tapi yang seharusnya tidak mempengaruhi sebagian besar aplikasi):
if __name__ == "__main__"
my_function
seharusnya tidak bergantung pada status bersama seperti berkomunikasi dengan variabel global karena status tidak dibagi di antara proses. fungsi murni (fungsi dalam indera matematika) adalah contoh fungsi yang tidak berbagi statussumber
Kesan saya tentang parfor adalah bahwa MATLAB merangkum detail implementasi, sehingga bisa menggunakan paralelisme memori bersama (yang Anda inginkan) dan paralelisme memori terdistribusi (jika Anda menjalankan server komputasi terdistribusi MATLAB ).
Jika Anda ingin paralelisme memori bersama, dan Anda menjalankan semacam tugas paralel, paket pustaka standar multiprosesing mungkin yang Anda inginkan, mungkin dengan front-end yang bagus, seperti joblib , seperti yang disebutkan dalam posting Doug. Perpustakaan standar tidak akan hilang, dan dipelihara, sehingga berisiko rendah.
Ada opsi lain di luar sana juga, seperti Parallel Python dan kemampuan paralel IPython . Pandangan sekilas pada Python Paralel membuat saya berpikir bahwa ini lebih dekat dengan semangat parfor, karena perpustakaan merangkum detail untuk kasing terdistribusi, tetapi biaya untuk melakukannya adalah Anda harus mengadopsi ekosistemnya. Biaya menggunakan IPython serupa; Anda harus mengadopsi cara IPython dalam melakukan sesuatu, yang mungkin atau mungkin tidak sepadan bagi Anda.
Jika Anda peduli dengan memori yang didistribusikan, saya sarankan mpi4py . Lisandro Dalcin bekerja dengan baik, dan mpi4py digunakan dalam pembungkus PETSc Python, jadi saya tidak berpikir itu akan hilang dalam waktu dekat. Seperti multiprocessing, ini adalah antarmuka tingkat rendah (er) untuk paralelisme daripada parfor, tetapi yang cenderung bertahan untuk sementara waktu.
sumber
Sebelum mencari alat "kotak hitam", yang dapat digunakan untuk menjalankan fungsi python paralel "generik", saya akan menyarankan untuk menganalisis bagaimana
my_function()
dapat diparalelkan dengan tangan.Pertama, bandingkan waktu eksekusi
my_function(v)
untukfor
overhead python loop: [C] Pythonfor
loop sangat lambat, sehingga waktu yang dihabiskanmy_function()
bisa diabaikan.Pemeriksaan kedua jika ada implementasi vektor sederhana
my_function(v)
yang tidak memerlukan loop:F[:] = my_vector_function(X)
(Dua poin pertama ini cukup sepele, maafkan saya jika saya menyebutkannya di sini hanya untuk kelengkapan.)
Ketiga dan yang paling poin penting, setidaknya untuk implementasi CPython, adalah untuk memeriksa apakah
my_function
menghabiskan sebagian besar itu waktu di dalam atau di luar yang juru kunci global yang , atau GIL . Jika waktu dihabiskan di luar GIL, makathreading
modul perpustakaan standar harus digunakan. ( Ini contohnya). BTW, orang bisa menganggap menulismy_function()
sebagai ekstensi C hanya untuk melepaskan GIL.Akhirnya, jika
my_function()
tidak merilis GIL, seseorang dapat menggunakanmultiprocessing
modul .Referensi: Python docs tentang Eksekusi Bersamaan , dan intro numpy / scipy pada pemrosesan paralel .
sumber
Anda dapat mencoba Julia. Ini cukup dekat dengan Python, dan memiliki banyak konstruksi MATLAB. Terjemahan di sini adalah:
Ini membuat angka acak menjadi paralel juga, dan hanya menyatukan hasilnya pada akhirnya selama pengurangan. Itu menggunakan multiprocessing (jadi Anda perlu melakukan
addprocs(N)
untuk menambahkan proses sebelum menggunakan, dan ini juga berfungsi pada beberapa node pada HPC seperti yang ditunjukkan dalam posting blog ini ).Anda juga bisa menggunakan
pmap
:Jika Anda menginginkan paralelisme utas, Anda dapat menggunakan
Threads.@threads
(walaupun pastikan Anda membuat algoritme yang aman untuk thread). Sebelum membuka Julia, setel variabel lingkungan JULIA_NUM_THREADS, lalu itu:Di sini saya membuat array terpisah untuk setiap utas, sehingga mereka tidak berbenturan ketika menambahkan ke array, kemudian hanya menggabungkan array setelahnya. Threading cukup baru sehingga saat ini hanya ada penggunaan langsung dari thread, tapi saya yakin pengurangan dan peta yang di-threaded akan ditambahkan sama seperti untuk multiprocessing.
sumber
saya sarankan untuk menggunakan fungsi paralel dan tertunda pustaka joblib menggunakan modul "tempfile" untuk membuat memori bersama temp untuk array besar, contoh dan penggunaannya dapat ditemukan di sini https://pythonhosted.org/joblib/parallel.html
sumber