Ортогональная рекурсивная бисекция в часовне (алгоритм Барнса-Хата) - PullRequest
0 голосов
/ 26 февраля 2019

Я реализую распределенную версию симуляции тела Барнса-Хата в часовне.Я уже реализовал последовательную и разделяемую версии памяти, которые доступны на моем GitHub .

. Я следую алгоритму, описанному здесь (Глава 7):

  1. Выполнить ортогональную рекурсивную пополам и распределить тела так, чтобы у каждого процесса было одинаковое количество работы
  2. Построить локально существенное дерево для каждого процесса
  3. Вычислить силы и выдвинуть тела

У меня есть довольно хорошая идея о том, как реализовать алгоритм в C / MPI, используя MPI_Allreduce для деления пополам и простой передачи сообщений для связи между процессами (для передачи тела).А также MPI_Comm_split - очень удобная функция, которая позволяет мне разделять процессы на каждом шаге ORB.

У меня возникают некоторые проблемы при выполнении ORB с использованием параллельных / распределенных конструкций, которые предоставляет Chapel.Мне нужен какой-то способ суммирования (сокращения) работы между процессами (локали в часовне), разделения процессов на группы и межпроцессного взаимодействия для передачи тел.

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

1 Ответ

0 голосов
/ 30 марта 2019

После множества тупиков и сбоев мне удалось реализовать алгоритм в Chapel.Это можно найти здесь: https://github.com/novoselrok/parallel-algorithms/tree/75312981c4514b964d5efc59a45e5eb1b8bc41a6/nbody-bh/dm-chapel

Мне не удалось использовать большую часть необычного параллельного оборудования, которое предоставляет Часовня.Я полагался только на блочные распределенные массивы с sync элементами.Я также реплицировал модель SPMD.

В main.chpl Я настроил все необходимые массивы, которые будут использоваться для передачи данных.Каждый массив имеет соответствующий массив sync, используемый для синхронизации.Затем каждый работник начинается со своей доли тел и ранее упомянутых массивов.Worker.chpl содержит основную часть алгоритма.

Я заменил функциональность MPI_Comm_split на пользовательскую функцию determineGroupPartners, где я делаю то же самое вручную.Что касается MPI_Allreduce, я нашел хороший небольшой шаблон, который мог бы использовать везде:

var localeSpace = {0..#numLocales};
var localeDomain = localeSpace dmapped Block(boundingBox=localeSpace);

var arr: [localeDomain] SomeType;
var arr$: [localeDomain] sync int; // stores the ranks of inteded receivers
var rank = here.id;

for i in 0..#numLocales-1 {
    var intendedReceiver = (rank + i + 1) % numLocales;
    var partner = ((rank - (i + 1)) + numLocales) % numLocales;

    // Wait until the previous value is read
    if (arr$[rank].isFull) {
        arr$[rank];
    }

    // Store my value
    arr[rank] = valueIWantToSend;
    arr$[rank] = intendedReceiver;

    // Am I the intended receiver?
    while (arr$[partner].readFF() != rank) {}

    // Read partner value
    var partnerValue = arr[partner];

    // Do something with partner value

    arr$[partner]; // empty

    // Reset write, which blocks until arr$[rank] is empty
    arr$[rank] = -1;
}

Это несколько сложный способ реализации каналов FIFO (см. Julia RemoteChannel, где я получил вдохновение для этого шаблона).«).Обзор:

  • Сначала каждая локаль вычисляет своего предполагаемого получателя и своего партнера (где локаль будет читать значение)

  • Локаль проверяет, еслипредыдущее значение было прочитано

  • Locales сохраняет новое значение и «блокирует» значение, устанавливая arr$[rank] с помощью получателя

  • Localeждет, пока его партнер установит значение и установит соответствующий предполагаемый получатель

  • Как только локаль станет предполагаемым получателем, она считывает значение партнера и выполняет с ним некоторую операцию

  • Затем локаль очищает / разблокирует значение, читая arr$[partner]

  • Наконец, оно сбрасывает arr$[rank], записывая -1.Таким образом, мы также гарантируем, что значение, установленное локалью, было прочитано предполагаемым получателем

Я понимаю, что это может быть слишком сложным решением для этой проблемы.Вероятно, существует лучший алгоритм, который бы соответствовал глобальному представлению Chapels о параллельных вычислениях.Алгоритм, который я реализовал, пригоден для модели вычислений SPMD.

При этом я думаю, что Chapel по-прежнему хорошо справляется с работой. Здесь - это показатели производительности для Julia и C / MPI.По мере роста числа процессов производительность значительно возрастает.У меня не было возможности запустить тест на кластере с> 4 узлами, но я думаю, что Chapel получит респектабельные тесты.

...