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;
}

Литература

  1. Н.А. Коновалов, В.А. Крюков, А.А. Погребцов, Ю.Л. Сазанов. C-DVM - язык разработки мобильных параллельных программ. Препринт ИПМ им. М.В. Келдыша РАН N 86, Москва, 1997 г.
  2. N.A. Konovalov, V.A. Krukov, S.N. Mihailov, A.A. Pogrebtsov. Fortran-DVM language for portable parallel programs development. Proceeding of Software For Multiprocessors & Supercomputers: Theory, Practice, & Experience (SMS-TPE 94), Inst. for System Programming RAS, Moscow, Sept. 1994.
  3. В.А. Крюков, Р.В. Удовиченко. Средства отладки и мониторинга DVM-программ. Динамический отладчик. Отчет ИПМ РАН. Москва. 1997 г.
  4. В.Е. Денисов, В.Н. Ильяков, Н.В. Ковалёва, В.А. Крюков. Отладка эффективности DVM-программ. Препринт ИПМ им. М.В. Келдыша РАН N 74, Москва, 1998 г.

Lib-DVM - описание интерфейса (оглавление) Часть
1(1-5)
Часть 2
(6-7)
Часть 3
(8-11)
Часть 4
(12-13)
Часть 5
(14-15)
Часть 6
(16-18)
Часть 7
(19)