hydra:/usr/home/bin> make moj_program
Aby jednak to działało, należy jednak napisać własny plik tekstowy nazwany Makefile w którym podane zostaną (ale tylko raz) wszystkie parametry potrzebne do kompilowania i linkowania programu. Przykładowy plik Makefile, pozwalający na skompilowanie programu z dołączeniem bibliotek PETSc podajemy poniżej. Zmienna BOPT mówi jaka wersja programu ma być tworzona. BOPT=O oznacza program zoptymalizowany, BOPT=g oznacza wersję do odpluskwiania (debuggingu). Ważne jest, żeby gotowy (tzn. odpluskwiony) program kompilować z opcją BOPT=O, gdyż to daje kilkukrotnie mniejszy (około 5 razy) i szybszy kod wynikowy. Oczywiście, aby w ogóle dało się skompilować program, muszą być ustawione zmienne środowiskowe opisane w rozdziale "Zaczynamy" . Tworzenie Makefile'ów jest odrębną sztuką. Zamiast ją zgłebiać, proponujemy pisanie własnych przez prostą modyfikację poniższego:
Makefile
include $(PETSC_DIR)/bmake/$(PETSC_ARCH)/base
CC = gcc -DPETSC_LOG
CLINKER = gcc
CFLAGS = $(PCONF) $(PETSC_INCLUDE) $(BS_INCLUDE)
LIBBASE = libpetscsles libpetscsnes
OPTS = -O
BOPT = O
moj_program: moj_program.o
$(CLINKER) -o moj_program moj_program.o
-lm $(PETSC_LIB)
Bardziej rozbudowane Makefile, umożliwiające kompilację kilku różnych programów, znajdują się tutaj i tutaj.
hydra:/usr/home/bin> moj_program [opcje]
Drugi sposób stosujemy, gdy uruchamiamy program na maszynie wieloprocesorowej z zainstalowaną biblioteką MPI. Wówczas program uruchamia się komendą:
hydra:/usr/home/bin> mpirun -np 4 moj_program [opcje]
Opcja -np 4 oznacza liczbę procesorów, na których będzie uruchomiony moj_program (w tym wypadku 4). Dalej podajemy nazwę programu i ewentualne opcje samego programu.
#include "sles.h"
Jak już wspomnieliśmy, dzięki użyciu funkcji main() z argumentami argc, args oraz wywołaniu funkcji PetscInitialize(), tekst z linii komend zostanie przekazany bezpośrednio do programu i potraktowany jako opcje, co pozwala na sterowanie wieloma parametrami programu. Można zmieniać rozmiar zadania, podawać dodatkowe parametry itp.
W pełnym wykorzystaniu opcji pomocne będą funkcje: OptionsGetXXX(char* pre, char *name, XXX *zmienna,int *flag) gdzie w miejscu XXX wstawiamy typ wartości podawanej z linii komend: Int, Double, Scalar, String, DoubleArray. Na przykład funkcja
.... OptionsGetInt(PETSC_NULL,"-N",&rozmiar); ....
Argumenty funkcji OptionsGetXXX() mają następujące znaczenie: pierwszy to przedrostek, u nas będzie zawsze ustawiony na PETSC_NULL. Drugi to poszukiwany ciąg znaków, a trzeci argument to wskaźnik zmiennej do której będzie przekazywany wynik. Ostatni argument to wskaźnik do zmiennej, w której zapisane zostanie czy przypisanie wartości miało miejsce, czy nie. Przydatna jest też funkcja OptionsHasName(char* pre, char *name,int *flag), która sprawdza, czy dany ciąg znaków name pojawił się w linii komend i wynik zapisuje w zmiennej flag.
Ważnym ułatwieniem w pisaniu programów jest to, że wszystkie funkcje w PETSc zwracają kody błędów. Jest też makro CHKERRA(int ierr), która w przypadku wystąpienia błędu poda numer linii programu i nazwę pliku z kodem źródłowym oraz krótki opis błędu. Jeżeli zatem każdą funkcję PETSc wywołujemy następująco:
... ierr = VecCreate(MPI_COMM_WORLD,PETSC_DECIDE,N,&v); CHKERRA(ierr); ierr = VecSet(&val,v); CHKERRA(ierr); ...
Opcja -sles_view spowoduje wypisanie na konsolę informacji na temat SLESu
Opcja -vec_view po wywołaniu w programie funkcji VecAssemblyBegin(v) zostanie wypisany na konsolę wektor v. Podobna do niej -vec_view_draw narysuje w oknie graficznym wektor jako funkcję indeksu.
Opcja -mat_view po wywołaniu w programie funkcji MatAssemblyBegin(A,FINAL_ASSEMBLY) zostanie wypisana na konsolę macierz A. Podobna do niej -mat_view_draw narysuje w oknie graficznym strukturę miejsc niezerowych macierzy.
Opcja -draw_pause <n> spowoduje zatrzymanie przeglądarki graficznej (zarówno wywoływanej opcją z linii komend jak i z programu) na n sekund. Jeżeli n=0 to przeglądarka czeka na kliknięcie klawiszem myszki. To bardzo przydatna opcja, gdyż często przeglądarka jest zamykana zaraz po zakończeniu rysowania, co w wielu przypadkach nie wystarcza nawet na zauważenie, że okno pojawiło się na ekranie.
Opcją -ksp_type <typ> możemy zmienić rodzaj metody iteracyjnej używanej do rozwiązywania układu równań (szczegóły tutaj) Inne opcje będziemy omawiać na bieżąco.
Opis opcji dostępnych w każdym z programów jest wypisywany gdy uruchamiamy program z opcją help.
#include "sles.h" static char help[]="Pomoc"; int main(int argc,char **args) { int N=5,pc_flag=0; double af=0.1; PetscInitialize(&argc,&args,PETSC_NULL,help); OptionsGetInt(PETSC_NULL,"-N",&N); OptionsGetDouble(PETSC_NULL,"-alfa",&af); OptionsHasName(PETSC_NULL,"-bez_pc",&pc_flag); PetscPrintf(MPI_COMM_WORLD,"rozmiar=%i,af=%d,pc_flag=%i\n",N,af,pc_flag); PetscFinalize(); return(0) }
hydra:/usr/home/bin/> program -help -N 10 -alfa 0.22
spowoduje przypisanie zmiennej rozmiar wartości 10, zmiennej af wartości 0.22, oraz zostanie wypisana pomoc do pakietu z uwzględnieniem stałej tekstowej help (patrz wyżej).
hydra:/usr/home/bin/> program -N 23 -bez_pc
spowoduje przypisanie zmiennej rozmiar wartości 23, ustawienia pc_flag na TRUE, a zmienna af pozostanie bez zmian, tzn. równa 0.1.