Я хотел бы распараллелить скрипт, который возвращает список неэквивалентных объектов. (На практике «объекты» - это графы, и я ищу наборы неизоморфных графов в очень больших наборах графов.)
Вот некоторый псевдокод:
from itertools import combinations
from multiprocessing import Pool
p = Pool(number_of_threads)
def find_nonequivalent_objects(n,m):
list_of_objects = []
# LOOP 1: many billions of combinations
for c in combinations(n,m):
new_obj = generate_object_from_combination(c)
if not len(list_of_objects)==0:
compare_to_new_obj = lambda old_obj: check_equivalence(new_obj,
old_obj)
# MAP 1: a few hundred comparisons
if not np.any(map(compare_to_new_obj, list_of_objects)):
list_of_objects = list_of_objects + [new_obj]
else:
list_of_objects = [new_obj]
# return a list of a few hundred objects
return list_of_objects
IСначала попытался использовать p.map
для MAP 1 (заменив лямбда-функцию на functools.partial
), но дополнительные накладные расходы компенсировали ускорение, поэтому общее время выполнения увеличилось. Похоже, что лучший подход будет разделить LOOP 1 на куски. Для этого потребуется что-то вроде этого:
list_of_lists_of_objects = pool.map(LOOP1_function, combinations(n,m))
# compare list_of_objects from different chunks
for i in range(1, number_of_threads):
for new_obj in list_of_lists_of_objects[i]:
compare_to_new_obj = lambda old_obj: check_equivalence(new_obj, old_obj)
if not np.any(map(compare_to_new_obj, list_of_lists_of_objects[0])):
list_of_lists_of_objects[0] = list_of_lists_of_objects[0] + [new_obj]
list_of_objects = list_of_lists_of_objects[0]
Это приводит меня к двум проблемам:
Насколько я понимаю, использование p.map
в LOOP 1 означает, чтоЯ прошу машину создать список itertools.combinations(n,m)
. Это может привести к проблемам с памятью.
Каждый работник или блок должен иметь свой собственный list_of_objects
. Как я могу это сделать?