Итак, в настоящее время я пытаюсь использовать библиотеку OpenMPI Python для создания параллельного приложения для обхода графа. Я не продвинулся слишком далеко, прежде чем начал замечать, что параллельные процессы не совместно использовали один и тот же объект при обмене данными:
import pandas as pd
from collections import defaultdict
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
def add_edge(u,v,graph):
graph[u].append(v)
if rank == 0:
# A list to represent our graph
graph = defaultdict(list)
# Read in data and build list of edges
df = pd.read_csv('musae_facebook_edges.csv')
data = df.head(100)
for index, row in df.iterrows():
u = row['id_1']
v = row['id_2']
add_edge(u,v,graph)
else:
graph = None
graph = comm.bcast(graph, root = 0)
if rank != 0:
#graph = comm.recv(source=0, tag=11)
print("{} has data of id: ".format(rank))
print(id(graph))
print(len(graph))
Я заметил проблему, заключающуюся в том, что при попытке записать новое значение вграфик не будет распространяться на другие узлы. Запустив вышеуказанный код через mpiexec -np 3 python graphy-search.py
, я получаю следующий вывод:
1 has data of id:
139922629199920
18357
2 has data of id:
139664148236336
18357
Очевидно, каждый процесс имеет свою собственную копию графа где-то в памяти, потому что адрес каждого объекта графа различен для каждого рабочего узлаи корневой узел. Опять же, когда я пытаюсь обновить график во время поиска, изменение не отражается на других узлах.
Я думаю, что самый простой способ решить эту проблему - просто указать идентификатор графа каждого процессадо объекта, который находится по адресу, указанному в графе корневого узла, прежде чем мы начнем поиск, но я не могу найти способ сделать это. Я понимаю, что по своей сути вы не работаете с указателями в python, но значит ли это, что нет реального способа решить эту проблему? Если это так, разве это не кажется огромным ограничением python в отношении его приложений для параллельного программирования?
Я пробовал использовать bcast, send / Recieve и т. Д. MPI, но ни один из них, похоже, не дает каких-либо других отличий. Результаты. Единственный другой вариант, который я мог видеть, - это передавать изменения обратно корневому узлу каждый раз, когда это делается ... но с количеством данных и количеством операций, необходимых для каждого процесса, что на самом деле не представляется возможным.