rtsIDr (1158449), страница 24
Текст из файла (страница 24)
u0,j , uk-1,j , ui,0 , ui,k-1 (i,j = 0, ... , k-1)
определены краевыми условиями.
В представленных ниже программах (Фортран и C) решение уравнения (1) ищется по формулам (2) методом последовательных приближений. Итерационный процесс считается завершённым, если максимальное по всем узлам отклонение сеточной функции ui,j для двух последовательных итераций станет меньше значения переменной maxeps. В качестве начальных значений сеточной функции принимаются ui,j = 1+i+j (i,j = 1, … , k-2). Краевые условия нулевые: u0,j=0, uk-1,j=0, ui,0=0, ui,k-1=0 (i,j = 0, ... , k-1). Решение ищется на квадрате [0:7, 0:7].
ПРОГРАММА НА ЯЗЫКЕ ФОРТРАН
program cross
integer linit, lexit, getam, getps, crtamv, distr, crtda, align,
+ crtpl, dvmadr, mappl, endpl, exfrst, imlast, dopl,
+ tstio, crtrg, crtred, insred, strtrd, waitrd,
+ crtshg, inssh, strtsh, waitsh, delrg, delshg
real bptr(1)
integer dvm
integer amref, psref, mvref, plref, rgref, redref, shgref
integer amdim(2), disaxs(2), dispar(2)
integer shwdth(2), axis(2), coeff(2), const(2)
integer lvaddr(2), lvtype(2), iiniti(2), ilasti(2), istep(2)
integer oiniti(2), olasti(2), ostep(2)
C Число точек сетки по каждому измерению
С и максимальное число итераций
parameter (k = 8, itmax = 20)
real eps, maxeps
C Заголовок массива с предыдущими значениями сеточной функции
integer ahdr(3)
C Заголовок массива со следующими значениями сеточной функции
integer bhdr(3)
maxeps = 0.5e-7
C Инициализация системы поддержки
dvm = linit (0)
C Создание представления абстрактной машины
C и отображение его в процессорную подсистему
amref = getam ()
psref = getps (amref)
amdim(1) = k
amdim(2) = k
mvref = crtamv (amref, 2, amdim,0)
disaxs(1) = 1
disaxs(2) = 2
dispar(1) = 0
dispar(2) = 0
dvm = distr (mvref, psref, 2, disaxs, dispar)
C Создание и распределение массивов
C со значениями сеточной функции
shwdth(1) = 1
shwdth(2) = 1
dvm = crtda (ahdr, 1, bptr, 2, 4, amdim, 0, 0, shwdth, shwdth)
dvm = crtda (bhdr, 1, bptr, 2, 4, amdim, 0, 0, shwdth, shwdth)
axis(1) = 1
axis(2) = 2
coeff(1) = 1
coeff(2) = 1
const(1) = 0
const(2) = 0
dvm = align (ahdr, mvref, axis, coeff, const)
dvm = align (bhdr, mvref, axis, coeff, const)
C Параллельный цикл инициализации массивов
C со значениями сеточной функции
C (параллельный цикл с базовым массивом ahdr)
plref = crtpl (2)
lvaddr(1) = dvmadr (j)
lvaddr(2) = dvmadr (i)
lvtype(1) = 1
lvtype(2) = 1
iiniti(1) = 0
iiniti(2) = 0
ilasti(1) = k - 1
ilasti(2) = k - 1
istep(1) = 1
istep(2) = 1
dvm = mappl (plref, ahdr, axis, coeff, const, lvaddr, lvtype,
+ iiniti, ilasti, istep, oiniti, olasti, ostep)
4 if (dopl (plref) .eq. 0) goto 5
do 1 j = oiniti(1), olasti(1), ostep(1)
do 1 i = oiniti(2), olasti(2), ostep(2)
bptr( ahdr(3) + 1 + i + ahdr(2) * j ) = 0.
bptr( bhdr(3) + 1 + i + bhdr(2) * j ) = 1. + i + j
1 continue
goto 4
5 dvm = endpl (plref)
C Создание редукционой переменной и редукционной группы
C для вычисления максимального отклонения сеточной функции
C для двух последовательных итераций
redref = crtred ( 3, eps, 3, 1, 0, 0, 0)
rgref = crtrg (0, 0)
dvm = insred (rgref, redref, 0)
C Создание группы границ для обновления теневых граней
shgref = crtshg (0)
dvm = inssh (shgref, ahdr, shwdth, shwdth, 0)
C ОСНОВНОЙ ИТЕРАЦИОННЫЙ ЦИКЛ
do 2 it = 1,itmax
C Параллельный цикл вычисления максимального
C отклонения сеточной функции в переменной eps
C (параллельный цикл с базовым массивом ahdr)
plref = crtpl (2)
iiniti(1) = 1
iiniti(2) = 1
ilasti(1) = k - 2
ilasti(2) = k - 2
dvm = mappl (plref, ahdr, axis, coeff, const, lvaddr, lvtype,
+ iiniti, ilasti, istep, oiniti, olasti, ostep)
eps = 0.
6 if (dopl (plref) .eq. 0) goto 8
do 7 j = oiniti(1), olasti(1), ostep(1)
do 7 i = oiniti(2), olasti(2), ostep(2)
eps = max(eps, abs(bptr( bhdr(3)+1+i+bhdr(2)*j )
+ - bptr( ahdr(3)+1+i+ahdr(2)*j )))
bptr( ahdr(3) + 1 + i + ahdr(2) * j ) =
+ bptr( bhdr(3) + 1 + i + bhdr(2) * j )
7 continue
goto 6
8 dvm = endpl (plref)
C Вычисление редукционного максимума
dvm = strtrd (rgref)
dvm = waitrd (rgref)
C Обмен границами
dvm = strtsh (shgref)
dvm = waitsh (shgref)
C Параллельный цикл вычисления новых значений
C сеточной функции в массиве bhdr
C (параллельный цикл с базовым массивом bhdr)
plref = crtpl (2)
dvm = mappl ( plref, bhdr, axis, coeff, const, lvaddr, lvtype,
+ iiniti, ilasti, istep, oiniti, olasti, ostep)
9 if (dopl (plref) .eq. 0) goto 11
do 10 j = oiniti(1), olasti(1), ostep(1)
do 10 i = oiniti(2), olasti(2), ostep(2)
bptr(bhdr(3) + 1 + i + bhdr(2) * j) =
+ ( bptr(ahdr(3) + 1 + (i - 1) + ahdr(2) * j) +
+ bptr(ahdr(3) + 1 + i + ahdr(2) * (j - 1)) +
+ bptr(ahdr(3) + 1 + (i + 1) + ahdr(2) * j) +
+ bptr(ahdr(3) + 1 + i + ahdr(2) * (j + 1)) ) / 4.
10 continue
goto 9
11 dvm = endpl (plref)
C Печать текущего отклонения сеточной функции
if (tstio ()) print *,'IT = ',it,' EPS = ',eps
C Если заданная точность достигнута, то выход
if (eps .lt. maxeps) goto 3
2 continue
C КОНЕЦ ОСНОВНОГО ИТЕРАЦИОННОГО ЦИКЛА
C Завершение работы с системой поддержки
3 dvm = lexit (0)
end
ПРОГРАММА НА ЯЗЫКЕ C
#include "dvmlib.h"
int main(int argc, char *argv[])
{
long InitPar = 0, UserRes = 0, ExtHdr = 0;
long StaticMV = 0, StaticDA = 0, ReDistrDA = 0, StaticRV = 0,
DelRed = 0, StaticRG = 0, StaticShG = 0, FullShd = 0;
long i, j, it, Rank2 = 2, Long0 = 0, TypeSize = sizeof(float);
long RedFunc = rf_MAX, RVType = rt_FLOAT, RedArrayLength = 1;
AMRef amref;
PSRef psref;
AMViewRef mvref;
LoopRef plref;
RedGroupRef rgref;
RedRef redref;
ShadowGroupRef shgref;
AddrType lvaddr[2];
long lvtype[2] = {0,0};
long amdim[2], disaxs[2], dispar[2];
long shwdth[2], axis[2], coeff[2], cnst[2];
long iiniti[2], ilasti[2], istep[2];
long oiniti[2], olasti[2], ostep[2];
DVMFILE *OutFile;
float eps; /* текущая точность вычислений */
long k = 8; /* число точек сетки по каждому измерению */
float maxeps = 0.5e-2f; /* требуемая точность вычислений */
long itmax = 200; /* максимальное число итераций */
long Ahdr[3]; /* заголовок массива с предыдущими
значениями сеточной функции */
long Bhdr[3]; /* заголовок массива со следующими
значениями сеточной функции */
rtl_init(InitPar, argc, argv); /* инициализация системы поддержки */
/* Создание представления абстрактной машины
и отображение его в процессорную подсистему */
amref = getam_ ();
psref = getps_ (&amref);
amdim[0] = k;
amdim[1] = k;
mvref = crtamv_ (&amref, &Rank2, amdim, &StaticMV);
disaxs[0] = 1;
disaxs[1] = 2;
dispar[0] = 0;
dispar[1] = 0;
distr_ (&mvref, &psref, &Rank2, disaxs, dispar);
/* Создание и распределение массивов
со значениями сеточной функции */
shwdth[0] = 1;
shwdth[1] = 1;
/* Массив с предыдущими значениями сеточной функции */
crtda_ (Ahdr, &ExtHdr, NULL, &Rank2, &TypeSize, amdim,
&StaticDA, &ReDistrDA,shwdth, shwdth);
/* Массив со следующими значениями сеточной функции */
crtda_ (Bhdr, &ExtHdr, NULL, &Rank2, &TypeSize, amdim,
&StaticDA, &ReDistrDA, shwdth, shwdth);
axis[0] = 1;
axis[1] = 2;
coeff[0] = 1;
coeff[1] = 1;
cnst[0] = 0;
cnst[1] = 0;
align_ (Ahdr,&mvref,axis,coeff,cnst);
align_ (Bhdr,&mvref,axis,coeff,cnst);
/* Параллельный цикл инициализации массивов
со значениями сеточной функции
(параллельный цикл с базовым массивом Ahdr) */
plref = crtpl_ (&Rank2);
lvaddr[0] = (AddrType)&j;
lvaddr[1] = (AddrType)&i;
iiniti[0] = 0;
iiniti[1] = 0;
ilasti[0] = k - 1;
ilasti[1] = k - 1;
istep[0] = 1;
istep[1] = 1;
mappl_ (&plref, (PatternRef *)Ahdr, axis, coeff, cnst, lvaddr,
lvtype, iiniti, ilasti, istep, oiniti, olasti, ostep);
while (dopl_ (&plref))
for ( j = oiniti[0]; j <= olasti[0]; j += ostep[0] )
for ( i = oiniti[1]; i <= olasti[1]; i += ostep[1] )
{ DAElm2(Ahdr, float, j, i) = 0.;
DAElm2(Bhdr, float, j, i) = 1.f + i + j;
}
endpl_ (&plref);
/* Создание редукционой переменной и редукционной группы
для вычисления максимального отклонения сеточной функции
для двух последовательных итераций */
redref = crtred_ (&RedFunc, &eps, &RVType, &RedArrayLength,
NULL, &Long0, &StaticRV);
rgref = crtrg_ (&StaticRG, &DelRed);
insred_ (&rgref, &redref, NULL);
/* Создание группы границ для обновления теневых граней */
shgref = crtshg_ (&StaticShG);
inssh_ (&shgref, Ahdr, shwdth, shwdth, &FullShd);
/* ОСНОВНОЙ ИТЕРАЦИОННЫЙ ЦИКЛ */
for (it = 1; it <= itmax; it++)
{
/* Параллельный цикл вычисления максимального
отклонения сеточной функции в переменной eps
(параллельный цикл с базовым массивом Ahdr) */
plref = crtpl_ (&Rank2);
iiniti[0] = 1;
iiniti[1] = 1;
ilasti[0] = k - 2;
ilasti[1] = k - 2;
mappl_ (&plref, (PatternRef *)Ahdr, axis, coeff, cnst, lvaddr,
lvtype, iiniti, ilasti, istep, oiniti, olasti, ostep);
eps = 0.;
while (dopl_ (&plref))
for ( j = oiniti[0]; j <= olasti[0]; j += ostep[0] )
for ( i = oiniti[1]; i <= olasti[1]; i += ostep[1] )
{ eps = max(eps, dvm_abs( DAElm2(Bhdr,float,j,i) -
DAElm2(Ahdr,float,j,i) ));
DAElm2(Ahdr, float, j, i) =
DAElm2(Bhdr, float, j, i);
}
endpl_ (&plref);
/* Вычисление редукционного максимума */
strtrd_ (&rgref);
waitrd_ (&rgref);
/* Обмен границами */
strtsh_ (&shgref);
waitsh_ (&shgref);
/* Параллельный цикл вычисления новых значений
сеточной функции в массиве Bhdr
(параллельный цикл с базовым массивом Bhdr) */
plref = crtpl_ (&Rank2);
mappl_ (&plref, (PatternRef *)Bhdr, axis, coeff, cnst, lvaddr,
lvtype, iiniti, ilasti, istep, oiniti, olasti, ostep);
while (dopl_ (&plref))
for ( j = oiniti[0]; j <= olasti[0]; j += ostep[0] )
for ( i = oiniti[1]; i <= olasti[1]; i += ostep[1] )
DAElm2(Bhdr, float, j, i) =
( DAElm2(Ahdr, float, j, i-1) +
DAElm2(Ahdr, float, j-1, i) +
DAElm2(Ahdr, float, j, i+1) +
DAElm2(Ahdr, float, j+1, i) ) / 4.f;
endpl_ (&plref);
/* Печать текущего отклонения сеточной функции */
dvm_printf("IT = %ld EPS = %e\n", it, eps);
if(eps < maxeps)
break; /* выход, если заданная точность достигнута */
}
/* КОНЕЦ ОСНОВНОГО ИТЕРАЦИОННОГО ЦИКЛА */
/* Запись решения в файл и завершение работы с системой поддержки */
OutFile = dvm_fopen("cross.dat", "w+b");
if(OutFile)
{ dvm_dfwrite(Bhdr, 0, OutFile);
dvm_fclose(OutFile);
}
lexit_ (&UserRes);
return (int)UserRes;
}
19.2Параллельный цикл с регулярной зависимостью по данным между витками
Приведённые ниже программы (языки С и Фортран) являются примерами реализации с помощью функций системы поддержки параллельного цикла с прямой (потоковой) и обратной зависимостями по данным между витками. Параллельный цикл представлен двухмерным циклом вида
| for( | j = 1; j <= k-2; j++ ) | ||||
| for( | i = 1; i <= k-2; i++ ) | ||||
| A[j,i] = ( | A[jFDL1, i] | /* прямая зависимость по измерению 1 */ | |||
| A[jADL1, i] | /* обратная зависимость по измерению 1 */ | ||||
| A[j, iFDL2] | /* прямая зависимость по измерению 2 */ | ||||
| A[j, iADL2] | /* обратная зависимость по измерению 2 */ | ||||
| ) | / 4; | ||||
Здесь:
| k | – | размер измерений массива A; |
| FDL1 | – | длина прямой зависимости для измерения 1; |
| ADL1 | – | длина обратной зависимости для измерения 1; |
| FDL2 | – | длина прямой зависимости для измерения 2; |
| ADL2 | – | длина обратной зависимости для измерения 2. |
ПРОГРАММА НА ЯЗЫКЕ ФОРТРАН
program across
integer linit, lexit,getam, getps, crtamv, distr, crtda, align,















