Создание MPI-коммуникаторов для чтения файлов

Мне нужна некоторая помощь с коммуникаторами MPI, предмет, который я относительно новый.

У меня есть код MPI, который будет читать входные данные из нескольких входных файлов. Каждый процесс будет читать по крайней мере из одного файла, большинство будет читать из более чем одного. Каждый файл будет прочитан.

Мне нужно создать коммуникатор для каждого файла. Скажем, например, что процессы 0, 1 и 2 читают из файла "A.dat", процессы 2, 3 и 4 читают из файла "B.dat", а процессы 4, 5 и 6 читают из "C. Дат". (На практике будет гораздо больше процессов и файлов.) Поэтому мне нужно три коммуникатора. Первый должен содержать процы 0, 1 и 2; вторые 2, 3 и 4; третьи 4, 5 и 6. Я довольно в растерянности относительно того, как это сделать. Кто-нибудь знает как?

1 ответ

Решение

Можно разделить более крупный коммуникатор на более мелкие коммуникаторы некоторого предпочтительного размера:

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) {
    // Initialize the MPI environment
    MPI_Init(NULL, NULL);

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

    int color = world_rank / 4; //4 process (colors) for each communicator

    MPI_Comm row_comm;

    /*
     The first argument is the communicator that will be used as the basis for the new communicators.
     The second argument determines to which new communicator each processes will belong.
     The third argument determines the ordering (rank) within each new communicator...
     The process which passes in the smallest value for the third argument will be rank 0, the next smallest will be rank 1, and so on.
     The final argument returns the new communicator back to the user.
     */
    MPI_Comm_split(MPI_COMM_WORLD, color, world_rank, &row_comm);

    int row_rank, row_size;
    MPI_Comm_rank(row_comm, &row_rank);
    MPI_Comm_size(row_comm, &row_size);

    printf("WORLD RANK/SIZE: %d/%d \t ROW RANK/SIZE: %d/%d\n",
           world_rank, world_size, row_rank, row_size);

    MPI_Comm_free(&row_comm);

    // Finalize the MPI environment.
    MPI_Finalize();
}

Или вы можете создавать группы (более гибкий способ)

#include <mpi.h>
#include <stdio.h>

int main(int argc, char** argv) {
    // Initialize the MPI environment
    MPI_Init(NULL, NULL);

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

    // Get the group of processes in MPI_COMM_WORLD
    MPI_Group world_group;
    MPI_Comm_group(MPI_COMM_WORLD, &world_group);

    int prime_group_size = 6;
    const int ranks[6] = {2, 3, 5, 7, 11, 13};

    // Construct a group containing all of the prime ranks in world_group
    MPI_Group prime_group;
    MPI_Group_incl(world_group, prime_group_size, ranks, &prime_group);

    // Create a new communicator based on the group
    MPI_Comm prime_comm;
    MPI_Comm_create_group(MPI_COMM_WORLD, prime_group, 0, &prime_comm);

    int prime_rank = -1, prime_size = -1;
    // If this rank isn't in the new communicator, it will be
    // MPI_COMM_NULL. Using MPI_COMM_NULL for MPI_Comm_rank or
    // MPI_Comm_size is erroneous
    if (MPI_COMM_NULL != prime_comm) {
        MPI_Comm_rank(prime_comm, &prime_rank);
        MPI_Comm_size(prime_comm, &prime_size);

        printf("WORLD RANK/SIZE: %d/%d \t PRIME RANK/SIZE: %d/%d\n",
               world_rank, world_size, prime_rank, prime_size);

        MPI_Group_free(&prime_group);
        MPI_Comm_free(&prime_comm);
    }


    MPI_Group_free(&world_group);

    // Finalize the MPI environment.
    MPI_Finalize();
}

ССЫЛКА

Другие вопросы по тегам