Verarbeitung von Listen von Eingaben
Zuletzt aktualisiert am 2025-04-05 | Diese Seite bearbeiten
Übersicht
Fragen
- “Wie kann ich mehrere Dateien auf einmal verarbeiten?”
- “Wie kombiniere ich mehrere Dateien miteinander?”
Ziele
- “Verwenden Sie Snakemake, um alle unsere Proben auf einmal zu verarbeiten”
- “Erstellen Sie ein Skalierbarkeitsdiagramm, das unsere Ergebnisse zusammenfasst”
Wir haben eine Regel erstellt, die eine einzige Ausgabedatei erzeugen kann, aber wir werden nicht mehrere Regeln für jede Ausgabedatei erstellen. Wir wollen alle Ausführungsdateien mit einer einzigen Regel erzeugen, wenn es möglich ist, und Snakemake kann tatsächlich eine Liste von Eingabedateien annehmen:
PYTHON
rule generate_run_files:
output: "p_{parallel_proportion}_runs.txt"
input: "p_{parallel_proportion}/runs/amdahl_run_2.json", "p_{parallel_proportion}/runs/amdahl_run_6.json"
shell:
"echo {input} done > {output}"
Das ist großartig, aber wir wollen nicht alle Dateien, an denen wir interessiert sind, einzeln auflisten müssen. Wie können wir dies tun?
Definieren einer Liste von zu verarbeitenden Proben
Um dies zu tun, können wir einige Listen als Snakemake globale Variablen definieren.
Globale Variablen sollten vor den Regeln in der Snakefile hinzugefügt werden.
- Anders als bei Variablen in Shell-Skripten können wir Leerzeichen um
das
=
-Zeichen setzen, aber sie sind nicht zwingend erforderlich. - Die Listen der in Anführungszeichen gesetzten Zeichenketten werden in eckige Klammern gesetzt und durch Kommata getrennt. Wenn Sie Python kennen, werden Sie dies als Python-Listensyntax erkennen.
- Eine gute Konvention ist die Verwendung von großgeschriebenen Namen für diese Variablen, aber das ist nicht zwingend.
- Obwohl diese als Variablen bezeichnet werden, können Sie die Werte nicht mehr ändern, sobald der Arbeitsablauf läuft, so dass auf diese Weise definierte Listen eher Konstanten sind.
Verwendung einer Snakemake-Regel zur Definition eines Stapels von Ausgaben
Nun wollen wir unser Snakefile aktualisieren, um die neue globale Variable zu nutzen und eine Liste von Dateien zu erstellen:
PYTHON
rule generate_run_files:
output: "p_{parallel_proportion}_runs.txt"
input: expand("p_{{parallel_proportion}}/runs/amdahl_run_{count}.json", count=NTASK_SIZES)
shell:
"echo {input} done > {output}"
Die Funktion expand(...)
in dieser Regel erzeugt eine
Liste von Dateinamen, indem sie das erste Element in den einfachen
Klammern als Vorlage nimmt und {count}
durch alle
NTASK_SIZES
ersetzt. Da die Liste 5 Elemente enthält,
ergibt dies 5 Dateien, die wir erstellen wollen. Beachten Sie, dass wir
unseren Platzhalter in einem zweiten Satz von Klammern schützen mussten,
damit er nicht als etwas interpretiert wird, das erweitert werden
muss.
In unserem aktuellen Fall verlassen wir uns immer noch auf den
Dateinamen, um den Wert des Platzhalters
parallel_proportion
zu definieren, also können wir die
Regel nicht direkt aufrufen, sondern müssen immer noch eine bestimmte
Datei anfordern:
Wenn Sie beim Ausführen von Snakemake auf der Befehlszeile keinen Namen für eine Zielregel oder Dateinamen angeben, wird standardmäßig die erste Regel in der Snake-Datei als Ziel verwendet.
Regeln als Ziele
Wenn Sie Snakemake den Namen einer Regel auf der Kommandozeile geben, funktioniert das nur, wenn diese Regel keine Platzhalter in den Ausgaben hat, weil Snakemake keine Möglichkeit hat, zu wissen, was die gewünschten Platzhalter sein könnten. Sie erhalten die Fehlermeldung “Target rules may not contain wildcards” Dies kann auch passieren, wenn Sie in der Befehlszeile keine expliziten Ziele angeben und Snakemake versucht, die erste im Snakefile definierte Regel auszuführen.
Regeln, die mehrere Eingaben kombinieren
Unsere generate_run_files
Regel ist eine Regel, die eine
Liste von Eingabedateien annimmt. Die Länge dieser Liste ist nicht durch
die Regel festgelegt, sondern kann sich je nach NTASK_SIZES
ändern.
In unserem Arbeitsablauf besteht der letzte Schritt darin, alle
generierten Dateien in einem Plot zu kombinieren. Vielleicht haben Sie
schon gehört, dass einige Leute dafür eine Python-Bibliothek namens
matplotlib
verwenden. Es würde den Rahmen dieses Tutorials
sprengen, das Python-Skript zu schreiben, um einen endgültigen Plot zu
erstellen, daher stellen wir Ihnen das Skript als Teil dieser Lektion
zur Verfügung. Sie können es herunterladen mit
Das Skript plot_terse_amdahl_results.py
benötigt eine
Befehlszeile, die wie folgt aussieht:
BASH
python plot_terse_amdahl_results.py --output <output image filename> <1st input file> <2nd input file> ...
Lass uns das in unsere generate_run_files
Regel
einfügen:
PYTHON
rule generate_run_files:
output: "p_{parallel_proportion}_runs.txt"
input: expand("p_{{parallel_proportion}}/runs/amdahl_run_{count}.json", count=NTASK_SIZES)
shell:
"python plot_terse_amdahl_results.py --output {output} {input}"
Aufgabe
Dieses Skript verlässt sich auf matplotlib
, ist es als
Umgebungsmodul verfügbar? Fügen Sie diese Bedingung zu unserer Regel
hinzu.
Jetzt können wir endlich ein Skalierungsdiagramm erstellen! Führen Sie den letzten Snakemake-Befehl aus:
Aufgabe
Erzeugen Sie das Skalierbarkeitsdiagramm für alle Werte von 1 bis 10 Kernen.
Aufgabe
Wiederholung des Arbeitsablaufs für einen p
-Wert von
0,8
Bonusrunde
Erstellen Sie eine endgültige Regel, die direkt aufgerufen werden
kann und ein Skalierungsdiagramm für 3 verschiedene Werte von
p
erzeugt.
Hauptpunkte
- “Verwenden Sie die Funktion
expand()
, um Listen von Dateinamen zu erzeugen, die Sie kombinieren wollen” - “Jede
{input}
zu einer Regel kann eine Liste variabler Länge sein”