Я распараллеливаю научный код 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 в этом конкретном ранге. На ум приходят другие операции вместо суммы, но я стараюсь избежать таких накладных расходов.
Есть идеи?