Вперед: 5.3. Заключение к главе 5
Назад: 5.2.4. Хранение разреженных матриц в MSR формате
К содержанию: Оглавление


5.2.5. Пример использования библиотеки Aztec

В заключение настоящего параграфа рассмотрим пример программы, в которой Aztec используется для решения системы уравнений, возникающей при конечно-разностной аппроксимации 3-х мерного оператора Лапласа. Для простоты мы не будем использовать систему уравнений, связанную с решением какой-либо реальной физической задачи, а вместо этого будем формировать правую часть таким образом, чтобы получить заранее известное решение, например, x(i) = i + 1.

Программа azt.f

	program azt
    include 'mpif.h'
    include 'az_aztecf.h'
    integer NULL
    parameter (NULL = 0)
    integer  n 
    common  /global/ n
    integer i,j,IAM,NPROCS,ierr,nz,K,in,ik,nz1,nzz
    integer proc_config(0:AZ_PROC_SIZE), options(0:AZ_OPTIONS_SIZE)
    double precision params(0:AZ_PARAMS_SIZE)
    double precision status(0:AZ_STATUS_SIZE)
    double precision s,time,total
    integer N_update,ierror,recb(0:63),disp(0:63)
    CHARACTER*8 met(0:4)

    integer, dimension(:), allocatable:: data_org, update
    integer, dimension(:), allocatable:: external, update_index
    integer, dimension(:), allocatable:: extern_index, bindx    
    real(KIND=8), dimension(:), allocatable:: b,x,tmp,val

    CALL MPI_Init(ierror)  
    met(0) = 'cg'
    met(1) = 'gmres'
    met(2) = 'cgs'
    met(3) = 'tfqmr'
    met(4) = 'bicgstab'
C Инициализация коммуникационного окружения
    call AZ_processor_info(proc_config)
    IAM = proc_config(AZ_node)
    NPROCS = proc_config (AZ_N_procs)
    if (IAM.eq.0) then
   write(6,1)
  1 format(' '//
   $    ' Victor N. Datsyuk'/
   $    ' High Performance Computers Department'/
   $    ' Rostov State University'/
   $    ' Rostov-on-Don, phone 219-97-13'//
   $    ' email: root@rsusu1.rnd.runnet.ru'/
   $    ' Internet: http://rsusu1.rnd.runnet.ru'/)
   write(6,2)
  2 format(' '/
   $ ' Aztec example driver'//
   $ ' This program create an MSR matrix corresponding to'/
  $ ' a 7pt discrete approximation to the 3D Poisson operator'/ 
  $ ' on an n x n x n square and solve it various methods.'//)                            
  
    open(10, FILE='size.dat', FORM='FORMATTED')
    read(10,*) n
    endif
с  Рассылка параметров задачи на все процессоры. Можно использовать
с  либо процедуру из Aztec, либо из MPI 
c    call AZ_broadcast(n,4,proc_config,AZ_PACK)
c    call AZ_broadcast(NULL,0,proc_config,AZ_SEND)
c
    call MPI_BCAST(n,1,MPI_INTEGER,0,MPI_COMM_WORLD,ierr)
    nz = n*n*n
    nzz = nz/NPROCS + 1
c  Резервирование памяти под локальные массивы в зависимости от
с  размера решаемой задачи и числа процессоров.
    allocate( data_org(0:nzz) )
    allocate( update(0:nzz) ) 
    allocate( external(0:nzz) )
    allocate( update_index(0:nzz) )
    allocate( extern_index(0:nzz) )
    allocate( bindx(0:nzz*7) )
    allocate( b(0:nzz) )
    allocate( x(0:nz) )
    allocate( tmp(0:nzz) )
    allocate( val(0:nzz*7) )

    total = 0.0 
с  Цикл по методам решения системы уравнений. Метод GMRES(номер 1)
с  пропускается из-за очевидных проблем с его реализацией
    DO 777 K = 0,4
	IF (K .EQ.1) GOTO 777 
    time = MPI_Wtime()
с  Определение параметров разбиения системы уравнений по 
с  процессорам
    call AZ_read_update(N_update,update,proc_config,nz,1,0)
с  Формирование распределенной матрицы системы уравннений.
с  Каждый процессор заполняет только свою часть матрицы
    bindx(0) = N_update+1
    do 250 i = 0, N_update-1
    call add_row_7pt(update(i),i,val,bindx)
250  continue
с  Формирование правой части системы уравнений по алгоритму:
c  b(i) = sum(A(i,j)*j), в следствии чего решение будет иметь вид:
с  x(i) = i ;   
    do 341 i = 0, N_update-1
     in = bindx(i)
     ik = bindx(i+1) - 1
     s = val(i)*(update(i)+1)
    do 342 j = in,ik
     s = s + val(j)*(bindx(j)+1)
 342  continue
     tmp(i) = s   
 341  continue

c  Трансформация глобальной индексации массивов в локальную 
    call AZ_transform(proc_config,external,bindx,val,update,
  $          update_index,extern_index,data_org,
 $          N_update,NULL,NULL,NULL,NULL,AZ_MSR_MATRIX)

с  Инициализация параметров решателя
    call AZ_defaults(options, params)
    options(AZ_solver) = K
с    options(AZ_precond) = AZ_dom_decomp
с    options(AZ_subdomain_solve) = AZ_ilut
    options(4) = 1
    options(AZ_output) = AZ_none
    options(AZ_max_iter) = 2000
    params(AZ_tol) = 1.d-8

    if (IAM.eq.0) then
    write(6,780)
 780 format (16x,11(2H**))
    write (6,*) '        Method solve is =',met(k)
    write(6,780)
    write (6,*) '        Dimension matrices =',nz,
   +'  NPROCS = ', NPROCS
    endif    
с  Задание начального приближения и переиндексация массивов
    do 350 i = 0, N_update-1
     x(update_index(i)) = 0.0
     b(update_index(i)) = tmp(i)  
 350  continue 
с   Решение системы уравнений  

    call AZ_solve(x,b, options, params, NULL,bindx,NULL,NULL,
   $        NULL,val, data_org, status, proc_config)
c   Обратная переиндексация массивов
   DO 415 I = 0,N_update - 1
 415 tmp(i) = x(update_index(i))

c  Сборка частей решения со всех процессоров
   CALL MPI_ALLgather(N_update,1,MPI_INTEGER,recb,1,
   *MPI_INTEGER,MPI_COMM_WORLD,ierror)
   CALL MPI_BARRIER(MPI_COMM_WORLD,ierror)
   DISP(0) = 0
   DO 404 I = 1,NPROCS-1
 404 DISP(I) = DISP(I-1) + RECB(I-1)
   CALL MPI_ALLgatherv(tmp,N_update,MPI_DOUBLE_PRECISION,x,recb,
   *disp,MPI_DOUBLE_PRECISION,MPI_COMM_WORLD,ierror)
   CALL MPI_BARRIER(MPI_COMM_WORLD,ierror)
c  Печать контрольных компонент решения
    nz1 = nz-1
    if (IAM.eq.0) then
    do 348 i = 0,nz1,nz1
     s = x(i) 
    write (6,956) i,s      
 348  continue
 956 format (2x,'i=',I12,2x,'x(i)=',F18.8)
    endif 
    time = MPI_Wtime() - time
    total = total + time
    if(iam.eq.0) write(*,435) time
 435  FORMAT(2x,'TIME CALCULATION (SEC.) = ',F12.4)
    CALL FLUSH(6)
 777  continue
    if(iam.eq.0) write(*,436) total
 436  FORMAT(/,2x,' TOTAL TIME CALCULATION (SEC.) = ',F12.4)    
    CALL MPI_FINALIZE(IERROR)
    stop
    end

C****************************************************************
C****************************************************************
с  Подпрограмма добавления очередной строки матрицы

    subroutine add_row_7pt(row,location,val,bindx)
    integer row,location,bindx(0:*)
    double precision val(0:*)
    integer  n,n3
    common  /global/ n
C
C Параметры:
C row   == глобальный номер строки, добавляемый к матрице
C location == локальный номер строки
C val,bindx == массивы для хранения ненулевых матричных 
C    элементов и номеров их столбцов 
C
    integer k
с  проверка наличия соседей в расчетной сетке и добавление 
с  ненулевых элементов, если таковые существуют 
    n3 = n*n*n - 1
    k = bindx(location)
    bindx(k) = row + 1
    if (bindx(k).le.n3) then
     val(k) = -1.
     k = k + 1
    endif
    bindx(k) = row - 1
    if (bindx(k) .ge. 0) then
     val(k) = -1.
      k = k + 1
    endif
    bindx(k) = row + n
    if (bindx(k).le.n3) then
     val(k) = -1.
     k = k + 1
    endif
    bindx(k) = row - n
    if (bindx(k).ge. 0) then
     val(k) = -1.
     k = k + 1
    endif
    bindx(k) = row + n*n
    if (bindx(k) .le. n3) then
     val(k) = -1.
     k = k + 1
    endif
    bindx(k) = row - n*n
    if (bindx(k) .ge. 0) then
     val(k) = -1.
     k = k + 1
    endif
    bindx(location+1) = k
    val(location)  = 6.0
    return
    end

Для компиляции программы использовался Makefile:

PROG	= azt
OBJ 	= $(PROG).o
FC	= mpif90
CC	= mpicc
FFLAGS = -O 
LDFLAGS = -O

LIBS = -laztec -lmkl -lguide 

all: exe
exe: $(OBJ)
	${FC} ${LDFLAGS} -o $(PROG) ${OBJ} ${LIBS}
clean :
	rm -f *.o

.f.o : ; $(FC) -c ${FFLAGS} $*.f
.c.o : ; $(CC) -c $(CCFLAGS) $(CDEFS) $*.c

Следует обратить внимание на то, что при компиляции программы помимо библиотеки Aztec необходимо подключать оптимизированную библиотеку blas. В данном случае используется библиотека Intel MKL. Текстовая версия библиотеки blas включена в дистрибутив библиотеки Aztec и может быть собрана вместе с библиотекой aztec, однако производительность при этом будет значительно ниже, чем при использовании бинарной оптимизированной библиотеки blas.



Вперед: 5.3. Заключение к главе 5
Назад: 5.2.4. Хранение разреженных матриц в MSR формате
К содержанию: Оглавление