Right now I'm working on a task where I have create a huge symmetrical numpy array (e.g. a 1788x1788 matrix), calculate the values for the upper triangle (as it's symmetrical, it saves me 50% time) and them mirror it down to the under triangle.
Right now, my code looks like this:
# Create an array with the correct size
matrix_M = np.zeros((numb_functions, numb_functions))
# For each value in the upper triangle, calculate the wanted value and insert it into the matrix
for k in range(len(matrix_M)):
for l in range(k, len(matrix_M)):
matrix_M[k, l] = matrix_m_value_calculation(k, l, list_function_hashes, functions_dict)
# Mirror the upper triangle to the under triangle to get the complete matrix
inds = np.triu_indices_from(matrix_M, k=1)
matrix_M[(inds[1], inds[0])] = matrix_M[inds]
This works fine so far! It takes a while, but it gets the job done.
But since it takes so long, the idea was to create a Pool
and call matrix_m_value_calculation
with all possible combinations of k,l and use the results to fill the matrix_M. However, this got me into a couple of issues as:
- Using
apply_async
so many times on the same pool uses lots of memory, resulting in memory issues. - Creating a new
Pool
for each iteration solves the memory issue, but is slower than not using multiprocessing at all (the penalty of spawning/forking a new process is bigger than the run time of the function itself) map
/starmap
wants to have an iterable. Here, I'm not sure how to recreate this nested loop in one statement (maybe this is the solution?) and passing all possible combinations ofk,l
also results requires way too much memory for this to actually work.- Putting all combinations of k,l in a
multiprocessing.Queue
to pass to another process takes way less memory than the other approach, but it's still unfeasible and I run out of memory eventually.
So, my current idea is that I need to combine this nested loop in one iterable that I can pass to a Pool without running out of memory. What's a good approach to solve this?