Lib-DVM - описание интерфейса (оглавление) | Часть 1(1-5) |
Часть 2 (6-7) |
Часть 3 (8-11) |
Часть 4 (12-13) |
Часть 5 (14-15) |
Часть 6 (16-18) |
Часть 7 (19) |
создан: февраль, 2001 | - последнее обновление 03.05.01 - |
19 Примеры программ, использующих функции системы поддержки
19.1 Решение уравнения Лапласа методом Якоби
Применение основных функций системы поддержки проиллюстрируем примером численного решения двухмерного уравнения Лапласа
¶ 2U ----- + ¶ x2 |
¶ 2U ----- = 0 (1) ¶ y2 |
в заданной прямоугольной области с заданными краевыми условиями (задача Дирихле).
Трехточечная аппроксимация частных производных уравнения (1) на квадратной сетке с использованием пятиточечного шаблона
(i-1,j) , (i+1,j) , (i,j) , (i,j-1) , (i,j+1)
даёт разностное уравнение (схему "крест"), приводимое к виду
ui,j = (ui+1,j + ui-1,j + ui,j+1 + ui,j-1)/4 (i,j = 1, ... , k-2) (2) ,
где: | k | - | число точек сетки по каждому измерению; |
ui,j | - | значение сеточной функции в узле (i,j). |
Значения сеточной функции
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[j- FDL1, i] + | /* прямая зависимость по измерению 1 */ | |||
A[j+ ADL1, i] + | /* обратная зависимость по измерению 1 */ | ||||
A[j, i- FDL2] + | /* прямая зависимость по измерению 2 */ | ||||
A[j, i+ ADL2] | /* обратная зависимость по измерению 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)
C Параллельный цикл инициализации массива C с регулярной зависимостью по данным
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)
2 if (dopl (plref) .eq. 0) goto 3
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 ) = 1.
1 continue
goto 2
3 dvm = endpl (plref)
C Создание группы границ для обеспечения C обратной зависимости по данным
shgref = crtshg (0)
C Нулевая ширина нижней границы по измерению 1
lshwd(1) = 0
C Нулевая ширина нижней границы по измерению 2
lshwd(2) = 0
C Ширина верхней границы по измерению 1 - длина C обратной зависимости по данным для измерения 1
hshwd(1) = ADL1
C Ширина верхней границы по измерению 2 - длина C обратной зависимости по данным для измерения 2
hshwd(2) = ADL2
dvm = inssh (shgref, ahdr, lshwd, hshwd, 0)
C Инициализация теневых граней для обеспечения C обратной зависимости по данным
dvm = strtsh (shgref) dvm = waitsh (shgref)
C Создание группы границ для обеспечения C прямой зависимости по данным
shgref = crtshg (0)
C Ширина нижней границы по измерению 1 - длина C прямой зависимости по данным для измерения 1
lshwd(1) = FDL1
C Ширина нижней границы по измерению 2 - длина C прямой зависимости по данным для измерения 2
lshwd(2) = FDL2
C Нулевая ширина верхней границы по измерению 1
hshwd(1) = 0
C Нулевая ширина верхней границы по измерению 2
hshwd(2) = 0
if (finssh .eq. 0) goto 4
C Для регистрации массива в группе границ используем inssh_
dvm = inssh (shgref, ahdr, lshwd, hshwd, 0) goto 5
C Для регистрации массива в группе границ используем insshd_ C По измерениям 1 и 2 используется только нижняя граница
4 shsign(1) = 3 shsign(2) = 3
dvm = insshd (shgref, ahdr, lshwd, hshwd, 1, shsign) goto 5
C Прием импортируемых элементов для С обеспечения прямой зависимости по данным
5 dvm = recvsh (shgref) dvm = waitsh (shgref)
C ПАРАЛЛЕЛЬНЫЙ ЦИКЛ С ПРЯМОЙ И ОБРАТНОЙ C ЗАВИСИМОСТЯМИ ПО ДАННЫМ МЕЖДУ ВИТКАМИ
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)
6 if (dopl (plref) .eq. 0) goto 7
do 8 j = oiniti(1), olasti(1), ostep(1) do 8 i = oiniti(2), olasti(2), ostep(2)
bptr(ahdr(3) + 1 + i + ahdr(2) * j) = + ( bptr(ahdr(3) + 1 + (i - FDL2) + ahdr(2) * j) + + bptr(ahdr(3) + 1 + i + ahdr(2) * (j - FDL1)) + + bptr(ahdr(3) + 1 + (i + ADL2) + ahdr(2) * j) + + bptr(ahdr(3) + 1 + i + ahdr(2) * (j + ADL1)) ) / 4.
8 continue goto 6
7 dvm = endpl (plref)
C Передача экспортируемых элементов для C обеспечения прямой зависимости по данным
dvm = sendsh (shgref) dvm = waitsh (shgref)
C Завершение работы с системой поддержки
dvm = lexit (0)
end
ПРОГРАММА НА ЯЗЫКЕ C
#include "dvmlib.h"
int main(int argc, char *argv[]) { long InitPar = 0, UserRes = 0; long StaticMV = 0, StaticDA = 0, ReDistrDA = 0, StaticShG = 0, FullShd = 0, MaxShdCount = 1; long ShdSignArray[2]; long i, j, Rank2 = 2, TypeSize = sizeof(float); AMRef amref; PSRef psref; AMViewRef mvref; LoopRef plref; ShadowGroupRef fshgref, ashgref; AddrType lvaddr[2]; long lvtype[2] = {0,0}; long amdim[2], disaxs[2], dispar[2]; long lshwdth[2], hshwdth[2], axis[2], coeff[2], cnst[2]; long iiniti[2], ilasti[2], istep[2]; long oiniti[2], olasti[2], ostep[2]; long ExtHdrSign = 0; DVMFILE *OutFile;
long k = 200; /* размер каждого измерения массива с регулярной зависимостью по данным */
long FDL1 = 4; /* длина прямой зависимости по данным для измерения 1 */
long FDL2 = 3; /* длина прямой зависимости по данным для измерения 2 */
long ADL1 = 2; /* длина обратной зависимости по данным для измерения 1 */
long ADL2 = 1; /* длина обратной зависимости по данным для измерения 2 */
int f_inssh = 0; /* признак использования функции inssh_ для регистрации массива в группе границ; при нулевом значении f_inssh используется функция insshd_ */
long Ahdr[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);
/* Создание и распределение массива с регулярной зависимостью по данным */
lshwdth[0] = FDL1; /* ширина нижней границы по измерению 1 - длина прямой зависимости по данным для измерения 1 */ lshwdth[1] = FDL2; /* ширина нижней границы по измерению 2 - длина прямой зависимости по данным для измерения 2 */ hshwdth[0] = ADL1; /* ширина верхней границы по измерению 1 - длина обратной зависимости по данным для измерения 1 */ hshwdth[1] = ADL2; /* ширина верхней границы по измерению 2 - длина обратной зависимости по данным для измерения 2 */
crtda_ (Ahdr, &ExtHdrSign, NULL, &Rank2, &TypeSize, amdim, &StaticDA, &ReDistrDA, lshwdth, hshwdth);
axis[0] = 1; axis[1] = 2; coeff[0] = 1; coeff[1] = 1; cnst[0] = 0; cnst[1] = 0;
align_ (Ahdr,&mvref,axis,coeff,cnst);
/* Параллельный цикл инициализации массива с регулярной зависимостью по данным */
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) = 1.f; endpl_ (&plref);
/* Создание группы границ для обеспечения обратной зависимости по данным */
ashgref = crtshg_ (&StaticShG);
lshwdth[0] = 0; /* нулевая ширина нижней границы по измерению 1 */ lshwdth[1] = 0; /* нулевая ширина нижней границы по измерению 2 */ hshwdth[0] = ADL1; /* ширина верхней границы по измерению 1 - длина обратной зависимости по данным для измерения 1 */ hshwdth[1] = ADL2; /* ширина верхней границы по измерению 2 - длина обратной зависимости по данным для измерения 2 */
inssh_ (&ashgref, Ahdr, lshwdth, hshwdth, &FullShd);
/* Инициализация теневых граней для обеспечения обратной зависимости по данным */
strtsh_ (&ashgref); waitsh_ (&ashgref);
/* Создание группы границ для обеспечения прямой зависимости по данным */
fshgref = crtshg_ (&StaticShG);
lshwdth[0] = FDL1; /* ширина нижней границы по измерению 1 - длина прямой зависимости по данным для измерения 1 */ lshwdth[1] = FDL2; /* ширина нижней границы по измерению 2 - длина прямой зависимости по данным для измерения 2 */ hshwdth[0] = 0; /* нулевая ширина верхней границы по измерению 1 */ hshwdth[1] = 0; /* нулевая ширина верхней границы по измерению 2 */
if(f_inssh) /* с какой функцией работаем, с inssh_ или с insshd_ */ { /* Для регистрации массива в группе границ используем inssh_ */
inssh_ (&fshgref, Ahdr, lshwdth, hshwdth, &FullShd); } else {
/* Для регистрации массива в группе границ используем insshd_ */
ShdSignArray[0] = 3; /* по измерению 1 используется только нижняя граница */ ShdSignArray[1] = 3; /* по измерению 2 используется только нижняя граница */ insshd_ (&fshgref, Ahdr, lshwdth, hshwdth, &MaxShdCount, ShdSignArray); }
/* Прием импортируемых элементов для обеспечения прямой зависимости по данным */
recvsh_ (&fshgref); waitsh_ (&fshgref);
/* ПАРАЛЛЕЛЬНЫЙ ЦИКЛ С ПРЯМОЙ И ОБРАТНОЙ ЗАВИСИМОСТЯМИ ПО ДАННЫМ МЕЖДУ ВИТКАМИ */
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);
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) = ( DAElm2(Ahdr, float, j, i-FDL2) + DAElm2(Ahdr, float, j-FDL1, i) + DAElm2(Ahdr, float, j, i+ADL2) + DAElm2(Ahdr, float, j+ADL1, i) ) / 4.f;
endpl_ (&plref);
/* Передача экспортируемых элементов для обеспечения прямой зависимости по данным */
sendsh_ (&fshgref); waitsh_ (&fshgref);
/* Запись результирующего массива в файл и завершение работы с системой поддержки */
OutFile = dvm_fopen("across.dat", "w+b");
if(OutFile) { dvm_dfwrite(Ahdr, 0, OutFile); dvm_fclose(OutFile); }
lexit_ (&UserRes); return (int)UserRes; }