Views

ATLAS: Przykład w Fortranie

From Centrum Komputerów Dużej Mocy, ICM Uniwersytet Warszawski

Jump to: navigation, search
ATLAS
Produkt: ATLAS
Producent: środowisko open source
Licencja: BSD
Zainstalowany na: halo
Wersja: 3.6.0
Email: pomoc@icm.edu.pl
Podstawowe informacje
Przykład w C
Przykład w Fortranie

Contents

Kod

Oto przykładowy program w języku Fortran wywołujący funkcję mnożenia macierzy przez wektor (GEMV) z biblioteki BLAS. Kod programu dostępny jest tu.

 001.        subroutine print_matrix(m, n, lda, a)
 002.          implicit none
 003.
 004.          integer m, n, lda
 005.          double precision a(lda, n)
 006.          integer i, j
 007.          character(len=80) frmt
 008.
 009.          frmt = '(   (X,F5.1))'
 010.          write(frmt(2:4), '(I3)') n
 011.
 012.          do j = 1, m
 013.            write(*,frmt) (a(j,i), i=1,n)
 014.          end do
 015.        end
 016.
 017.        subroutine print_vector(m, x)
 018.          implicit none
 019.
 020.          integer m
 021.          double precision x(m)
 022.          integer j
 023.
 024.          do j = 1, m
 025.            write(*,'(X,F5.1)') x(j)
 026.          end do
 027.        end
 028.
 029.        program testatlas
 030.          implicit none
 031.
 032.          integer lda, m, n
 033.          parameter (lda = 7, m = 5, n = 3)
 034.
 035.          double precision a(lda, n), x(n), y(m)
 036.          double precision alpha, beta
 037.          integer i, j
 038.
 039.          alpha = 0.5
 040.          beta = 0.0
 041.
 042.          do j = 1, m
 043.            do i = 1, n
 044.              a(j, i) = 0.0
 045.            end do
 046.          end do
 047.
 048.          a(1, 1) = 1.0
 049.          a(1, 2) = -2.0
 050.          a(2, 2) = 3.0
 051.          a(3, 3) = -0.5
 052.          a(4, 2) = 0.5
 053.          a(5, 1) = 1.0
 054.          a(5, 2) = -1.0
 055.
 056.          x(1) = 10.0
 057.          x(2) = 20.0
 058.          x(3) = 30.0
 059.
 060.          print *, 'Macierz A:'
 061.          call print_matrix(m, n, lda, a)
 062.
 063.          print *
 064.          print *, 'Wektor X:'
 065.          call print_vector(n, x)
 066.
 067.          call dgemv('N', m, n, alpha, a, lda, x, 1, beta, y, 1)
 068.
 069.          print *
 070.          print *, 'Wektor Y:'
 071.          call print_vector(m, y)
 072.        end

Kompilacja i linkowanie

Na klastrze halo, używając kompilatorów GNU, program kompilujemy i linkujemy następująco (korzystamy z 64-bitowej wersji biblioteki ATLAS):

 g77 -c -o testatlas.o testatlas.f
 g77 -o testatlas.x testatlas.o -L/opt/atlas/64/lib -lf77blas -latlas

Jeśli używamy kompilatorów Portland Group, wydajemy następujące polecenia (również korzystając z 64-bitowej wersji ATLASa):

 use_pgi
 pgf77 -c -o testatlas.o testatlas.c
 pgf77 -o testatlas.x testatlas.o -L/opt/atlas/64/lib -lf77blas -latlas -lf2c

Uwaga: zarówno w przypadku kompilatorów GNU, jak i Portland Group, zmiana kolejności argumentów podawanych w czasie linkowania (drugie polecenie) może spowodować błąd. Należy dbać o to aby nie zmieniać kolejności bibliotek wewnątrz zaznaczonego na czerwono fragmentu, oraz aby pliki obiektowe znajdowały się przed tym fragmentem.

Komentarz do programu

Linie 001-027: pomocnicze procedury służące do wypisywania zawartości macierzy i wektorów.

Linie 032-033: stałe opisujące wielkość macierzy i wektorów.

Linia 035: definicja macierzy A i wektorów X, Y. Deklarujemy macierz A o rozmiarach 7x3, choć korzystać będziemy jedynie z fragmentu tej pamięci: podmacierzy 5x3. Ponadto deklarujemy wektor X o rozmiarze 3 oraz wektor Y o rozmiarze 5. Zauważmy, że wszędzie używamy liczb zmiennoprzecinkowych podwójnej precyzji (double precision).

Linie 039-040: stałe używane w funkcji GEMV (patrz linia 067).

Linie 042-058: inicjalizacja macierzy A i wektora X.

Linie 060-065: wypisanie danych wejściowych (macierzy A i wektora X).

Linia 067: wywołujemy funkcję DGEMV z bibioteki BLAS liczącą y: = αAx + βy. Przedrostek D w nazwie funkcji oznacza, że używamy liczb zmiennoprzecinkowych podwójnej precyzji (double precision). Ponieważ w linii 040 ustawiliśmy β = 0, to nie musieliśmy inicjalizować wektora Y.

Linie 069-071: wypisanie wyniku (wektora Y).

Wynik działania

  Macierz A:
    1.0  -2.0   0.0
    0.0   3.0   0.0
    0.0   0.0  -0.5
    0.0   0.5   0.0
    1.0  -1.0   0.0
 
  Wektor X:
   10.0
   20.0
   30.0
 
  Wektor Y:
  -15.0
   30.0
   -7.5
    5.0
   -5.0