Is this a good paralyzation problem? I have 2 really large arrays [273x1025x2048] and have to calculate stuff with them to generate 3 other equally as large arrays:
'''
Calculate stuff with 2 different arrays (input), resulting in 3 arrays (output)
'''
import numpy as np
YYY = np.linspace(-90,90,1025)
XXX = np.linspace(0,360,2048)
ZZZ = np.linspace(0,600,273)
globalvar1 = np.random.rand(np.size(ZZZ),np.size(YYY),np.size(XXX))
globalvar2 = np.random.rand(np.size(XXX),np.size(YYY),np.size(ZZZ))
def calc1(y,z):
GV1 = globalvar1[z,y,:] #array with shape (273, 1025, 2048)
GV2 = globalvar2[:,y,z] #array with shape (2048, 1025, 273)
OUT1 = np.exp(-GV1/GV2)
return OUT1
def calc2(y,z):
GV1 = globalvar1[z,y,:] #array with shape (273, 1025, 2048)
GV2 = globalvar2[:,y,z] #array with shape (2048, 1025, 273)
OUT1 = np.cos(-GV1/GV2)
return OUT1
def calc3(y,z):
GV1 = globalvar1[z,y,:] #array with shape (273, 1025, 2048)
GV2 = globalvar2[:,y,z] #array with shape (2048, 1025, 273)
OUT1 = np.sin(-GV1/GV2)
return OUT1
output1aux,output2,output3=[],[],[]
for j in range(np.size(XXX)):
output1aux,output2aux,outputaux=[],[],[]
for k in range(np.size(YYY)):
output1aux.append(calc1(j,k))
output2aux.append(calc2(j,k))
output3aux.append(calc3(j,k))
output1.append(output1aux)
output2.append(output2aux)
output3.append(output3aux)
print(XXX[j])
output1 = np.array(output1)
output2 = np.array(output2)
output3 = np.array(output3)
I tried the solution posted here: Parallelize these nested for loops in python, which involves creating wrappers for the indices and running each subroutine separately. I adapted my code to this:
import numpy as np
import multiprocessing
YYY = np.linspace(-90,90,1025)
XXX = np.linspace(0,360,2048)
ZZZ = np.linspace(0,600,273)
globalvar1 = np.random.rand(np.size(ZZZ),np.size(YYY),np.size(XXX))
globalvar2 = np.random.rand(np.size(XXX),np.size(YYY),np.size(ZZZ))
def index_wrapper1(indices):
calc1(*indices)
def index_wrapper2(indices):
calc2(*indices)
def index_wrapper3(indices):
calc3(*indices)
def calc1(y,z):
GV1 = globalvar1[z,y,:] #array with shape (273, 1025, 2048)
GV2 = globalvar2[:,y,z] #array with shape (2048, 1025, 273)
OUT1 = np.exp(-GV1/GV2)
return OUT1
def calc2(y,z):
GV1 = globalvar1[z,y,:] #array with shape (273, 1025, 2048)
GV2 = globalvar2[:,y,z] #array with shape (2048, 1025, 273)
OUT2 = np.cos(-GV1/GV2)
return OUT2
def calc3(y,z):
GV1 = globalvar1[z,y,:] #array with shape (273, 1025, 2048)
GV2 = globalvar2[:,y,z] #array with shape (2048, 1025, 273)
OUT3 = np.sin(-GV1/GV2)
return OUT3
def run():
PROCESSES = 96
print('Creating pool with %d processes\n' % PROCESSES)
with multiprocessing.Pool(PROCESSES) as pool:
XXX = np.arange(np.shape(globalvar2)[0])
YYY = np.arange(np.shape(globalvar2)[1])
ZZZ = np.arange(np.shape(globalvar2)[2])
print('Creating empty array...')
OUT1arr = np.zeros((np.size(XXX), np.size(YYY), np.size(ZZZ)))
OUT2arr = np.zeros((np.size(XXX), np.size(YYY), np.size(ZZZ)))
OUT3arr = np.zeros((np.size(XXX), np.size(YYY), np.size(ZZZ)))
print('Arrays created!')
print('Loading Pool...')
for i in range(np.size(XXX)):
print(XXX[i])
for j in range(np.size(YYY)):
OUT1arr[i,j,:] = pool.map(index_wrapper1,\
[(i,j,k) for k in range(ZZZ)])
OUT2arr[i,j,:] = pool.map(index_wrapper2,\
[(i,j,k) for k in range(ZZZ)])
OUT3arr[i,j,:] = pool.map(index_wrapper3,\
[(i,j,k) for k in range(ZZZ)])
return [OUT1arr,OUT2arr,OUT3arr]
if __name__ == '__main__':
OUTPUT = run()
print(np.shape(OUTPUT))
This seems to work not as fast as it should. The serial processing is behaving way faster. I thought this would be a good problem for the multiprocessing library. Am I missing something? As in, is this not a good paralyzation problem?
I'm using jupyter notebook, python 3, in a linux cluster. Thanks y'all!