Разброс словаря в python с использованием MPI

#python #numpy #mpi #mpi4py

#python #numpy #mpi #mpi4py

Вопрос:

Я довольно новичок в мире python и MPI. Я смотрю на метод scatter и задаюсь вопросом, возможно ли разбросать словарь.

Я работал с целыми числами и другими типами данных, но поскольку словарь может содержать что угодно, я не уверен, что его можно разбросать как объект numpy. Ниже приведено то, что я пробовал, но это, очевидно, не работает. Я не знаю, как разбросать «данные», даже если это возможно, поскольку данные — это словарь.

 from mpi4py import MPI
import numpy as np

comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()

#data = None
data = {'a': 7,'b': 3.14}
if rank == 0:
   data = np.linspace(1,size) #this is wrong...how do I scatter a dictionary

recvbuf = np.empty(data,dtype=None)
print  comm.Scatter(data, recvbuf, root=0)

print "Rank: ",rank," recvbuf received:",recvbuf
  

Ответ №1:

Из документации mpi4py:

Он поддерживает двухточечную (отправляет, получает) и коллективную (транслирует, рассеивает, собирает) связь любого выделяемого объекта Python, а также оптимизированную связь объекта Python, предоставляющую интерфейс односегментного буфера (массивы NumPy, встроенные объекты bytes / string / array)

Методы для выбираемых объектов python (таких как словари) отличаются от методов для объектов, предоставляющих интерфейс с односегментным буфером. Вам придется работать либо с первым, либо со вторым семейством методов.

В вашем случае, я полагаю, вы хотите разбросать словарь как пару ключ / значение. Следующее работает не так, как вы могли ожидать, поскольку разбросаны только ключи словаря:

 from __future__ import print_function
from collections import OrderedDict
from mpi4py import MPI

comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()

if rank == 0:
    data = OrderedDict({'a': 7, 'b': 3.14})
else:
    data = None

data = comm.scatter(data, root=0)

data_type = type(data)
print(f'Data is {data} on rank {rank} with type {data_type}')

# Output
# Data is a on rank 0 with type <class 'str'>
# Data is b on rank 1 with type <class 'str'>
  

В вашем случае лучшим подходом кажется создание списка словарей и его разброс:

 from __future__ import print_function
from collections import OrderedDict
from mpi4py import MPI

comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()

if rank == 0:
    data = [{'a': 7}, {'b': 3.14}]
else:
    data = None

data = comm.scatter(data, root=0)

data_type = type(data)
print(f'Data is {data} on rank {rank} with type {data_type}')

# Output:
# Data is {'a': 7} on rank 0 with type <class 'dict'>
# Data is {'b': 3.14} on rank 1 with type <class 'dict'>
  

Комментарии:

1. Взгляните на dask, который поддерживает распределенные наборы данных. Похоже, это то, что вы хотите.