JuliaKurs23/chapters/5_TricksHelp.qmd

240 lines
7.2 KiB
Plaintext

---
engine: julia
---
# Arbeit mit Julia: REPL, Pakete, Introspection
```{julia}
#| error: false
#| echo: false
#| output: false
using InteractiveUtils
import QuartoNotebookWorker
Base.stdout = QuartoNotebookWorker.with_context(stdout)
myactive_module() = Main.Notebook
Base.active_module() = myactive_module()
# https://github.com/JuliaLang/julia/blob/master/base/show.jl#L516-L520
# https://github.com/JuliaLang/julia/blob/master/base/show.jl#L3073-L3077
```
## Dokumentation
Die offizielle Julia-Dokumentation [https://docs.julialang.org/](https://docs.julialang.org/) enthält zahlreiche Übersichten, darunter:
- [https://docs.julialang.org/en/v1/base/punctuation/](https://docs.julialang.org/en/v1/base/punctuation/) Verzeichnis der Symbole
- [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
- [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
## Julia REPL (Read - Eval - Print - Loop)
Nach dem Start von Julia in einem Terminal kann man neben Julia-Code auch verschiedene Kommandos eingeben
:::{.narrow}
| Kommando | Wirkung |
| :----------------------------| :------------------------ |
| `exit()` oder `Ctrl-d` | exit Julia |
| `Ctrl-c` | interrupt |
| `Ctrl-l` | clear screen |
| Kommando mit `;` beenden | Ausgabe unterdrückt |
| `include("filename.jl")` | Datei mit Julia-Code einlesen und ausführen |
Der REPL hat verschiedene Modi:
| Modus | Prompt | Modus starten | Modus verlassen |
| :- | :- | :- | :- |
| default| `julia>` | | `Ctrl-d` (beendet Julia) |
| Package manager | `pkg>` | `]` | `backspace` |
| Help | `help?>` | `?`| `backspace `|
|Shell | `shell>` | `;` | `backspace`|
:::
## Jupyter-Notebooks (IJulia)
In einem Jupyter-Notebook sind die Modi sind als Einzeiler in einer eigenen Input-Zelle nutzbar:
(i) ein Kommando des Paket-Managers:
```{julia}
#| eval: false
] status
```
(ii) eine Help-Abfrage:
```{julia}
#| eval: false
?sin
```
(iii) Ein Shell-Kommando:
```{julia}
#| eval: false
;ls
```
## Der Paketmanager
Wichtiger Teil des _Julia Ecosystems_ sind die zahlreichen Pakete, die Julia erweitern.
- Einige Pakete sind Teil jeder Julia-Installation und müssen nur mit einer `using Paketname`-Anweisung aktiviert werden.
- Sie bilden die sogenannte _Standard Library_ und dazu gehören
- `LinearAlgebra`, `Statistics`, `SparseArrays`, `Printf`, `Pkg` und andere.
- Über 9000 Pakete sind offiziell registriert, siehe [https://julialang.org/packages/](https://julialang.org/packages/).
- Diese können mit wenigen Tastendrücken heruntergeladen und installiert werden.
- Dazu dient der _package manager_ `Pkg`.
- Man kann ihn auf zwei Arten verwenden:
- als normale Julia-Anweisungen, die auch in einer `.jl`-Programmdatei stehen können:
```
using Pkg
Pkg.add("PaketXY")
```
- im speziellen pkg-Modus des Julia-REPLs:
```
] add PaketXY
```
- Anschließend kann das Paket mit `using PaketXY` verwendet werden.
- Man kann auch Pakete aus anderen Quellen und selbstgeschriebene Pakete installieren.
### Einige Funktionen des Paketmanagers
| Funktion | `pkg` - Mode | Erklärung |
|:------------------------|:--------------------------| :-------------------------------------------------------|
| `Pkg.add("MyPack")` | `pkg> add MyPack` | add `MyPack.jl` to current environment |
| `Pkg.rm("MyPack")` | `pkg> remove MyPack` | remove `MyPack.jl` from current environment |
| `Pkg.update()` | `pkg> update` | update packages in current environment |
| `Pkg.activate("mydir")` | `pkg> activate mydir` | activate directory as current environment |
| `Pkg.status()` | `pkg> status` | list packages |
| `Pkg.instantiate()` | `pg> instantiate` | install all packages according to `Project.toml` |
### Installierte Pakete und Environments
- Julia und der Paketmanager verwalten
1. eine Liste der mit dem Kommando `Pkg.add()` bzw. `]add` explizit installierten Pakete mit genauer Versionsbezeichnung in einer Datei `Project.toml` und
2. eine Liste aller dabei auch als implizite Abhängigkeiten installierten Pakete in der Datei `Manifest.toml`.
- Das Verzeichnis, in dem diese Dateien stehen, ist das `environment` und wird mit `Pkg.status()` bzw. `]status` angezeigt.
- Im Normalfall sieht das so aus:
```
(@v1.10) pkg> status
Status `~/.julia/environments/v1.10/Project.toml`
[6e4b80f9] BenchmarkTools v1.5.0
[5fb14364] OhMyREPL v0.5.24
[91a5bcdd] Plots v1.40.4
[295af30f] Revise v3.5.14
```
- Man kann für verschiedene Projekte eigene `environments` benutzen. Dazu kann man entweder Julia mit
```shell
julia --project=path/to/myproject
```
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`)
### Zum Installieren von Paketen auf unserem Jupyter-Server `misun103`:
- Es gibt ein zentrales Repository, in dem alle in diesem Kurs erwähnten Pakete bereits installiert sind.
- Dort haben Sie keine Schreibrechte.
- Sie können aber zusätzliche Pakete in Ihrem `HOME` installieren. Dazu ist als erster Befehl nötig, das aktuelle Verzeichnis zu aktivieren:
```{julia}
#| eval: false
] activate .
```
(Man beachte den Punkt!)
Danach können Sie mit `add` im Pkg-Modus auch Pakete installieren:
```{julia}
#| eval: false
] add PaketXY
```
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.
## Der Julia JIT _(just in time)_ Compiler: Introspection
Julia baut auf die Werkzeuge des _LLVM Compiler Infrastructure Projects_ auf.
:::{.narrow}
Stages of Compilation
| stage & result | introspection command |
| :--- | :--- |
|Parse $\Longrightarrow$ Abstract Syntax Tree (AST) | `Meta.parse()` |
| Lowering: transform AST $\Longrightarrow$ Static Single Assignment (SSA) form | `@code_lowered`|
| Type Inference | `@code_warntype`, `@code_typed` |
| Generate LLVM intermediate representation | `@code_llvm`|
| Generate native machine code | `@code_native` |
:::
```{julia}
function f(x,y)
z = x^2 + log(y)
return 2z
end
```
```{julia}
p = Meta.parse( "function f(x,y); z=x^2+log(y); return 2x; end ")
```
```{julia}
using TreeView
walk_tree(p)
```
```{julia}
@code_lowered f(2,4)
```
```{julia}
@code_warntype f(2,4)
```
```{julia}
@code_typed f(2,4)
```
```{julia}
@code_llvm f(2,4)
```
```{julia}
@code_native f(2,4)
```