rtsIDr (1158390), страница 24
Текст из файла (страница 24)
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,
+ crtpl, dvmadr, mappl, endpl, dopl,
+ crtshg, inssh, insshd, strtsh, recvsh, sendsh, waitsh
real bptr(1)
integer dvm
integer amref, psref, mvref, plref, shgref
integer amdim(2), disaxs(2), dispar(2)
integer lshwd(2), hshwd(2), shsign(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)
integer FDL1, FDL2, ADL1, ADL2, finssh
C Размер каждого измерения массива
C с регулярной зависимостью по данным
parameter (k = 200)
C Заголовок массива с регулярной зависимостью по данным
integer ahdr(6)
ahdr(5) = 1
ahdr(6) = 1
C Длина прямой зависимости по данным для измерения 1
FDL1 = 4
C Длина прямой зависимости по данным для измерения 2
FDL2 = 3
C Длина обратной зависимости по данным для измерения 1
ADL1 = 2
C Длина обратной зависимости по данным для измерения 2
ADL2 = 1
C Признак использования функции inssh_ для регистрации
C массива в группе границ; при нулевом значении finssh
C используется функция insshd_
finssh = 0
C Инициализация системы поддержки
dvm = linit (1)
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 с регулярной зависимостью по данным
C Ширина нижней границы по измерению 1 - длина
C прямой зависимости по данным для измерения 1
lshwd(1) = FDL1
C Ширина нижней границы по измерению 2 - длина
C прямой зависимости по данным для измерения 2
lshwd(2) = FDL2
C Ширина верхней границы по измерению 1 - длина
C обратной зависимости по данным для измерения 1
hshwd(1) = ADL1
C Ширина верхней границы по измерению 2 - длина
C обратной зависимости по данным для измерения 2
hshwd(2) = ADL2
dvm = crtda (ahdr, 1, bptr, 2, 4, amdim, 0, 0, lshwd, hshwd)
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)















