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;
}
