MPI_Reduce и MPI_Allreduce — Как хранить отдельные итоги на узле с рангом 0?

#c #parallel-processing #mpi

Вопрос:

Я пытаюсь создать программу, которая распределяет процессы по разным группам, а затем каждая подгруппа суммирует свой мир и ранги подгрупп, используя MPI_Reduce.

Так, например, скажем, у меня есть MPI_COMM_WORLD размер 6. А затем я разделил их на 3 подгруппы. Каждая подгруппа будет иметь 2 узла с мировым рангом и рангом подгруппы. (Например, для узла № 3 он будет иметь мировой ранг 3 и ранг подгруппы 1)

Я успешно реализовал эту часть ниже:

 MPI_Init(NULL, NULL);

// Get the rank and size in the original communicator
int world_rank, world_size;
MPI_Comm_rank(MPI_COMM_WORLD, amp;world_rank);
MPI_Comm_size(MPI_COMM_WORLD, amp;world_size);

int group_size = 2;
int color = world_rank / group_size; // Determine color based on subgroup

// Split the communicator based on the color and use the original rank for ordering
MPI_Comm sub_comm;
MPI_Comm_split(MPI_COMM_WORLD, color, world_rank, amp;sub_comm);

int sub_rank, sub_size;
MPI_Comm_rank(sub_comm, amp;sub_rank);
MPI_Comm_size(sub_comm, amp;sub_size);
 

Теперь мне нужно, чтобы отдельные итоги хранились на узлах с рангом подгруппы 0. Это то, что у меня есть до сих пор:

 // Sum the numbers locally
int local_sum[1] = {0};
int global_sum[1] = {0};

if(sub_rank == 0) {
    for (int i = 0; i < group_size; i  ) {
        local_sum[0]  = (world_rank   sub_rank);
    }
    //subgroup sum
    printf("local_sum = %d n", local_sum[0]);
}
 

При последующем вызове MPI_Allreduce эти узлы должны умножать частичные результаты. Узел с МИРОВЫМ рангом 0, наконец, выводит результат.

Вот где у меня сейчас возникают проблемы. Как я могу использовать MPI_Reduce для суммирования локальных подгрупп, а затем использовать MPI_Allreduce для умножения частичных результатов?

Любая помощь была бы очень признательна.

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

1. Развивая этот комментарий, вам нужен «охватывающий» коммуникатор, который соединяет один ранг от каждого из субкомов. Вы можете сделать это, вызвав MPI_Comm_split с цветом=sub_rank. Для вашего конкретного примера, который даст вам два коммуникатора, каждый размером 3. Предполагая, что это sub_rank=0, у которого есть частичная сумма, которую вы могли бы затем выполнить: если (sub_rank == 0) MPI_Allreduce (…, span_comm);