Wstęp
Załóżmy, że mamy do rozwiązania stacjonarne, eliptyczne równanie różniczkowe
cząstkowe. Po dyskretyzacji metodą elementu skończonego lub różnic skończonych,
prowadzi ono z reguły do wielkiego układu równań liniowych:
Aby rozwiązać powyższy układ przy pomocy komputera
(być może równoległego) należy:
-
Utworzyć wektory x i b i wpisać w wektor b odpowiednie wartości.
-
Utworzyć i wpisać odpowiednie wartości w macierz A.
-
Napisać procedury rozwiązywania takiego układu równań bądź metodą iteracyjną
z preconditionerem, bądź bezpośrednią.
-
Rozwiązać powyższy układ.
Wygląda to dosyć prosto, dopóki nie uzmysłowimy
sobie, jakie problemy stoją przed programistą. Musi on, po pierwsze, zintegrować
procedury rozwiązywania równań z pozostałą częścią programu. Po drugie,
rozwiązać problem przechowywania danych w komputerze, z uwzględnieniem
jego ewentualnej architektury równoległej. Po trzecie, wstawić wartości
do macierzy i wektora prawej strony, uwzględniając rozproszenie danych
po procesorach. Po czwarte, macierze pochodzące z dyskretyzacji równań
różniczkowych mają z reguły strukturę rozrzedzoną, wobec czego trzeba rozwiązać
problem efektywnego przechowywania takich macierzy w pamięci. Poza tym,
dobrze byłoby móc testować i porównywać różne podejścia do problemu: zmieniać
parametry, metody rozwiązywania układów równań, w szczególności - preconditionery.
Program powinien wykorzystywać w pełni moc obliczeniową komputera, a dobrze,
gdyby przy okazji był niezależny od platformy sprzętowej. Oczywiście, program
powinien być wolny od błędów. Gdy spełnimy powyższe postulaty, okaże się,
że program nabrał rozmiarów sporego pakietu. W tym przypadku mamy dwie
możliwości - pisać samemu od podstaw własny pakiet lub wykorzystać istniejące
oprogramowanie biblioteczne. Projekt
PETSc
jest rozwijany z myślą o osobach opowiadających się za tym drugim rozwiązaniem.
Inicjatorem projektu jest
Barry
Smith, który w 1991 roku napisał pierwszą wersję pakietu do rozwiązywania
układów równań liniowych: PETSc 1.0. W ciągu kilku lat zestaw procedur
przekształcił się w duży pakiet narzędzi do rozwiązywania równań różniczkowych
cząstkowych, używany w wielu renomowanych ośrodkach obliczeniowych na świecie.
Obecnie nad PETSc pracują Satish Balay, Willam Gropp, Lois Curfman McInnes
i Barry Smith z
Argonne National Laboratory
(USA), wspomagani okazjonalnie przez grupy studentów - praktykantów. Akronim
PETSc oznacza
Portable, Extensible Toolkit for Scientific computation.
Jak już wspomnieliśmy, pakiet jest w dużym stopniu niezależny od platformy
sprzętowej. Programy można kompilować i uruchamiać na różnych architekturach,
nie tracąc przy tym zbyt wiele z efektywności kodu, a jednocześnie wykorzystując
potencjał konkretnego komputera. Obecnie obsługiwane architektury to:
-
komputery osobiste klasy IBM PC, pracujące pod kontrolą systemów Linux,
Windows 95 i NT 4.0;
-
unixowe stacje robocze, z jednym lub kilkoma procesorami RISC: DEC
Alpha, Silicon Graphics (także Origin
i Power Challenge), Sun, IBM
RS6000, itp.;
-
sieć wyżej wymienionych komputerów połączonych Ethernetem;
-
superkomputery masywnie równoległe (IBM
SP2, Cray T3D/T3E, Convex
Exemplar).
Zwróćmy uwagę, jak różne są te architektury! Osiągnięcie
pełnej przenośności kodu jest naprawdę imponującym dokonaniem. Można
napisać program, którego poprawność przetestujemy na małym komputerze używając
małego zadania, a potem uruchomimy dla poważnych obliczeń na superkomputerze.
Poza tym mniejsze stacje robocze mają zwykle przyjaźniejszy interfejs użytkownika
i narzędzia do pisania programów niż superkomputery. Podkreślają to także
autorzy pakietu, którzy superkomputera (Cray T3E) używają jedynie po przetestowaniu
kodu na stacjach roboczych Sun Sparcstation.
Drugim przymiotnikiem z nazwy jest Extensible
(rozszerzalny) - autorzy położyli duży nacisk na to aby pakiet był modularny
i można było także wykorzystywać, ostatnio bardzo modne, programowanie
obiektowe.
"PETSc jest dowodem na to, że nowoczesne metody programowania
mogą ułatwić rozwój wielkich aplikacji numerycznych w Fortranie, C i C++.
Oprogramowanie, które tworzymy od kilku lat, rozwinęło się w potężny pakiet
narzędzi do numerycznego rozwiązywania równań różniczkowych cząstkowych
na superkomputerach" [2].
Warto
dodać, że PETSc na pewno będzie dalej rozwijane przez parę najbliższych
lat, jako że autorom pakietu przyznano grant rządowy. Każdy użytkownik
pakietu może zwrócić się do autorów o pomoc, ponadto ma do dyspozycji listę
dyskusyjną oraz sporo dodatkowych wydawnictw, głownie w formie elektronicznej.
Szczegóły można znaleźć na stronie
WWW
poświęconej PETSc w
Argonne National
Laboratory.
Struktura PETSc
Pakiet PETSc jest zbiorem bibliotek napisanych
w języku C. Programy używające PETSc można pisać w języku C (także C++)
lub w Fortranie. Do zrozumienia zasad posługiwania się PETSc wystarczy
w zasadzie podstawowa znajomość programowania w języku C. Funkcje PETSc
wykorzystują, w sposób transparentny dla użytkownika, znane i popularne
biblioteki numeryczne, takie jak
BLAS
[17] (podstawowe procedury obsługi
wektorów i macierzy gęstych, zoptymalizowane pod kątem współczesnych architektur
komputerowych),
LAPACK [1]
(nowoczesny pakiet algebry liniowej dla macierzy gęstych, stanowiący rozwinięcie
powszechnie stosowanego LINPACKa) oraz
MPI
[9] (standaryzowany zestaw procedur
ułatwiających programowanie równoległe, implementowany na większości masywnie
równoległych komputerów, a także dla sieci stacji roboczych).
PETSc zawiera wiele składników podobnych do klas
w C++. Każdy składnik dysponuje wydzieloną rodziną typów danych (na przykład
wektorów) i operacji wykonywalnych na nich. Zarówno obiekty, jak operacje,
opracowano na podstawie wieloletniego doświadczenia autorów (i użytkowników
pakietu!) w rozwiązywaniu równań różniczkowych cząstkowych. Moduły PETSc
operują obiektami takimi jak:
-
wektory,
-
macierze,
-
iteracyjne i bezpośrednie solvery układów równań liniowych,
-
preconditionery dla metod iteracyjnych,
-
solvery zadań nieliniowych (na przykład metoda Newtona) oraz solvery zadań
ewolucyjnych,
-
urządzenia graficzne takie jak okna czy strony,
-
zbiory indeksów, w tym permutacje,
-
tablice rozproszone, użyteczne przy programowaniu równoległym.
Weźmy na przykład typowy algorytm rozwiązywania
eliptycznego równania różniczkowego cząstkowego. Okazuje się, że prawie
na każdym jego kroku możemy wykorzystać PETSc.
Krok algorytmu
|
Wykorzystanie PETSc
|
1. Generuj triangulację |
|
2. Generuj macierze sztywności |
Obiekty i operacje macierzowe (Mat) |
3. Generuj prawą stronę równania i przybliżenie początkowe |
Obiekty i operacje wektorowe (Vec) |
4. Obejrzyj utworzone wektory i macierze |
Przeglądarki obiektów PETSc (Viewer) |
5. Generuj preconditioner |
Obiekty i operacje macierzowe i wektorowe |
6. Rozwiąż |
Narzędzia do rozwiązywania równań liniowych i nieliniowych (SLES,
SNES). Obiekty kontrolujące przebieg metod iteracyjnych (KSP,
PC). Opcje wywołania i kontroli (Options). |
7. Obejrzyj wyniki |
|
Każdy ze składników PETSc ma własny interfejs
(zbiór wywołań procedur) i jedną lub więcej implementacji. Dzięki temu
PETSc zapewnia przejrzysty i efektywny kod na różnych etapach rozwiązywania
równań różniczkowych cząstkowych. Gwarantuje także łatwość testowania różnych
podejść do rozwiązywanego problemu, to znaczy zastosowania konkretnych
algorytmów czy preconditionerów.
W PETSc wszystkie funkcje nazywane są zgodnie
z konwencją TypObiektuCzynność(), na przykład:
MatCreate() - generuje macierz
MatMult() - mnoży dwie macierze
VecAXBY() - wykonuje na wektorach
operację
OptionsGetInt() - pobiera z opcji
zmienną typu int
Nazwy są długie, co nie oszczędza nam stukania w
klawiaturę, ale za to większość nazw funkcji jest zrozumiała i łatwa do
zapamiętania, co wspomaga pisanie i czytanie programów korzystających z
biblioteki PETSc.
Jak czytać ten podręcznik?
Wyszliśmy z założenia, że poznawanie PETSc należy
zacząć od prostych przykładów i nieskomplikowanych zagadnień. Dlatego ograniczyliśmy
się do wersji sekwencyjnej tej biblioteki, skupiając się na podstawowych
problemach spotykanych w praktyce numerycznej: rozwiązywaniu układów równań.
Podręcznik składa się więc z dwóch części: w pierwszej
wykładamy podstawy użytkowania PETSc i w oparciu o nie pokazujemy, jak
można wykorzystać PETSc do rozwiązywania wielkich układów równań liniowych
za pomocą nowoczesnych metod iteracyjnych. W drugiej części omawiamy bardziej
zaawansowane techniki oraz metody wykorzystania PETSc do rozwiązywania
układów równań nieliniowych. Obie części bogato ilustrujemy pouczającymi
przykładami, związanymi najczęściej z eliptycznymi równaniami różniczkowymi
cząstkowymi.
Wydaje się więc, że podręcznik ten trzeba czytać
w sposób, hmm... monotoniczny, to znaczy "od początku do końca". Zachęcamy
Czytelnika do pisania własnych programów i do testowania świeżo zdobytej
wiedzy. W szczególności, dla dobrego wykonania ćwiczeń, którymi kończymy
większość rozdziałów, warto jest zawsze zerknąć nie tylko do naszego podręcznika,
ale też do man pages oraz oficjalnego manuala.
Nie da się ukryć, aby nauczyć się korzystać z PETSc,
trzeba włożyć trochę wysiłku. Przede wszystkim, trzeba zacząć pisać programy.
Dlatego zachęcamy do lektury poniższego pouczającego rozdziału.
Zaczynamy!
Poniżej przedstawiony jest najprostszy program
używający PETSc, będący mutacją klasycznego przykładu "Hello, world!",
pojawiającego się na początku wielu podręczników programowania:
program1.c
#include "sles.h"
static char help[]="Najprostszy program uzywajacy
PETSc\n";
int main(int argc,char **args)
{
PetscInitialize(&argc,&args,PETSC_NULL,help);
PetscPrintf(MPI_COMM_WORLD,"PETSc działa
i pozdrawia\n");
PetscFinalize();
}
Uruchomienie powyższego programu spowoduje, jak
łatwo się domyślić, wypisanie na konsolę tekstu:
hydra:/usr/home/students/bojko> program1
PETSc działa i pozdrawia
hydra:/usr/home/students/bojko> _
Dzięki deklaracji funkcji main() z argumentami
argc, args oraz wywołaniu funkcji PetscInitialize(),
tekst z linii komend zostanie przekazany bezpośrednio do programu. Dzięki
temu, będziemy mogli używać rozmaitych parametrów wywołania programu (tzw.
opcji), sterując wieloma parametrami PETSc i samego programu, bez konieczności
nieustannego rekompilowania go.
Mimo, że kod źródłowy jest bardzo krótki, skompilowanie
tego programu spowoduje wygenerowanie dość dużego pliku wynikowego, a to
dlatego, że do każdego programu dołączany jest szereg procedur ułatwiających
życie programistom i użytkownikom - chociażby zestaw procedur do śledzenia
pracy programu. Na przykład, uruchomienie tego samego programu z opcją
-help spowoduje wypisanie:
hydra: /usr/home/students/bojko> program1 -help
--------------------------------------------------------------------------
PETSc Version 2.0.22, Released April 28, 1998.
The PETSc Team: Satish Balay, Bill Gropp, Lois Curfman McInnes, Barry Smith
Bug reports, questions: petsc-maint@mcs.anl.gov
Web page: http://www.mcs.anl.gov/petsc/
See docs/copyright.html for copyright information
See docs/changes.html for recent updates.
See docs/troubleshooting.html hints for problems.
See docs/manualpages/manualpages.html for help.
Libraries linked from /usr/local/petsc/petsc-2.0.22/lib/libO/solaris
-----------------------------------------------------------------------
Options for all PETSc programs:
-on_error_abort: cause an abort when an error is detected. Useful
only when run in the debugger
-on_error_attach_debugger [dbx,xxgdb,ups,noxterm]
start the debugger (gdb by default) in new xterm
unless noxterm is given
-start_in_debugger [dbx,xxgdb,ups,noxterm]
start all processes in the debugger
-debugger_nodes [n1,n2,..] Nodes to start in debugger
-debugger_pause [m] : delay (in seconds) to attach debugger
-display display: Location where graphics and debuggers are displayed
-no_signal_handler: do not trap error signals
-mpi_return_on_error: MPI returns error code, rather than abort on internal error
-fp_trap: stop on floating point exceptions
note on IBM RS6000 this slows run greatly
-trdump: dump list of unfreed memory at conclusion
-trmalloc: use our error checking malloc
-trmalloc_off: don't use error checking malloc
-trmalloc_nan: initialize memory locations with NaNs
-trinfo: prints total memory usage
-trdebug: enables extended checking for memory corruption
-optionstable: dump list of options inputted
-optionsleft: dump list of unused options
-log[_all _summary]: logging objects and events
-log_summary_exclude: <vec,mat,sles,snes>
-log_trace [filename]: prints trace of all PETSc calls
-log_info: print informative messages about the calculations
-v: prints PETSc version number and release date
-options_file <file>: reads options from file
-----------------------------------------------
Najprostszy program uzywajacy PETSc
PETSc działa i pozdrawia
hydra:/usr/home/students/bojko>_
Widać więc, że opcja -help powoduje wypisanie
własnych komunikatów PETSc dotyczących opcji dostępnych w składnikach pakietu
używanych w naszym programie oraz naszego komunikatu ze stałej help.
Wszystkie procedury udostępniane przez pakiet działają tylko między funkcjami
PetscInitialize() i PetscFinalize(), więc część programu
korzystająca z PETSc powinna zawierać się między nimi.
Zanim rozpoczniemy nasze bliskie spotkanie z PETSc,
jeszcze krótko omówimy sposób kompilowania i uruchamiania programów korzystających
z PETSc (wersja 2.0.22) na komputerze
hydra.mimuw.edu.pl. Ponieważ
instalacje (i wersje) mogą różnić się od siebie detalami należy skonsultować
się z lokalnym administratorem lub lokalnym guru PETSc (często będą to
różne osoby).
Po pierwsze aby móc skompilować swój program należy ustawić zmienne
środowiskowe PETSC_DIR, PETSC_ARCH, BLAS_DIR,
LAPACK_DIR, LD_LIBRARY_PATH jak następuje:
setenv PETSC_DIR /usr/local/petsc/petsc-2.0.22
setenv PETSC_ARCH solaris
setenv BLAS_DIR /usr/local/petsc/blaslapack
setenv LAPACK_DIR /usr/local/petsc/blaslapack
setenv LD_LIBRARY_PATH /opt/SUNWspro/lib:/lib:/usr/local/petsc/petsc-2.0.22/lib/libO/solaris:/usr/lib/X11:/usr/openwin/lib
(dokładny opis tych zmiennych można znaleźć w
odpowiednim pliku w katalogu
głównym PETSc, w przypadku
hydry.mimuw.edu.pl.
jest to katalog
/usr/local/petsc/petsc-XXX, gdzie
XXX jest numerem aktualnej wersji PETSc).
Najlepiej umieścić powyższe dyrektywy w pliku
.cshrc w katalogu
użytkownika. Poniżej podany jest plik
Makefile, który musi znaleźć
się w tym samym katalogu co plik źródłowy
program1.c,
dzięki
któremu program będzie można skompilować używając polecenia
make program1.
Szczegóły dotyczące uruchamiania programów można znaleźć w rozdziale "
Uruchamianie
programów".
Makefile
BOPT=O
include $(PETSC_DIR)/bmake/$(PETSC_ARCH)/base
CFLAG
= $(CPPFLAGS) -D__SDIR__='"$(LOCDIR)"' $(BS_INCLUDE)
LIBBASE
= libpetscsles
LOCDIR
= /usr/home/students/bojko/source/
program1: program1.o
-$(CLINKER) -o program1 program1.o $(PETSC_LIB)
$(RM) program1.o
Oczywiście, parametr LOCDIR powinien być ustawiony na ścieżkę
z Twoimi plikami źródłowymi.
Ćwiczenia
-
W katalogu $PETSC_DIR/docs znajdują się: manual [2]
oraz man pages [3] dla PETSc, w formacie HTML. Odnajdź te pliki
i przejrzyj ich zawartość przy użyciu jakiejś przeglądarki do stron WWW
(np. Netscape). Będziesz ich bardzo
często potrzebować, więc warto.
-
Ten pordęcznik ma także swoje wcielenie papierowe - zobacz Raport RW
98-06 (44), Instytut Matematyki Stosowanej, Wydział Matematyki Mechaniki
i Informatyki, Uniwersytet Warszawski, wrzesien 1998. Można go także
ściągnąć w formie pliku PostScriptowego petsc.ps,
petsc.zip, petsc.gz, lub
pliku petsc.pdf w formacie Adobe
Acrobat Readera 3.0, (takze z osadzonymi polskimi
czcionkami), jednak najaktualniejszą wersją jest zawsze HTMLowa wersja,
którą obecnie czytasz.
-
Skompiluj i uruchom przykładowy program używający biblioteki PETSc. W przypadku
kłopotów skontaktuj się z jakimś bardziej doświadczonym użytkownikiem pakietu.
Warto poświęcić chwilę czasu na ustawienie (raz, a dobrze!) zmiennych środowiskowych
i napisanie własnego Makefile. Zaprocentuje to w przyszłości!
-
Na przykładzie programu "PETSc działa i pozdrawia" zobacz, jak
działają inne opcje PETSc, w szczególności: -log, -v,
-trinfo.
Copyright (C) Marcin Bojko i Piotr Krzyzanowski,
1998.
Ostatnia modyfikacja: 09.X.98.