Level 3
Mit Tag 6 solltet ihr fertig sein, d.h.
-
mindestens eine Level 1 Funktion wurde mit SSE/AVX optimiert und
-
in einem Benchmark wurde das graphisch gezeigt.
Vorbereitungen
Im Moment ist level1 ein Top-Level Verzeichnis. Wenn jetzt aber level3 dazu kommt, dann sollen beise Verzeichnisse eine Ebene weiter nach unten rutschen. Die Struktur soll so aussehen:
|+bench/
|+refblas/
|~src/
| |+auxiliary/
| |+level1/
| |+level3/
| |-Makefile
| `-ulmblas.h
|+test/
|-Makefile
`-Readme.md
Es kommt also auf oberster Ebene das Verzeichnis src hinzu. Dies enthält folgende Dinge:
-
src/auxiliary/ für Hilfsfunktionen, die allgemein benötigt werden. Das wird insbesondere die Funktion xerbla sein, die von Level2 und Level 3 Routinen zur Ausgabe von Fehlermeldungen benötigt wird.
-
src/level1 für unsere Level 1 Funktionen (die wir bereits haben).
-
src/level3 hier sollen unsere Level 3 Funktionen reinkommen.
Aufgabe:
-
Anlegen bzw. Verschieben der Verzeichnisse
Makefile
Damit wir die Makefiles verstehen schreiben wir sie selber! Dazu freunden wir und mit GNU Make und insbesondere der make documentation an. Das Makefile entwickeln wir iterativ.
Unterverzeichnisse Scannen
Aufgabe: Schreibt in src/ ein Makefile das nach und nach folgendes tut:
-
Mit make werden zunächst alle Files mit Endung *.c ausgegeben.
-
Dann soll make zusätzlich die Fileliste ausgeben bei der die Endungen mit .o ersetzt wurden.
-
Dann soll make zusätzlich Filelisten ausgeben bei der *.c Dateien das Präfix atl_ haben.
-
Dann soll make zusätzlich Filelisten ausgeben bei der *.o Dateien das Präfix atl_ haben.
-
Mit make clean wird aufgeräumt.
Hinweis:
-
Es geht natürlich darum, dass ihr im Makefile Variablen SOURCE_FILES, OBJECT_FILES, ATL_SOURCE_FILES und ATL_OBJECT_FILES anlegt und mit den richtigen Werten füllt.
-
Man kann sich im Makefile eine Variable DIRS = auxiliary level1 level3 anlegen und dann mit Dingen wie foreach, patsubst, basename und wildcard arbeiten. Es gibt hier eine Vielzahl an Möglichkeiten. Schaut euch mal den Abschnitt Functions in der GNU Make Documentation an.
-
Mit z.B. echo $(SOURCE_FILES) kann man dann in einem Target den Inhalt der Variablen ausgeben.
-
Die meisten Unterverzeichnisse von src/ sind noch leer. Zum testen sollte man also Dummy Source Files in den Verzeichnissen anlegen.
Alten Stand wiederherstellen
Aufgabe: Die Dummy Source Files wieder löschen. Das Makefile so erweitern, dass
-
mit make die Bibliotheken libulmblas.a und libatlulmblas wieder im obersten Verzeichnis angelegt bzw. aktualisiert werden.
-
Ein Object File neu übersetzt wird, wenn sich das Source File geändert hat.
Hinweis:
-
Die Compiler Flags müssen angepasst werden.
-
Der Benchmark in bench/ und der Test in test/ sollte wieder tun.
Level 3: GEMM
Wir entwickeln die Implementierung von Level 3 BLAS wieder schrittweise.
Rümpfe
-
In src/auxiliary/ die Funktion xerbla implementieren.
-
In src/level3/stubs.c/ stubs für dsyr2k, dsyrk, dtrmm, dtrsm anlegen. Also zum Beispiel:
void
F77BLAS(dsyr2k)()
{
}
void
ULMBLAS(dsyr2k)()
{
}
// ...
-
In src/level3/dgemm.c die Funktion mit richtiger Signatur für dgemm anlegen. Wie in level1/ gibt es eine F77BLAS(dgemm) Variantem, die skalare Argumente dereferenzieren soll und dann die ULMBLAS(dgemm) Variante aufrufen soll.
-
In Fortran werden Optionen für das Transponieren als Charakter übergeben. Für unsere eigene C Implementierung wollen wir aber Enum-Konstanten benutzen. Das heisst F77BLAS(dgemm) muss Charakter in Enum-Konstanten umwandeln. Die Konstanten sollen in ulmblas.h definiert werden als
enum Trans {
NoTrans = 111, // 'n', 'N'
Trans = 112, // 't', 'T'
ConjTrans = 113, // 'c', 'C'
Conj = 114 // 'r', 'R'
};
Natürlich lohnt es sich auch ein Macro charToTrans(ch) in ulmblas.h zu definieren.
Aufgabe: Übersetzen und damit libatlulmblas.a und libulmblas.a erzeugen.
Level 3 Test
-
Den Level 3 Test dblat3.f und den zugehörigen Testcase dblat3.dat in test/ kopieren.
Aufgabe:
-
Das bisherige Makefile sollte bereits dblat3_ulm und dblat3_ref erzeugen. Prüft, ob das wirklich so ist. Wenn ja, dann lernt zu verstehen wieso. Wenn nein, dann löst das.
-
Mit ./dblat3_ulm < dblat3.dat wird zum Beispiel die Level 3 Implementierung von libulmblas getestet. Das Ergebnis wird in die Datei DBLAT3.SUMM das Ergbnis geschrieben. Probiert das aus.
-
Mit make check_ulm sollen alte *.SUMM Files gelöscht werden und der Level 1 und Level 3 Test für libulmblas.a durchgeführt werden.
-
Mit make clean sollen jetzt auch *.SUMM Files gelöscht werden.
-
Ändert die Datei dblat3.dat so, dass nur noch DGEMM getestet wird.
Fehlerbehandlung für dgemm
Aufgabe:
-
Baut in eure dgemm Implementierung die Fehlerbehandlung ein. Damit sollte der erste Teil des BLAS Tests bereits bestanden werden.
-
Damit der Error-Exit-Test bestanden wird muss die xerbla Funktion mit den richtigen Fehlercodes aufgerufen werden. Findet heraus welche xerbla Implementierung von dblat3 wirklich aufgerufen wird.
Implementierung von dgemm
Aufgabe: Jetzt soll die dgemm Implementierung auch das richtige Ergebnis liefern.