Aktuálně je nainstalován UMFPack verze 5.4. Aby to nebylo tak jednoduché, tak tu máme hned dva. UMFPack používá pro své potřeby volání knihovny blas. Protože na našem clusteru jsou k dipozici dvě různé blasové implementace, jsou k dispozici i dva různě optimalizované UMFPacky.
Uživatel si může vybrat buď velmi standartní optimalizaci gcc kompilátorem, nebo pomocí nástrojů společnosti Intel, které máme k dispozici a které by měli produkovat efektivnější kód vzhledem k použitému hardwaru.
GCC optimalizace
Balík je nainstalován v adresáři
/usr/local/pkg/umfpack/5.4/gcc
a byl přeložen s volbami
-O3 -fexceptions -ffast-math -funroll-loops -mtune=native
Pro kompilaci budete potřebovat kompilátoru upřesnit cesty, odkud má includovat header soubory a linkeru napovědět, kde jsou k dispozici knihovny. Pokud se orientujete v syntaxiMakefile, pak pro vám máme stručný návod:
CC=gcc UMFPACKDIR=/usr/local/pkg/umfpack/5.4/gcc CFLAGS = -Wall -asi -pedantic -O3 -ffast-math -I${UMFPACKDIR}/include LIBS = -lumfpack -lamd -lblas -L${UMFPACKDIR}/lib umfpack-prilad1: umfpack-priklad1.o $(CC) $(CFLAGS) umfpack-example1.o -o $@ $(LIBS) clean: rm -r *.o umfpack-example1
Intel optimalizace
Velmi podobně můžete využít UMFPack kompilovaná kompilátorem icc s knihovnou MKL. Stačí použít lehce upravený Makefile
CC=icc UMFPACKDIR=/usr/local/pkg/umfpack/5.4/intel CFLAGS = -fast -I${UMFPACKDIR}/include LIBS = -mkl -lumfpack -L${UMFPACKDIR}/lib umfpack-prilad1: umfpack-priklad1.o $(CC) $(CFLAGS) umfpack-example1.o -o $@ $(LIBS) clean: rm -r *.o umfpack-example1
Ukázka použití
Pokud si budete chtít sáhnout na kód, který je v Makefile příkladech citován jako umfpack-example1.c, můžete využít např. následující kód.
/* Jednoduchý příklad řešení lineárního problému pomocí klinovny UMFPACK. Podle návodu v UMFPACK's QuickStart.pdf Řešení problému Ax=b, kde: A = 2 3 0 0 0 3 0 4 0 6 0 -1 -3 2 0 0 0 1 0 0 0 4 2 0 1 b = (8, 45, -3, 3, 19) Řešení x je pak: x = (1, 2, 3, 4, 5) */ #include <stdio.h> #include "umfpack.h" int main(void) { int n = 5; double x[5]; void *Symbolic, *Numeric; int i; /* Matice se prochází po SLOUPCÍCH * budeme potřebovat počty hodnot, umístění vmatici a příslušné hodnoty. */ /* počty hodnot v matici (kumulativně) */ int Ap[] = { 0, 2, 5, 9, 10, 12 }; /* řádkové indexy hodnot (připomínám, procházíme po sloupcích) */ int Ai[] = { 0, 1, 0, 2, 4, 1, 2, 3, 4, 2, 1, 4 }; /* a konečně hodnoty */ double Ax[] = { 2, 3, 3, -1, 4, 4, -3, 1, 2, 2, 6, 1 }; /* vektor pravé strany */ double b[] = { 8, 45, -3, 3, 19 }; /* Nejprve necháme provest symbolickou analýzu */ umfpack_di_symbolic(n, n, Ap, Ai, Ax, &Symbolic, NULL, NULL); /* LU faktorizaci */ umfpack_di_numeric(Ap, Ai, Ax, Symbolic, &Numeric, NULL, NULL); umfpack_di_free_symbolic(&Symbolic); /* a vyřešíme soustavu */ umfpack_di_solve(UMFPACK_A, Ap, Ai, Ax, x, b, Numeric, NULL, NULL); umfpack_di_free_numeric(&Numeric); /* výsledné řešení vypíšeme */ for (i = 0; i < n; i++) printf("x[%d] = %g\n", i, x[i]); return 0; }