Das Performance Instrumentation R efinement A utomation Framework PIRA nähert sich der zeitaufwändigen Aufgabe, bei Verwendung von Score-P eine sinnvolle Leistungsmessung für eine unbekannte Codebasis zu generieren. Weitere Informationen finden Sie in unseren Dokumenten:
[PI18] | Jan-Patrick Lehr, Alexander Hück, Christian Bischof. PIRA: Automatisierung der Verfeinerung der Leistungsinstrumentierung. Im 5. ACM SIGPLAN International Workshop on Artificial Intelligence and Empirical Methods for Software Engineering and Parallel Computing Systems (AI-SEPS) , Seiten 1-10, ACM, 2018. |
[PI19] | Jan-Patrick Lehr, Alexandru Calotoiu, Christian Bischof, Felix Wolf. Automatische Verfeinerung der Instrumentierung für die empirische Leistungsmodellierung. In International Workshop on Programming and Performance Visualization Tools (ProTools) , Seiten 40-47, IEEE, 2019. |
[PI21] | Peter Arzt, Yannic Fischler, Jan-Patrick Lehr, Christian Bischof. Automatische Lastungleichgewichtserkennung bei geringem Overhead in MPI-Anwendungen. In Euro-Par 2021: Parallelverarbeitung. Lecture Notes in Computer Science, Band 12820 , Seiten 19–34, Springer, 2021. |
PIRA führt die folgenden vier Phasen durch (2–4 werden iteriert):
PIRA unterstützt sowohl die Filterung von Funktionen zur Kompilierungszeit als auch zur Laufzeit , einschließlich der Laufzeitfilterung von MPI-Funktionen durch automatisch generierte Wrapper. Bei der Filterung zur Kompilierungszeit werden nur die gewünschten Funktionen zur Kompilierungszeit instrumentiert, wodurch der Gesamteinfluss auf die Messung erheblich reduziert wird. Im Gegensatz dazu fügt der Compiler bei der Laufzeitfilterung Instrumentierungs-Hooks in jede Funktion der Zielanwendung ein, und die Filterung erfolgt zur Laufzeit.
PIRA erfordert CMake (>=3.16), Clang/LLVM 10, Python 3, Qt5 und OpenMPI 4. Es (oder MetaCG) wird weiter heruntergeladen (und erstellt)
Wenn Sie PIRA in einer Umgebung ohne Internetzugang erstellen möchten, sehen Sie sich bitte das Skript resources/build_submodules.sh
an und passen Sie es an Ihre Bedürfnisse an.
Klonen Sie das PIRA-Repository.
$> git clone https://github.com/tudasc/pira
$> cd pira
Zweitens erstellen Sie die abhängigen Submodule mithilfe des bereitgestellten Skripts oder übergeben Sie Werte für die verschiedenen Optionen (siehe Nutzungsinformationen über -h
für verfügbare Optionen). Alle heruntergeladenen und erstellten Dateien werden in external/src/
abgelegt, während alle Installationen in external/install/
abgelegt werden. Geben Sie die Anzahl der Kompilierungsprozesse an, die für die Kompilierung der externen PIRA-Dateien erzeugt werden sollen. Das Skript lädt die Abhängigkeiten von PIRA in ihrer Standardversion herunter. Diese Versionen werden auch in unserem CI getestet und werden voraussichtlich funktionieren.
$> cd resources
$> ./build_submodules.sh -p <ncores>
Als letzten Schritt schreibt das Build-Skript die Installationspfade der Submodule in die Datei resources/setup_paths.sh
. Wenn Sie PIRA neu erstellen möchten, denken Sie bitte git restore
.
Wir stellen auch eine (experimentelle) Dockerfile
zur Verfügung, um PIRA zu erstellen und auszuprobieren.
$> podman build -t pira:master -f docker/Dockerfile .
Wenn Sie innerhalb des Containers beispielsweise die Integrationstests ausführen, rufen Sie die Skripte bitte wie folgt auf.
$> cd resources
$> . setup_paths.sh
$> cd ../test/integration/GameOfLife # Example test case
# By default PIRA will look into $HOME/.local, which is not currently existent in the docker
# XDG_DATA_HOME signals where to put the profiling data PIRA generates
$> XDG_DATA_HOME=/tmp ./run.sh
Ein vollständiges Beispiel für die Verwendung von PIRA finden Sie in den run.sh
-Skripts im Ordner /test/integration/*
. Ein potenziell guter Ausgangspunkt ist der GameOfLife
-Ordner und sein Testfall.
Richten Sie zunächst die erforderlichen Pfade ein, indem Sie das Skript im resources
ablegen.
$> cd resources/
$> . setup_paths.sh
Anschließend können Sie eine Beispielanwendung von PIRA auf einer sehr einfachen Implementierung von Conways Game of Life ausführen, indem Sie das bereitgestellte run.sh
Skript im Ordner ./test/integration/GameOfLife
verwenden.
$> cd ./test/integration/GameOfLife
$> ./run.sh
Das Skript führt alle von Anfang an erforderlichen Schritte durch, dh die Vorbereitung aller Komponenten für einen neuen Zielcode, um schließlich PIRA aufzurufen. In den folgenden Abschnitten werden die Schritte näher erläutert. Die Schritte sind:
config
Pfad zur Konfigurationsdatei (erforderliches Argument)--config-version [1,2]
Version der PIRA-Konfiguration, 2 ist die Standardeinstellung und wird empfohlen; 1 ist veraltet.--runtime-filter
Laufzeitfilterung verwenden, der Standardwert ist false. Bei der Filterung zur Kompilierzeit werden die Funktionen nicht zur Kompilierungszeit instrumentiert, wodurch sich der Gesamtmesseinfluss erheblich verringert, das Ziel jedoch in jeder Iteration neu erstellt werden muss. Im Gegensatz dazu fügt der Compiler bei der Laufzeitfilterung Instrumentierungs-Hooks in jede Funktion der Zielanwendung ein.--iterations [number]
Anzahl der Pira-Iterationen, der Standardwert ist 3.--repetitions [number]
Anzahl der Messwiederholungen, der Standardwert ist 3.--tape
Speicherort, auf den ein (etwas umfangreiches) Protokollierungsband geschrieben werden soll.--extrap-dir
Das Basisverzeichnis, in dem die Extra-p-Ordnerstruktur abgelegt wird.--extrap-prefix
Extra-P-Präfix, sollte eine Folge von Zeichen sein.--version
Gibt die Versionsnummer der PIRA-Installation aus--analysis-parameters
Pfad zur Konfigurationsdatei mit Analyseparametern für PGIS. Erforderlich sowohl für den Extra-P- als auch für den LIDe-Modus.--slurm-config [path to slurm cfg file]
Ermöglicht die Ausführung des Zielcodes auf einem Slurm-Cluster. Es wird eine Slurm-Konfigurationsdatei benötigt. Weitere Informationen finden Sie in diesem Abschnitt. --hybrid-filter-iters [number]
Nach [Anzahl] Iterationen neu kompilieren, dazwischen Laufzeitfilterung verwenden.--export
Fügt die generierten Extra-P-Modelle und Datensatzgrößen in die IPCG-Datei des Ziels ein.--export-runtime-only
Erfordert --export
; Hängt den Funktionen nur den mittleren Laufzeitwert aller Wiederholungen an. Nur verfügbar, wenn Extra-P nicht verwendet wird.--load-imbalance-detection [path to cfg file]
Aktiviert und konfiguriert den Lastungleichgewichtserkennungsmodus. Bitte lesen Sie diesen Abschnitt für weitere Informationen. PIRA verwendet Quellcodeinformationen zum Erstellen einer anfänglichen Instrumentierung und zur Entscheidung, welche Funktionen während der iterativen Verfeinerung zu einer Instrumentierung hinzugefügt werden sollen. Es stellt ein Clang-basiertes Call-Graph-Tool bereit, das alle erforderlichen Informationen sammelt und die Informationen in einer .json
Datei ausgibt. Sie finden das cgcollector
Tool im Unterverzeichnis ./extern/src/metacg/cgcollector
. PIRA erfordert, dass die Callgraph-Datei im MetaCG-Dateiformat in Version 2 (MetaCG v2) vorliegt.
Weitere Informationen zum CGCollector und seinen Komponenten finden Sie in der MetaCG-Dokumentation.
Die Anwendung des CGCollector erfolgt normalerweise in zwei Schritten.
Zunächst wird cgc
für jede Quelldatei im Projekt aufgerufen. z.B:
for f in $(find ./src -type f ( -iname "*.c" -o -iname "*.cpp" ) ); do
cgc --metacg-format-version=2 $f
done
Die in Schritt 1 erstellten .ipcg
-Dateien werden dann mit cgmerge
zu einer allgemeinen Datei zusammengeführt.
"null"
enthält. 2. Wenn Ihr Projekt mehr als eine main
enthält, führen Sie die Datei bitte nur mit der richtigen main
zusammen. echo "null" > $IPCG_FILENAME
find ./src -name "*.ipcg" -exec cgmerge $IPCG_FILENAME $IPCG_FILENAME {} +
Der endgültige Graph muss im Verzeichnis des Callgraph-Analyzers abgelegt werden. Da derzeit PGIS für die CG-Analyse verwendet wird, wird die generierte gesamte Programmdatei in das PGIS-Verzeichnis kopiert. Derzeit ist es wichtig, dass die Datei im PGIS-Verzeichnis nach dem Muster item_flavor.mcg
benannt wird. Ein Artikel steht für eine Zielanwendung. Mehr zu den Begriffen Geschmack und Artikel im nächsten Abschnitt.
# Assuming $PIRA holds the top-level PIRA directory
$> cp my-app.mcg $PIRA/extern/install/pgis/bin/item_flavor.mcg
Die PIRA-Konfiguration enthält alle erforderlichen Informationen, damit PIRA den automatischen Prozess ausführen kann. Die verschiedenen Verzeichnisse, die in der Konfigurationsdatei angegeben werden müssen, können entweder absolute Pfade oder Pfade relativ zum Ausführungspfad von pira sein. Pfade können Umgebungsvariablen enthalten, z. B. $HOME
. Die Beispiele stammen aus dem GameOfLife-Beispiel in ./test/integration/GameOfLife
.
Der Benutzer gibt Folgendes an: das Verzeichnis , in dem nach nachfolgend definierten Elementen gesucht werden soll. Im Beispiel lautet das Verzeichnis ./gol/serial_non_template
. Diese Verzeichnisse erhalten Aliase, die mit dem „%“-Zeichen dereferenziert werden. Ein Element in PIRA ist eine Zielanwendung, die auf eine bestimmte Art und Weise erstellt wurde. Aus diesem Grund wird es in der Konfiguration unter „Builds“ gruppiert.
{
"builds": {
"%gol": {
"items": {
"gol": {
...
}
}
}
}
"directories": {
"gol": "./gol/serial_non_template"
}
}
Jedes Element gibt an, welcher Analysator verwendet werden soll. Der Standardanalysator wird mit PIRA ausgeliefert und die Quellen finden Sie in ./extern/src/metacg/pgis
bzw. die Installation in ./extern/install/pgis/bin
. Der Analysator ist für die Steuerung der Instrumentierungsverfeinerung verantwortlich und daher ein wesentlicher Bestandteil des PIRA-Frameworks.
Das Feld argmap gibt die verschiedenen Argumente an, die beim Ausführen der Leistungsexperimente an die Zielanwendung übergeben werden. Wie die Argumente an die Zielanwendung übergeben werden, wird von verschiedenen Mappern definiert. Im Beispiel wird ein linearer Mapper verwendet, der einfach die Werte des Parameters namens size in der in der Liste angegebenen Reihenfolge iteriert.
"argmap": {
"mapper": "Linear",
"size": [50, 80, 110, 150, 300, 500]
}
Das Würfelfeld ist der Ort, an dem PIRA die erhaltenen Score-P-Profile speichern soll. An diesem Speicherort wird ein Verzeichnisbaum erstellt, sodass der Benutzer nach Abschluss von PIRA auch problemlos das Extra-P-Modellierungstool aufrufen kann, indem er ihm einfach den entsprechenden Speicherort übergibt, im Beispiel also /tmp/pira .
"cubes": "/tmp/pira"
Das Feld „Flavours“ fügt eine weitere Ebene der möglichen Unterscheidung hinzu, da Zielanwendungen in verschiedenen Geschmacksrichtungen erstellt werden können. Ein Beispiel wäre die Angabe verschiedener Mathematikbibliotheken, mit denen die Zielanwendung verknüpft werden soll.
Schließlich verweist das Funktorenverzeichnis PIRA auf den Speicherort, an dem es nach den vom Benutzer bereitgestellten Python-Funktionen sucht, die PIRA letztendlich mitteilen, wie die Zielanwendung erstellt, ausgeführt und analysiert werden soll. Im Beispiel wird PIRA auf ein Verzeichnis namens Funktoren relativ zum Speicherort der Konfiguration verwiesen.
"flavors": [
"ct"
],
"functors": "./functors",
"mode": "CT"
Das Modusfeld wird in dieser Version von PIRA ignoriert.
Ab sofort muss der Benutzer fünf verschiedene Funktoren implementieren:
analyze_<ITEM>_<FLAVOR>.py
: ruft den Analysator auf.clean_<ITEM>_<FLAVOR>.py
: bereinigt das Build-Verzeichnis.<ITEM>_<FLAVOR>.py
: Erstellen Sie die instrumentierte Version.no_instr_<ITEM>_<FLAVOR>.py
: erstellt die Vanilla-Version.runner_<ITEM>_<FLAVOR>.py
: führt die Zielanwendung aus. Funktoren unterstützen im Allgemeinen zwei Aufrufmodi: aktiv und passiv . Der Funktor teilt PIRA mit, welchen Modus es verwendet, indem er den entsprechenden Wert im von der Funktion get_method()
zurückgegebenen Wörterbuch auf True
setzt.
Im aktiven Modus ruft der Funktor selbst die erforderlichen Befehle auf, um beispielsweise die Software zu erstellen. Beim Aufruf wird dem Funktor ein **kwargs
-Parameter übergeben, der beispielsweise das aktuelle Verzeichnis und eine Instanz einer Unterprozess-Shell enthält.
Der passive Modus gibt lediglich die auszuführenden Befehle zurück, z. B. die Zeichenfolge make
um ein einfaches Makefile im Verzeichnis der obersten Ebene des Elements aufzurufen. Außerdem wird ein kwargs
-Parameter übergeben, der spezifische Informationen enthält, wie zum Beispiel vordefinierte Werte, die zum Hinzufügen zu CXXFLAGS benötigt werden, oder zusätzliche Linker-Flags. Ein Beispiel für einen passiven Funktor finden Sie in den examples
und test
. Derzeit verwenden alle implementierten Funktoren den passiven Modus.
PIRA übergibt die folgenden Schlüsselwortargumente an alle Funktoren. Darüber hinaus können verschiedene PIRA-Komponenten zusätzliche Argumente übergeben.
Wichtig : Wir versenden jetzt unsere eigene Score-P-Version. Somit ist es nicht mehr erforderlich, Kompilierungsbefehle in PIRA anzupassen. Schauen Sie sich die Funktionen in test/integration/AMG2013
an, um Beispiele für die Verwendung der verschiedenen Informationen zu finden.
Derzeit werden keine Informationen an alle Funktoren weitergegeben
[0]
greift auf das erste Argument zu, [1]
auf das zweite und so weiter..so
Datei, die die MPI-Wrapper-Funktionen implementiert (entscheidend für die MPI-Filterung). Für einige Analysemodi sind zusätzliche Parameter erforderlich. Insbesondere erfordern PIRA LIDe (siehe unten) und Extra-P-Modellierungsanalysen vom Benutzer bereitgestellte Parameter. Erstellen Sie eine JSON-Datei und geben Sie ihren Pfad zu PIRA mit dem Schalter --analysis-parameters
an. Das folgende Beispiel enthält Parameter für den Extra-P-Modellierungsmodus. Die verfügbaren Strategien zum Aggregieren mehrerer Extra-P-Modelle (wenn eine Funktion in verschiedenen Kontexten aufgerufen wird) sind: FirstModel
, Sum
, Average
, Maximum
.
{
"Modeling": {
"extrapolationThreshold": 2.1,
"statementThreshold": 200,
"modelAggregationStrategy": "Sum"
}
}
Weitere Einzelheiten zur Lastungleichgewichtserkennungsfunktion finden Sie in [PI21]. Geben Sie dem PIRA-Aufruf mithilfe des Parameters --load-imbalance-detection
einen Pfad zu einer Konfigurationsdatei an. Diese JSON-Datei muss die folgende Struktur haben:
{
"metricType": "ImbalancePercentage",
"imbalanceThreshold": 0.05,
"relevanceThreshold": 0.05,
"contextStrategy": "None",
"contextStepCount": 5,
"childRelevanceStrategy": "RelativeToMain",
"childConstantThreshold": 1,
"childFraction": 0.001
}
Um PIRA auf einem Cluster mit dem SLURM-Workload-Manager auszuführen, rufen Sie ihn mit dem Flag --slurm-config
auf. Geben Sie dabei den Pfad zu Ihrer Batch-Systemkonfigurationsdatei an. Siehe die Integrationstests mit dem Suffix _Slurm
( test/integration/*_Slurm/
). PIRA unterstützt derzeit Batch-Systeme mit dem SLURM-Workload-Manager. PIRA unterstützt die Verwendung eines module
, das auf Slurm-Clustern zu finden ist.
Die Batch-Systemkonfigurationsdatei ist eine JSON-Datei, die wie folgt aufgebaut ist:
{
"general": {
"backend": "slurm",
"interface": "pyslurm",
"timings": "subprocess"
},
"module-loads": [
{
"name": "gcc",
"version": "8.5"
},
{
"name": "llvm",
"version": "10.0.0",
"depends-on": [
{
"name": "gcc",
"version": "8.5"
}
]
}
],
"batch-settings": {
"time_str": "00:10:00",
"mem_per_cpu": 3800,
"number_of_tasks": 1,
"partition": null,
"reservation": null,
"account": "your_account_here",
"cpus_per_task": 96
}
}
Abbauen:
general
Abschnitt: Hier können Sie auswählen, auf welche Weise PIRA Ihren Code auf dem Batch-System ausführen soll. Da jede Option in diesem Abschnitt optional ist, können Sie den gesamten Abschnitt weglassen, wenn Sie mit der Verwendung der Standardeinstellungen einverstanden sind:backend
: Welcher Workload-Manager verwendet werden soll. Auswahlmöglichkeiten: slurm
, für den Slurm-Workload-Manager. Standard: slurm
, daher optional.interface
: Auf welche Weise PIRA mit Ihrem Batch-Systemmanager interagieren soll. Für das SLURM-Backend sind dies: pyslurm
, um PySlurm zu verwenden (dazu muss PySlurm installiert sein, siehe diesen Abschnitt); sbatch-wait
, um Standard sbatch
mit dem Flag --wait
zu verwenden; os
, für Standard sbatch
und squeue
-Interaktionsaufrufe. Standard: pyslurm
, daher optional.timings
: Wie das Timing des Zielcodes erfolgen soll. Auswahlmöglichkeiten: subprocess
, für das Timing mit einem Python-Wrapper und os.times
in einem Unterprozess (genau wie PIRA es macht, wenn es lokal ausgeführt wird); os
, /usr/bin/time
zu verwenden. Standard: subprocess
, daher optional.force-sequential
: Standardmäßig false
. Auf true
setzen, um PIRA/Ihr Batch-System zu zwingen, alle Läufe in sequentieller Reihenfolge durchzuführen (jeweils nur eine Ausführung des Zielcodes). Das bedeutet, dass PIRA dafür sorgt, dass Ihr Batch-System Wiederholungen sowie verschiedene Jobs bei Skalierungsexperimenten in sequentieller Reihenfolge ausführt. Wenn auf false
gesetzt/belassen, versucht PIRA, das Batch-System anzuweisen, in jeder Iteration so viele Ausführungen wie möglich parallel durchzuführen.module-loads
: Derzeit nicht in PIRA verwendet, in Arbeit! Derzeit müssen Sie alle Module manuell laden, bevor Sie PIRA starten! Bedeutet, welche Module mit dem module
geladen werden sollen. Dazu muss eine vorhanden sein (die Befehle module load
und module purge
können von PIRA verwendet werden). Wenn Sie über kein module
verfügen oder es nicht verwenden möchten, lassen Sie diesen Abschnitt entweder vollständig weg oder setzen Sie "module-loads": null
. Um die Module anzugeben, die PIRA laden soll, geben Sie eine Liste von Modulen an, wie im obigen Beispiel.name
haben.version
ist optional. Wenn sie nicht angegeben wird, hängt sie davon ab, was das module
als Standardmodulversion lädt. Es wird empfohlen, Versionen immer explizit anzugeben.depends-on
ist ebenfalls optional. Geben Sie eine Liste der Module an, von denen dieses Modul abhängt. Diese Module müssen einen name
haben und können optional eine version
erhalten. Die hier definierten Abhängigkeiten werden von PIRA verwendet, um die Reihenfolge zu bestimmen, in der Module geladen werden sollennull
setzen, wird davon ausgegangen, dass dieses Modul keine Abhängigkeiten hat.depends-on
angegeben sind, wird PIRA (versuchen) die Module in genau der Reihenfolge zu laden, die in der Konfigurationsdatei angegeben ist.batch-setting
: Die tatsächlichen Hardware- und Joboptionen für das Batch-System. Einige Optionen in diesem Abschnitt sind obligatorisch. Sie können diesen Abschnitt nicht auslassen.time
: Die Option sbatch --time
, obligatorisch.mem-per-cpu
: Die sbatch --mem-per-cpu
, obligatorisch.ntasks
: Die sbatch --ntasks
, obligatorisch.partition
, reservation
, account
(alle sind standardmäßig null
= nicht angegeben), cpus-per-task
(standardmäßig 4
), exclusive
(standardmäßig true
; wird nicht mit pyslurm
unterstützt) und cpu-freq
(standardmäßig null
).sbatch
-Optionen gibt, die Sie in dieser Konfiguration nicht definieren können. Dies liegt an einigen von PIRA intern verwendeten Optionen, beispielsweise der Option --array
, um die Wiederholungen auf Job-Arrays abzubilden. Wie und welche Version von PySlurm Sie auf Ihrem Cluster installieren, hängt stark von Ihrer SLURM-Version und Ihrer SLURM-Installation ab. Die Installations- und Verpackungslösung für Pyslurm mit PIRA ist in Arbeit. Weitere Informationen finden Sie in der README-Datei. Sie könnten Folgendes ausprobieren:
include
und einem lib
-Verzeichnis.python3 setup.py build --slurm-lib=/opt/slurm/21.08.6/lib --slurm-inc=/opt/slurm/21.08.6/include
python3 setup.py install --slurm-lib=/opt/slurm/21.08.6/lib --slurm-inc=/opt/slurm/21.08.6/include
.