Reputation: 2659
I have a Python script like this:
from modules import functions
a=1
parameters = par_vals
for i in range(large_number):
#do lots of stuff dependent on a, plot stuff, save plots as png
When I run this for a value of "a" it takes half an hour, and uses only 1 core of my 6 core machine.
I want to run this code for 100 different values of "a"
The question is: How can I parallelize this so I use all cores and try all values of "a"?
my first approach following an online suggestion was:
from joblib import Parallel, delayed
def repeat(a):
from modules import functions
parameters = par_vals
for i in range(large_number):
#do lots of stuff dependent on a, plot stuff, save plots as png
A=list_100_a #list of 100 different a values
Parallel(n_jobs=6,verbose=0)(delayed(repeat)(a) for a in A)
This successfully use all my cores in the computer but it was computing for all the 100 values of a at the same time. after 4 hours my 64GB RAM memory and 64GB swap memory would be saturated and the performance dropped drastically. So I tried to manually cue the function doing it 6 times at a time inside a for loop. But the problem was that the memory would be consumed also.
I don't know where the problem is. I guess that somehow the program is keeping unnecessary memory.
What can I do so that I don't have this memory problem.
In summary: When I run this function for a specific value of "a" everything is ok. When I run this function in parallel for 6 values of "a" everything is ok. When I sequencially run this function in parallel the memory gradually inscreases until the computer can no longer work.
UPDATE: I found a solution for the memory problem even though I don't understand why.
It appears that changing the backend of matplotlib to 'Agg' no longer produced the memory problem.
just add this before any import and you should be fine:
from matplotlib import use
use('Agg')
Upvotes: 0
Views: 1405
Reputation: 5993
Here's how I would do it with multiprocessing
. I'll use your repeat
function to do the work for one value of a
.
def repeat(a):
from modules import functions
parameters = par_vals
for i in range(large_number):
#do lots of stuff dependent on a, plot stuff, save plots as png
Then I'd use multiprocessing.pool
like this:
import multiprocessing
pool = multiprocessing.Pool(processes=6) # Create a pool with 6 workers.
A=list_100_a #list of 100 different a values
# Use the workers in the pool to call repeat on each value of a in A. We
# throw away the result of calling map, since it looks like the point of calling
# repeat(a) is for the side effects (files created, etc).
pool.map(repeat, A)
# Close the pool so no more jobs can be submitted to it, then wait for
# all workers to exit.
pool.close()
pool.join()
If you wanted the result of calling repeat, you could just do result = pool.map(repeat, A)
.
I don't think you'll run into any issues, but it's also useful to read the programming guidelines for using multiprocessing
.
Upvotes: 1