1 Punkte von GN⁺ 2024-04-07 | 1 Kommentare | Auf WhatsApp teilen
  • Um alte wissenschaftliche und technische Rechenressourcen in Form von Fortran-Numerikcode in den Browser zu bringen, ist ein WebAssembly-Kompilierungspfad nötig; webR verwendet dafür ein gepatchtes LLVM flang-new
  • f2c, LFortran, Dragonegg, Classic Flang und LLVM Flang haben jeweils Grenzen bei Unterstützung für modernes Fortran, Zielarchitekturen und Wartbarkeit; eine einfache Standardlösung gibt es daher noch nicht
  • LLVM Flang unterstützt das Target wasm32-unknown-emscripten nicht direkt, sodass TargetWasm32 ergänzt werden muss; beim Verknüpfen der Runtime verursacht der Unterschied in der Größe von long zwischen Host und Target Probleme
  • Kombiniert man das gepatchte flang-new, Emscripten und statische Bibliotheken der Fortran-Runtime, lassen sich Fortran-Subroutinen aus C oder JavaScript aufrufen und auch PRINT, ALLOCATE sowie CHARACTER-Argumente verarbeiten
  • Die Referenzimplementierungen von BLAS 3.12.0 und LAPACK 3.12.0 wurden als statische WebAssembly-Bibliotheken gebaut, um Demos für Handschrifterkennung von Ziffern und Polynominterpolation im Browser auszuführen

Bestehenden Fortran-Numerikcode in den Browser bringen

  • Fortran ist eine alte Sprache aus dem Jahr 1957, wurde aber lange in wissenschaftlichen und technischen Berechnungen eingesetzt; modernes Fortran hat die meisten Beschränkungen des festen Formats von Fortran 77 hinter sich gelassen
  • Ziel ist es, moderne Fortran-Routinen nach WebAssembly zu kompilieren, im Browser auszuführen, numerische Argumente entgegenzunehmen, BLAS- und LAPACK-Routinen zu berechnen und anschließend Ergebnisse zurückzugeben oder auf der Konsole auszugeben
  • Dieser Ansatz ermöglicht es, höhere Programmierumgebungen wie SciPy oder R, die auf BLAS und LAPACK angewiesen sind, ins Web zu bringen
  • Statt numerische Routinen in JavaScript oder Rust neu zu schreiben, lassen sich bereits validierte Fortran-basierte Werkzeuge und Bibliotheken nutzen
  • Das webR-Projekt kompiliert Fortran-Code mit einem gepatchten LLVM flang-new-Compiler nach WebAssembly
  • Der aktuelle Ansatz beruht auf Hacks; ohne Hilfe erfahrenerer Compiler-Entwickler ist es schwierig, die Änderungen zu LLVM beizutragen

Stand der Werkzeuge für Fortran→WebAssembly

  • Stand 2024 gibt es mehrere Werkzeuge und Toolchains, aber noch keine einfache Lösung mit vollständigem Funktionsumfang
  • f2c

    • f2c wandelt Fortran 77 in C-Code um, den Emscripten anschließend nach WebAssembly kompilieren kann
    • Pyodide nutzt diesen Ansatz beim Kompilieren von Python-Paketen, die Fortran-Code enthalten
    • Auch in der Pyodide-Roadmap wird dieser Ansatz als „funktioniert nicht gut“ bewertet
    • Für modernen Fortran-Code passt er nicht, und selbst nach der Umwandlung sind gravierende Fehler und umfangreiche Patches nötig
  • LFortran

    • LFortran hat in den letzten Jahren deutlich an Funktionsumfang gewonnen und kann direkt nach WebAssembly kompilieren
    • Da es sich noch in der Alpha-Phase befindet, weisen die Entwickler darauf hin, dass beim Kompilieren realer Codebasen mit Problemen zu rechnen ist
    • Einige Projekte wie MINPACK lassen sich kompilieren, doch da nicht die vollständige Fortran-Spezifikation unterstützt wird, können größere Projekte scheitern
    • Entwicklungsziel ist die vollständige Unterstützung von Fortran 2018; eine auffällige Funktion ist ein interaktives Fortran-REPL ähnlich Jupyter
  • Dragonegg

    • Dragonegg ist ein GCC-Plugin, das GCC-Frontends verwendet und LLVM IR ausgibt
    • Über das LLVM-Backend kann WebAssembly-Ausgabe erzeugt werden; so kompilierte webR anfänglich Fortran-Quellen nach WebAssembly
    • Die neuesten unterstützten Versionen sind gcc-4.8 und llvm-3.3, sodass sehr alte GCC- und LLVM-Versionen nötig sind
    • Die meisten Nutzer brauchen eine VM oder einen Docker-Container, und das von Dragonegg ausgegebene LLVM IR muss für die WebAssembly-Ausgabe zusätzlich nachbearbeitet werden
    • Im Jahr 2020 war dies praktisch die einzige realistische Methode, um Fortran-Code nach WebAssembly zu kompilieren
  • Classic Flang

    • Classic Flang ist ein auf dem als Open Source veröffentlichten PGI/NVIDIA pgfortran basierender Fortran-Compiler für LLVM
    • Da er keine 32-Bit-Ausgabe unterstützt, kann er nicht für das Target wasm32 verwendet werden
    • Firefox, Chrome und Node unterstützen zum Zeitpunkt der Erstellung wasm64, allerdings hinter Feature-Flags
    • Auch die Projektdokumentation weist darauf hin, dass es möglicherweise keine gute Idee ist, Classic Flang für neue Projekte zu wählen
  • LLVM Flang

    • LLVM Flang ist ein Projekt, das ein Fortran-Frontend für LLVM von Grund auf neu implementiert; seit LLVM 11 ist es Teil des LLVM-Projekts
    • Es gilt zwar noch nicht als produktionsreif, doch die Pre-Production-Version von flang-new ist inzwischen für das Kompilieren realen Fortran-Codes recht brauchbar
    • Im Ausgangszustand kann es keine WebAssembly-Ausgabe erzeugen
    • Dank des modularen Designs von LLVM lassen sich das Flang-Frontend und das LLVM-WebAssembly-Backend gemeinsam nutzen
    • Auch 2020 war das schon möglich, erforderte aber größere LLVM-Patches, das Einschleusen eigener Mathematik-Routinen und einen mehrstufigen Kompilierungsprozess
    • Heute lässt sich dank der Entwicklung des flang-new-Frontends mit nur kleinen Änderungen am LLVM-Quellcode ein Compiler für Fortran→WebAssembly erstellen

LLVM Flang für WebAssembly bauen

  • Ein über den Paketmanager installiertes LLVM enthält möglicherweise kein flang-new-Binary
    • Beispielsweise findet man bei LLVM v17.0.6 aus macOS Homebrew den Befehl flang-new nicht
  • Da der LLVM-Flang-Quellcode geändert werden muss, wird LLVM v18.1.1 aus dem Quellcode selbst gebaut
  • Die CMake-Konfiguration setzt das Standard-Target-Triple auf wasm32-unknown-emscripten und aktiviert das Target WebAssembly sowie die Projekte clang;flang;mlir
  • Nach Abschluss des Builds lässt sich mit build/bin/flang-new --version Folgendes prüfen
    • Version: flang-new version 18.1.1
    • Target: wasm32-unknown-emscripten
    • Thread-Modell: posix

Erstes Problem: Target wasm32 nicht implementiert

  • Kompiliert man die einfache Fortran-Subroutine foo.f08 mit flang-new, tritt folgender Fehler auf
    • not yet implemented: target not implemented
  • Ursache ist, dass das Target-Triple wasm32-unknown-emscripten in flang-new noch nicht implementiert ist
  • Die Lösung ist ein Patch, der in flang/lib/Optimizer/CodeGen/Target.cpp die Target-Eigenschaften von TargetWasm32 ergänzt
    • Die Standardbreite wird auf 32 gesetzt
    • Das Marshalling, das komplexe Argumente und Rückgabetypen in LLVM-Typen auf WebAssembly-Seite umwandelt, wird definiert
    • Im Zweig llvm::Triple::ArchType::wasm32 wird TargetWasm32 angebunden
  • Nach dem Patch und erneutem Build wird die Fortran-Quelle zu einem WebAssembly-Objekt kompiliert
    • Ergebnis von file foo.o: WebAssembly (wasm) binary module version 0x1 (MVP)
    • In llvm-nm foo.o ist das Symbol foo_ sichtbar

Fortran-Subroutinen aus C und JavaScript aufrufen

  • Fortran-Routinen übergeben Argumente üblicherweise per Referenz, und mit INTENT() lässt sich deklarieren, wie Argumente verwendet werden
  • Die beispielhafte Fortran-Subroutine foo nimmt die Integer-Argumente x, y und z entgegen und führt z = x + y aus
  • Führt man in einem nativen Build gfortran -c foo.f08 -o foo.o aus, kann der Symbolname wie foo_ einen angehängten Unterstrich erhalten
  • Beim Aufruf aus C deklariert man das externe Symbol etwa als extern void foo_(int*, int*, int*); und übergibt die Argumente per Adresse
  • In WebAssembly kann das mit flang-new erstellte foo.o per Emscripten mit C-Code verknüpft werden
    • emcc main.c foo.o -o main.js
    • Ausgabe von node main.js: 1 + 1 = 2
  • Direkter Aufruf aus JavaScript

    • Fortran-Subroutinen lassen sich auch ohne C-Code direkt aus JavaScript aufrufen
    • Beim Emscripten-Link-Schritt werden _foo_, _malloc und _free exportiert
    • emcc foo.o -sEXPORTED_FUNCTIONS=_foo_,_malloc,_free -o foo.js
    • JavaScript reserviert mit Module._malloc() Speicher für Integer-Werte, schreibt Werte in Module.HEAPU32 und ruft anschließend Module._foo_(x, y, z) auf
    • Das Ausführungsergebnis sieht so aus
    • x = 123
    • y = 456
    • x + y = 579
    • Im Browser lassen sich foo.js und standalone.js aus HTML laden, um dasselbe Ergebnis in der JavaScript-Konsole zu sehen

Zweites Problem: Fortran-Runtime-Bibliothek

  • Baut man eine Fortran-Subroutine mit PRINT *, "Hello, World!", tritt beim Linken ein Fehler wegen fehlender Runtime-Symbole auf
    • _FortranAioBeginExternalListOutput
    • _FortranAioOutputAscii
    • _FortranAioEndIoStatement
  • Ursache ist, dass die LLVM-Fortran-Runtime-Bibliothek noch nicht für WebAssembly kompiliert wurde
  • Die Runtime-Bibliothek ist in C++ im Verzeichnis llvm-project/flang/runtime des LLVM-Quellbaums geschrieben
  • Baut man die Runtime-Quellen mit em++ und emar aus Emscripten, kann man die statische Bibliothek build/flang/runtime/libFortranRuntime.a erstellen
  • Verlinkt man diese Bibliothek, schreitet der Build von Hello, World! fort, zunächst erscheinen jedoch Warnungen zu nicht übereinstimmenden Funktionssignaturen

Drittes Problem: Unterschiedliche long-Größe bei Host und Target

  • Beim Verknüpfen von hello.o mit der Fortran-Runtime-Bibliothek erscheint eine Warnung wegen nicht übereinstimmender Signaturen für _FortranAioOutputAscii
    • Das Fortran-Objekt erwartet (i32, i32, i64) -> i32
    • Die mit Emscripten gebaute Runtime definiert (i32, i32, i32) -> i32
  • WebAssembly verlangt, dass die Argument- und Rückgabetypen von Symbolen, die über mehrere Compilation Units hinweg definiert sind, konsistent sind
  • Dieses Problem bleibt nicht bei einer Warnung; die Ausführung in Node scheitert mit RuntimeError: unreachable
  • In LLVM Flangs RTBuilder.h gibt es einen TODO-Kommentar, wonach die Verwendung von sizeof build == host == target voraussetzt
  • Auf modernen 64-Bit-Unix-artigen Hosts ist sizeof(long) 8 Byte, beim Target wasm32-unknown-emscripten muss es jedoch 4 Byte sein
  • Beim Übergeben von Argumenten des Fortran-Typs CHARACTER an Funktionen oder Subroutinen kann ein verstecktes Argument zur Zeichenkettenlänge hinzugefügt werden
  • In der Fortran-Runtime-Bibliothek ist dieses Längenargument als size_t deklariert und wird über eine typedef-Kette zu unsigned long
  • Dieser Größenunterschied beim versteckten Argument verursacht die Abweichung zwischen i64 und i32

Vorläufiger Patch: 4-Byte-Werte erzwingen

  • Die ideale Lösung wäre, dass flang-new beim Cross-Compiling unabhängig vom Host i32 oder i64 passend zur Target-Architektur und zum Datenmodell ausgibt
  • Derzeit wird ein Patch verwendet, der die Größe von long fest auf 4 Byte für wasm32 und Emscripten setzt
  • Der Patch besteht aus zwei Teilen
    • In RTBuilder.h werden die Modelltypen für long und unsigned long nicht aus 8 * sizeof(...), sondern erzwungen als 8 * 4 gesetzt
    • In CodeGen.cpp werden Argumente für malloc()-Aufrufe als 32-Bit- statt 64-Bit-Integer erzeugt, und die Allokationsgröße wird nach i32 gecastet
  • Diese Änderung behebt auch die in Fortran 90 eingeführte dynamische Allokation mit ALLOCATE()
  • Nach dem erneuten Build lassen sich hello.f08 und hello.c ohne Warnungen mit der Runtime-Bibliothek verknüpfen, und Node gibt Folgendes aus
    • Hello, World!

BLAS nach WebAssembly bauen

  • BLAS ist eine Sammlung von Low-Level-Routinen für gängige Operationen der linearen Algebra, etwa Matrix-Vektor-Multiplikation
  • Die ursprünglichen BLAS-Routinen wurden 1979 veröffentlicht und sind de facto Standard im Bereich numerischer Berechnungen
  • Die Referenzimplementierung BLAS 3.12.0 ist in Fortran 90 geschrieben und bei netlib erhältlich
  • In make.inc werden für den Build folgende Werkzeuge angegeben
    • FC = ../build/bin/flang-new
    • FFLAGS = -O2
    • AR = emar
    • RANLIB = emranlib
  • Als Build-Ergebnis entsteht die statische Bibliothek blas_LINUX.a
  • Die beispielhafte Fortran-Routine bar ruft die BLAS-Level-2-Routine ZGEMV() auf
  • ZGEMV() führt komplexwertige Matrix-Vektor-Operationen aus; das Beispiel verwendet Argumente vom Typ COMPLEX(KIND=8) sowie das CHARACTER-Konfigurationsargument 'N'
  • Ein C-Programm erstellt komplexe Arrays, übergibt sie an die Fortran-Routine und gibt anschließend das Ergebnis aus
  • Das Ergebnis der Ausführung in Node lautet wie folgt
    • Y[0]: 23.000000 + 6.000000i
    • Y[1]: 18.000000 + 10.000000i
    • Y[2]: 6.000000 + 16.000000i
  • Dieses Ergebnis bestätigt, dass aus Fortran-90-Quellen kompilierte BLAS-Routinen unter WebAssembly laufen

Browser-Beispiel: Klassifikator für handgeschriebene Ziffern

  • Die Demo klassifiziert von Hand gezeichnete Ziffern von 0 bis 9 mit einem künstlichen neuronalen Netz vom Typ Multilayer Perceptron (MLP)
  • Nutzer können mit Maus oder Touchscreen eine Ziffer zeichnen; die vom Netzwerk vorhergesagten relativen Wahrscheinlichkeiten werden im Diagramm rechts angezeigt
  • Die Modellgewichte wurden mit Python vortrainiert, die Klassifikation erfolgt zur Laufzeit jedoch im Browser mit JavaScript und WebAssembly
  • Der MLP-Klassifikationsprozess besteht im Kern aus wiederholten Matrix-Vektor-Additionen und -Multiplikationen
  • Die rechenintensiven Teile übernimmt eine Fortran-Subroutine, die die BLAS-Level-2-Routine DGEMV() verwendet

LAPACK nach WebAssembly bauen

  • LAPACK ist eine Softwarebibliothek zur numerischen Lösung von Problemen der linearen Algebra und baut auf BLAS auf
  • Die Referenzimplementierung LAPACK 3.12.0 wird von netlib bereitgestellt und unter einer modifizierten BSD-Lizenz vertrieben
  • Nach dem Kopieren von make.inc.example nach make.inc werden folgende Einstellungen geändert
    • FC wird auf den vollständigen Pfad des gebauten flang-new gesetzt
    • FFLAGS = -O2
    • AR = emar
    • RANLIB = emranlib
    • TIMER = INT_CPU_TIME
  • Mit dem Befehl make lib wird die statische WebAssembly-Bibliothek liblapack.a erzeugt
  • Anschließend lassen sich LAPACK-Routinen ähnlich wie im BLAS-Beispiel aufrufen

Browser-Beispiel: Polynominterpolation mit linearer Algebra

  • Die Demo findet ein Interpolationspolynom für eine Menge von Punkten und zeigt, dass LAPACK-Routinen im Browser laufen
  • Wenn Nutzer durch Klicken in das Diagramm einen neuen Punkt hinzufügen, wird ein Interpolationspolynom gesucht, das durch alle Punkte verläuft
  • Das Verfahren nutzt die Vandermonde-Methode
  • Das dabei entstehende lineare Gleichungssystem wird numerisch mit der LAPACK-Routine DGELS() gelöst
  • Für n Datenpunkte lässt sich stets ein Polynom vom Grad n-1 finden, das alle Punkte exakt enthält
  • Wenn n größer wird, kann zwischen benachbarten Datenpunkten das Runge-Phänomen auftreten, bei dem das Polynom stark oszilliert; dies lässt sich durch Spline-Interpolation vermeiden

Offene Aufgaben und bereitgestellte Werkzeuge

  • Mit einem gepatchten LLVM Flang lässt sich moderner Fortran-Code zu WebAssembly-Objekten kompilieren
  • Der Vorteil dieses Ansatzes besteht darin, vorhandene Fortran-Werkzeuge und -Bibliotheken zu nutzen, statt numerische Algorithmen für das Web in JavaScript neu zu schreiben
  • Wenn flang-new WebAssembly offiziell unterstützt, sinkt der Aufwand, für webR und R-Pakete einen LLVM-Fork zu pflegen
  • Derzeit ist ein besserer Weg nötig, um LLVM Flang und Cross-Compilation-Probleme für alle Targets korrekt zu beheben
  • Für Nutzer, die LLVM Flang nicht selbst bauen können oder wollen, steht in der GitHub Container Registry ein Docker-Container mit gepatchten LLVM-Flang-Binaries bereit

1 Kommentare

 
GN⁺ 2024-04-07
Hacker-News-Kommentare
  • Um etwas Kontext zu geben: Diese Fortran-Erkundung ist Teil von Georges hervorragender Arbeit an WebR, mit der er R im Browser zum Laufen bringen will.
    Im R-Quellcode steckt ziemlich viel Fortran-Code, und soweit ich weiß, kompilierte WebR Fortran ursprünglich zuerst mit f2c nach C und dann dieses C nach wasm.
    Dank des LLVM-Flang-Patches lässt sich WebR nun mit einem echten Fortran-Compiler bauen.
    George hat es in seinem Blogpost nicht direkt gesagt, aber er hat erwähnt, dass er hofft, Flang werde diesen Patch übernehmen oder auf bessere Weise implementieren.
    Dann müsste kein separater Patch mehr gepflegt werden, und ein unverändertes Flang könnte nach wasm kompilieren, was auch anderen Projekten zugutekäme, die Fortran verwenden.
    https://docs.r-wasm.org/webr/latest/

    • Pull Requests sind immer willkommen (https://github.com/llvm/llvm-project); wenn Hilfe nötig ist, kann man sich an die LLVM-Fortran-Entwickler-Community wenden (https://discourse.llvm.org/c/subprojects/flang/33).
      Allerdings konzentriere ich mich auf die Arbeiten, die nötig sind, um Nvidias Fortran-Produktentwicklung abzuschließen, daher bleibt mir für solche Arbeiten keine Zeit.
    • F77 per Source-to-Source-Transformation nach JavaScript zu bringen, ist schon ziemlich ordentlich, aber WASM ist besser.
  • Vor 20 Jahren habe ich bei Xilinx an der FORTRAN-Kompilierung gearbeitet, und das Einzige, woran ich mich erinnere, ist, dass es in der Header-Datei f2c.h eine Definition von barf gab.
    /* f2c.h -- Standard Fortran to C header file /
    /* barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed."
    (https://www.netlib.org/clapack/f2c.h)

    • Sagt es etwas über mich aus, dass ich FORTRAN komplett in Großbuchstaben schreibe? Für mich sieht Fortran ungewohnt aus.
  • Ich finde es wirklich gut, als Erkläransatz das einfachste nicht-triviale Beispiel zu verwenden.
    Der Artikel basiert auf dem konkreten Problem „eine BLAS-Funktion aus JavaScript aufrufen“, dadurch hatte ich das Gefühl, viel gelernt zu haben; ein großartiger Beitrag.

  • Ich weiß nicht, ob ich beeindruckt oder entsetzt sein soll, wahrscheinlich beides.
    Beim Bauen von f18 empfehle ich, die aktuellsten Quellen aus llvm-project/main zu verwenden.
    Das Projekt bewegt sich schnell; es ist Zeitverschwendung, Probleme zu debuggen, die schon behoben sind, oder Funktionen zu verpassen, die bereits implementiert wurden.

    • Ich habe den LLVM-Quellcode nicht gut genug verstanden, um den Kernpunkt zu erfassen.
      Geht es darum, am WebAssembly-Port zu arbeiten und ihn an den Punkt zu bringen, an dem der Zwischencode bis hin zu Fortran funktioniert?
  • Mit WebAssembly-Entwicklung kenne ich mich nicht gut aus.
    Gibt es aus Verbrauchersicht etwas, das WebAssembly schon heute bietet? Oder ist es eher Grundlagenarbeit für eine Zukunft, in der Programme wirklich portabel werden?
    Ich habe gehört, dass die WebAssembly-Vorrichtung Zugriffsbeschränkungen etwa auf Netzwerk oder Dateien erleichtert, weiß aber nicht, ob das Theorie ist oder bereits implementiert wurde.

    • Im Grunde ist Wasm eine virtuelle Maschine und in Sachen Portabilität der JVM sehr ähnlich.
      Der zentrale Unterschied ist, dass Wasm selbst weder eine Standardbibliothek hat noch Ein-/Ausgabefunktionen bereitstellt.
      Deshalb kann der Host, also derjenige, der die VM baut, Funktionen bereitstellen, die ein Wasm-Binary importieren kann; das Wasm-Binary kann ausschließlich über diese Funktionen auf die Außenwelt zugreifen.
      Ein weiterer Vorteil ist, dass das Binärformat nicht proprietär ist und eine Spezifikation hat, sodass jeder eine Wasm-VM implementieren kann.
      Allerdings ist der Stand derzeit noch nicht wirklich gut; es ist noch sehr früh, viele neue Funktionen werden in Gruppen ähnlich dem W3C standardisiert, und der Prozess ist sehr langsam.
    • Wenn man als Entwickler oder beim Ausliefern eines Produkts robustes Sandboxing will, ist WASM ziemlich nah an der besten Option, die derzeit verfügbar ist.
      Es gibt auch Möglichkeiten, es auf die meisten Ziele auszuliefern oder dafür zu cross-kompilieren.
    • Wenn es richtig umgesetzt ist, sollte man es als Kunde nicht bemerken.
      Das ist ähnlich wie bei der Frage, ob der Computer eine ARM- oder x86-CPU hat: In der Regel weiß man es nicht und kümmert sich auch nicht groß darum.
      Wenn einem also Details wie „läuft es als nativer Code oder auf einer VM wie JVM, .NET oder WASM“ egal sind, ist es schwer zu sagen, was es gegenüber anderen Lösungen zusätzlich bietet.
      Meist fallen nur die schlechten Beispiele auf, und daraus werden dann Memes wie „alle Electron-Programme sind aufgeblähte, ressourcenfressende Monster, und jede native App ist automatisch ein Wunderwerk effizienter Softwaretechnik“.
  • Schade, wenn ich den Fortran-78-Code aufbewahrt hätte, den ich 1981/82 geschrieben habe, hätte ich testen können, ob er hier läuft.
    Es war ein Quellcode-Formatter für die Programmiersprache Jovial, und eigentlich war das nichts, was man in Fortran machen sollte, aber damals war das die einzige Option.

    • Hast du bei Hughes in Orange County gearbeitet?
  • Gibt es ein halbwegs production-reifes Linear-Algebra-Ökosystem für JavaScript?
    Wenn ich suche, finde ich meist nur JavaScript-Ports bekannter Bibliotheken, die etwa 10 Jahre alt sind, zum Beispiel Ports über emscripten; ich frage mich, ob ich etwas übersehe.

    • Gibt es auf WebGPU oder WebNN ein Äquivalent zu BLAS?
  • Es ist seltsam, dass LFortran nicht ausführlicher behandelt wird
    Es gibt auch ein hervorragendes und beeindruckendes WASM-Beispiel, das online läuft
    https://dev.lfortran.org/

    • Im Artikel steht, dass sich der LFortran-Compiler in den letzten Jahren stark weiterentwickelt hat
      2020 fehlten noch viele Funktionen, und es wurde nur eine sehr kleine Teilmenge von Fortran unterstützt; inzwischen unterstützt er aber einen deutlich größeren Teil der Sprachfeatures und kann recht viel Fortran-Code kompilieren
      Auch die native Kompilierung nach WebAssembly ist möglich
      Allerdings gibt es bei der Nutzung von LFortran noch raue Kanten; die Entwickler weisen darauf hin, dass das Projekt derzeit als Alpha gilt und beim Kompilieren von echtem Code Probleme auftreten können
      Einige Projekte wie MINPACK lassen sich erfolgreich kompilieren, doch da die vollständige Fortran-Spezifikation noch nicht unterstützt wird, lassen sich viele größere Projekte weiterhin nicht kompilieren
      Die LFortran-Entwickler zielen auf vollständige Unterstützung von Fortran 2018 ab, und ein auffälliges Feature ist ein interaktives Fortran-REPL wie in Jupyter
      Mit ein paar weiteren Jahren Entwicklung dürfte es eine hervorragende Option zum Kompilieren von Fortran-Code für WebAssembly werden
      Außerdem wird auf die LFortran-Demo unter https://dev.lfortran.org verwiesen; sie ist sehr beeindruckend, aber mein erster Versuch, x * 2 in x * 3 zu ändern, wurde vom aktuellen Codegenerator nicht unterstützt
  • Es gibt auch Fortran auf .NET und Java
    https://www.silverfrost.com/14/ftn95/ftn95_fortran_95_for_microsoft_dotnet_features.aspx
    https://dl.acm.org/doi/10.1145/376656.376833

  • Als ich an https://medium.com/@tomasreimers/compiling-tensorflow-for-the-browser-f3387b8e1e1c gearbeitet habe, war ich wirklich froh, dass TensorFlow Eigen nutzt und nicht die beliebten, in Fortran geschriebenen Mathematikbibliotheken BLAS/Lapack
    Sonst wäre es deutlich mehr Arbeit gewesen