{ "cells": [ { "cell_type": "markdown", "id": "32301000", "metadata": {}, "source": [ "# Arbeit mit Julia: REPL, Pakete, Introspection\n", "\n", "\n", "\n", "## Dokumentation\n", "\n", "Die offizielle Julia-Dokumentation [https://docs.julialang.org/](https://docs.julialang.org/) enthält zahlreiche Übersichten, darunter:\n", "\n", " - [https://docs.julialang.org/en/v1/base/punctuation/](https://docs.julialang.org/en/v1/base/punctuation/) Verzeichnis der Symbole\n", " - [https://docs.julialang.org/en/v1/manual/unicode-input/](https://docs.julialang.org/en/v1/manual/unicode-input/) Verzeichnis spezieller Unicode-Symbole und deren Eingabe in Julia via Tab-Vervollständigung\n", " - [https://docs.julialang.org/en/v1/manual/mathematical-operations/#Rounding-functions](https://docs.julialang.org/en/v1/manual/mathematical-operations/#Rounding-functions) Liste mathematischer Funktionen \n", "\n", "\n", "\n", "\n", "## Julia REPL (Read - Eval - Print - Loop)\n", "\n", "Nach dem Start von Julia in einem Terminal kann man neben Julia-Code auch verschiedene Kommandos eingeben \n", "\n", ":::{.narrow}\n", "| Kommando | Wirkung |\n", "| :----------------------------| :------------------------ |\n", "| `exit()` oder `Ctrl-d` | exit Julia |\n", "| `Ctrl-c` | interrupt |\n", "| `Ctrl-l` | clear screen |\n", "| Kommando mit `;` beenden | Ausgabe unterdrückt |\n", "| `include(\"filename.jl\")` | Datei mit Julia-Code einlesen und ausführen |\n", "\n", "\n", "\n", "Der REPL hat verschiedene Modi: \n", "\n", "| Modus | Prompt | Modus starten | Modus verlassen |\n", "| :- | :- | :- | :- |\n", "| default| `julia>` | | `Ctrl-d`|\n", "| Package manager | `pkg>` | `]` | `backspace` |\n", "| Help | `help?>` | `?`| `backspace `|\n", "|Shell | `shell>` | `;` | `backspace`|\n", "\n", ":::\n", "\n", "\n", "## Jupyter-Notebooks (IJulia)\n", "\n", "\n", "In einem Jupyter-Notebook sind die Modi sind als Einzeiler in einer eigenen Input-Zelle nutzbar: \n", "\n", "(i) ein Kommando des Paket-Managers:\n" ] }, { "cell_type": "code", "execution_count": null, "id": "efacde4f", "metadata": {}, "outputs": [], "source": [ "#| eval: false\n", "] status " ] }, { "cell_type": "markdown", "id": "85fec425", "metadata": {}, "source": [ "(ii) eine Help-Abfrage:\n" ] }, { "cell_type": "code", "execution_count": null, "id": "80535b76", "metadata": {}, "outputs": [], "source": [ "#| eval: false\n", "?sin" ] }, { "cell_type": "markdown", "id": "581aae68", "metadata": {}, "source": [ "(iii) Ein Shell-Kommando:\n" ] }, { "cell_type": "code", "execution_count": null, "id": "c2438155", "metadata": {}, "outputs": [], "source": [ "#| eval: false\n", ";ls " ] }, { "cell_type": "markdown", "id": "bd2c64b7", "metadata": {}, "source": [ "## Der Paketmanager\n", "\n", "Wichtiger Teil des _Julia Ecosystems_ sind die zahlreichen Pakete, die Julia erweitern.\n", "\n", "- Einige Pakete sind Teil jeder Julia-Installation und müssen nur mit einer `using Paketname`-Anweisung aktiviert werden. \n", " - Sie bilden die sogenannte _Standard Library_ und dazu gehören \n", " - `LinearAlgebra`, `Statistics`, `SparseArrays`, `Printf`, `Pkg` und andere.\n", "- Über 9000 Pakete sind offiziell registriert, siehe [https://julialang.org/packages/](https://julialang.org/packages/). \n", " - Diese können mit wenigen Tastendrücken heruntergeladen und installiert werden.\n", " - Dazu dient der _package manager_ `Pkg`.\n", " - Man kann ihn auf zwei Arten verwenden: \n", " - als normale Julia-Anweisungen, die auch in einer `.jl`-Programmdatei stehen können:\n", " ```\n", " using Pkg\n", " Pkg.add(\"PaketXY\")\n", " ```\n", " - im speziellen pkg-Modus des Julia-REPLs:\n", " ```\n", " ] add PaketXY\n", " ```\n", " - Anschließend kann das Paket mit `using PaketXY` verwendet werden.\n", "- Man kann auch Pakete aus anderen Quellen und selbstgeschriebene Pakete installieren.\n", "\n", " \n", "### Einige Funktionen des Paketmanagers\n", "\n", "| Funktion | `pkg` - Mode | Erklärung |\n", "|:------------------------|:--------------------------| :-------------------------------------------------------|\n", "| `Pkg.add(\"MyPack\")` | `pkg> add MyPack` | add `MyPack.jl` to current environment |\n", "| `Pkg.rm(\"MyPack\")` | `pkg> remove MyPack` | remove `MyPack.jl` from current environment |\n", "| `Pkg.update()` | `pkg> update` | update packages in current environment |\n", "| `Pkg.activate(\"mydir\")` | `pkg> activate mydir` | activate directory as current environment |\n", "| `Pkg.status()` | `pkg> status` | list packages |\n", "| `Pkg.instantiate()` | `pg> instantiate` | install all packages according to `Project.toml` |\n", "\n", "\n", "### Installierte Pakete und Environments \n", "\n", "- Julia und der Paketmanager verwalten \n", " 1. eine Liste der mit dem Kommando `Pkg.add()` bzw. `]add` explizit installierten Pakete mit genauer Versionsbezeichnung in einer Datei `Project.toml` und \n", " 2. eine Liste aller dabei auch als implizite Abhängigkeiten installierten Pakete in der Datei `Manifest.toml`. \n", "- Das Verzeichnis, in dem diese Dateien stehen, ist das `environment` und wird mit `Pkg.status()` bzw. `]status` angezeigt. \n", "- Im Normalfall sieht das so aus: \n", "\n", "```\n", "(@v1.8) pkg> status\n", " Status `~/.julia/environments/v1.8/Project.toml`\n", " [1dea7af3] OrdinaryDiffEq v6.7.1\n", " [91a5bcdd] Plots v1.27.1\n", " [438e738f] PyCall v1.93.1\n", "```\n", "\n", "- Man kann für verschiedene Projekte eigene `environments` benutzen. Dazu kann man entweder Julia mit \n", "```shell\n", "julia --project=path/to/myproject\n", "```\n", "starten oder in Julia das environment mit `Pkg.activate(\"path/to/myproject\")` aktivieren. Dann werden `Project.toml, Manifest.toml` dort angelegt und verwaltet. (Die Installation der Paketdateien erfolgt weiterhin irgendwo unter `$HOME/.julia`) \n", "\n", "\n", "### Zum Installieren von Paketen auf unserem Jupyter-Server `misun103`:\n", "\n", "- Es gibt ein zentrales Repository, in dem alle in diesem Kurs erwähnten Pakete bereits installiert sind. \n", "- Dort haben Sie keine Schreibrechte.\n", "- Sie können aber zusätzliche Pakete in Ihrem `HOME` installieren. Dazu ist als erster Befehl nötig, das aktuelle Verzeichnis zu aktivieren: \n" ] }, { "cell_type": "code", "execution_count": null, "id": "87138f78", "metadata": {}, "outputs": [], "source": [ "#| eval: false\n", "] activate ." ] }, { "cell_type": "markdown", "id": "da9c6bb6", "metadata": {}, "source": [ "(Man beachte den Punkt!)\n", "\n", "\n", "Danach können Sie mit `add` im Pkg-Modus auch Pakete installieren:\n" ] }, { "cell_type": "code", "execution_count": null, "id": "7a9e6ab0", "metadata": {}, "outputs": [], "source": [ "#| eval: false\n", "] add PaketXY" ] }, { "cell_type": "markdown", "id": "d5fc8aef", "metadata": {}, "source": [ "Achtung! Das kann dauern! Viele Pakete haben komplexe Abhängigkeiten und lösen die Installation von weiteren Paketen aus. Viele Pakete werden beim Installieren vorkompiliert. Im REPL sieht man den Installationsfortschritt, im Jupyter-Notebook leider nicht.\n", "\n", "\n", "\n", "\n", "\n", "## Der Julia JIT _(just in time)_ Compiler: Introspection\n", "\n", "Julia baut auf die Werkzeuge des _LLVM Compiler Infrastructure Projects_ auf.\n", "\n", ":::{.narrow}\n", "Stages of Compilation \n", "\n", "| stage & result | introspection command |\n", "| :--- | :--- |\n", "|Parse $\\Longrightarrow$ Abstract Syntax Tree (AST) | `Meta.parse()` |\n", "| Lowering: transform AST $\\Longrightarrow$ Static Single Assignment (SSA) form | `@code_lowered`|\n", "| Type Inference | `@code_warntype`, `@code_typed` |\n", "| Generate LLVM intermediate representation | `@code_llvm`|\n", "| Generate native machine code | `@code_native` |\n", "\n", ":::\n" ] }, { "cell_type": "code", "execution_count": null, "id": "bc5fdcec", "metadata": {}, "outputs": [], "source": [ "function f(x,y)\n", " z = x^2 + log(y)\n", " return 2z\n", "end" ] }, { "cell_type": "code", "execution_count": null, "id": "bb56b5a6", "metadata": {}, "outputs": [], "source": [ "p = Meta.parse( \"function f(x,y); z=x^2+log(y); return 2x; end \")" ] }, { "cell_type": "code", "execution_count": null, "id": "9a8825dd", "metadata": {}, "outputs": [], "source": [ "using TreeView\n", "\n", "walk_tree(p)" ] }, { "cell_type": "code", "execution_count": null, "id": "aa2d2ada", "metadata": {}, "outputs": [], "source": [ "@code_lowered f(2,4)" ] }, { "cell_type": "code", "execution_count": null, "id": "e6303b02", "metadata": {}, "outputs": [], "source": [ "@code_warntype f(2,4)" ] }, { "cell_type": "code", "execution_count": null, "id": "05f5a0cd", "metadata": {}, "outputs": [], "source": [ "@code_typed f(2,4)" ] }, { "cell_type": "code", "execution_count": null, "id": "523e86a5", "metadata": {}, "outputs": [], "source": [ "@code_llvm f(2,4)" ] }, { "cell_type": "code", "execution_count": null, "id": "953d5e83", "metadata": {}, "outputs": [], "source": [ "@code_native f(2,4)" ] } ], "metadata": { "kernelspec": { "display_name": "Julia 1.10.2", "language": "julia", "name": "julia-1.10" } }, "nbformat": 4, "nbformat_minor": 5 }