Новости
О Центре
Кластер
Обучение
Основной курс по параллельному программированию
Учебные курсы
Магистратура
Дополнительное образование
Работы студентов
Библиотека
Исследования
Конференции
Полезные ссылки
NVIDIA
Контакты
О сайте
Имя:
Пароль:
запомнить:
Забыли пароль? Регистрация

Параллельная схема

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

В приведённом ниже коде для краткости опущен ввод/вывод, а также реализация самого поиска в ширину.

struct link_data
{
    int articles_count, links_count;
    std::vector link_indices, link_targets;
};

struct article_metrics
{
    int eccentricity;
    double average_dist;
    int farthest;
};

MPI_Datatype g_mpi_article_metrics;

void void_MPI_Finalize()
{
    MPI_Finalize();
}

void free_mpi_article_metrics()
{
    MPI_Type_free(&g_mpi_article_metrics);
}

int main(int argc, char * argv[])
{
    MPI_Init(&argc, &argv);
    atexit(void_MPI_Finalize);

    int * host, flag, rank, size;
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_HOST, &host, &flag);

    if (!flag)
        return EXIT_FAILURE;

    int article_metrics_blocklengths[] = { 1, 1, 1, 1 }; 
    MPI_Aint article_metrics_displacements[] = {
        offsetof(article_metrics, eccentricity),
        offsetof(article_metrics, average_dist),
        offsetof(article_metrics, farthest),
        sizeof(article_metrics)
    };
    MPI_Datatype article_metrics_types[] =
    { MPI_INT, MPI_DOUBLE, MPI_INT, MPI_UB };

    MPI_Type_struct(
        sizeof article_metrics_types / sizeof *article_metrics_types,
        article_metrics_blocklengths,
        article_metrics_displacements,
        article_metrics_types,
        &g_mpi_article_metrics
    );

    MPI_Type_commit(&g_mpi_article_metrics);
    atexit(free_mpi_article_metrics);

    int scalars[2];
    link_data data;
    std::vector components;

    if (rank == *host)
    {
        // вводим data и components

        scalars[0] = data.articles_count;
        scalars[1] = data.links_count;
    }

    MPI_Bcast(scalars, 2, MPI_INT, *host, MPI_COMM_WORLD);

    if (rank != *host)
    {
        data.articles_count = scalars[0];
        data.links_count = scalars[1];
        data.link_indices.resize(data.articles_count + 1);
        data.link_targets.resize(data.links_count);
        components.resize(data.articles_count);
    }

    MPI_Bcast(&data.link_indices.front(), data.articles_count + 1, MPI_INT,
        *host, MPI_COMM_WORLD);
    MPI_Bcast(&data.link_targets.front(), data.links_count, MPI_INT, *host,
        MPI_COMM_WORLD);
    MPI_Bcast(&components.front(), data.articles_count, MPI_INT, *host,
        MPI_COMM_WORLD);

    std::vector queue(data.articles_count);
    std::vector distances(data.articles_count);
    std::vector part_lengths(size), part_disps(size);

    int part_length = (data.articles_count + size - 1) / size;

    for (int i = 0; i < size; ++i)
    {
        part_lengths[i] = part_length;
        part_disps[i] = part_length * i;
    }

    if (part_length * size != data.articles_count)
        part_lengths[size - 1] = data.articles_count % part_length;

    std::vector partial_results(part_lengths[rank]);

    for (int i = 0; i < part_lengths[rank]; ++i)
    {
        if (components[i + part_disps[rank]] == -1) continue;

        calculate_metrics(i + part_disps[rank], data.articles_count,
            &data.link_indices.front(), &data.link_targets.front(),
            &components.front(), &queue.front(), &distances.front(),
            &partial_results[i]);
    }

    if (rank == *host)
    {
        std::vector full_results(data.articles_count);

        MPI_Gatherv(&partial_results.front(), part_lengths[rank],
            g_mpi_article_metrics, &full_results.front(), &part_lengths.front(),
            &part_disps.front(), g_mpi_article_metrics, rank, MPI_COMM_WORLD);

        // выводим full_results
    }
}

Новости

22.10.2012
04.09.2012
05.04.2012
06.03.2012
02.03.2012