MPI: сбор данных синтаксического анализа для всех процессов - PullRequest
0 голосов
/ 19 июня 2020

Я распараллеливаю научный код c с MPI, в котором определенные вычисления выполняются в виде сетки (массива). В этом массиве хранится распределенная вероятность, которая понадобится затем для различных вычислений в каждой из задач.

Чтобы распределить эти вычисления, я пришел к выводу, что лучший способ сбалансировать вычислительную нагрузку - это сделать каждая отдельная задача MPI выполняет вычисление для каждой позиции, которая является целым числом, кратным идентификатору задачи (фактически, идентификатор задачи +1). Например, при выполнении mpi с четырьмя задачами (mpi_size = 4), если в массиве 10 элементов, задача 1 будет вычислять позиции 1, 5 и 9; задание 2: 2, 6 и 10; задание 3: 3 и 7; задача 4: 4 и 8.

Итак, по сути, в каждой задаче я запускаю al oop над массивом с шагом mpi_size и начиная со смещения = (идентификатор задачи + 1). После этого мне нужно, чтобы все задачи имели результаты, которые были вычислены всеми другими задачами. Это похоже на типичный случай mpi_allgatherv, но, насколько я понимаю, нет способа собрать разрозненные данные таким образом, поскольку сообщение каждой задачи затем сохраняется в кластерах. Графическое объяснение того, что я имею в виду (до операции MPI --left--, «vn» будет значениями, обновленными текущей задачей, тогда как пробелы будут значениями, обновленными другими задачами):

Sparse computation of V (what I am trying to achieve):                       
task#1: V#1 = [v1][  ][  ][  ][v5][  ][  ][  ][v9][   ]
task#2: V#2 = [  ][v2][  ][  ][  ][v6][  ][  ][  ][V10] => V#1=V#2=V#3=V#4 = [v1][v2]...[v9][v10]
task#3: V#3 = [  ][  ][v3][  ][  ][  ][v7][  ][  ][   ]  ^
task#4: V#4 = [  ][  ][  ][v4][  ][  ][  ][v8][  ][   ]  ( HOW ??? )

Clustered computation of V    
task#1: V#1 = [v1][v2][v3][  ][  ][  ][  ][  ][  ][   ]      
task#2: V#2 = [  ][  ][  ][v4][v5][v6][  ][  ][  ][   ] => V#1=V#2=V#3=V#4 = [v1][v2]...[v9][v10]
task#3: V#3 = [  ][  ][  ][  ][  ][  ][v7][v8][  ][   ]  ^    
task#4: V#4 = [  ][  ][  ][  ][  ][  ][  ][  ][v9][v10]  ( MPI_ALLGATHERV )

Самое простое решение, которое я нашел, - это использовать allreduce с, например, операцией MPI_SUM, где элементы, которые не вычисляются в каждом ранге (пробелы выше), устанавливаются на 0 в этом конкретном ранге. На ум приходят другие операции вместо суммы, но я стараюсь избежать таких накладных расходов.

Есть идеи?

...