Search code examples
python-3.xnumpyparallel-processingpython-multiprocessing

python-3 parallelizing my functions issue


I am using python-3.x and I would like to speed my code by parallelizing my functions using the multiprocessing, I applied the multiprocessing but for some reason, it didn't work probably, I am not sure where is the problem?

so the following is a small example of what I did. Any suggestions are appreciated

import numpy as np
import math
import multiprocessing as mp

lower_bound = -500
upper_bound =500 
dimension =1000
Base_Value = 10
Popula_size = 3000
MinResolution = 8

population_in = np.random.choice ( np.linspace ( lower_bound , upper_bound , Base_Value ** MinResolution ) , size = ( Popula_size , dimension ) , replace = True )
resolution = np.random.randint(1, 8, size = (1, dimension))

def Discretiz(lower_bound, upper_bound, DiscPopulation, resolution):
        
    pop_size = int(len(DiscPopulation))
    the_new_population = np.zeros ((pop_size, dimension))
    for i in range (pop_size) :
        for ii in range (dimension):          
            decimal = int(np.round((DiscPopulation[i][ii] - lower_bound) / ((upper_bound-lower_bound)/(math.pow(Base_Value,resolution[:,ii])-1))))
            the_new_population[i, ii]  = (lower_bound + decimal *  ((upper_bound-lower_bound)/(math.pow(Base_Value,resolution[:,ii])-1)))
    return the_new_population


# without_parallelizing
# the_new_population = Discretiz(lower_bound, upper_bound, population_in, resolution)


# wit_parallelizing
pool = mp.Pool(mp.cpu_count())
the_new_population = [pool.apply(Discretiz, args=(lower_bound, upper_bound, population_in, resolution))]


print (the_new_population)

Solution

  • With:

    population_in = np.random.choice ( np.linspace ( lower_bound , upper_bound , Base_Value ** MinResolution ) , size = ( Popula_size , dimension ) , replace = True )
    

    you make a 2d array (Popula_size, dimension) shape. This is passed as DiscPopulation.

    resolution = np.random.randint(1, 8, size = (1, dimension))
    

    The double iteration function can be replaced with one that operates on whole arrays without the slow iteration:

    def Discretiz(lower_bound, upper_bound, DiscPopulation, resolution):
        pop_size = DiscPopulation[0]  # no need for the 'int'
        num = DiscPopulation - lower_bound
        divisor = (upper_bound-lower_bound)/(Base_value**resolution-1)
        decimal = num/divisor
        # this divide does (pop,dimension)/(1,dimension); ok by broadcasting)
        decimal = np.round(decimal)  # no need for int
        the_new_population = lower_bound + decimal * divisor
        return the_new_population
    

    I wrote this in-place here. It is syntactically correct, but I have not tried to run it.