DVMH-Indirect (1158460), страница 3

Файл №1158460 DVMH-Indirect (Раздаточные материалы) 3 страницаDVMH-Indirect (1158460) страница 32019-09-18СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 3)

i0000m(rows4 + 1 * rows3 + i * rows2) = (i — 1) * 2 + 1

i0000m(rows4 + 2 * rows3 + i * rows2) = i * 2 + 1

Enddo

для первого варианта и

Do i = begIdx, endIdx

i0000m(calc_idx(rows, i0000m, i, 1)) = (i — 1) * 2 + 1

i0000m(calc_idx(rows, i0000m, i, 2)) = i * 2 + 1

Enddo

для второго варианта, т. е. РТС выдает диапазон глобальных индексов, и компилятор ведет счет в глобальных. Такая реализация довольно медленная, далее будет цикл с указанием REFERENCE, там будет улучшенный вариант. Также возникает вопрос, как быть с тем, что множество индексов цикла исходного может переходить в не непрерывное множество индексов локальной части процесса, это, думаю, лучше решать на уровне РТС, т. е. будет несколько вызовов обработчика с непрерывными участками. Другой вариант — делаем вызов на объемлющий участок, а компилятор вставит условие проверки на включение витка, есть опасение, что будет слишком неэффективно на каждом витке иметь if.

Идем дальше – как скомпилировать такой REALIGN:

!DVM$ REALIGN cols(rows(1, i):rows(2, i) - 1) WITH rows(*, i)?

Вариант первый: конвертер, имея более широкие возможности (может сразу подставлять указанные пользователем выражения) вычисляет “поэлементное” выравнивание, прогоняя цикл по локальной части массива rows и записывая начало и конец в массив, который затем передается РТС под видом объединения интервалов. (этот вариант должен быть самым быстрым) – вполне годится.

Вариант второй: конвертер, опять же имя более широкие возможности, готовит небольшую функцию, которая будет возвращать концы интервала для каждого из индексов rows, передает ссылку на нее в РТС, а прогон осуществляет уже РТС. (помедленнее, т.к. много вызовов)

Вариант третий: придумываем как можно описать заданные пользователем формулы, передаем их в РТС, она их вычисляет. (самый медленный вариант, и сложный).

Идем дальше. Идет внешне похожий на предыдущий цикл, но с особенностями:

!DVM$ PARALLEL(i) ON rows(*, i)

Do i = 2, n - 1

cols(2 * i - 1) = i - 1

cols(2 * i) = i + 1

Enddo

Плох он тем, что выравнен на одно, а работа внутри идет совсем с другим.

При этом тут такая неприятность: rows распределен блочно, а cols, который на него выравнен, - нет. Тут нарушается наше предположение, что в параллельных циклах, отображенных на блочно-распределенный массив, все используемые массивы блочно-распределенные. Надеемся, что компилятор в силах для цикла определить все используемые в нем массивы, тогда пусть используется старая технология только если все (а не только тот, на который отображен цикл) используемые массивы распределены блочно. Тогда ничего фатального в том, что cols будет считаться распределенным поэлементно, не будет.

Лучше бы его переписать, но и в таком виде можно его скомпилировать по общему правилу: компилятор готовит два варианта выполнения и проверяет, все ли массивы распределены блочно (rows и cols). Зарисуем соответствующие обработчики:

Do i = begIdx, endIdx

i0000m(cols3 + (2 * i - 1) * cols2) = i — 1

i0000m(cols3 + (2 * i) * cols2) = i + 1

Enddo

для первого варианта и

Do i = begIdx, endIdx

i0000m(calc_idx(cols, i0000m, 2 * i - 1)) = i — 1

i0000m(calc_idx(cols, i0000m, 2 * i)) = i + 1

Enddo

для второго варианта, т. е. РТС выдает диапазон глобальных индексов, а компилятор строит обращения как к поэлементно распределенным массивам, индексируемым глобальными индексами. Этот цикл вряд ли удастся улучшить в рамках текущего предложения по расширению, так как значения индексных переменных цикла используются как значения, а значит нельзя переходить к локальной индексации.

Идем далее. Применяется полученное извне поэлементное распределение, производятся нужные выравнивания.

Теперь новые теневые грани. Теневая грань — это набор элементов, не принадлежащих текущему процессу (требование принадлежности соседнему процессу снимается), для которых

  1. возможен доступ без специальных указаний откуда угодно

  2. обновление производится указанием SHADOW_RENEW

Теневые грани для поэлементно распределенных массивов по-умолчанию пустые и их можно наращивать, т. е. директива SHADOW становится исполняемой, в ней задается множество элементов теневой грани и имя (у массива бывает несколько теневых граней). При этом множество элементов задается примерно как при выравнивании одного массива на другой. Например:

!DVM$ SHADOW x(cols(rows(1, i):rows(2, i) - 1)) NAME=own

означает создать теневую грань для массива x под названием own и отнести к ней элементы с индексами от cols(j), где j пробегает от rows(1,i) до rows(2,i)-1, перебирая всю локальную часть rows (естественно, за вычетом локальной части массива x, это РТС отбросит автоматически). Предлагаю делать так же — компилятор осуществляет проход по rows, затем проход от rows(1,i) до rows(2,i)-1 и заполняет массив ссылок, потом отдает его РТС, она вычитает локальную часть массива x и получается теневая грань с именем own. Проблема в размере этого массива — с одной стороны в том, что он потенциально довольно большой (стоит рассмотреть передачу в РТС теневой грани частями), а с другой стороны его размер и вовсе неизвестен, пока не перебрать все указанные элементы. Вероятно, следует передавать порциями, тогда обе проблемы решатся.

Далее следует довольно интересный вид параллельного цикла:

!DVM$ PARALLEL(i) ON a(i), REFERENCE(a(:) <= i)

Do i = 1, 2 * n

a(i) = 0.5

Enddo

Это — цикл с локальной индексацией. В нем сказано, что всякое обращение к массиву a есть обращение по переменной цикла i, а также, что любое использование переменной цикла i есть индексация массива a. Для такого цикла делается один вариант реализации — только с поддержкой поэлементных распределений (который, кстати говоря, в этом конкретном примере совпадает с реализацией для циклов с только блочно-распределенными массивами). В вызове loop_create делается указание на то, что цикл надо вести по локальным индексам, а чьим локальным индексам определяется правилом выравнивания. Параллельный цикл с указанием REFERENCE может быть только одномерным, в указании REFERENCE в правой части может стоять только переменная цикла, а в левой части обязан стоять массив, на который цикл отображен, а также могут находится иные массивы, но тогда действует правило связывания, т. е. компилятор, видя, что в REFERENCE в левой части не один массив, делает дополнительный вызов связывания массивов с тем, чтобы их можно было бы индексировать одним и тем же локальным индексом.

Обработчик выглядит так:

Do i = begIdx, endIdx

r0000m(a3 + i * a2) = 0.5

Enddo

Далее имеется цикл, который использует значение глобального индекса, а значит ситуация полностью аналогична второму циклу — будет сгенерировано 2 варианта и будет выбран вариант 2, в котором будет переход от глобальных индексов к локальным. Схематично обработчик:

Do i = begIdx, endIdx

r0000m(calc_idx(y, r0000m, i)) = i

Enddo

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

Далее идет новая мощная конструкция:

!DVM$ STRICT REFERENCING REGION, REFERENCE(x(:), y(:), rows(*, :) <= cols(i)), REFERENCE(a(:), cols(:) <= rows(1, i):rows(2, i) - 1)

Эта конструкция, по сути, - указание компилятору какие массивы можно будет индексировать локальными индексами, а также место пересчета индексных массивов в локальные индексы. Конструкция предполагается статической, так как активно используется компилятором и значительно влияет на генерируемый код. Ее суть пояснена в тексте программы. Остается вопрос как это скомпилировать. Можно разбить ее компиляцию на следующие этапы — определяем количество групп связанных массивов, вызываем процедуры связывания для каждой группы; затем для каждого массива из правых частей делаем вызов, который регистрирует ссылку (для не являющихся диапазонами); для диапазонов делаем свой вызов, который регистрирует ссылку на диапазон (т. е. сразу для пары индексных выражений). Так как в правой части запрещены каскадные индексации и арифметические операции с i (но разрешены линейные преобразования над значениями индексных массивов), то не будет неподъемной задачей выразить то, что написал там пользователь. Так как требования довольно жесткие по индексации в ней выражаются, то дополнительно надо будет включать ее действие в циклах указанием BYREF, дабы не было нужды разрывать такой регион (что может быть очень дорого), тем более, что он никак не мешает обрабатывать циклы так же, как и вне такого региона (слово регион вроде как уже занято, но другого не придумалось). Это указание BYREF и есть пометка цикла, как цикла по графу, но без слова граф и специфических для него понятий вроде вершин и ребер.

Про оставшиеся два цикла пояснения в программе довольно развернутые. Здесь упомяну, что компилятор для них делает только 1 вариант — с поддержкой поэлементных распределений и действует с выполнением указаний REFERENCE, т. е. всякая ссылка на массив, появляющийся в левой части указания REFERENCE делается по локальным индексам, а всякая ссылка на массив, появляющийся в правой части указания REFERENCE заменяется на ссылку на другой массив, который подготовит РТС при входе в этот регион (в нем значения будут локальными индексами). При этом если массив встречается и в левой части и в правой, то применяются оба правила — ссылка заменяется на ссылку на другой массив, а индексируется он локальными индексами.

Рассмотрим следующий цикл:

!DVM$ PARALLEL(i) ON x(i), BYREF

Do i = 1, n

x(i) = y(i)

Enddo

Его обработчик будет выглядеть так:

Do i = begIdx, endIdx

r0000m(x3 + i * x2) = r0000m(y3 + i * y2)

Enddo

То есть прямо как для блочно-распределенных массивов.

Следующий цикл уже немного интереснее:

!DVM$ PARALLEL(i) ON y(i), BYREF, SHADOW_RENEW(x(own))

Do i = 1, n

s = 0

Do j = rows(1, i), rows(2, i) - 1

s = s + a(j) * x(cols(j))

Enddo

y(i) = s

Enddo

Его обработчик будет выглядеть так:

Do i = begIdx, endIdx

s = 0

Do j = i0000m(rows_localized4 + 1 * rows_localized3 + i * rows_localized2), i0000m(rows_localized4 + 2 * rows_localized3 + i * rows_localized2) - 1

s = s + r0000m(a3 + j * a2) * r0000m(x3 + i0000m(cols_localized3 + j * cols_localized2) * x2)

Enddo

r0000m(y3 + i * y2) = s

Enddo

Пример программы. Неструктурные сетки.

Используем имеющиеся конструкции, но расширяем их возможности.

Рассмотрим пока только узловые функции. При этом, как следствие, неважно какова размерность пространства – геометрические свойства ячеек и прочее, имеется только набор «соседей».

Пример – алгоритм Якоби на кольце.

Исходная программа:

Program test2

Parameter (nnode=1000, maxneigh=10)

Real fi(nnode), psi(nnode)

Integer neighbor(nnode, maxneigh)

! Кол-во соседей

Integer neighbors(nnode)

! Init

! Grid

Do I = 1, nnode

! одномерное кольцо

Neighbors(i) = 2

Neighbor(I, 1) = modulo(I, nnode) + 1

Neighbor(I, 2) = modulo(I – 2, nnode) + 1

Enddo

! Functions

Do I = 1, nnode

Fi(i) = 1

Psi(i) = 2

enddo

! Calculate

Do it = 1, itcount

! Jacobi iteration

Do I = 1, nnode

Psi(i) = 0

Do j = 1, neighbors(i)

Psi(i) = psi(i) + fi(neighbor(I,j)) / neighbors(i)

enddo

Enddo

Do I = 1, nnode

fi(i) = 0

Do j = 1, neighbors(i)

fi(i) = fi(i) + psi(neighbor(I,j)) / neighbors(i)

enddo

Enddo

enddo

end

DVM-программа:

Program test2dvm

Parameter (nnode=1000, maxneigh=10)

Real fi(nnode), psi(nnode)

Integer neighbor(nnode, maxneigh)

! Кол-во соседей

Integer neighbors(nnode)

!DVM$ ALIGN :: fi, psi, neighbor, neighbors

!DVM$ DYNAMIC :: fi, psi, neighbor, neighbors

!DVM$ SHADOW neighbor(0:0, 0:0)

!DVM$ SHADOW neighbors(0:0)

! Init

!DVM$ REDISTRIBUTE(BLOCK) :: neighbors

!DVM$ REALIGN neighbor(I, *) with neighbors(i)

! Grid

!DVM$ PARALLEL(i) on neighbors(i)

Do I = 1, nnode

Характеристики

Список файлов учебной работы

Свежие статьи
Популярно сейчас
Зачем заказывать выполнение своего задания, если оно уже было выполнено много много раз? Его можно просто купить или даже скачать бесплатно на СтудИзбе. Найдите нужный учебный материал у нас!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6510
Авторов
на СтудИзбе
302
Средний доход
с одного платного файла
Обучение Подробнее