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:

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:
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:
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

  1. 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.
  2. 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.
  3. 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!
  4. Na przykładzie programu "PETSc działa i pozdrawia" zobacz, jak działają inne opcje PETSc, w szczególności: -log, -v, -trinfo.
 
Od autorów Spis treści I. Rozwiązywanie układów równań liniowych
 

Copyright (C) Marcin Bojko i Piotr Krzyzanowski, 1998.
Ostatnia modyfikacja: 09.X.98.