├── src ├── assets │ ├── styles │ │ ├── sidebar.css │ │ ├── newdefault.css │ │ ├── lecture_header.css │ │ ├── homepage.css │ │ ├── layout.css │ │ └── index.css │ ├── favicon.ico │ ├── jgu_logo.jpg │ ├── homepage │ │ ├── bg.afdesign │ │ ├── swoosh.png │ │ └── bg.svg │ ├── scripts │ │ ├── get_highlights.jl │ │ ├── sidebar.js │ │ ├── get_subjects.jl │ │ ├── get_schedule.jl │ │ └── search.js │ ├── favicon.svg │ ├── julia-logo-color.svg │ └── julia-logo-dark.svg ├── index.jlmd ├── exercises │ ├── Colab.mp4 │ ├── exercise_11_gpu.md │ ├── exercise_12_mpi.md │ ├── exercise_3_type_stability.jl │ ├── exercise_8_github.jl │ ├── exercise_14_ml.jl │ ├── exercise_1_multithreading.jl │ └── exercise_13_reverse.jl ├── mod1_introduction │ ├── arch.png │ ├── moore.png │ ├── p100.png │ ├── gpu_system.png │ ├── quad_core.png │ └── parallel_efficiency.png ├── netlify.toml ├── _includes │ ├── md.jlmd │ ├── welcome.jlmd │ └── layout.jlhtml ├── _data │ ├── tracks.jl │ ├── sidebar.jl │ ├── course_info.jl │ └── homepage.jl ├── search.md ├── cheatsheets.md ├── logistics.md ├── installation.md └── mod2_principles_of_rse │ └── recordings │ └── gdb.cast ├── .gitattributes ├── Project.toml ├── Procfile ├── .gitignore ├── README.md ├── extra_outputs └── index.html ├── .github ├── dependabot.yml └── workflows │ ├── pr_comment.yml │ ├── preview_cleanup.yml │ ├── KeepCacheFresh.yml │ └── ExportNotebooks.yml ├── .vscode ├── tasks.json ├── extensions.json └── settings.json ├── pluto-deployment-environment ├── PlutoDeployment.toml └── Project.toml ├── generate.jl ├── tools └── update_notebook_packages.jl ├── Dockerfile ├── LICENSE.md ├── develop.jl └── Website maintenance.md /src/assets/styles/sidebar.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | page/* linguist-vendored 2 | * text=auto -------------------------------------------------------------------------------- /Project.toml: -------------------------------------------------------------------------------- 1 | [deps] 2 | Pluto = "c3e4b0f8-55cb-11ea-2926-15256bba5781" 3 | -------------------------------------------------------------------------------- /src/index.jlmd: -------------------------------------------------------------------------------- 1 | --- 2 | tags: ["homepage"] 3 | layout: "welcome.jlmd" 4 | --- 5 | -------------------------------------------------------------------------------- /src/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vchuravy/rse-course/HEAD/src/assets/favicon.ico -------------------------------------------------------------------------------- /src/assets/jgu_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vchuravy/rse-course/HEAD/src/assets/jgu_logo.jpg -------------------------------------------------------------------------------- /src/exercises/Colab.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vchuravy/rse-course/HEAD/src/exercises/Colab.mp4 -------------------------------------------------------------------------------- /src/assets/homepage/bg.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vchuravy/rse-course/HEAD/src/assets/homepage/bg.afdesign -------------------------------------------------------------------------------- /src/assets/homepage/swoosh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vchuravy/rse-course/HEAD/src/assets/homepage/swoosh.png -------------------------------------------------------------------------------- /src/mod1_introduction/arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vchuravy/rse-course/HEAD/src/mod1_introduction/arch.png -------------------------------------------------------------------------------- /src/mod1_introduction/moore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vchuravy/rse-course/HEAD/src/mod1_introduction/moore.png -------------------------------------------------------------------------------- /src/mod1_introduction/p100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vchuravy/rse-course/HEAD/src/mod1_introduction/p100.png -------------------------------------------------------------------------------- /src/netlify.toml: -------------------------------------------------------------------------------- 1 | [[headers]] 2 | for = "/*" 3 | [headers.values] 4 | Access-Control-Allow-Origin = "*" 5 | -------------------------------------------------------------------------------- /src/mod1_introduction/gpu_system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vchuravy/rse-course/HEAD/src/mod1_introduction/gpu_system.png -------------------------------------------------------------------------------- /src/mod1_introduction/quad_core.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vchuravy/rse-course/HEAD/src/mod1_introduction/quad_core.png -------------------------------------------------------------------------------- /src/_includes/md.jlmd: -------------------------------------------------------------------------------- 1 | --- 2 | layout: "layout.jlhtml" 3 | --- 4 | 5 |
6 |
7 | $(content) 8 |
9 |
-------------------------------------------------------------------------------- /src/mod1_introduction/parallel_efficiency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vchuravy/rse-course/HEAD/src/mod1_introduction/parallel_efficiency.png -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: julia --project="pluto-deployment-environment" -e "import PlutoSliderServer; PlutoSliderServer.run_directory(\".\"; port=$PORT , host=\"0.0.0.0\")" 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | 4 | reduced_phil.png 5 | notebooks/week9/testCSVwrite.csv 6 | 7 | _cache 8 | _site 9 | generation_report.html 10 | src/week9/testCSVwrite.csv 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Research software engineering with Julia 2 | 3 |

4 | Go to course website :balloon:
5 |

6 | -------------------------------------------------------------------------------- /src/_data/tracks.jl: -------------------------------------------------------------------------------- 1 | [ 2 | "principles" => "Principles of RSE", 3 | "performance" => "Performance Engineering", 4 | "parallel" => "Parallel programming", 5 | "ad" => "Automatic Differentiation" 6 | ] -------------------------------------------------------------------------------- /extra_outputs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/_data/sidebar.jl: -------------------------------------------------------------------------------- 1 | [ 2 | "welcome" => "Welcome", 3 | "module1" => "Module 1: Introduction", 4 | "module2" => "Module 2: Principles of Research Software Engineering", 5 | "module3" => "Module 3: Parallelism", 6 | "module4" => "Module 4: Automatic Differentiation", 7 | "module5" => "Module 5: Performance Engineering", 8 | ] -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | groups: 5 | # Group all GitHub Actions PRs into a single PR: 6 | all-github-actions: 7 | patterns: 8 | - "*" 9 | directory: "/" 10 | schedule: 11 | interval: "monthly" 12 | open-pull-requests-limit: 100 13 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "PlutoPages: run development server", 8 | "type": "shell", 9 | "command": "julia develop.jl", 10 | "group": "build" 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /src/_data/course_info.jl: -------------------------------------------------------------------------------- 1 | Dict( 2 | "course_name" => "Research Software Engineering with Julia", 3 | "course_subtitle" => "", 4 | "code" => "", 5 | "semester" => "2025", 6 | "authors" => [ 7 | "Valentin Churavy" => "https://vchuravy.dev", 8 | ], 9 | "institution" => "University of Mainz", 10 | "institution_logo" => "jgu_logo.jpg", 11 | "repo" => "https://github.com/vchuravy/rse-course" 12 | ) -------------------------------------------------------------------------------- /src/search.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Search results" 3 | tags: [] 4 | layout: "md.jlmd" 5 | --- 6 | 7 | 8 |
9 |
10 |

Search

11 | 17 | 18 |

Results

19 |
20 | Loading... 21 |
22 | 23 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=827846 to learn about workspace recommendations. 3 | // Extension identifier format: ${publisher}.${name}. Example: vscode.csharp 4 | 5 | // List of extensions which should be recommended for users of this workspace. 6 | "recommendations": [ 7 | "esbenp.prettier-vscode", 8 | "julialang.language-julia", 9 | ], 10 | // List of extensions recommended by VS Code that should not be recommended for users of this workspace. 11 | "unwantedRecommendations": [ 12 | 13 | ] 14 | } -------------------------------------------------------------------------------- /pluto-deployment-environment/PlutoDeployment.toml: -------------------------------------------------------------------------------- 1 | [Export] 2 | baked_state = false 3 | baked_notebookfile = false 4 | offer_binder = true 5 | ignore_cache = [ 6 | "index.jl", 7 | ] 8 | create_index = false 9 | exclude = [ 10 | # these are in the repo but not used on the website 11 | "tools/*", 12 | "PlutoPages.jl", 13 | ] 14 | 15 | [SliderServer] 16 | port = 8080 17 | host = "0.0.0.0" 18 | exclude=[ 19 | # these are in the repo but not used on the website 20 | "tools/*", 21 | "PlutoPages.jl", 22 | 23 | # notebooks not interactive 24 | 25 | # don't run exercises 26 | "*/exercise*.jl", 27 | ] 28 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "*.jlmd": "markdown", 4 | "*.jlhtml": "html", 5 | }, 6 | 7 | "prettier.printWidth": 160, 8 | "prettier.tabWidth": 4, 9 | "prettier.semi": false, 10 | "prettier.quoteProps": "consistent", 11 | "prettier.singleQuote": false, 12 | 13 | "editor.formatOnSave": false, 14 | "[javascript]": { 15 | "editor.defaultFormatter": "esbenp.prettier-vscode", 16 | "editor.formatOnSave": true 17 | }, 18 | "[css]": { 19 | "editor.defaultFormatter": "esbenp.prettier-vscode", 20 | "editor.formatOnSave": true 21 | } 22 | } -------------------------------------------------------------------------------- /src/assets/scripts/get_highlights.jl: -------------------------------------------------------------------------------- 1 | if isempty(get(metadata["homepage"], "highlights", [])) 2 | nothing 3 | else 4 | highlights = [ 5 | @htl(""" 6 |
7 |
8 |

$(x["name"])

9 |

$(x["text"])

10 |
11 |
12 | 13 |
14 |
15 | """) for x in metadata["homepage"]["highlights"] 16 | ] 17 | 18 | @htl(""" 19 |
20 |

Highlights

21 |
22 | $(highlights) 23 |
24 |
25 | """) 26 | end -------------------------------------------------------------------------------- /src/cheatsheets.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Resources" 3 | tags: ["welcome"] 4 | order: 3 5 | layout: "md.jlmd" 6 | --- 7 | 8 | # Resources 9 | 10 | - [Modern Julia Workflows](https://modernjuliaworkflows.org/) 11 | - [JuliaLang Discourse](https://discourse.julialang.org) 12 | - [JuliaLang Documentation](https://docs.julialang.org) 13 | - [Julia Community](https://julialang.org/community/) 14 | 15 | ## Cheatsheets 16 | 17 | - [Fastrack to Julia](https://juliadocs.github.io/Julia-Cheat-Sheet/) cheatsheet. 18 | - [MATLAB-Julia-Python comparative cheatsheet](https://cheatsheets.quantecon.org/) by [QuantEcon group](https://quantecon.org) 19 | - [Plots.jl cheatsheet](https://github.com/sswatson/cheatsheets/blob/master/plotsjl-cheatsheet.pdf) 20 | -------------------------------------------------------------------------------- /src/_includes/welcome.jlmd: -------------------------------------------------------------------------------- 1 | --- 2 | layout: "layout.jlhtml" 3 | --- 4 | 5 | 6 | 7 | 10 | 11 | $(isempty(get(metadata["homepage"], "disclaimer", "")) ? nothing : @htl("""""")) 12 | 13 |
14 | 16 | $(Base.include(@__MODULE__, joinpath(@__DIR__, "..", "assets", "scripts", "get_schedule.jl"))) 17 |
-------------------------------------------------------------------------------- /generate.jl: -------------------------------------------------------------------------------- 1 | import Pluto 2 | 3 | s = Pluto.ServerSession() 4 | 5 | # s.options.server.disable_writing_notebook_files = true 6 | s.options.server.launch_browser = false 7 | 8 | @info "PlutoPages: Starting..." 9 | nb = Pluto.SessionActions.open(s, joinpath(@__DIR__, "PlutoPages.jl"); run_async=false) 10 | @info "PlutoPages: Finished. Analyzing result..." 11 | 12 | write("generation_report.html", Pluto.generate_html(nb)) 13 | 14 | failed = filter(c -> c.errored, nb.cells) 15 | 16 | for c in failed 17 | println(stderr, "Cell errored: ", c.cell_id) 18 | println(stderr) 19 | show(stderr, MIME"text/plain"(), c.output.body) 20 | println(stderr) 21 | println(stderr) 22 | end 23 | 24 | Pluto.SessionActions.shutdown(s, nb) 25 | 26 | if !isempty(failed) 27 | exit(1) 28 | end 29 | -------------------------------------------------------------------------------- /.github/workflows/pr_comment.yml: -------------------------------------------------------------------------------- 1 | name: PR Comment # Write a comment in the PR with a link to the preview of the given website 2 | 3 | on: 4 | pull_request: 5 | types: [opened, reopened] 6 | 7 | jobs: 8 | pr_comment: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Create PR comment 12 | if: github.event_name == 'pull_request' && github.repository == github.event.pull_request.head.repo.full_name # if this is a pull request build AND the pull request is NOT made from a fork 13 | uses: thollander/actions-comment-pull-request@24bffb9b452ba05a4f3f77933840a6a841d1b32b 14 | with: 15 | message: 'Once the build has completed, you can preview your PR at this URL: https://${{ github.event.pull_request.base.repo.owner.login }}.github.io/${{ github.event.pull_request.base.repo.name }}/previews/PR${{ github.event.number }}/' 16 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 17 | -------------------------------------------------------------------------------- /src/logistics.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Class logistics" 3 | tags: ["welcome"] 4 | order: 1 5 | layout: "md.jlmd" 6 | --- 7 | 8 | 14 | 15 | # Course logistics 16 | 17 | ## Projects 18 | 19 | 1. Choose project by **2025-05-14** 20 | - Discuss idea first with me. 21 | - Half-page project proposal. 22 | 2. Project presentations: **2025-07-16** 23 | 3. Project should be relevant both to your work and topics discussed in class. 24 | 4. Demonstrate best practices for research software development. 25 | - Testing 26 | - Reproducibility 27 | - Documentation 28 | - Accessibility 29 | 5. Develop "in the open" on Github. 30 | 31 | ### Grades 32 | 33 | If you need a grade for this class, in addition to the project presentation, you will need to submit a short project report (2 pages) and your repository with instruction on how to reproduce your results. 34 | -------------------------------------------------------------------------------- /.github/workflows/preview_cleanup.yml: -------------------------------------------------------------------------------- 1 | # from https://github.com/CliMA/ClimaTimeSteppers.jl 2 | name: Site Preview Cleanup 3 | 4 | on: 5 | pull_request: 6 | types: [closed] 7 | 8 | jobs: 9 | doc-preview-cleanup: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout gh-pages branch 13 | uses: actions/checkout@v4 14 | with: 15 | ref: gh-pages 16 | - name: Delete preview and history + push changes 17 | run: | 18 | if [ -d "previews/PR${{ github.event.number }}" ]; then 19 | git config user.name "Documenter.jl" 20 | git config user.email "documenter@juliadocs.github.io" 21 | git rm -rf "previews/PR${{ github.event.number }}" 22 | git commit -m "delete preview" 23 | git branch gh-pages-new $(echo "delete history" | git commit-tree HEAD^{tree}) 24 | git push --force origin gh-pages-new:gh-pages 25 | fi 26 | -------------------------------------------------------------------------------- /src/exercises/exercise_11_gpu.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Introduction to KernelAbstractions" 3 | order: 9.1 4 | exercise_number: 11 5 | chapter: 3 6 | section: 2 7 | layout: "md.jlmd" 8 | image: "" 9 | tags: ["module3", "track_parallel", "exercises"] 10 | --- 11 | 12 | ## Getting started on Google Colab 13 | 14 | Recently Google Colab started supporting Julia directly. One needs to switch the change the "runtime type" to "Julia", 15 | and Google Colab also provides some GPU support for free. 16 | 17 | 18 | 19 | 20 | **To get started with today's exercise:** 21 | 22 | [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/vchuravy/rse-course/blob/main/src/mod3_parallelism/Introduction_to_KernelAbstractions.ipynb) 23 | 24 | 25 | -------------------------------------------------------------------------------- /tools/update_notebook_packages.jl: -------------------------------------------------------------------------------- 1 | if !isdir("pluto-deployment-environment") || length(ARGS) != 1 2 | error(""" 3 | Run me from the root of the repository directory, using: 4 | 5 | julia tools/update_notebook_packages.jl 6 | 7 | Where is one of: PATCH, MINOR, MAJOR 8 | """) 9 | end 10 | 11 | if VERSION < v"1.6.0-aaa" 12 | @error "Our website needs to be generated with Julia 1.6. Go to julialang.org/downloads to install it." 13 | end 14 | 15 | import Pkg 16 | Pkg.activate("./pluto-deployment-environment") 17 | Pkg.instantiate() 18 | 19 | import Pluto 20 | 21 | flatmap(args...) = vcat(map(args...)...) 22 | 23 | 24 | all_files_recursive = flatmap(walkdir("src")) do (root, _dirs, files) 25 | joinpath.((root,), files) 26 | end 27 | 28 | all_notebooks = filter(Pluto.is_pluto_notebook, all_files_recursive) 29 | 30 | level = getfield(Pkg, Symbol("UPLEVEL_$(ARGS[1])")) 31 | 32 | for n in all_notebooks 33 | @info "Updating" n 34 | Pluto.update_notebook_environment(n; backup=false, level) 35 | end 36 | -------------------------------------------------------------------------------- /src/assets/styles/newdefault.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Alegreya:ital,wght@0,500;0,700;1,500;1,700&display=swap"); 2 | @import url("https://fonts.googleapis.com/css2?family=Inter:wght@100;200;300;400;500;600;700;800;900&display=swap"); 3 | @import url("https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap"); 4 | @import url("https://fonts.googleapis.com/css2?family=Vollkorn:ital,wght@0,400;0,500;0,600;0,700;0,800;0,900;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"); 5 | 6 | html { 7 | box-sizing: border-box; 8 | font-size: 17px; 9 | /* color: #3c3c3c; */ 10 | } 11 | 12 | body { 13 | /* background: #f1e7e7; */ 14 | font-family: "Open Sans", sans-serif; 15 | overflow-wrap: break-word; 16 | } 17 | main h1 { 18 | font-family: "Vollkorn", serif; 19 | font-weight: 800; 20 | font-style: italic; 21 | margin-block-end: 0.5em; 22 | font-size: 2.5rem; 23 | margin-block-start: 0; 24 | letter-spacing: -0.2px; 25 | } 26 | -------------------------------------------------------------------------------- /src/assets/styles/lecture_header.css: -------------------------------------------------------------------------------- 1 | .lecture-header { 2 | background: #282936; 3 | color: white; 4 | padding: 1rem; 5 | /* min-height: 500px; */ 6 | /* width: 100%; */ 7 | display: block; 8 | border-radius: 1rem; 9 | margin: 1rem; 10 | } 11 | 12 | .lecture-header * { 13 | color: white; 14 | } 15 | 16 | .lecture-header, 17 | .lecture-header h1 { 18 | font-family: Vollkorn, serif; 19 | font-weight: 700; 20 | font-feature-settings: "lnum", "pnum"; 21 | } 22 | 23 | .lecture-header .number { 24 | font-style: italic; 25 | font-size: 1.5rem; 26 | opacity: 0.8; 27 | } 28 | 29 | .lecture-header h1 { 30 | text-align: center; 31 | font-size: 2rem; 32 | } 33 | .lecture-header .video > div { 34 | display: flex; 35 | justify-content: center; 36 | overflow: hidden; 37 | max-width: 400px; 38 | margin: 0 auto; 39 | } 40 | .lecture-header .video iframe, 41 | .lecture-header .video lite-youtube { 42 | /* max-width: 400px; */ 43 | aspect-ratio: 16/9; 44 | flex: 1 1 auto; 45 | } 46 | -------------------------------------------------------------------------------- /.github/workflows/KeepCacheFresh.yml: -------------------------------------------------------------------------------- 1 | name: Keep caches fresh 2 | on: 3 | schedule: 4 | - cron: "5 4 1/4 * *" # every 4 days 5 | 6 | jobs: 7 | build-and-deploy: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: ⏱ Cache notebook states 11 | uses: actions/cache@v4 12 | with: 13 | path: _cache 14 | key: ${{ runner.os }}-pluto_state_cache-v3-${{ hashFiles('**/Project.toml', '**/Manifest.toml') }}-${{ github.run_id }} 15 | restore-keys: | 16 | ${{ runner.os }}-pluto_state_cache-v3-${{ hashFiles('**/Project.toml', '**/Manifest.toml') }} 17 | 18 | - name: ⏱ Cache .julia 19 | uses: actions/cache@v4 20 | with: 21 | path: ~/.julia 22 | key: ${{ runner.os }}-dotjulia-v1-${{ hashFiles('**/Project.toml', '**/Manifest.toml') }}-${{ github.run_id }} 23 | restore-keys: | 24 | ${{ runner.os }}-dotjulia-v1-${{ hashFiles('**/Project.toml', '**/Manifest.toml') }} 25 | 26 | -------------------------------------------------------------------------------- /pluto-deployment-environment/Project.toml: -------------------------------------------------------------------------------- 1 | [deps] 2 | BetterFileWatching = "c9fd44ac-77b5-486c-9482-9798bd063cc6" 3 | CommonMark = "a80b9123-70ca-4bc0-993e-6e3bcb318db6" 4 | Deno_jll = "04572ae6-984a-583e-9378-9577a1c2574d" 5 | Gumbo = "708ec375-b3d6-5a57-a7ce-8257bf98657a" 6 | HypertextLiteral = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" 7 | JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" 8 | LRUCache = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637" 9 | Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" 10 | MarkdownLiteral = "736d6165-7244-6769-4267-6b50796e6954" 11 | Memoize = "c03570c3-d221-55d1-a50c-7939bbd78826" 12 | Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" 13 | Pluto = "c3e4b0f8-55cb-11ea-2926-15256bba5781" 14 | PlutoHooks = "0ff47ea0-7a50-410d-8455-4348d5de0774" 15 | PlutoLinks = "0ff47ea0-7a50-410d-8455-4348d5de0420" 16 | PlutoSliderServer = "2fc8631c-6f24-4c5b-bca7-cbb509c42db4" 17 | PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8" 18 | ProgressLogging = "33c8b6b6-d38a-422a-b730-caa89a2f386c" 19 | ThreadsX = "ac1d9e8a-700a-412c-b207-f0111f4b6c0d" 20 | URIs = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" 21 | Unicode = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" 22 | YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6" 23 | -------------------------------------------------------------------------------- /src/assets/scripts/sidebar.js: -------------------------------------------------------------------------------- 1 | const sidebar = document.querySelector("#pages-sidebar") 2 | const layout = document.querySelector("#pages-layout") 3 | const navtoggle = document.querySelector("#toggle-nav") 4 | 5 | document.querySelector("#toggle-nav").addEventListener("click", function (e) { 6 | console.log(e) 7 | layout.classList.toggle("pages_show_sidebar") 8 | e.stopPropagation() 9 | }) 10 | 11 | window.addEventListener("click", function (e) { 12 | if (!sidebar.contains(e.target) && !navtoggle.contains(e.target)) { 13 | layout.classList.remove("pages_show_sidebar") 14 | } 15 | }) 16 | 17 | document.querySelectorAll(".track-chooser select").forEach((trackSelect) => { 18 | const ontrack = () => { 19 | let track = trackSelect.value 20 | 21 | localStorage.setItem("chosen track", track) 22 | 23 | let lectures_exercises = Array.from(sidebar.querySelectorAll(".lecture,.exercise,.indepth")) 24 | 25 | lectures_exercises.forEach((el) => { 26 | let intrack = track === "" || el.classList.contains(`tag_track_${track}`) || el.classList.contains(`tag_welcome`) 27 | el.classList.toggle("not_in_track", !intrack) 28 | }) 29 | } 30 | 31 | trackSelect.value = localStorage.getItem("chosen track") 32 | ontrack() 33 | trackSelect.addEventListener("change", ontrack) 34 | }) 35 | -------------------------------------------------------------------------------- /src/assets/scripts/get_subjects.jl: -------------------------------------------------------------------------------- 1 | let 2 | sections = metadata["sidebar"] 3 | sections = [ 4 | @htl(""" 5 | $([ 6 | let 7 | input = other_page.input 8 | output = other_page.output 9 | 10 | name = get(output.frontmatter, "title", basename(input.relative_path)) 11 | desc = get(output.frontmatter, "description", nothing) 12 | tags = get(output.frontmatter, "tags", String[]) 13 | 14 | image = get(output.frontmatter, "image", nothing) 15 | 16 | class = [ 17 | "no-decoration", 18 | ("tag_$(replace(x, " "=>"_"))" for x in tags)..., 19 | ] 20 | 21 | image === nothing || isempty(image) ? nothing : @htl(""" 22 |

$(name)

23 | 24 |
""") 25 | end for other_page in collections[section_id].pages 26 | ]) 27 | """) 28 | for (section_id, section_name) in sections 29 | ] 30 | 31 | isempty(sections) ? nothing : @htl("""
32 |

Subjects

33 |
34 | $(sections) 35 |
36 |
37 | """) 38 | end -------------------------------------------------------------------------------- /src/assets/scripts/get_schedule.jl: -------------------------------------------------------------------------------- 1 | let 2 | sections = metadata["sidebar"] 3 | sections = [ 4 | @htl(""" 5 | $([ 6 | let 7 | input = other_page.input 8 | output = other_page.output 9 | 10 | name = get(output.frontmatter, "title", basename(input.relative_path)) 11 | desc = get(output.frontmatter, "description", nothing) 12 | tags = get(output.frontmatter, "tags", String[]) 13 | date = get(output.frontmatter, "date", nothing) 14 | 15 | class = [ 16 | "no-decoration", 17 | ("tag_$(replace(x, " "=>"_"))" for x in tags)..., 18 | ] 19 | if date !== nothing 20 | @htl(""" 21 |

$(name)

22 | $(date) 23 |
""") 24 | else 25 | nothing 26 | end 27 | end for other_page in collections[section_id].pages 28 | ]) 29 | """) 30 | for (section_id, section_name) in sections 31 | ] 32 | 33 | isempty(sections) ? nothing : @htl("""
34 |

Schedule

35 |
36 | $(sections) 37 |
38 |
39 | """) 40 | end -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Hi there! 2 | 3 | # This Dockerfile does _not_ run the Pluto notebooks. You can _not_ use it to work on the homework exercises. Instead, take a look at our website to learn how to get started with Pluto: http://computationalthinking.mit.edu . If you want to run a Pluto Container (e.g. for homework) take a look here: https://github.com/JuliaPluto/docker-stacks 4 | 5 | # This is an internal Dockerfile for the Pluto "@bind server" for the course website. It runs all the sliders, buttons and camera inputs, so that you can interact with them directly on the website, without having to wait for binder or a local Pluto session. 6 | # Take a look at https://github.com/JuliaPluto/PlutoSliderServer.jl for more info. 7 | 8 | # -fonsi 9 | 10 | FROM julia:1.8.2 11 | 12 | # HTTP port 13 | EXPOSE 1234 14 | RUN apt-get update -y && apt-get upgrade -y 15 | # add a new user called "pluto" 16 | RUN useradd -ms /bin/bash pluto 17 | # set the current directory 18 | WORKDIR /home/pluto 19 | # run the rest of commands as pluto user 20 | USER pluto 21 | # copy the contents of the github repository into /home/pluto 22 | COPY --chown=pluto . ${HOME} 23 | 24 | 25 | # Initialize the julia project environment that will be used to run the bind server. 26 | RUN julia --project=${HOME}/pluto-deployment-environment -e "import Pkg; Pkg.instantiate(); Pkg.precompile()" 27 | 28 | # The "default command" for this docker thing. 29 | CMD ["julia", "--project=/home/pluto/pluto-deployment-environment", "-e", "import PlutoSliderServer; PlutoSliderServer.run_directory(\".\"; SliderServer_port=1234 , SliderServer_host=\"0.0.0.0\")"] -------------------------------------------------------------------------------- /src/assets/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | My license here: 2 | 3 | The material in this repository is licensed as follows: 4 | 5 | - The **code** is under the [MIT license](https://opensource.org/licenses/MIT). 6 | 7 | - The **text** is under the [CC BY-SA 4.0 license](https://creativecommons.org/licenses/by-sa/4.0). 8 | 9 | Copyright Valentin Churavy, 2025 10 | 11 | 12 | This repository was generated from https://github.com/JuliaPluto/computational-thinking-template which is licensed as follows: 13 | 14 | Copyright 2023 Luca Ferranti, Fons van der Plas and the MIT Computational Thinking team: computationalthinking.mit.edu 15 | 16 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 17 | 18 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /src/_data/homepage.jl: -------------------------------------------------------------------------------- 1 | Dict( 2 | "title" => @htl("Research Software Engineering with Julia"), 3 | 4 | # # add a disclaimer to the course webpage. Remove it if you dont want to include it. 5 | # "disclaimer" => md""" 6 | # """, 7 | 8 | # Highlights the key features of your class to make it more engaging. Remove it if you dont want to include it. 9 | "highlights" => [ 10 | Dict("name" => "Easy to customise", 11 | "text" => md"Let the template automate all of the website development and infrastructure, so that you can focus on the most important thing: 12 | **easily develop your lesson materials!**", 13 | "img" => "https://user-images.githubusercontent.com/6933510/168320383-a401459b-97f5-41df-bc7b-ebe76e4886cc.png" 14 | ), 15 | Dict("name" => "Revolutionary interactivity with Pluto.jl", 16 | "text" => md""" 17 | Thanks to Pluto.jl, the website is built using real code, and instead of a book, we have a series of interactive notebooks. 18 | **On the website, students can play with sliders, buttons and images to interact with our simulations.** 19 | You can even go further, and modify and run any code on our website! 20 | """, 21 | "img" => "https://user-images.githubusercontent.com/6933510/136196607-16207911-53be-4abb-b90e-d46c946e6aaf.gif" 22 | ), 23 | Dict("name" => "Learn Julia", 24 | "text" => md""" 25 | In literature it's not enough to just know the technicalities of grammar. 26 | In music it's not enough to learn the scales. The goal is to communicate experiences and emotions. 27 | For a computer scientist, it's not enough to write a working program, 28 | the program should be written with beautiful high level abstractions that speak to your audience. 29 | **Julia is designed with this purpose in mind, use it in your teaching to harness its power.** 30 | """, 31 | "img" => "https://user-images.githubusercontent.com/6933510/136203632-29ce0a96-5a34-46ad-a996-de55b3bcd380.png" 32 | ) 33 | ] 34 | ) -------------------------------------------------------------------------------- /.github/workflows/ExportNotebooks.yml: -------------------------------------------------------------------------------- 1 | name: Export Pluto notebooks & Deploy 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | workflow_dispatch: 11 | 12 | concurrency: 13 | group: export 14 | cancel-in-progress: true 15 | 16 | permissions: 17 | contents: write 18 | 19 | jobs: 20 | build-and-deploy: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - name: Checkout source 24 | uses: actions/checkout@v4 25 | 26 | - name: Install LIKWID 27 | run: | 28 | wget http://ftp.fau.de/pub/likwid/likwid-stable.tar.gz 29 | mkdir likwid 30 | tar -xaf likwid-stable.tar.gz -C likwid --strip-components=1 31 | cd likwid 32 | make 33 | sudo make install 34 | /usr/local/bin/likwid-topology -c -C -g 35 | sudo modprobe msr 36 | /usr/local/bin/likwid-perfctr -i 37 | /usr/local/bin/likwid-perfctr -a 38 | 39 | - name: 🙌 Install Julia 40 | uses: julia-actions/setup-julia@v2 41 | with: 42 | version: "1.11" 43 | 44 | - name: ⏱ Cache notebook states 45 | uses: actions/cache@v4 46 | with: 47 | path: _cache 48 | key: ${{ runner.os }}-pluto_state_cache-v3-${{ hashFiles('**/Project.toml', '**/Manifest.toml') }}-${{ github.run_id }} 49 | restore-keys: | 50 | ${{ runner.os }}-pluto_state_cache-v3-${{ hashFiles('**/Project.toml', '**/Manifest.toml') }} 51 | 52 | - name: ⏱ Cache .julia 53 | uses: actions/cache@v4 54 | with: 55 | path: ~/.julia 56 | key: ${{ runner.os }}-dotjulia-v1-${{ hashFiles('**/Project.toml', '**/Manifest.toml') }}-${{ github.run_id }} 57 | restore-keys: | 58 | ${{ runner.os }}-dotjulia-v1-${{ hashFiles('**/Project.toml', '**/Manifest.toml') }} 59 | 60 | - name: 🪴 Generate site 61 | run: julia --project=pluto-deployment-environment -e ' 62 | import Pkg; 63 | Pkg.instantiate(); 64 | 65 | include("./generate.jl")' 66 | 67 | 68 | - name: 📰 Upload site generation report 69 | uses: actions/upload-artifact@v4 70 | if: always() 71 | with: 72 | path: generation_report.html 73 | 74 | - name: 🚀 Deploy to GitHub Pages (main) 75 | if: github.event_name == 'push' && github.ref == 'refs/heads/main' 76 | uses: JamesIves/github-pages-deploy-action@v4 77 | with: 78 | BRANCH: gh-pages 79 | FOLDER: _site 80 | CLEAN_EXCLUDE: | 81 | previews/* 82 | 83 | - name: Deploy PR preview 84 | if: github.event_name == 'pull_request' && github.repository == github.event.pull_request.head.repo.full_name # if this build is a PR build and the PR is NOT from a fork 85 | uses: JamesIves/github-pages-deploy-action@v4 86 | with: 87 | BRANCH: gh-pages 88 | FOLDER: _site 89 | TARGET_FOLDER: "previews/PR${{ github.event.number }}" # The website preview is going to be stored in the previews subfolder 90 | -------------------------------------------------------------------------------- /src/exercises/exercise_12_mpi.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Running MPI.jl locally" 3 | order: 10.1 4 | exercise_number: 12 5 | chapter: 3 6 | section: 3 7 | layout: "md.jlmd" 8 | image: "" 9 | tags: ["module3", "track_parallel", "exercises"] 10 | --- 11 | 12 | ## Configuration 13 | 14 | There are multiple MPI implementations 15 | 16 | - OpenMPI 17 | - MPICH 18 | - Intel MPI 19 | - Microsoft MPI 20 | - IBM Spectrum MPI 21 | - MVAPICH 22 | - Cray MPICH 23 | - Fujitsu MPI 24 | - HPE MPT/HMPT 25 | 26 | ```julia-repl 27 | julia> using MPI 28 | 29 | julia> MPI.versioninfo() 30 | 31 | MPIPreferences: 32 | binary: MPICH_jll 33 | abi: MPICH 34 | 35 | Package versions 36 | MPI.jl: 0.20.22 37 | MPIPreferences.jl: 0.1.11 38 | MPICH_jll: 4.3.0+1 39 | 40 | Library information: 41 | libmpi: /home/vchuravy/.julia/artifacts/05d8c79b270470018e9de8dd24ddb6d7954aff9d/lib/libmpi.so 42 | libmpi dlpath: /home/vchuravy/.julia/artifacts/05d8c79b270470018e9de8dd24ddb6d7954aff9d/lib/libmpi.so 43 | MPI version: 4.1.0 44 | Library version: 45 | MPICH Version: 4.3.0 46 | MPICH Release date: Mon Feb 3 09:09:47 AM CST 2025 47 | MPICH ABI: 17:0:5 48 | MPICH Device: ch3:nemesis 49 | MPICH configure: --build=x86_64-linux-musl --disable-dependency-tracking --disable-doc --enable-fast=ndebug,O3 --enable-static=no --host=x86_64-linux-gnu --prefix=/workspace/destdir --with-device=ch3 --with-hwloc=/workspace/destdir 50 | MPICH CC: cc -DNDEBUG -DNVALGRIND -O3 51 | MPICH CXX: c++ -DNDEBUG -DNVALGRIND -O3 52 | MPICH F77: gfortran -O3 53 | MPICH FC: gfortran -O3 54 | MPICH features: 55 | ``` 56 | 57 | On Unix, `MPI.jl` will install and use `MPICH` through the `MPICH_jll` package. 58 | 59 | ### MPIPreferences 60 | 61 | To switch which MPI implementation `MPI.jl` uses you can use the package `MPIPreferences.jl`. 62 | 63 | For more information see: [https://juliaparallel.org/MPI.jl/stable/configuration/](https://juliaparallel.org/MPI.jl/stable/configuration/) 64 | 65 | When executing on a cluster you will likely need to configure `MPI.jl` to use the system provided MPI. 66 | 67 | ## Installing `mpiexecjl` 68 | 69 | ```julia-repl 70 | julia> using MPI 71 | julia> MPI.install_mpiexecjl() 72 | ``` 73 | 74 | By default, it will install to `~/.julia/bin`, but you can also choose to install it somewhere else 75 | 76 | As an example to install it in the current working directory. 77 | 78 | ``` 79 | julia> using MPI 80 | julia> MPI.install_mpiexecjl(destdir=".") 81 | ``` 82 | 83 | After installing it, you can use it to start Julia. 84 | 85 | ``` 86 | mpiexecjl --project=/path/to/project -n 4 julia script.jl 87 | # or 88 | ./mpiexecjl --project=/path/to/project -n 4 julia script.jl 89 | ``` 90 | 91 | ## Exercises 92 | 93 | MPI.jl has a series of examples: 94 | 95 | - [Hello word](https://juliaparallel.org/MPI.jl/v0.20/examples/01-hello/) 96 | - [Broadcast](https://juliaparallel.org/MPI.jl/v0.20/examples/02-broadcast/) 97 | - [Reduce](https://juliaparallel.org/MPI.jl/v0.20/examples/03-reduce/) 98 | - [Send/receive](https://juliaparallel.org/MPI.jl/v0.20/examples/04-sendrecv/) 99 | 100 | ### Diffusion 101 | 102 | In [exercise 2](https://vchuravy.dev/rse-course/exercises/exercise_2_accelerated/) we looked at a diffusion kernel. 103 | Instead of implementing this on the GPU you can also implement it with MPI. 104 | 105 | !!! note 106 | The "hard" part is the handling of the boundary-conditions and ghost cells. So focus on that in the beginning. 107 | How are you going to split the computational domain? Who needs to talk to whom? -------------------------------------------------------------------------------- /develop.jl: -------------------------------------------------------------------------------- 1 | cd(@__DIR__) 2 | notebook_path = joinpath(@__DIR__, "PlutoPages.jl") 3 | 4 | @assert VERSION >= v"1.6.0" 5 | 6 | begin 7 | begin 8 | begin 9 | # copy paste from pluto source code 10 | function detectwsl() 11 | Sys.islinux() && 12 | isfile("/proc/sys/kernel/osrelease") && 13 | occursin(r"Microsoft|WSL"i, read("/proc/sys/kernel/osrelease", String)) 14 | end 15 | 16 | function open_in_default_browser(url::AbstractString)::Bool 17 | try 18 | if Sys.isapple() 19 | Base.run(`open $url`) 20 | true 21 | elseif Sys.iswindows() || detectwsl() 22 | Base.run(`powershell.exe Start "'$url'"`) 23 | true 24 | elseif Sys.islinux() 25 | Base.run(`xdg-open $url`) 26 | true 27 | else 28 | false 29 | end 30 | catch ex 31 | false 32 | end 33 | end 34 | end 35 | end 36 | end 37 | 38 | 39 | 40 | import Pkg 41 | Pkg.activate("./pluto-deployment-environment") 42 | Pkg.instantiate() 43 | import Pluto 44 | import Deno_jll 45 | 46 | 47 | pluto_port_channel = Channel{UInt16}(1) 48 | function on_event(e::Pluto.ServerStartEvent) 49 | put!(pluto_port_channel, e.port) 50 | end 51 | function on_event(e) 52 | # ignore 53 | end 54 | 55 | req_s = false 56 | 57 | # We create a session: 58 | sesh = Pluto.ServerSession(options=Pluto.Configuration.from_flat_kwargs(; 59 | # workspace_use_distributed=false, 60 | # disable_writing_notebook_files=true, 61 | auto_reload_from_file=true, 62 | launch_browser=false, 63 | on_event, 64 | require_secret_for_access=req_s, 65 | require_secret_for_open_links=req_s 66 | )) 67 | 68 | notebook_launch_task = @async Pluto.SessionActions.open(sesh, notebook_path; run_async=true) 69 | 70 | @info "Pluto app: Starting server..." 71 | 72 | println("Ignore the message \"Go to ... in your browser\":") 73 | pluto_server_task = @async Pluto.run(sesh) 74 | 75 | pluto_port = take!(pluto_port_channel) # This waits for the server to get ready 76 | @info "Pluto app: waiting for notebook to launch..." 77 | notebook = fetch(notebook_launch_task) # This waits for the notebook to finish 78 | 79 | output_dir = joinpath(@__DIR__, "_site") 80 | 81 | dev_server_port = rand(40507:40999) 82 | 83 | 84 | dev_server_task = @async run(`$(Deno_jll.deno()) run --allow-read --allow-net https://deno.land/std@0.102.0/http/file_server.ts --cors --port $(dev_server_port) $(output_dir)`) # <=v"0.102.0" because of https://github.com/denoland/deno_std/issues/2251 85 | 86 | sleep(.5) 87 | 88 | ccall(:jl_exit_on_sigint, Cvoid, (Cint,), 0) 89 | @info "Press Ctrl+C multiple times to exit" 90 | 91 | isolated_cell_ids = [ 92 | "cf27b3d3-1689-4b3a-a8fe-3ad639eb2f82" 93 | "7f7f1981-978d-4861-b840-71ab611faf74" 94 | "7d9cb939-da6b-4961-9584-a905ad453b5d" 95 | "4e88cf07-8d85-4327-b310-6c71ba951bba" 96 | "079a6399-50eb-4dee-a36d-b3dcb81c8456" 97 | "b0006e61-b037-41ed-a3e4-9962d15584c4" 98 | "06edb2d7-325f-4f80-8c55-dc01c7783054" 99 | "e0a25f24-a7de-4eac-9f88-cb7632de09eb" 100 | ] 101 | 102 | isolated_cell_query = join("&isolated_cell_id=$(i)" for i in isolated_cell_ids) 103 | 104 | dev_server_url = "http://localhost:$(dev_server_port)/" 105 | pluto_server_url = "http://localhost:$(pluto_port)/edit?id=$(notebook.notebook_id)$(isolated_cell_query)" 106 | 107 | @info """ 108 | 109 | ✅✅✅ 110 | 111 | Ready! To see the website, visit: 112 | ➡️ $(dev_server_url) 113 | 114 | To inspect the generation process, go to: 115 | ➡️ $(pluto_server_url) 116 | 117 | ✅✅✅ 118 | 119 | """ 120 | 121 | 122 | 123 | open_in_default_browser(dev_server_url) 124 | open_in_default_browser(pluto_server_url) 125 | 126 | wait(dev_server_task) 127 | wait(pluto_server_task) -------------------------------------------------------------------------------- /src/assets/homepage/bg.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Website maintenance.md: -------------------------------------------------------------------------------- 1 | # Website maintenance 2 | 3 | This document describes how the website works. 4 | 5 | # Overview 6 | 7 | This is the source code for the computational thinking website! It uses a site generation system inspired by [https://www.11ty.dev/](https://www.11ty.dev/), but there are only three template systems: 8 | - **`.jlhtml` files** are rendered by [HypertextLiteral.jl](https://github.com/JuliaPluto/HypertextLiteral.jl) 9 | - **`.jlmd` files** are rendered by [MarkdownLiteral.jl](https://github.com/JuliaPluto/MarkdownLiteral.jl) 10 | - **`.jl` files** are rendered by [PlutoSliderServer.jl](https://github.com/JuliaPluto/PlutoSliderServer.jl) 11 | 12 | The `/src/` folder is scanned for files, and all files are turned into HTML pages. 13 | 14 | Paths correspond to URLs. For example, `src/data_science/pca.jl` will become available at `https://computationalthinking.mit.edu/data_science/pca/`. For files called *"index"*, the URL will point to its parent, e.g. `src/docs/index.jlmd` becomes `https://computationalthinking.mit.edu/docs/`. Remember that changing URLs is very bad! You can't share this site with your friends if the links break. 15 | 16 | > **To add something to our website, just create a new file!** Fons will be happy to figure out the technical bits. 17 | 18 | You can generate & preview the website locally (more on this later), and we have a github action generating the website when we push to the `Fall23` branch. The result (in the `Fall23-output` branch) is deployed with GitHub Pages. 19 | 20 | # Content 21 | 22 | ## Literal templates 23 | We use *Julia* as our templating system! Because we use HypertextLiteral and MarkdownLiteral, you can write regular Markdown files and HTML files, but you can also include `$(interpolation)` to spice up your documents! For example: 24 | 25 | ```markdown 26 | # Hey there! 27 | 28 | This is some *text*. Here is a very big number: $(1 + 1). 29 | ``` 30 | 31 | Besides small inline values, you can also write big code blocks, with `$(begin ... end)`, and you can output HTML. Take a look at some of our files to learn more! 32 | 33 | ## Pluto notebooks 34 | 35 | Pluto notebooks will be rendered to HTML and included in the page. What you see is what you get! 36 | 37 | On a separate system, we are running a PlutoSliderServer that is synchronized to the `Fall23` brach. This makes our notebooks interactive! 38 | 39 | Notebook outputs are **cached** (for a long time) by the file hash. This means that a notebook file will only ever run once, which makes it much faster to work on the website. If you need to re-run your notebook, add a space somewhere in the code :) 40 | 41 | ## `.css`, `.html`, `.gif`, etc 42 | 43 | Web assets go through the system unchanged. 44 | 45 | # Front matter 46 | 47 | Like many SSG systems, we use [*front matter*](https://www.11ty.dev/docs/data-frontmatter/) to add metadata to pages. In `.jlmd` files, this is done with a front matter block, e.g.: 48 | ```markdown 49 | --- 50 | title: "🌼 How to install" 51 | description: "Instructions to install Pluto.jl" 52 | tags: ["docs", "introduction"] 53 | layout: "md.jlmd" 54 | --- 55 | 56 | # Let's install Pluto 57 | 58 | here is how you do it 59 | ``` 60 | 61 | Every page **should probably** include: 62 | - *`title`*: Will be used in the sidebar, on Google, in the window header, and on social media. 63 | - *`description`*: Will be used on hover, on Google, and on social media. 64 | - *`tags`*: List of *tags* that are used to create collections out of pages. Our sidebar uses collections to know which pages to list. (more details in `sidebar data.jl`) 65 | - *`layout`*: The name of a layout file in `src/_includes`. For basic Markdown or HTML, you probably want `md.jlmd`. For Pluto, you should use `layout.jlhtml`. 66 | 67 | ## How to write front matter 68 | For `.jlmd` files, see the example above. 69 | 70 | For `.jl` notebooks, use the [Frontmatter GUI](https://github.com/fonsp/Pluto.jl/pull/2104) built into Pluto. 71 | 72 | For `.jlhtml`, we still need to figure something out 😄. 73 | 74 | # Running locally 75 | 76 | ## Developing *content, styles, etc.* 77 | 78 | Open this repository in VS Code, and install the recommended extensions. 79 | 80 | To start running the development server, open the VS Code *command palette* (press `Cmd+Shift+P`), and search for **`Tasks: Run Task`**, then **`PlutoPages: run development server`**. The first run can take some time, as it builds up the notebook outputs cache. Leave it running. 81 | 82 | This will start two things in parallel: the PlutoPages.jl notebook (which generates the website), and a static file server (with Deno_jll). It will open two tabs in your browser: one is the generation dashboard (PlutoPages), the other is the current site preview (Deno_jll). 83 | 84 | Whenever you edit a file, PlutoPages will automatically regenerate! Refresh your browser tab. If it does not pick up the change, go to the generation dashboard and click the "Read input files again" button. 85 | 86 | This workflow is recommended for writing static content, styles, and for site maintenance. But for writing Pluto notebooks, it's best to prepare the notebook first, and then run the site (because it re-runs the entire notebook on any change). 87 | 88 | ## Developing PlutoPages itself 89 | 90 | 91 | You need to manually run the notebook with Pluto: 92 | 1. Go to this folder, and run `julia --project=pluto-deployment-environment`. Then `import Pkg; Pkg.instantiate();`. 93 | 1. `import Pluto; Pluto.run()` and open the `PlutoPages.jl` notebook in this repository. The first run can take some time, as it builds up the notebook outputs cache. Leave it running. 94 | 2. In a second terminal, go to this folder, and run `julia --project=pluto-deployment-environment`, then: 95 | ```julia 96 | import Deno_jll 97 | run(`$(Deno_jll.deno()) run --allow-read --allow-net https://deno.land/std@0.102.0/http/file_server.ts _site`) 98 | ``` 99 | 3. Go to the URL printed to your terminal. 100 | 4. Whenever you edit a file, PlutoPages will automatically regenerate! Refresh your browser tab. If it does not pick up the change, go to the generation dashboard and click the "Read input files again" button. 101 | 102 | # PlutoPages.jl? 103 | 104 | The PlutoPages.jl is still in experimental stage, and I'm not sure if the Julia community is waiting for another SSG system. So right now it's sort of released in secret. If you use it, be sure to respect our LICENSE and be sure to share your feedback with fons@plutojl.org! Bug reports welcome. 105 | -------------------------------------------------------------------------------- /src/assets/julia-logo-color.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/assets/julia-logo-dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/assets/scripts/search.js: -------------------------------------------------------------------------------- 1 | const root_href = document.head.querySelector("link[rel='root']").getAttribute("href") 2 | 3 | const minby = (arr, fn) => arr.reduce((a, b) => (fn(a) < fn(b) ? a : b)) 4 | const maxby = (arr, fn) => arr.reduce((a, b) => (fn(a) > fn(b) ? a : b)) 5 | const range = (length) => [...Array(length).keys()] 6 | 7 | const sortby = (arr, fn) => arr.sort((a, b) => fn(a) - fn(b)) 8 | 9 | const setup_search_index = async () => { 10 | const search_data_href = document.head.querySelector("link[rel='pp-search-data']").getAttribute("href") 11 | console.log(search_data_href) 12 | 13 | const search_data = await (await fetch(search_data_href)).json() 14 | window.search_data = search_data 15 | 16 | console.log(search_data) 17 | 18 | // create a search bar powered by lunr 19 | // const search_bar = document.createElement('div') 20 | // search_bar.id = 'search-bar' 21 | // search_bar.innerHTML = ` 22 | // 23 | //
24 | // ` 25 | // document.body.appendChild(search_bar) 26 | 27 | // create a search index 28 | const before = Date.now() 29 | const search_index = window.lunr(function () { 30 | this.ref("url") 31 | 32 | this.field("title", { boost: 10 }) 33 | this.field("tags", { boost: 5 }) 34 | this.field("text") 35 | this.metadataWhitelist = ["position"] 36 | search_data.forEach(function (doc) { 37 | this.add(doc) 38 | }, this) 39 | }) 40 | const after = Date.now() 41 | console.info(`lunr: Indexing ${search_data.length} documents took ${after - before}ms`) 42 | window.search_index = search_index 43 | 44 | return { search_data, search_index } 45 | } 46 | 47 | const excerpt_length = 200 48 | const excerpt_padding = 50 49 | 50 | const init_search = async () => { 51 | const query = new URLSearchParams(window.location.search).get("q") 52 | console.warn({ query }) 53 | 54 | document.querySelector(".search-bar.big input").value = query 55 | 56 | const { search_data, search_index } = await setup_search_index() 57 | 58 | if (query) { 59 | const results = search_index.search(query) 60 | console.log(results) 61 | 62 | const search_results = document.getElementById("search-results") 63 | 64 | if (results.length !== 0) { 65 | search_results.innerHTML = "" 66 | results.forEach((result) => { 67 | const { url, title, tags, text } = search_data.find((doc) => doc.url === result.ref) 68 | const result_div = document.createElement("a") 69 | result_div.classList.add("search-result") 70 | result_div.innerHTML = ` 71 |

72 |

73 |

74 | ` 75 | console.log(root_href) 76 | result_div.querySelector(".title").innerText = title 77 | result_div.href = new URL(url, new URL(root_href, window.location.href)).href 78 | result_div.querySelector(".tags").innerText = tags.join(", ") 79 | result_div.querySelector(".snippet").innerText = text.substring(0, excerpt_length) + "..." 80 | 81 | const text_match_positions = Object.values(result?.matchData?.metadata ?? {}) 82 | .flatMap((z) => z?.text?.position ?? []) 83 | .sort(([a, _a], [b, _b]) => a - b) 84 | const title_match_positions = Object.values(result?.matchData?.metadata ?? {}) 85 | .flatMap((z) => z?.title?.position ?? []) 86 | .sort(([a, _a], [b, _b]) => a - b) 87 | 88 | console.error(title_match_positions) 89 | if (title_match_positions.length > 0) { 90 | const strong_el = document.createElement("strong") 91 | strong_el.innerText = title 92 | result_div.querySelector(".title").innerHTML = `` 93 | result_div.querySelector(".title").appendChild(strong_el) 94 | } 95 | 96 | if (text_match_positions.length > 0) { 97 | // console.log(text_match_positions) 98 | // console.log(find_longest_run(text_match_positions, 50)) 99 | // console.log(find_longest_run(text_match_positions, 100)) 100 | // console.log(find_longest_run(text_match_positions, 200)) 101 | // console.log(find_longest_run(text_match_positions, 300)) 102 | // console.log(find_longest_run(text_match_positions, 400)) 103 | 104 | const [start_index, num_matches] = find_longest_run(text_match_positions, excerpt_length) 105 | 106 | const excerpt_start = text_match_positions[start_index][0] 107 | const excerpt_end = excerpt_start + excerpt_length 108 | 109 | const highlighted_ranges = text_match_positions.slice(start_index, start_index + num_matches) 110 | 111 | const elements = highlighted_ranges.flatMap(([h_start, h_length], i) => { 112 | const h_end = h_start + h_length 113 | const word = text.slice(h_start, h_end) 114 | const filler = text.slice(h_end, highlighted_ranges[i + 1]?.[0] ?? excerpt_end) 115 | const word_el = document.createElement("strong") 116 | word_el.innerText = word 117 | return [word_el, filler] 118 | }) 119 | 120 | const snippet_p = result_div.querySelector(".snippet") 121 | snippet_p.innerHTML = `` 122 | ;["...", text.slice(excerpt_start - excerpt_padding, excerpt_start).trimStart(), ...elements, "..."].forEach((el) => snippet_p.append(el)) 123 | } 124 | 125 | // text_match_positions.slice(start_index, start_index + num_matches).forEach(([start, length]) => { 126 | 127 | search_results.appendChild(result_div) 128 | }) 129 | } else { 130 | search_results.innerText = `No results found for "${query}"` 131 | } 132 | } 133 | } 134 | 135 | const count = (arr, fn) => arr.reduce((a, b) => fn(a) + fn(b), 0) 136 | 137 | const find_longest_run = (/** @type{Array<[number, number]>} */ positions, max_dist) => { 138 | const legal_run_size = (start_index) => 139 | positions.slice(start_index).filter(([start, length]) => start + length < positions[start_index][0] + max_dist).length 140 | 141 | console.warn(range(positions.length).map(legal_run_size)) 142 | 143 | const best_start = maxby(range(positions.length), legal_run_size) 144 | const best_length = legal_run_size(best_start) 145 | return [best_start, best_length] 146 | } 147 | 148 | window.init_search = init_search 149 | -------------------------------------------------------------------------------- /src/assets/styles/homepage.css: -------------------------------------------------------------------------------- 1 | @import url("newdefault.css"); 2 | 3 | body { 4 | background: url("../homepage/bg.svg"); 5 | background-color: hsl(231deg 14% 57%); 6 | background-size: cover; 7 | backdrop-filter: blur(3vw); 8 | } 9 | main h1 { 10 | font-family: "Vollkorn", serif; 11 | font-weight: 800; 12 | font-style: italic; 13 | margin-block-end: 0.5em; 14 | font-size: 3rem; 15 | margin-block-start: 0; 16 | border-bottom: 5px solid #74747414; 17 | letter-spacing: -0.2px; 18 | color: #424250; 19 | padding: 0px 10px; 20 | text-shadow: 7px 5px 0px #e5dbb8; 21 | } 22 | 23 | a { 24 | text-decoration: none; 25 | /* background: #f3f3ff; */ 26 | /* border: 3px solid; */ 27 | color: black; 28 | /* border-bottom: 0.2em solid rgba(0, 0, 0, 0.3); */ 29 | } 30 | .homepage a:not(.no-decoration) { 31 | background-position: 0 0.83em; 32 | background-repeat: repeat-x; 33 | background-size: 2px 8px; 34 | background-image: linear-gradient(to bottom, rgba(165, 213, 235, 0.3) 33%, rgba(165, 213, 235, 0.3)); 35 | /* text-shadow: 2px 2px white, 2px -2px white, -2px 2px white, -2px -2px white; */ 36 | transition: background-position 50ms linear, background-size 50ms linear; 37 | } 38 | 39 | a:hover { 40 | background-position: 0 0em; 41 | background-size: 2px auto; 42 | } 43 | 44 | div.banner { 45 | min-height: 20rem; 46 | display: grid; 47 | place-items: center; 48 | } 49 | 50 | div.banner h1 { 51 | transform: perspective(187px) rotate3d(0, 2, 0, 0deg); 52 | font-family: "Alegreya", sans-serif; 53 | background: #000000ad; 54 | padding: 0.2em 0.5em; 55 | margin: 0px 10px; 56 | border-radius: 0.4em; 57 | transition: transform 200ms ease-in-out; 58 | color: #ffffffc7; 59 | font-style: normal; 60 | border: none; 61 | backdrop-filter: blur(6px); 62 | /* flex: 1 1 auto; */ 63 | /* display: block; */ 64 | } 65 | div.banner h1 strong { 66 | color: white; 67 | } 68 | 69 | div.banner:hover h1 { 70 | /* transform: perspective(187px) rotate3d(0, 2, 0, 3deg) scale(1.05); */ 71 | } 72 | 73 | #title { 74 | background-image: url("../homepage/swoosh.png"); 75 | 76 | background-size: cover; 77 | image-rendering: pixelated; 78 | } 79 | 80 | img.logo { 81 | position: absolute; 82 | top: 5px; 83 | left: 5px; 84 | z-index: 10; 85 | height: 2rem; 86 | background: #ffffff96; 87 | padding: 3px; 88 | } 89 | 90 | .twocols { 91 | column-count: 2; 92 | color: #fffffff7; 93 | background: linear-gradient(155deg, #7c7e87, #5a594a); 94 | } 95 | 96 | main { 97 | /* background: white; */ 98 | padding: 1em; 99 | max-width: 86rem; 100 | z-index: -1; 101 | margin: 3em auto 0 auto; 102 | padding-bottom: 5rem !important; 103 | } 104 | main > div { 105 | z-index: 4; 106 | background: white; 107 | padding: 2rem; 108 | margin-block-end: 5rem; 109 | border-radius: 1rem; 110 | box-shadow: 0px 6px 7px #1c12120d; 111 | 112 | max-width: 700px; 113 | margin-left: auto; 114 | margin-right: auto; 115 | } 116 | 117 | main > div.wide { 118 | max-width: unset; 119 | } 120 | 121 | main > div:last-of-type { 122 | margin-block-end: 0px; 123 | } 124 | main > div > *:last-child, 125 | main > div > .contain > *:last-child { 126 | margin-block-end: 0px; 127 | margin-bottom: 0em; 128 | } 129 | main thingy { 130 | background: #ff00005e; 131 | width: 300vw; 132 | border-radius: 50%; 133 | height: 60vh; 134 | display: block; 135 | /* position: unset; */ 136 | z-index: -4; 137 | /* transform: translate(10px, -64px); */ 138 | /* transform: rotate(11deg); */ 139 | } 140 | .asdf { 141 | position: absolute; 142 | transform: translate(-); 143 | overflow: hidden; 144 | max-width: 100vw; 145 | } 146 | .contain { 147 | max-width: 700px; 148 | margin-left: auto; 149 | margin-right: auto; 150 | } 151 | 152 | blockquote { 153 | border-left: 0.6em solid #b97777; 154 | padding: 0.5em 1em; 155 | max-width: 30em; 156 | font-style: italic; 157 | background: #f9f9f9; 158 | font-size: 1rem; 159 | margin: 0 auto; 160 | } 161 | 162 | blockquote.banner { 163 | margin-top: -46px; 164 | font-style: unset; 165 | font-size: 1rem; 166 | border-radius: 0.5em; 167 | box-shadow: 0px 3px 17px #0000001a; 168 | } 169 | 170 | .pillars { 171 | display: flex; 172 | flex-direction: row; 173 | justify-content: space-between; 174 | overflow-x: auto; 175 | } 176 | 177 | .pillars > div { 178 | color: white; 179 | padding: 1em; 180 | background: #434366; 181 | min-height: 300px; 182 | flex: 1 1 33%; 183 | margin: 0px 10px; 184 | } 185 | 186 | .scrolly { 187 | /* max-height: 20em; */ 188 | /* overflow-y: auto; */ 189 | } 190 | .pillars > div ul { 191 | padding-left: 0.6rem; 192 | } 193 | .pillars > div li { 194 | list-style: "- "; 195 | margin-bottom: 0.3rem; 196 | margin-right: 0.5rem; 197 | } 198 | .pillars > div li::marker { 199 | color: rgba(255, 255, 255, 0.4); 200 | } 201 | 202 | .subjects { 203 | display: grid; 204 | grid-template-columns: repeat(3, auto); 205 | grid-gap: 1rem; 206 | /* display: flex; */ 207 | /* flex-wrap: wrap; */ 208 | } 209 | 210 | @media (max-width: 1350px) { 211 | .subjects { 212 | grid-template-columns: repeat(2, auto); 213 | } 214 | } 215 | @media (max-width: 850px) { 216 | .subjects { 217 | grid-template-columns: repeat(1, auto); 218 | } 219 | } 220 | 221 | @media (min-width: 1250px) { 222 | .subjectscontainer { 223 | display: flex; 224 | flex-direction: row; 225 | margin-block-start: 5rem; 226 | } 227 | 228 | .subjectscontainer h1 { 229 | flex-shrink: 0; 230 | position: sticky; 231 | top: 100px; 232 | align-self: flex-start; 233 | margin-block-start: 0px; 234 | /* padding-right: 0; */ 235 | margin-right: 1em; 236 | } 237 | } 238 | 239 | .subjects > a { 240 | display: block; 241 | border: 7px solid #c19d1c1f; 242 | min-height: 200px; 243 | min-width: min(90vw, 188px); 244 | padding: 1em; 245 | border-radius: 1em; 246 | transition: transform 100ms ease-in-out; 247 | /* width: 27%; */ 248 | box-shadow: 0px 6px 7px #1c12120d; 249 | } 250 | 251 | .subjects > a:hover { 252 | transform: scale(1.05); 253 | } 254 | 255 | .subjects > a img { 256 | max-width: 100%; 257 | width: 100%; 258 | } 259 | section { 260 | display: flex; 261 | flex-direction: row; 262 | background: linear-gradient(145deg, #a6b8ef, #daeaff); 263 | padding: 1em; 264 | background-repeat: repeat-x; 265 | border-radius: 1em; 266 | margin-bottom: 2em; 267 | } 268 | 269 | .shadow, 270 | section { 271 | box-shadow: 0px 6px 9px #0606060f; 272 | padding: 1rem; 273 | border-radius: 1rem; 274 | } 275 | 276 | @media (max-width: 500px) { 277 | section { 278 | flex-direction: column; 279 | } 280 | } 281 | 282 | section > div { 283 | flex: 1 1 60%; 284 | } 285 | 286 | section > div.content { 287 | margin-right: 1em; 288 | } 289 | section > div.preview { 290 | flex: 0 1 40%; 291 | } 292 | 293 | section > div.preview > img { 294 | width: 100%; 295 | } 296 | 297 | .homepage, 298 | .banner { 299 | color: #3c3c3c; 300 | } 301 | -------------------------------------------------------------------------------- /src/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Software installation" 3 | tags: ["welcome"] 4 | order: 2 5 | layout: "md.jlmd" 6 | youtube_id: "OOjKEgbt8AI" 7 | --- 8 | 9 | $( 10 | begin 11 | # these special elements will automatically update to read the latest Julia version. See the JavaScript snippet at the bottom of this page to see how it works! 12 | 13 | version = html"1.8.2" 14 | pkg_version = html"1.8" 15 | 16 | nothing 17 | end 18 | ) 19 | 20 | # First-time setup: Install Julia & Pluto 21 | 22 | \\ 23 | \\ 24 | \\ 25 | **Text and pictures version:** 26 | 27 | ## Step 1: Install Julia $version 28 | 29 | Go to [https://julialang.org/install/](https://julialang.org/install/) and download `juliaup`, `juliaup` will install the current stable release, Julia $(version), using the correct version for your operating system (Linux x86, Mac, Windows, etc). 30 | 31 | ## Step 2: Run Julia 32 | 33 | After installing, **make sure that you can run Julia**. On some systems, this means searching for the "Julia $(version)" program installed on your computer; in others, it means running the command `julia` in a terminal. Make sure that you can execute `1 + 1`: 34 | 35 | ![image](https://user-images.githubusercontent.com/6933510/91439734-c573c780-e86d-11ea-8169-0c97a7013e8d.png) 36 | 37 | *Make sure that you are able to launch Julia and calculate `1+1` before proceeding!* 38 | 39 | ## Step 3: Install [`Pluto`](https://github.com/fonsp/Pluto.jl) 40 | 41 | Next we will install the [**Pluto**](https://github.com/fonsp/Pluto.jl), the notebook environment that we will be using during the course. Pluto is a Julia _programming environment_ designed for interactivity and quick experiments. 42 | 43 | Open the **Julia REPL**. This is the command-line interface to Julia, similar to the previous screenshot. 44 | 45 | Here you type _Julia commands_, and when you press ENTER, it runs, and you see the result. 46 | 47 | To install Pluto, we want to run a _package manager command_. To switch from _Julia_ mode to _Pkg_ mode, type `]` (closing square bracket) at the `julia>` prompt: 48 | 49 |

 50 | julia> ]
 51 | 
 52 | (@v$(pkg_version)) pkg>
 53 | 
54 | 55 | The line turns blue and the prompt changes to `pkg>`, telling you that you are now in _package manager mode_. This mode allows you to do operations on **packages** (also called libraries). 56 | 57 | To install Pluto, run the following (case sensitive) command to *add* (install) the package to your system by downloading it from the internet. 58 | You should only need to do this *once* for each installation of Julia: 59 | 60 |

 61 | (@v$(pkg_version)) pkg> add Pluto
 62 | 
63 | 64 | This might take a couple of minutes, so you can go get yourself a cup of tea! 65 | 66 | ![image](https://user-images.githubusercontent.com/6933510/91440380-ceb16400-e86e-11ea-9352-d164911774cf.png) 67 | 68 | You can now close the terminal. 69 | 70 | ## Step 4: Use a modern browser: Mozilla Firefox or Google Chrome 71 | We need a modern browser to view Pluto notebooks with. Firefox and Chrome work best. 72 | 73 | 74 | # Second time: _Running Pluto & opening a notebook_ 75 | Repeat the following steps whenever you want to work on a project or homework assignment. 76 | 77 | ## Step 1: Start Pluto 78 | 79 | Start the Julia REPL, like you did during the setup. In the REPL, type: 80 | ```julia 81 | julia> using Pluto 82 | 83 | julia> Pluto.run() 84 | ``` 85 | 86 | ![image](https://user-images.githubusercontent.com/6933510/91441094-eb01d080-e86f-11ea-856f-e667fdd9b85c.png) 87 | 88 | The terminal tells us to go to `http://localhost:1234/` (or a similar URL). Let's open Firefox or Chrome and type that into the address bar. 89 | 90 | ![image](https://user-images.githubusercontent.com/6933510/199279574-4b1d0494-2783-49a0-acca-7b6284bede44.png) 91 | 92 | > If you're curious about what a _Pluto notebook_ looks like, have a look at the **Featured Notebooks**. These notebooks are useful for learning some basics of Julia programming. 93 | > 94 | > If you want to hear the story behind Pluto, have a look a the [JuliaCon presentation](https://www.youtube.com/watch?v=IAF8DjrQSSk). 95 | 96 | If nothing happens in the browser the first time, close Julia and try again. And please let us know! 97 | 98 | ## Step 2a: Opening a notebook from the web 99 | 100 | This is the main menu - here you can create new notebooks, or open existing ones. Our homework assignments will always be based on a _template notebook_, available in this GitHub repository. To start from a template notebook on the web, you can _paste the URL into the blue box_ and press ENTER. 101 | 102 | For example, homework 0 is available [here](/hw0/). Go to this page, and on the top right, click on the button that says "Edit or run this notebook". From these instructions, copy the notebook link, and paste it into the box. Press ENTER, and select OK in the confirmation box. 103 | 104 | ![image](https://user-images.githubusercontent.com/6933510/91441968-6b750100-e871-11ea-974e-3a6dfd80234a.png) 105 | 106 | **The first thing we will want to do is to save the notebook somewhere on our own computer; see below.** 107 | 108 | ## Step 2b: Opening an existing notebook file 109 | When you launch Pluto for the second time, your recent notebooks will appear in the main menu. You can click on them to continue where you left off. 110 | 111 | If you want to run a local notebook file that you have not opened before, then you need to enter its _full path_ into the blue box in the main menu. More on finding full paths in step 3. 112 | 113 | ## Step 3: Saving a notebook 114 | We first need a folder to save our homework in. Open your file explorer and create one. 115 | 116 | Next, we need to know the _absolute path_ of that folder. Here's how you do that in [Windows](https://www.top-password.com/blog/copy-full-path-of-a-folder-file-in-windows/), [MacOS](https://www.josharcher.uk/code/find-path-to-folder-on-mac/) and [Ubuntu](). 117 | 118 | For example, you might have: 119 | 120 | - `C:\\Users\\fons\\Documents\\18S191_assignments\\` on Windows 121 | 122 | - `/Users/fons/Documents/18S191_assignments/` on MacOS 123 | 124 | - `/home/fons/Documents/18S191_assignments/` on Ubuntu 125 | 126 | Now that we know the absolute path, go back to your Pluto notebook, and at the top of the page, click on _"Save notebook..."_. 127 | 128 | ![image](https://user-images.githubusercontent.com/6933510/91444741-77fb5880-e875-11ea-8f6b-02c1c319e7f3.png) 129 | 130 | This is where you type the **new path+filename for your notebook**: 131 | 132 | ![image](https://user-images.githubusercontent.com/6933510/91444565-366aad80-e875-11ea-8ed6-1265ded78f11.png) 133 | 134 | Click _Choose_. 135 | 136 | ## Step 4: Sharing a notebook 137 | 138 | After working on your notebook (your code is autosaved when you run it), you will find your notebook file in the folder we created in step 3. This the file that you can share with others, or submit as your homework assignment to Canvas. 139 | 140 | 141 | 156 | -------------------------------------------------------------------------------- /src/assets/styles/layout.css: -------------------------------------------------------------------------------- 1 | /* COLOR */ 2 | 3 | #pages-layout { 4 | /* --bg-color: set by pluto */ 5 | --sidebar-bg: #fafafa; 6 | --sidebar-color: rgb(82, 82, 82); 7 | --sidebar-li-active-bg: rgb(235, 235, 235); 8 | --sidebar-li-hover-bg: rgb(247, 240, 190); 9 | } 10 | @media (prefers-color-scheme: dark) { 11 | #pages-layout { 12 | --sidebar-bg: #303030; 13 | --sidebar-color: rgb(255, 255, 255); 14 | --sidebar-li-active-bg: rgb(82, 82, 82); 15 | --sidebar-li-hover-bg: rgb(108, 94, 70); 16 | } 17 | } 18 | 19 | /* LAYOUT */ 20 | 21 | #pages-layout { 22 | display: flex; 23 | flex-direction: row; 24 | min-height: 100vh; 25 | align-items: stretch; 26 | } 27 | 28 | #pages-sidebar { 29 | font-family: system-ui, sans-serif; 30 | flex: 0 0 auto; 31 | width: 15rem; 32 | font-weight: 400; 33 | z-index: 1900; 34 | } 35 | 36 | #pages-content { 37 | display: block; 38 | flex: 1 1 auto; 39 | min-width: 0; 40 | } 41 | 42 | #pages-sidebar > div { 43 | margin: 1rem; 44 | margin-right: 0; 45 | padding: 0.5rem; 46 | /* padding-bottom: 2rem; */ 47 | border-radius: 1rem; 48 | background: var(--sidebar-bg); 49 | color: var(--sidebar-color); 50 | } 51 | 52 | #toggle-nav { 53 | display: none; 54 | cursor: pointer; 55 | } 56 | 57 | /* SIDEBAR COLLAPSING */ 58 | 59 | #pages-content::after { 60 | content: ""; 61 | z-index: 23400; 62 | touch-action: none; 63 | pointer-events: none; 64 | position: fixed; 65 | top: 0; 66 | left: 0; 67 | right: 0; 68 | bottom: 0; 69 | transition: background-color 0.2s ease-out; 70 | } 71 | 72 | @media screen and (max-width: 768px) { 73 | #pages-layout { 74 | flex-direction: column; 75 | } 76 | #toggle-nav { 77 | display: inline-flex; 78 | align-self: start; 79 | border: none; 80 | background: none; 81 | } 82 | #toggle-nav::after { 83 | --size: 40px; 84 | content: " "; 85 | display: inline-block; 86 | width: var(--size); 87 | height: var(--size); 88 | background-image: url(https://cdn.jsdelivr.net/gh/ionic-team/ionicons@5.5.1/src/svg/menu-outline.svg); 89 | background-size: var(--size) var(--size); 90 | filter: var(--image-filters); 91 | } 92 | #pages-sidebar { 93 | position: fixed; 94 | top: 0; 95 | bottom: 0; 96 | right: 100%; 97 | overflow-y: auto; 98 | transition: transform 300ms cubic-bezier(0.18, 0.89, 0.45, 1.12); 99 | } 100 | @media (prefers-reduced-motion) { 101 | #pages-sidebar { 102 | transition: none; 103 | } 104 | } 105 | 106 | .pages_show_sidebar #pages-sidebar { 107 | transform: translateX(100%); 108 | z-index: 23401; 109 | } 110 | .pages_show_sidebar #pages-content::after { 111 | display: block; 112 | background-color: rgba(0, 0, 0, 0.5); 113 | } 114 | } 115 | 116 | /* SIDEBAR */ 117 | 118 | #pages-sidebar { 119 | --child-padding: 0.2em 0.6em; 120 | --border-radius: 0.5em; 121 | } 122 | 123 | #pages-sidebar > div > ul { 124 | margin-block-start: 0px; 125 | margin-block-end: 0px; 126 | } 127 | 128 | #pages-sidebar li, 129 | #pages-sidebar ul { 130 | padding: 0px; 131 | list-style-type: none; 132 | } 133 | 134 | #pages-sidebar a { 135 | color: unset; 136 | text-decoration: none; 137 | } 138 | 139 | #pages-sidebar li li a, 140 | #pages-sidebar li h3 { 141 | border-radius: var(--border-radius); 142 | padding: var(--child-padding); 143 | } 144 | 145 | #pages-sidebar li h3 { 146 | color: var(--sidebar-accent-1); 147 | font-variant-caps: all-petite-caps; 148 | margin-block-start: 3rem; 149 | margin-block-end: 0; 150 | } 151 | 152 | #pages-sidebar li hr { 153 | margin: 3rem 1rem; 154 | /* border-color: red; */ 155 | border-style: solid; 156 | opacity: 0.2; 157 | } 158 | 159 | #pages-sidebar li:first-of-type h3 { 160 | margin-block-start: 0; 161 | } 162 | 163 | #pages-sidebar li, 164 | #pages-sidebar ul { 165 | display: flex; 166 | flex-direction: column; 167 | align-items: stretch; 168 | } 169 | 170 | #pages-sidebar li li.exercise { 171 | padding-left: 1ch; 172 | /* background: yellow; */ 173 | } 174 | 175 | #pages-sidebar li li.indepth { 176 | padding-left: 1ch; 177 | /* background: yellow; */ 178 | } 179 | 180 | #pages-sidebar li li a { 181 | margin: 0.2em 0; 182 | } 183 | 184 | #pages-sidebar li li.exercise a { 185 | /* background: #ffb60012; */ 186 | margin: 0.4em 0px; 187 | outline: 3px dashed #92929278; 188 | outline-offset: -1px; 189 | } 190 | 191 | #pages-sidebar li li.indepth a { 192 | /* background: #ffb60012; */ 193 | margin: 0.4em 0px; 194 | outline: 3px dashed #92929278; 195 | outline-offset: -1px; 196 | } 197 | 198 | /* #pages-sidebar li li.exercise a::before { 199 | content: "👉 "; 200 | } */ 201 | 202 | #pages-sidebar li li span.entry-number { 203 | opacity: 0.6; 204 | } 205 | #pages-sidebar li li.exercise span.entry-number { 206 | display: block; 207 | } 208 | #pages-sidebar li li.indepth span.entry-number { 209 | display: block; 210 | } 211 | 212 | #pages-sidebar li li.active a { 213 | background-color: var(--sidebar-li-active-bg); 214 | } 215 | #pages-sidebar li li:hover a { 216 | background-color: var(--sidebar-li-hover-bg); 217 | } 218 | #pages-sidebar li li.not_in_track { 219 | opacity: 0.4; 220 | } 221 | 222 | /* TRACK CHOOSER */ 223 | 224 | .track-chooser { 225 | margin-top: 3em; 226 | padding: 0.5em; 227 | border: 3px solid var(--track-bg-accent); 228 | background: var(--track-bg); 229 | color: var(--fg); 230 | border-radius: 0.3em; 231 | display: flex; 232 | flex-direction: column; 233 | align-items: center; 234 | } 235 | 236 | .track-chooser h2:not(#asdf) { 237 | font-weight: 900; 238 | font-family: sans-serif; 239 | font-style: normal; 240 | font-size: 1.2rem; 241 | margin-block-end: 0.3em; 242 | margin-block-start: 0; 243 | } 244 | 245 | .track-chooser label { 246 | display: contents; 247 | } 248 | 249 | .track-chooser select { 250 | max-width: 100%; 251 | } 252 | 253 | /* SIDEBAR LOGO */ 254 | 255 | #pages-sidebar .home_link img { 256 | height: 1.2em; 257 | width: 1.2em; 258 | } 259 | #pages-sidebar a.home_link { 260 | font-size: 1.7rem; 261 | padding: 0.3em; 262 | font-weight: 800; 263 | display: flex; 264 | flex-direction: row; 265 | align-items: center; 266 | gap: 0.5ch; 267 | } 268 | 269 | /* Markdown content */ 270 | 271 | .pages-markdown main { 272 | max-width: 700px; 273 | margin-left: auto; 274 | margin-right: auto; 275 | margin-top: 5rem; 276 | } 277 | 278 | /* footnote */ 279 | 280 | main { 281 | padding-bottom: 5rem !important; 282 | } 283 | 284 | .github-logo { 285 | width: 1em; 286 | } 287 | 288 | .page-foot { 289 | z-index: 4; 290 | background: white; 291 | padding: 2rem; 292 | border-radius: 1rem; 293 | box-shadow: 0px 0px 10px 5px #1c12120d; 294 | 295 | max-width: 700px; 296 | margin-left: auto; 297 | margin-right: auto; 298 | margin-block-end: 5rem; 299 | margin-bottom: 10em; 300 | } 301 | 302 | .page-foot a { 303 | text-decoration: none; 304 | /* background: #f3f3ff; */ 305 | /* border: 3px solid; */ 306 | color: black; 307 | /* border-bottom: 0.2em solid rgba(0, 0, 0, 0.3); */ 308 | } 309 | .page-foot a:not(.no-decoration) { 310 | background-position: 0 0.83em; 311 | background-repeat: repeat-x; 312 | background-size: 2px 8px; 313 | background-image: linear-gradient(to bottom, rgba(165, 213, 235, 0.3) 33%, rgba(165, 213, 235, 0.3)); 314 | /* text-shadow: 2px 2px white, 2px -2px white, -2px 2px white, -2px -2px white; */ 315 | transition: background-position 50ms linear, background-size 50ms linear; 316 | } 317 | 318 | .page-foot a:hover { 319 | background-position: 0 0em; 320 | background-size: 2px auto; 321 | } 322 | -------------------------------------------------------------------------------- /src/assets/styles/index.css: -------------------------------------------------------------------------------- 1 | /* a minimalist set of CSS resets */ 2 | 3 | @import url("https://cdn.jsdelivr.net/npm/normalize.css@8.0.1/normalize.css"); 4 | @import url("lecture_header.css"); 5 | @import url("newdefault.css"); 6 | 7 | /* @import url('https://cdn.jsdelivr.net/gh/fonsp/Pluto.jl@0.18.0/frontend/vollkorn.css'); */ 8 | /* @import url('https://fonts.googleapis.com/css2?family=Jaldi:wght@400;700&display=swap'); */ 9 | /* @import url('https://fonts.googleapis.com/css2?family=Jaldi:wght@400;700&family=Work+Sans:ital,wght@0,400;0,500;0,600;0,700;0,800;0,900;1,400;1,500;1,600;1,700;1,800;1,900&family=Yantramanav:wght@400;500;700;900&display=swap'); */ 10 | 11 | *, 12 | *:before, 13 | *:after { 14 | box-sizing: inherit; 15 | } 16 | 17 | :root { 18 | --system-fonts: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Cantarell, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji", 19 | "Segoe UI Symbol", system-ui, sans-serif; 20 | --system-fonts-mono: Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; 21 | 22 | --fg: #000; 23 | --faded-1: #858585; 24 | --faded-2: rgb(161, 161, 161); 25 | --sidebar-accent-1: #c89393; 26 | --search-bg: hsl(78deg 10% 85%); 27 | --search-bg-accent: #f4f4f5; 28 | 29 | --track-bg: hsl(56 50% 94% / 1); 30 | --track-bg-accent: #a3987c; 31 | } 32 | 33 | @media (prefers-color-scheme: dark) { 34 | :root { 35 | --fg: #ddd; 36 | --faded-1: #b3b3b3; 37 | --faded-2: #999999; 38 | 39 | --sidebar-accent-1: #d0a493; 40 | --search-bg: #363b33; 41 | --search-bg-accent: #4d6542; 42 | 43 | --track-bg: #545346; 44 | --track-bg-accent: #dad1b9; 45 | } 46 | } 47 | 48 | /* adjust typography defaults */ 49 | body { 50 | margin: 0; 51 | padding: 0; 52 | /* font-family: Noto; */ 53 | /* font-family: sans-serif; */ 54 | /* font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", sans-serif; */ 55 | width: 100vw; 56 | overflow-x: hidden; 57 | background: hsl(235deg 19% 16%); 58 | color: var(--pluto-output-color); 59 | 60 | /* background: url(bg.svg); */ 61 | /* background-color: hsl(231deg 14% 57%); */ 62 | /* background-size: cover; */ 63 | word-break: break-word; 64 | } 65 | 66 | .pages-markdown p, 67 | .pages-markdown ol { 68 | line-height: 1.5; 69 | } 70 | 71 | .pages-markdown h1, 72 | .pages-markdown h2 { 73 | font-weight: 800; 74 | } 75 | 76 | .pages-markdown h1, 77 | .pages-markdown h2, 78 | .pages-markdown h3, 79 | .pages-markdown h4, 80 | .pages-markdown h5, 81 | .pages-markdown h6 { 82 | color: var(--pluto-output-h-color); 83 | } 84 | 85 | pre { 86 | tab-size: 4; 87 | white-space: pre-wrap; 88 | word-break: break-word; 89 | } 90 | 91 | pre, 92 | code { 93 | font-family: var(--system-fonts-mono); 94 | } 95 | 96 | /* images and videos max out at full width */ 97 | img, 98 | video { 99 | height: auto; 100 | max-width: 100%; 101 | } 102 | 103 | a { 104 | font-weight: 500; 105 | text-decoration: none; 106 | } 107 | .pages-markdown a, 108 | .pages-markdown a:visited { 109 | color: #4674bc; 110 | } 111 | a:hover { 112 | text-decoration: underline; 113 | } 114 | h1 a, 115 | h2 a, 116 | h3 a { 117 | font-weight: inherit; 118 | } 119 | 120 | a.arrow::after { 121 | content: " →"; 122 | } 123 | card-text > a.arrow { 124 | margin-top: auto; 125 | } 126 | 127 | /* SIDEBAR LOGO */ 128 | 129 | a.pluto_home_link img { 130 | height: 1.2em; 131 | width: 1.2em; 132 | } 133 | a.pluto_home_link { 134 | font-size: 1.7em; 135 | font-weight: 800; 136 | color: inherit; 137 | padding: 0.3em; 138 | display: flex; 139 | flex-direction: row; 140 | align-items: center; 141 | gap: 0.5ch; 142 | } 143 | 144 | .sidebar-about .logos { 145 | display: flex; 146 | flex-direction: row; 147 | gap: 1em; 148 | padding: 1em; 149 | align-items: center; 150 | } 151 | 152 | .sidebar-about .logos picture { 153 | flex: 1 1 auto; 154 | min-width: 0; 155 | height: auto; 156 | object-fit: contain; 157 | } 158 | 159 | .sidebar-about .course-numbers { 160 | opacity: 0.6; 161 | } 162 | .sidebar-about .course-numbers > span { 163 | font-family: var(--system-fonts-mono); 164 | font-size: 0.9em; 165 | } 166 | .sidebar-about .course-numbers::before { 167 | /* content: " | "; */ 168 | } 169 | 170 | .semester-details, 171 | .authors { 172 | border-radius: var(--border-radius); 173 | padding: var(--child-padding); 174 | } 175 | .semester-details > a { 176 | font-weight: 700; 177 | } 178 | 179 | #pages-sidebar h1 { 180 | font-size: 1.4rem; 181 | margin-block-end: 0px; 182 | margin: 0; /* line-height: 1; */ 183 | } 184 | 185 | #pages-sidebar h2 { 186 | font-size: 1rem; 187 | font-weight: 500; 188 | font-style: italic; 189 | opacity: 0.8; 190 | margin-block-start: 0.2em; 191 | } 192 | 193 | .authors { 194 | color: var(--faded-2); 195 | } 196 | .authors { 197 | color: var(--faded-2); 198 | } 199 | #pages-sidebar .authors > a { 200 | color: var(--fg); 201 | } 202 | 203 | .search-result strong { 204 | --bg-color: #73731e94; 205 | background: var(--bg-color); 206 | outline: 0.15em solid var(--bg-color); 207 | border-radius: 0.1em; 208 | } 209 | 210 | #pages-sidebar .search-bar form { 211 | display: flex; 212 | flex-direction: row; 213 | } 214 | #pages-sidebar .search-bar input[type="search"] { 215 | flex: 1 1 auto; 216 | min-width: 0px; 217 | } 218 | 219 | a.search-result, 220 | a.search-result:visited { 221 | color: inherit; 222 | display: block; 223 | text-decoration: none; 224 | background: var(--search-bg); 225 | padding: 0.7rem; 226 | margin: 2rem 1rem 2rem 0rem; 227 | --br: 0.4em; 228 | border-radius: var(--br); 229 | position: relative; 230 | } 231 | 232 | .search-result h3 { 233 | margin-block-start: 0; 234 | } 235 | 236 | .search-result .tags { 237 | opacity: 0.6; 238 | font-family: var(--system-fonts-mono); 239 | } 240 | 241 | a.search-result::before { 242 | content: ""; 243 | display: block; 244 | position: absolute; 245 | z-index: -1; 246 | --off: -3px; 247 | top: var(--off); 248 | right: var(--off); 249 | left: var(--off); 250 | bottom: var(--off); 251 | background: var(--search-bg-accent); 252 | transform: rotate(356.9deg) translate(0px, 0px); 253 | border-radius: var(--br); 254 | } 255 | 256 | .student-feedback .card { 257 | box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2); 258 | margin: 1rem 0rem; 259 | border-radius: 0.4rem; 260 | padding: 0.2rem 1rem; 261 | } 262 | 263 | @media (prefers-color-scheme: dark) { 264 | .student-feedback .card { 265 | background: #4b4b4b; 266 | } 267 | } 268 | .student-feedback .card-container { 269 | padding: 4px 16px; 270 | } 271 | .student-feedback .card-container::after, 272 | .student-feedback .row::after { 273 | content: ""; 274 | clear: both; 275 | display: table; 276 | } 277 | .student-feedback .semester { 278 | opacity: 0.6; 279 | } 280 | .student-feedback .feedback { 281 | /* margin-top: 0.5em; */ 282 | } 283 | 284 | .student-feedback { 285 | margin-bottom: 4rem; 286 | } 287 | 288 | blockquote.twitter-tweet { 289 | margin: 0rem; 290 | } 291 | 292 | /* modify Pluto's styles to avoid a visual glitch. This will make the header always display fixed at the top. */ 293 | 294 | body:not(.asdfsdfa) pluto-editor:not(.asdffdas) header#pluto-nav { 295 | position: fixed; 296 | top: 0; 297 | left: 56px; 298 | right: 56px; 299 | z-index: 1998; 300 | width: auto; 301 | border-radius: 0 0 10px 10px; 302 | } 303 | 304 | /* Make space for the Pluto header */ 305 | body.binder:not(.offer_binder) { 306 | padding-top: 60px; 307 | } 308 | 309 | /* Another strategy: leave the header in place but make the export menu hidden when it is not opened. */ 310 | /* 311 | header.show_export aside#export { 312 | visibility: initial; 313 | } 314 | 315 | aside#export { 316 | visibility: hidden; 317 | } */ 318 | -------------------------------------------------------------------------------- /src/exercises/exercise_3_type_stability.jl: -------------------------------------------------------------------------------- 1 | ### A Pluto.jl notebook ### 2 | # v0.20.13 3 | 4 | #> [frontmatter] 5 | #> order = "3.2" 6 | #> exercise_number = "3" 7 | #> title = "Type-stability" 8 | #> tags = ["module1", "track_parallel", "exercises"] 9 | #> layout = "layout.jlhtml" 10 | #> description = "sample exercise" 11 | 12 | using Markdown 13 | using InteractiveUtils 14 | 15 | # ╔═╡ 56f4e39a-24fc-11f0-0ca8-d165077e3024 16 | using BenchmarkTools 17 | 18 | # ╔═╡ d3e99111-ed4e-4300-a8e5-461b3f5f435f 19 | md""" 20 | ## Type-stability 21 | 22 | One way to optimize code in Julia is to ensure type stability. If the type(s) of some variables in a function are subject to change or ambiguity, the compiler cannot reason as well about those variables, and performance will take a hit. Conversely, we allow the compiler to optimize and generate more efficient machine code when we declare variables so that their types will be fixed throughout the function body. 23 | 24 | For example, let's say we had functions called `baz` and `bar` with the following definitions 25 | """ 26 | 27 | # ╔═╡ af6027cf-1a1c-49f7-8738-1a212504f1b0 28 | function baz() 29 | s = rand() 30 | if s > 2/3 31 | return .666667 32 | elseif s > 1/3 33 | return 1//3 34 | else 35 | return 0 36 | end 37 | end 38 | 39 | # ╔═╡ cc38d8fd-fdaa-4391-b68b-fab20d63d20c 40 | function bar() 41 | s = rand() 42 | if s > 2/3 43 | return .666667 44 | elseif s > 1/3 45 | return .3333333 46 | else 47 | return 0.0 48 | end 49 | end 50 | 51 | # ╔═╡ da76d161-644a-4be2-b379-741799540cfe 52 | @benchmark baz() 53 | 54 | # ╔═╡ ed14feba-cbed-4bdc-a343-985e6655f5f5 55 | @benchmark bar() 56 | 57 | # ╔═╡ d2057241-fda7-4565-bffe-4b927ee7e265 58 | md""" 59 | I see that `bar` is almost three times as fast as `baz!` The reason is that `bar` is type stable while `baz` is not: the compiler can tell that `bar` will always return a `Float64`, whereas `baz` could return a `Float64`, an `Int`, or a `Rational`. When the compiler can tell what the types of outputs from a function, or variables declared within a function are without running the code, it can do much better. 60 | """ 61 | 62 | # ╔═╡ 33ef979b-9ff6-4ecb-afc4-af72d9678388 63 | Base.return_types(baz) 64 | 65 | # ╔═╡ a061ee77-7e86-4040-9899-678e870e7ef8 66 | Base.return_types(bar) 67 | 68 | # ╔═╡ 77ce1801-fca6-49bc-b79f-fb5b68884ac1 69 | md""" 70 | ### Exercise 1 71 | 72 | The following definition for `my_sum` is not type stable. 73 | 74 | ```julia 75 | function my_sum(A) 76 | output = 0 77 | for x in A 78 | output += x 79 | end 80 | return output 81 | end 82 | ``` 83 | 84 | Copy and execute the above code into a new cell. Benchmark it using A = rand(10^3). Then write a new function called `my_sum2` with the same function body as `my_sum`. Update `my_sum2` to make it type stable, and benchmark it for a randomly populated array with 10^3 entries. 85 | 86 | How much does type stability impact performance? If you'd like, try this same exercise for multiple sizes of `A` to see if this changes your answer! 87 | """ 88 | 89 | # ╔═╡ cf7f150b-7869-4ae0-aeec-8987ba4949db 90 | md""" 91 | ### Exercise 2 92 | 93 | Make the following code type stable. You'll know your efforts are paying off when you see a performance boost! ​ 94 | 95 | ```julia 96 | # Calculate the square root of `x` with Newton's method. 97 | function my_sqrt(x) 98 | output = 1 99 | for i in 1:1000 100 | output = .5 * (output + x/output) 101 | end 102 | output 103 | end 104 | ``` 105 | """ 106 | 107 | 108 | # ╔═╡ 00000000-0000-0000-0000-000000000001 109 | PLUTO_PROJECT_TOML_CONTENTS = """ 110 | [deps] 111 | BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" 112 | 113 | [compat] 114 | BenchmarkTools = "~1.6.0" 115 | """ 116 | 117 | # ╔═╡ 00000000-0000-0000-0000-000000000002 118 | PLUTO_MANIFEST_TOML_CONTENTS = """ 119 | # This file is machine-generated - editing it directly is not advised 120 | 121 | julia_version = "1.11.5" 122 | manifest_format = "2.0" 123 | project_hash = "2a7392fbc86bcb1608a6d4c3fafc922aa7051ef7" 124 | 125 | [[deps.Artifacts]] 126 | uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" 127 | version = "1.11.0" 128 | 129 | [[deps.BenchmarkTools]] 130 | deps = ["Compat", "JSON", "Logging", "Printf", "Profile", "Statistics", "UUIDs"] 131 | git-tree-sha1 = "e38fbc49a620f5d0b660d7f543db1009fe0f8336" 132 | uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" 133 | version = "1.6.0" 134 | 135 | [[deps.Compat]] 136 | deps = ["TOML", "UUIDs"] 137 | git-tree-sha1 = "8ae8d32e09f0dcf42a36b90d4e17f5dd2e4c4215" 138 | uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" 139 | version = "4.16.0" 140 | weakdeps = ["Dates", "LinearAlgebra"] 141 | 142 | [deps.Compat.extensions] 143 | CompatLinearAlgebraExt = "LinearAlgebra" 144 | 145 | [[deps.CompilerSupportLibraries_jll]] 146 | deps = ["Artifacts", "Libdl"] 147 | uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" 148 | version = "1.1.1+0" 149 | 150 | [[deps.Dates]] 151 | deps = ["Printf"] 152 | uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" 153 | version = "1.11.0" 154 | 155 | [[deps.JSON]] 156 | deps = ["Dates", "Mmap", "Parsers", "Unicode"] 157 | git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" 158 | uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" 159 | version = "0.21.4" 160 | 161 | [[deps.Libdl]] 162 | uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" 163 | version = "1.11.0" 164 | 165 | [[deps.LinearAlgebra]] 166 | deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] 167 | uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" 168 | version = "1.11.0" 169 | 170 | [[deps.Logging]] 171 | uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" 172 | version = "1.11.0" 173 | 174 | [[deps.Mmap]] 175 | uuid = "a63ad114-7e13-5084-954f-fe012c677804" 176 | version = "1.11.0" 177 | 178 | [[deps.OpenBLAS_jll]] 179 | deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] 180 | uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" 181 | version = "0.3.27+1" 182 | 183 | [[deps.Parsers]] 184 | deps = ["Dates", "PrecompileTools", "UUIDs"] 185 | git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" 186 | uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" 187 | version = "2.8.3" 188 | 189 | [[deps.PrecompileTools]] 190 | deps = ["Preferences"] 191 | git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" 192 | uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" 193 | version = "1.2.1" 194 | 195 | [[deps.Preferences]] 196 | deps = ["TOML"] 197 | git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" 198 | uuid = "21216c6a-2e73-6563-6e65-726566657250" 199 | version = "1.4.3" 200 | 201 | [[deps.Printf]] 202 | deps = ["Unicode"] 203 | uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" 204 | version = "1.11.0" 205 | 206 | [[deps.Profile]] 207 | uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" 208 | version = "1.11.0" 209 | 210 | [[deps.Random]] 211 | deps = ["SHA"] 212 | uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" 213 | version = "1.11.0" 214 | 215 | [[deps.SHA]] 216 | uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" 217 | version = "0.7.0" 218 | 219 | [[deps.Statistics]] 220 | deps = ["LinearAlgebra"] 221 | git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" 222 | uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" 223 | version = "1.11.1" 224 | 225 | [deps.Statistics.extensions] 226 | SparseArraysExt = ["SparseArrays"] 227 | 228 | [deps.Statistics.weakdeps] 229 | SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" 230 | 231 | [[deps.TOML]] 232 | deps = ["Dates"] 233 | uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" 234 | version = "1.0.3" 235 | 236 | [[deps.UUIDs]] 237 | deps = ["Random", "SHA"] 238 | uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" 239 | version = "1.11.0" 240 | 241 | [[deps.Unicode]] 242 | uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" 243 | version = "1.11.0" 244 | 245 | [[deps.libblastrampoline_jll]] 246 | deps = ["Artifacts", "Libdl"] 247 | uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" 248 | version = "5.11.0+0" 249 | """ 250 | 251 | # ╔═╡ Cell order: 252 | # ╠═56f4e39a-24fc-11f0-0ca8-d165077e3024 253 | # ╟─d3e99111-ed4e-4300-a8e5-461b3f5f435f 254 | # ╠═af6027cf-1a1c-49f7-8738-1a212504f1b0 255 | # ╠═cc38d8fd-fdaa-4391-b68b-fab20d63d20c 256 | # ╠═da76d161-644a-4be2-b379-741799540cfe 257 | # ╠═ed14feba-cbed-4bdc-a343-985e6655f5f5 258 | # ╟─d2057241-fda7-4565-bffe-4b927ee7e265 259 | # ╠═33ef979b-9ff6-4ecb-afc4-af72d9678388 260 | # ╠═a061ee77-7e86-4040-9899-678e870e7ef8 261 | # ╟─77ce1801-fca6-49bc-b79f-fb5b68884ac1 262 | # ╟─cf7f150b-7869-4ae0-aeec-8987ba4949db 263 | # ╟─00000000-0000-0000-0000-000000000001 264 | # ╟─00000000-0000-0000-0000-000000000002 265 | -------------------------------------------------------------------------------- /src/_includes/layout.jlhtml: -------------------------------------------------------------------------------- 1 | $(begin 2 | import Pluto 3 | "The contents of `` from a Pluto HTML export." 4 | const pluto_head = let 5 | default = Pluto.generate_html(; 6 | pluto_cdn_root=Pluto.PLUTO_VERSION < v"0.19" ? "https://cdn.jsdelivr.net/gh/fonsp/Pluto.jl@9ca70c36/frontend/" : nothing) 7 | m = match(r"(.*)"s, default) 8 | reduce([ 9 | # r""s 10 | r"" 11 | r"" 12 | r"" 13 | r"" 14 | ]; init=m[1]) do s,r 15 | replace(s, r => "") 16 | end |> HTML 17 | end 18 | 19 | f(x,y) = get(page.output.frontmatter, x, y) 20 | 21 | function section_number(frontmatter) 22 | ch = get(frontmatter, "chapter", nothing) 23 | se = get(frontmatter, "section", nothing) 24 | 25 | isnothing(ch) || isnothing(se) ? nothing : "$(ch).$(se)" 26 | end 27 | 28 | nothing 29 | end) 30 | 31 | 32 | $(f("title", splitext(basename(page.input.relative_path))[1])) — $(metadata["course_info"]["course_name"]) 33 | $(let d = f("description", nothing) 34 | if d !== nothing 35 | @htl("""""") 36 | end 37 | end) 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | $(pluto_head) 62 | 63 | 64 | 65 |
66 | 67 | 180 |
181 | $(isempty(f("title", "")) ? nothing : @htl("""
182 | $(if !isempty(f("exercise_number", "")) 183 | @htl("""

Exercise $(f("exercise_number", ""))

""") 184 | elseif !isempty(f("indepth_number", "")) 185 | @htl("""

In-depth $(f("indepth_number", ""))

""") 186 | elseif !isempty(f("chapter", "")) && !isempty(f("section", "")) 187 | @htl("""

Section $(f("chapter", "-")).$(f("section", "-"))

""") 188 | else 189 | nothing 190 | end) 191 |

$( 192 | f("title", basename(page.input.relative_path)) 193 | )

194 | 195 | $(!isempty(f("youtube_id", "")) ? @htl(""" 196 |
197 | 198 |

Lecture Video

199 |
200 | 201 |
202 |
203 | """) : nothing) 204 |
""")) 205 | $(content) 206 |
207 | 211 |
212 |
213 |
214 | 215 | 216 | -------------------------------------------------------------------------------- /src/exercises/exercise_8_github.jl: -------------------------------------------------------------------------------- 1 | ### A Pluto.jl notebook ### 2 | # v0.20.13 3 | 4 | #> [frontmatter] 5 | #> order = "5.1" 6 | #> exercise_number = "8" 7 | #> title = "Github" 8 | #> tags = ["module2", "track_principles", "exercises"] 9 | #> license = "MIT" 10 | #> layout = "layout.jlhtml" 11 | #> description = "sample exercise" 12 | #> 13 | #> [[frontmatter.author]] 14 | #> name = "Valentin Churavy" 15 | #> image = "https://avatars.githubusercontent.com/u/145258?v=4" 16 | #> url = "https://vchuravy.dev" 17 | 18 | using Markdown 19 | using InteractiveUtils 20 | 21 | # ╔═╡ fe97db1b-5fe4-45ad-bf7d-f13d333772fc 22 | begin 23 | using PlutoTeachingTools, PlutoUI 24 | using PlutoUI: Slider 25 | PlutoUI.TableOfContents(; depth=4) 26 | end 27 | 28 | # ╔═╡ 26f81c4d-fa00-444a-91e9-ead4965ed7a0 29 | md""" 30 | # Exercise: Github 31 | """ 32 | 33 | # ╔═╡ 61f44406-d9ce-4775-89af-c2351cc9c738 34 | md""" 35 | ## Learn Git Branching 36 | 37 | [Learn Git Branching](https://learngitbranching.js.org/) is a niffty little website to explore Git concepts. If you want you may spend a few minutes exploring it. 38 | """ 39 | 40 | # ╔═╡ 2eaa476a-d74a-4edf-b7ca-b20367e01cc9 41 | md""" 42 | ## Getting started on Github 43 | 44 | 1. Create a Github account 45 | 2. On Windows: 46 | - I have few personal experiences, but I suspect you might want to stick to Github Desktop or the VSCode integration 47 | 3. On Mac/Linux: 48 | - Optional: Setup a SSH key https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent 49 | """ 50 | 51 | # ╔═╡ 1eecc02d-40ec-4a00-a77f-adeb1a68a800 52 | md""" 53 | ## Setup a repository for your Project 54 | 55 | - Minimum features: 56 | - README.md 57 | - LICENSE.md 58 | - .gitignore 59 | - Most likely: 60 | - Basic Julia project structure 61 | - `src/` 62 | - Project.toml 63 | - Julia focused CI infrastructure 64 | - Tests 65 | - Documentation 66 | - Benchmarking 67 | """ 68 | 69 | # ╔═╡ 145489d8-8297-45d1-a298-763da9103267 70 | md""" 71 | ## Contribute to another Github repository 72 | 73 | - Grab a friend/neighbor and open a pull-request to their repository 74 | """ 75 | 76 | # ╔═╡ 00000000-0000-0000-0000-000000000001 77 | PLUTO_PROJECT_TOML_CONTENTS = """ 78 | [deps] 79 | PlutoTeachingTools = "661c6b06-c737-4d37-b85c-46df65de6f69" 80 | PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8" 81 | 82 | [compat] 83 | PlutoTeachingTools = "~0.4.1" 84 | PlutoUI = "~0.7.65" 85 | """ 86 | 87 | # ╔═╡ 00000000-0000-0000-0000-000000000002 88 | PLUTO_MANIFEST_TOML_CONTENTS = """ 89 | # This file is machine-generated - editing it directly is not advised 90 | 91 | julia_version = "1.11.5" 92 | manifest_format = "2.0" 93 | project_hash = "63c6081505b9e3340ca9775b44b1baa456cbd34d" 94 | 95 | [[deps.AbstractPlutoDingetjes]] 96 | deps = ["Pkg"] 97 | git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" 98 | uuid = "6e696c72-6542-2067-7265-42206c756150" 99 | version = "1.3.2" 100 | 101 | [[deps.ArgTools]] 102 | uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" 103 | version = "1.1.2" 104 | 105 | [[deps.Artifacts]] 106 | uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" 107 | version = "1.11.0" 108 | 109 | [[deps.Base64]] 110 | uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" 111 | version = "1.11.0" 112 | 113 | [[deps.ColorTypes]] 114 | deps = ["FixedPointNumbers", "Random"] 115 | git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" 116 | uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" 117 | version = "0.12.1" 118 | 119 | [deps.ColorTypes.extensions] 120 | StyledStringsExt = "StyledStrings" 121 | 122 | [deps.ColorTypes.weakdeps] 123 | StyledStrings = "f489334b-da3d-4c2e-b8f0-e476e12c162b" 124 | 125 | [[deps.CompilerSupportLibraries_jll]] 126 | deps = ["Artifacts", "Libdl"] 127 | uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" 128 | version = "1.1.1+0" 129 | 130 | [[deps.Dates]] 131 | deps = ["Printf"] 132 | uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" 133 | version = "1.11.0" 134 | 135 | [[deps.Downloads]] 136 | deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] 137 | uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" 138 | version = "1.6.0" 139 | 140 | [[deps.FileWatching]] 141 | uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" 142 | version = "1.11.0" 143 | 144 | [[deps.FixedPointNumbers]] 145 | deps = ["Statistics"] 146 | git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" 147 | uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" 148 | version = "0.8.5" 149 | 150 | [[deps.Format]] 151 | git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" 152 | uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" 153 | version = "1.3.7" 154 | 155 | [[deps.Hyperscript]] 156 | deps = ["Test"] 157 | git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" 158 | uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" 159 | version = "0.0.5" 160 | 161 | [[deps.HypertextLiteral]] 162 | deps = ["Tricks"] 163 | git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" 164 | uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" 165 | version = "0.9.5" 166 | 167 | [[deps.IOCapture]] 168 | deps = ["Logging", "Random"] 169 | git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" 170 | uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" 171 | version = "0.2.5" 172 | 173 | [[deps.InteractiveUtils]] 174 | deps = ["Markdown"] 175 | uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" 176 | version = "1.11.0" 177 | 178 | [[deps.JSON]] 179 | deps = ["Dates", "Mmap", "Parsers", "Unicode"] 180 | git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" 181 | uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" 182 | version = "0.21.4" 183 | 184 | [[deps.LaTeXStrings]] 185 | git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" 186 | uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" 187 | version = "1.4.0" 188 | 189 | [[deps.Latexify]] 190 | deps = ["Format", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] 191 | git-tree-sha1 = "4f34eaabe49ecb3fb0d58d6015e32fd31a733199" 192 | uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" 193 | version = "0.16.8" 194 | 195 | [deps.Latexify.extensions] 196 | DataFramesExt = "DataFrames" 197 | SparseArraysExt = "SparseArrays" 198 | SymEngineExt = "SymEngine" 199 | TectonicExt = "tectonic_jll" 200 | 201 | [deps.Latexify.weakdeps] 202 | DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" 203 | SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" 204 | SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" 205 | tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" 206 | 207 | [[deps.LibCURL]] 208 | deps = ["LibCURL_jll", "MozillaCACerts_jll"] 209 | uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" 210 | version = "0.6.4" 211 | 212 | [[deps.LibCURL_jll]] 213 | deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] 214 | uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" 215 | version = "8.6.0+0" 216 | 217 | [[deps.LibGit2]] 218 | deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] 219 | uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" 220 | version = "1.11.0" 221 | 222 | [[deps.LibGit2_jll]] 223 | deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] 224 | uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" 225 | version = "1.7.2+0" 226 | 227 | [[deps.LibSSH2_jll]] 228 | deps = ["Artifacts", "Libdl", "MbedTLS_jll"] 229 | uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" 230 | version = "1.11.0+1" 231 | 232 | [[deps.Libdl]] 233 | uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" 234 | version = "1.11.0" 235 | 236 | [[deps.LinearAlgebra]] 237 | deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] 238 | uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" 239 | version = "1.11.0" 240 | 241 | [[deps.Logging]] 242 | uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" 243 | version = "1.11.0" 244 | 245 | [[deps.MIMEs]] 246 | git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691" 247 | uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" 248 | version = "1.1.0" 249 | 250 | [[deps.MacroTools]] 251 | git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" 252 | uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" 253 | version = "0.5.16" 254 | 255 | [[deps.Markdown]] 256 | deps = ["Base64"] 257 | uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" 258 | version = "1.11.0" 259 | 260 | [[deps.MbedTLS_jll]] 261 | deps = ["Artifacts", "Libdl"] 262 | uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" 263 | version = "2.28.6+0" 264 | 265 | [[deps.Mmap]] 266 | uuid = "a63ad114-7e13-5084-954f-fe012c677804" 267 | version = "1.11.0" 268 | 269 | [[deps.MozillaCACerts_jll]] 270 | uuid = "14a3606d-f60d-562e-9121-12d972cd8159" 271 | version = "2023.12.12" 272 | 273 | [[deps.NetworkOptions]] 274 | uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" 275 | version = "1.2.0" 276 | 277 | [[deps.OpenBLAS_jll]] 278 | deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] 279 | uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" 280 | version = "0.3.27+1" 281 | 282 | [[deps.OrderedCollections]] 283 | git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" 284 | uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" 285 | version = "1.8.1" 286 | 287 | [[deps.Parsers]] 288 | deps = ["Dates", "PrecompileTools", "UUIDs"] 289 | git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" 290 | uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" 291 | version = "2.8.3" 292 | 293 | [[deps.Pkg]] 294 | deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] 295 | uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" 296 | version = "1.11.0" 297 | 298 | [deps.Pkg.extensions] 299 | REPLExt = "REPL" 300 | 301 | [deps.Pkg.weakdeps] 302 | REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" 303 | 304 | [[deps.PlutoTeachingTools]] 305 | deps = ["Downloads", "HypertextLiteral", "Latexify", "Markdown", "PlutoUI"] 306 | git-tree-sha1 = "537c439831c0f8d37265efe850ee5c0d9c7efbe4" 307 | uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" 308 | version = "0.4.1" 309 | 310 | [[deps.PlutoUI]] 311 | deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] 312 | git-tree-sha1 = "3151a0c8061cc3f887019beebf359e6c4b3daa08" 313 | uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" 314 | version = "0.7.65" 315 | 316 | [[deps.PrecompileTools]] 317 | deps = ["Preferences"] 318 | git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" 319 | uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" 320 | version = "1.2.1" 321 | 322 | [[deps.Preferences]] 323 | deps = ["TOML"] 324 | git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" 325 | uuid = "21216c6a-2e73-6563-6e65-726566657250" 326 | version = "1.4.3" 327 | 328 | [[deps.Printf]] 329 | deps = ["Unicode"] 330 | uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" 331 | version = "1.11.0" 332 | 333 | [[deps.Random]] 334 | deps = ["SHA"] 335 | uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" 336 | version = "1.11.0" 337 | 338 | [[deps.Reexport]] 339 | git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" 340 | uuid = "189a3867-3050-52da-a836-e630ba90ab69" 341 | version = "1.2.2" 342 | 343 | [[deps.Requires]] 344 | deps = ["UUIDs"] 345 | git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" 346 | uuid = "ae029012-a4dd-5104-9daa-d747884805df" 347 | version = "1.3.1" 348 | 349 | [[deps.SHA]] 350 | uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" 351 | version = "0.7.0" 352 | 353 | [[deps.Serialization]] 354 | uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" 355 | version = "1.11.0" 356 | 357 | [[deps.Statistics]] 358 | deps = ["LinearAlgebra"] 359 | git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" 360 | uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" 361 | version = "1.11.1" 362 | 363 | [deps.Statistics.extensions] 364 | SparseArraysExt = ["SparseArrays"] 365 | 366 | [deps.Statistics.weakdeps] 367 | SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" 368 | 369 | [[deps.TOML]] 370 | deps = ["Dates"] 371 | uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" 372 | version = "1.0.3" 373 | 374 | [[deps.Tar]] 375 | deps = ["ArgTools", "SHA"] 376 | uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" 377 | version = "1.10.0" 378 | 379 | [[deps.Test]] 380 | deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] 381 | uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" 382 | version = "1.11.0" 383 | 384 | [[deps.Tricks]] 385 | git-tree-sha1 = "6cae795a5a9313bbb4f60683f7263318fc7d1505" 386 | uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" 387 | version = "0.1.10" 388 | 389 | [[deps.URIs]] 390 | git-tree-sha1 = "24c1c558881564e2217dcf7840a8b2e10caeb0f9" 391 | uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" 392 | version = "1.6.0" 393 | 394 | [[deps.UUIDs]] 395 | deps = ["Random", "SHA"] 396 | uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" 397 | version = "1.11.0" 398 | 399 | [[deps.Unicode]] 400 | uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" 401 | version = "1.11.0" 402 | 403 | [[deps.Zlib_jll]] 404 | deps = ["Libdl"] 405 | uuid = "83775a58-1f1d-513f-b197-d71354ab007a" 406 | version = "1.2.13+1" 407 | 408 | [[deps.libblastrampoline_jll]] 409 | deps = ["Artifacts", "Libdl"] 410 | uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" 411 | version = "5.11.0+0" 412 | 413 | [[deps.nghttp2_jll]] 414 | deps = ["Artifacts", "Libdl"] 415 | uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" 416 | version = "1.59.0+0" 417 | 418 | [[deps.p7zip_jll]] 419 | deps = ["Artifacts", "Libdl"] 420 | uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" 421 | version = "17.4.0+2" 422 | """ 423 | 424 | # ╔═╡ Cell order: 425 | # ╟─fe97db1b-5fe4-45ad-bf7d-f13d333772fc 426 | # ╟─26f81c4d-fa00-444a-91e9-ead4965ed7a0 427 | # ╟─61f44406-d9ce-4775-89af-c2351cc9c738 428 | # ╟─2eaa476a-d74a-4edf-b7ca-b20367e01cc9 429 | # ╟─1eecc02d-40ec-4a00-a77f-adeb1a68a800 430 | # ╟─145489d8-8297-45d1-a298-763da9103267 431 | # ╟─00000000-0000-0000-0000-000000000001 432 | # ╟─00000000-0000-0000-0000-000000000002 433 | -------------------------------------------------------------------------------- /src/exercises/exercise_14_ml.jl: -------------------------------------------------------------------------------- 1 | ### A Pluto.jl notebook ### 2 | # v0.20.13 3 | 4 | #> [frontmatter] 5 | #> order = "11.2" 6 | #> exercise_number = "14" 7 | #> chapter = "4" 8 | #> section = "1" 9 | #> title = "Reverse mode AD" 10 | #> tags = ["module4", "track_ad", "exercises"] 11 | #> license = "MIT" 12 | #> layout = "layout.jlhtml" 13 | #> description = "sample exercise" 14 | #> 15 | #> [[frontmatter.author]] 16 | #> name = "Valentin Churavy" 17 | #> image = "https://avatars.githubusercontent.com/u/145258?v=4" 18 | #> url = "https://vchuravy.dev" 19 | 20 | using Markdown 21 | using InteractiveUtils 22 | 23 | # ╔═╡ fcbaac1e-19e9-4537-bb6b-6cd9625b3359 24 | using UnicodePlots 25 | 26 | # ╔═╡ 51bc9468-a61a-438c-b73d-3d2145f50f21 27 | md""" 28 | $x_j = b_j + \sum_i w_{ij} * x_i$ 29 | """ 30 | 31 | # ╔═╡ f8c6ade2-5196-11f0-34f7-7fa61b2cb26c 32 | function perceptron(inputs, weights, bias, f) 33 | f(sum(w[i] * input[i] for i in 1:length(inputs)) + bias) 34 | end 35 | 36 | # ╔═╡ ac3fdb66-def2-4f25-b29c-6f5da7643e35 37 | lineplot(-3,3, identity) 38 | 39 | # ╔═╡ 7867550c-d02f-4d25-ad37-b6765ea89bff 40 | relu(x) = max(0, x) 41 | 42 | # ╔═╡ 50662471-a138-47f6-9b4e-a277a826ec3f 43 | lineplot(-3,3, relu) 44 | 45 | # ╔═╡ 36e85e86-b2dc-42e0-a3be-20956561c9a5 46 | sigmoid(x) = 1/(1+exp(-x)) 47 | 48 | # ╔═╡ 87d4228c-1f21-43c7-97ea-a717a5412990 49 | lineplot(-3,3, sigmoid) 50 | 51 | # ╔═╡ 96689fc6-1043-430e-8525-640f97bda73f 52 | tanh(x) = (exp(x)-exp(-x))/(exp(x)+exp(-x)) 53 | 54 | # ╔═╡ 53d60247-74f0-428e-b390-8f94ea72c2fe 55 | lineplot(-3,3, tanh) 56 | 57 | # ╔═╡ 9a56c331-0894-4976-b896-823b560f026b 58 | md""" 59 | While one can define a perceptron like above, it is better to think of it in terms of matrix multiplication. 60 | """ 61 | 62 | # ╔═╡ 00a1cc5e-ef19-4230-a7c2-85da6c9181a2 63 | Ni = 10 64 | 65 | # ╔═╡ 1c8bf989-9d92-4a11-9c21-0ba8295fe45b 66 | Nn = 5 67 | 68 | # ╔═╡ 200758ea-01dd-470b-ae3e-c3085992b077 69 | x = rand(Ni) 70 | 71 | # ╔═╡ 9c9ea2aa-480e-4db8-bce9-b02bbd63122f 72 | b = rand(Nn) 73 | 74 | # ╔═╡ ae8e4d68-cb83-425a-a540-882bbecafc66 75 | W = rand(Nn, Ni) 76 | 77 | # ╔═╡ c2bb91a3-60c7-4fb5-b6aa-df60c310b285 78 | tanh.(W*x .+ b) 79 | 80 | # ╔═╡ 9bc5444c-987a-4f3d-9743-bf238084146c 81 | md""" 82 | #### Exercise 83 | 84 | - Write your own Neuronal Network model with a couple of layers (maybe 2) 85 | - Remember https://vchuravy.dev/rse-course/exercises/exercise_7_gradient_descent/ as a starting point. 86 | """ 87 | 88 | # ╔═╡ 00000000-0000-0000-0000-000000000001 89 | PLUTO_PROJECT_TOML_CONTENTS = """ 90 | [deps] 91 | UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228" 92 | 93 | [compat] 94 | UnicodePlots = "~3.8.0" 95 | """ 96 | 97 | # ╔═╡ 00000000-0000-0000-0000-000000000002 98 | PLUTO_MANIFEST_TOML_CONTENTS = """ 99 | # This file is machine-generated - editing it directly is not advised 100 | 101 | julia_version = "1.11.5" 102 | manifest_format = "2.0" 103 | project_hash = "6aca9711566244ef0bfb1b6b055ccaf250643674" 104 | 105 | [[deps.AliasTables]] 106 | deps = ["PtrArrays", "Random"] 107 | git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" 108 | uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" 109 | version = "1.1.3" 110 | 111 | [[deps.Artifacts]] 112 | uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" 113 | version = "1.11.0" 114 | 115 | [[deps.Base64]] 116 | uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" 117 | version = "1.11.0" 118 | 119 | [[deps.ColorSchemes]] 120 | deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] 121 | git-tree-sha1 = "403f2d8e209681fcbd9468a8514efff3ea08452e" 122 | uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" 123 | version = "3.29.0" 124 | 125 | [[deps.ColorTypes]] 126 | deps = ["FixedPointNumbers", "Random"] 127 | git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" 128 | uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" 129 | version = "0.12.1" 130 | 131 | [deps.ColorTypes.extensions] 132 | StyledStringsExt = "StyledStrings" 133 | 134 | [deps.ColorTypes.weakdeps] 135 | StyledStrings = "f489334b-da3d-4c2e-b8f0-e476e12c162b" 136 | 137 | [[deps.ColorVectorSpace]] 138 | deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] 139 | git-tree-sha1 = "8b3b6f87ce8f65a2b4f857528fd8d70086cd72b1" 140 | uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" 141 | version = "0.11.0" 142 | 143 | [deps.ColorVectorSpace.extensions] 144 | SpecialFunctionsExt = "SpecialFunctions" 145 | 146 | [deps.ColorVectorSpace.weakdeps] 147 | SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" 148 | 149 | [[deps.Colors]] 150 | deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] 151 | git-tree-sha1 = "37ea44092930b1811e666c3bc38065d7d87fcc74" 152 | uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" 153 | version = "0.13.1" 154 | 155 | [[deps.Compat]] 156 | deps = ["TOML", "UUIDs"] 157 | git-tree-sha1 = "8ae8d32e09f0dcf42a36b90d4e17f5dd2e4c4215" 158 | uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" 159 | version = "4.16.0" 160 | weakdeps = ["Dates", "LinearAlgebra"] 161 | 162 | [deps.Compat.extensions] 163 | CompatLinearAlgebraExt = "LinearAlgebra" 164 | 165 | [[deps.CompilerSupportLibraries_jll]] 166 | deps = ["Artifacts", "Libdl"] 167 | uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" 168 | version = "1.1.1+0" 169 | 170 | [[deps.Contour]] 171 | git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" 172 | uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" 173 | version = "0.6.3" 174 | 175 | [[deps.Crayons]] 176 | git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" 177 | uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" 178 | version = "4.1.1" 179 | 180 | [[deps.DataAPI]] 181 | git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" 182 | uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" 183 | version = "1.16.0" 184 | 185 | [[deps.DataStructures]] 186 | deps = ["Compat", "InteractiveUtils", "OrderedCollections"] 187 | git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" 188 | uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" 189 | version = "0.18.22" 190 | 191 | [[deps.Dates]] 192 | deps = ["Printf"] 193 | uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" 194 | version = "1.11.0" 195 | 196 | [[deps.DocStringExtensions]] 197 | git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" 198 | uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" 199 | version = "0.9.5" 200 | 201 | [[deps.FixedPointNumbers]] 202 | deps = ["Statistics"] 203 | git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" 204 | uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" 205 | version = "0.8.5" 206 | 207 | [[deps.InteractiveUtils]] 208 | deps = ["Markdown"] 209 | uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" 210 | version = "1.11.0" 211 | 212 | [[deps.IrrationalConstants]] 213 | git-tree-sha1 = "e2222959fbc6c19554dc15174c81bf7bf3aa691c" 214 | uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" 215 | version = "0.2.4" 216 | 217 | [[deps.Libdl]] 218 | uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" 219 | version = "1.11.0" 220 | 221 | [[deps.LinearAlgebra]] 222 | deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] 223 | uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" 224 | version = "1.11.0" 225 | 226 | [[deps.LogExpFunctions]] 227 | deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] 228 | git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" 229 | uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" 230 | version = "0.3.29" 231 | 232 | [deps.LogExpFunctions.extensions] 233 | LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" 234 | LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" 235 | LogExpFunctionsInverseFunctionsExt = "InverseFunctions" 236 | 237 | [deps.LogExpFunctions.weakdeps] 238 | ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" 239 | ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" 240 | InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" 241 | 242 | [[deps.MarchingCubes]] 243 | deps = ["PrecompileTools", "StaticArrays"] 244 | git-tree-sha1 = "0e893025924b6becbae4109f8020ac0e12674b01" 245 | uuid = "299715c1-40a9-479a-aaf9-4a633d36f717" 246 | version = "0.1.11" 247 | 248 | [[deps.Markdown]] 249 | deps = ["Base64"] 250 | uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" 251 | version = "1.11.0" 252 | 253 | [[deps.Missings]] 254 | deps = ["DataAPI"] 255 | git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" 256 | uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" 257 | version = "1.2.0" 258 | 259 | [[deps.NaNMath]] 260 | deps = ["OpenLibm_jll"] 261 | git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" 262 | uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" 263 | version = "1.1.3" 264 | 265 | [[deps.OpenBLAS_jll]] 266 | deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] 267 | uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" 268 | version = "0.3.27+1" 269 | 270 | [[deps.OpenLibm_jll]] 271 | deps = ["Artifacts", "Libdl"] 272 | uuid = "05823500-19ac-5b8b-9628-191a04bc5112" 273 | version = "0.8.5+0" 274 | 275 | [[deps.OrderedCollections]] 276 | git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" 277 | uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" 278 | version = "1.8.1" 279 | 280 | [[deps.PrecompileTools]] 281 | deps = ["Preferences"] 282 | git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" 283 | uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" 284 | version = "1.2.1" 285 | 286 | [[deps.Preferences]] 287 | deps = ["TOML"] 288 | git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" 289 | uuid = "21216c6a-2e73-6563-6e65-726566657250" 290 | version = "1.4.3" 291 | 292 | [[deps.Printf]] 293 | deps = ["Unicode"] 294 | uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" 295 | version = "1.11.0" 296 | 297 | [[deps.PtrArrays]] 298 | git-tree-sha1 = "1d36ef11a9aaf1e8b74dacc6a731dd1de8fd493d" 299 | uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" 300 | version = "1.3.0" 301 | 302 | [[deps.Random]] 303 | deps = ["SHA"] 304 | uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" 305 | version = "1.11.0" 306 | 307 | [[deps.Reexport]] 308 | git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" 309 | uuid = "189a3867-3050-52da-a836-e630ba90ab69" 310 | version = "1.2.2" 311 | 312 | [[deps.Requires]] 313 | deps = ["UUIDs"] 314 | git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" 315 | uuid = "ae029012-a4dd-5104-9daa-d747884805df" 316 | version = "1.3.1" 317 | 318 | [[deps.SHA]] 319 | uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" 320 | version = "0.7.0" 321 | 322 | [[deps.Serialization]] 323 | uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" 324 | version = "1.11.0" 325 | 326 | [[deps.SortingAlgorithms]] 327 | deps = ["DataStructures"] 328 | git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" 329 | uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" 330 | version = "1.2.1" 331 | 332 | [[deps.SparseArrays]] 333 | deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] 334 | uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" 335 | version = "1.11.0" 336 | 337 | [[deps.StaticArrays]] 338 | deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] 339 | git-tree-sha1 = "0feb6b9031bd5c51f9072393eb5ab3efd31bf9e4" 340 | uuid = "90137ffa-7385-5640-81b9-e52037218182" 341 | version = "1.9.13" 342 | 343 | [deps.StaticArrays.extensions] 344 | StaticArraysChainRulesCoreExt = "ChainRulesCore" 345 | StaticArraysStatisticsExt = "Statistics" 346 | 347 | [deps.StaticArrays.weakdeps] 348 | ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" 349 | Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" 350 | 351 | [[deps.StaticArraysCore]] 352 | git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" 353 | uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" 354 | version = "1.4.3" 355 | 356 | [[deps.Statistics]] 357 | deps = ["LinearAlgebra"] 358 | git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" 359 | uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" 360 | version = "1.11.1" 361 | weakdeps = ["SparseArrays"] 362 | 363 | [deps.Statistics.extensions] 364 | SparseArraysExt = ["SparseArrays"] 365 | 366 | [[deps.StatsAPI]] 367 | deps = ["LinearAlgebra"] 368 | git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" 369 | uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" 370 | version = "1.7.1" 371 | 372 | [[deps.StatsBase]] 373 | deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] 374 | git-tree-sha1 = "b81c5035922cc89c2d9523afc6c54be512411466" 375 | uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" 376 | version = "0.34.5" 377 | 378 | [[deps.SuiteSparse_jll]] 379 | deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] 380 | uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" 381 | version = "7.7.0+0" 382 | 383 | [[deps.TOML]] 384 | deps = ["Dates"] 385 | uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" 386 | version = "1.0.3" 387 | 388 | [[deps.TensorCore]] 389 | deps = ["LinearAlgebra"] 390 | git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" 391 | uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" 392 | version = "0.1.1" 393 | 394 | [[deps.UUIDs]] 395 | deps = ["Random", "SHA"] 396 | uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" 397 | version = "1.11.0" 398 | 399 | [[deps.Unicode]] 400 | uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" 401 | version = "1.11.0" 402 | 403 | [[deps.UnicodePlots]] 404 | deps = ["ColorSchemes", "ColorTypes", "Contour", "Crayons", "Dates", "LinearAlgebra", "MarchingCubes", "NaNMath", "PrecompileTools", "Printf", "SparseArrays", "StaticArrays", "StatsBase"] 405 | git-tree-sha1 = "de59fe48523decf3ca312cc1b56ee687f93a5b00" 406 | uuid = "b8865327-cd53-5732-bb35-84acbb429228" 407 | version = "3.8.0" 408 | 409 | [deps.UnicodePlots.extensions] 410 | FreeTypeExt = ["FileIO", "FreeType"] 411 | ImageInTerminalExt = "ImageInTerminal" 412 | IntervalSetsExt = "IntervalSets" 413 | TermExt = "Term" 414 | UnitfulExt = "Unitful" 415 | 416 | [deps.UnicodePlots.weakdeps] 417 | FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" 418 | FreeType = "b38be410-82b0-50bf-ab77-7b57e271db43" 419 | ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254" 420 | IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" 421 | Term = "22787eb5-b846-44ae-b979-8e399b8463ab" 422 | Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" 423 | 424 | [[deps.libblastrampoline_jll]] 425 | deps = ["Artifacts", "Libdl"] 426 | uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" 427 | version = "5.11.0+0" 428 | """ 429 | 430 | # ╔═╡ Cell order: 431 | # ╠═fcbaac1e-19e9-4537-bb6b-6cd9625b3359 432 | # ╟─51bc9468-a61a-438c-b73d-3d2145f50f21 433 | # ╠═f8c6ade2-5196-11f0-34f7-7fa61b2cb26c 434 | # ╠═ac3fdb66-def2-4f25-b29c-6f5da7643e35 435 | # ╠═7867550c-d02f-4d25-ad37-b6765ea89bff 436 | # ╠═50662471-a138-47f6-9b4e-a277a826ec3f 437 | # ╠═36e85e86-b2dc-42e0-a3be-20956561c9a5 438 | # ╠═87d4228c-1f21-43c7-97ea-a717a5412990 439 | # ╠═96689fc6-1043-430e-8525-640f97bda73f 440 | # ╠═53d60247-74f0-428e-b390-8f94ea72c2fe 441 | # ╠═9a56c331-0894-4976-b896-823b560f026b 442 | # ╠═00a1cc5e-ef19-4230-a7c2-85da6c9181a2 443 | # ╠═1c8bf989-9d92-4a11-9c21-0ba8295fe45b 444 | # ╠═200758ea-01dd-470b-ae3e-c3085992b077 445 | # ╠═9c9ea2aa-480e-4db8-bce9-b02bbd63122f 446 | # ╠═ae8e4d68-cb83-425a-a540-882bbecafc66 447 | # ╠═c2bb91a3-60c7-4fb5-b6aa-df60c310b285 448 | # ╟─9bc5444c-987a-4f3d-9743-bf238084146c 449 | # ╟─00000000-0000-0000-0000-000000000001 450 | # ╟─00000000-0000-0000-0000-000000000002 451 | -------------------------------------------------------------------------------- /src/exercises/exercise_1_multithreading.jl: -------------------------------------------------------------------------------- 1 | ### A Pluto.jl notebook ### 2 | # v0.20.13 3 | 4 | #> [frontmatter] 5 | #> order = "2.1" 6 | #> exercise_number = "1" 7 | #> title = "Shared-memory parallelism" 8 | #> tags = ["module1", "track_parallel", "exercises"] 9 | #> layout = "layout.jlhtml" 10 | #> description = "sample exercise" 11 | 12 | using Markdown 13 | using InteractiveUtils 14 | 15 | # ╔═╡ 75b9bee9-7d03-4c90-b828-43e9e946517b 16 | using PlutoTeachingTools, PlutoUI 17 | 18 | # ╔═╡ 8577787d-d72d-4d92-8c69-9e516a85b779 19 | ChooseDisplayMode() 20 | 21 | # ╔═╡ 3e5c3c97-4401-41d4-a701-d9b24f9acdc6 22 | PlutoUI.TableOfContents(; depth=4) 23 | 24 | # ╔═╡ 19f63d1f-99e5-4063-9af1-9c457c1cbda5 25 | md""" 26 | # Exercise: Shared-memory parallelism 27 | """ 28 | 29 | # ╔═╡ 64e33738-e7b0-4a7a-893c-69b0b48b6215 30 | md""" 31 | This notebook uses **$(Threads.nthreads()) threads** 32 | """ 33 | 34 | # ╔═╡ 2d039f15-fe74-4296-8e26-53cce9dde7c6 35 | md""" 36 | ## Parallel fibonacci 37 | 38 | Remember: 39 | 40 | ```julia 41 | t = Threads.@spawn begin # `@spawn` returns right away 42 | 3 + 3 43 | end 44 | 45 | fetch(t) # `fetch` waits for the task to finish 46 | ``` 47 | """ 48 | 49 | # ╔═╡ cbbfe10c-2131-42a0-8db7-06e7518508d9 50 | function fib(n) 51 | if n <= 1 52 | return n 53 | end 54 | return fib(n-1) + fib(n-2) 55 | end 56 | 57 | # ╔═╡ 89858748-ebe6-4d00-b09c-6cb1064e101f 58 | fib(12) 59 | 60 | # ╔═╡ 03228a70-2298-4dcd-96e8-2be48603b860 61 | # TODO: Implement pfib 62 | 63 | # ╔═╡ 031dc47b-8a1c-48a2-abe6-de88050ae1c7 64 | let 65 | if !@isdefined(pfib) 66 | func_not_defined(:pfib) 67 | elseif pfib(12) !== fib(12) 68 | keep_working(md"Your solution and the reference solution disagree!") 69 | else 70 | correct() 71 | end 72 | end 73 | 74 | # ╔═╡ 4e54a79b-4eb5-4f2d-adb4-cc4545a7930d 75 | answer_box(hint( 76 | md""" 77 | ```julia 78 | function pfib(n) 79 | if n <= 1 80 | return n 81 | end 82 | t = Threads.@spawn pfib(n-2) 83 | return pfib(n-1) + fetch(t)::Int 84 | end 85 | ``` 86 | """ 87 | )) 88 | 89 | # ╔═╡ 5d888f29-0204-4388-ab81-53aefafd5092 90 | md""" 91 | ## Multi-threaded map 92 | """ 93 | 94 | # ╔═╡ 0331dc20-fa0b-4b7f-badc-a2040795f15a 95 | using LinearAlgebra, Random 96 | 97 | # ╔═╡ 91f3684d-ed56-4ee2-b914-79ab4b6ed87a 98 | using BenchmarkTools 99 | 100 | # ╔═╡ 0c8cfee6-5edb-4400-b7cd-753c2975a1e4 101 | function tmap(fn, itr) 102 | # for each i ∈ itr, spawn a task to compute fn(i) 103 | tasks = map(i -> Threads.@spawn(fn(i)), itr) 104 | # fetch and return all the results 105 | return fetch.(tasks) 106 | end 107 | 108 | # ╔═╡ b2aecd04-115e-4aef-90d9-077aa886e70e 109 | Ms = [rand(100,100) for i in 1:(8 * Threads.nthreads())]; 110 | 111 | # ╔═╡ 4297ac26-de6b-4041-940e-531184860d84 112 | begin 113 | BLAS.set_num_threads(Sys.CPU_THREADS) # Fix number of BLAS threads 114 | # BLAS.set_num_threads(1) 115 | blas_edge = nothing 116 | end 117 | 118 | # ╔═╡ 1fe0391a-7cee-4b9a-a775-3b78335f475c 119 | begin 120 | blas_edge 121 | serial_map_svdals_b = @benchmark map(svdvals, $Ms) samples=10 evals=3 122 | end 123 | 124 | # ╔═╡ cb042477-6a3e-4940-b3e6-38511936d370 125 | begin 126 | blas_edge 127 | threaded_map_svdals_b = @benchmark tmap(svdvals, $Ms) samples=10 evals=3 128 | end 129 | 130 | # ╔═╡ 3923ae23-1000-49ab-b5a2-c31567822e5d 131 | (minimum(serial_map_svdals_b.times) / minimum(threaded_map_svdals_b.times)) / Threads.nthreads() * 100 # parallel efficiency 132 | 133 | # ╔═╡ c88229ac-c421-41e5-8db8-c62afdb54322 134 | md""" 135 | !!! note 136 | Vary the number of threads the BLAS library uses. 137 | (See the cell above with `BLAS.set_num_threads()`) 138 | """ 139 | 140 | # ╔═╡ 00000000-0000-0000-0000-000000000001 141 | PLUTO_PROJECT_TOML_CONTENTS = """ 142 | [deps] 143 | BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" 144 | LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" 145 | PlutoTeachingTools = "661c6b06-c737-4d37-b85c-46df65de6f69" 146 | PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8" 147 | Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" 148 | 149 | [compat] 150 | BenchmarkTools = "~1.6.0" 151 | PlutoTeachingTools = "~0.2.11" 152 | PlutoUI = "~0.7.51" 153 | """ 154 | 155 | # ╔═╡ 00000000-0000-0000-0000-000000000002 156 | PLUTO_MANIFEST_TOML_CONTENTS = """ 157 | # This file is machine-generated - editing it directly is not advised 158 | 159 | julia_version = "1.11.5" 160 | manifest_format = "2.0" 161 | project_hash = "af4111a530b8079da212f050883f029aa2bd1ceb" 162 | 163 | [[deps.AbstractPlutoDingetjes]] 164 | deps = ["Pkg"] 165 | git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" 166 | uuid = "6e696c72-6542-2067-7265-42206c756150" 167 | version = "1.3.2" 168 | 169 | [[deps.ArgTools]] 170 | uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" 171 | version = "1.1.2" 172 | 173 | [[deps.Artifacts]] 174 | uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" 175 | version = "1.11.0" 176 | 177 | [[deps.Base64]] 178 | uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" 179 | version = "1.11.0" 180 | 181 | [[deps.BenchmarkTools]] 182 | deps = ["Compat", "JSON", "Logging", "Printf", "Profile", "Statistics", "UUIDs"] 183 | git-tree-sha1 = "e38fbc49a620f5d0b660d7f543db1009fe0f8336" 184 | uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" 185 | version = "1.6.0" 186 | 187 | [[deps.CodeTracking]] 188 | deps = ["InteractiveUtils", "UUIDs"] 189 | git-tree-sha1 = "062c5e1a5bf6ada13db96a4ae4749a4c2234f521" 190 | uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" 191 | version = "1.3.9" 192 | 193 | [[deps.ColorTypes]] 194 | deps = ["FixedPointNumbers", "Random"] 195 | git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" 196 | uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" 197 | version = "0.12.1" 198 | weakdeps = ["StyledStrings"] 199 | 200 | [deps.ColorTypes.extensions] 201 | StyledStringsExt = "StyledStrings" 202 | 203 | [[deps.Compat]] 204 | deps = ["TOML", "UUIDs"] 205 | git-tree-sha1 = "8ae8d32e09f0dcf42a36b90d4e17f5dd2e4c4215" 206 | uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" 207 | version = "4.16.0" 208 | weakdeps = ["Dates", "LinearAlgebra"] 209 | 210 | [deps.Compat.extensions] 211 | CompatLinearAlgebraExt = "LinearAlgebra" 212 | 213 | [[deps.CompilerSupportLibraries_jll]] 214 | deps = ["Artifacts", "Libdl"] 215 | uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" 216 | version = "1.1.1+0" 217 | 218 | [[deps.Dates]] 219 | deps = ["Printf"] 220 | uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" 221 | version = "1.11.0" 222 | 223 | [[deps.Downloads]] 224 | deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] 225 | uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" 226 | version = "1.6.0" 227 | 228 | [[deps.FileWatching]] 229 | uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" 230 | version = "1.11.0" 231 | 232 | [[deps.FixedPointNumbers]] 233 | deps = ["Statistics"] 234 | git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" 235 | uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" 236 | version = "0.8.5" 237 | 238 | [[deps.Format]] 239 | git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" 240 | uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" 241 | version = "1.3.7" 242 | 243 | [[deps.Hyperscript]] 244 | deps = ["Test"] 245 | git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" 246 | uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" 247 | version = "0.0.5" 248 | 249 | [[deps.HypertextLiteral]] 250 | deps = ["Tricks"] 251 | git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" 252 | uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" 253 | version = "0.9.5" 254 | 255 | [[deps.IOCapture]] 256 | deps = ["Logging", "Random"] 257 | git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" 258 | uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" 259 | version = "0.2.5" 260 | 261 | [[deps.InteractiveUtils]] 262 | deps = ["Markdown"] 263 | uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" 264 | version = "1.11.0" 265 | 266 | [[deps.JSON]] 267 | deps = ["Dates", "Mmap", "Parsers", "Unicode"] 268 | git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" 269 | uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" 270 | version = "0.21.4" 271 | 272 | [[deps.JuliaInterpreter]] 273 | deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] 274 | git-tree-sha1 = "6ac9e4acc417a5b534ace12690bc6973c25b862f" 275 | uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" 276 | version = "0.10.3" 277 | 278 | [[deps.LaTeXStrings]] 279 | git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" 280 | uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" 281 | version = "1.4.0" 282 | 283 | [[deps.Latexify]] 284 | deps = ["Format", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] 285 | git-tree-sha1 = "4f34eaabe49ecb3fb0d58d6015e32fd31a733199" 286 | uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" 287 | version = "0.16.8" 288 | 289 | [deps.Latexify.extensions] 290 | DataFramesExt = "DataFrames" 291 | SparseArraysExt = "SparseArrays" 292 | SymEngineExt = "SymEngine" 293 | TectonicExt = "tectonic_jll" 294 | 295 | [deps.Latexify.weakdeps] 296 | DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" 297 | SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" 298 | SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" 299 | tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" 300 | 301 | [[deps.LibCURL]] 302 | deps = ["LibCURL_jll", "MozillaCACerts_jll"] 303 | uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" 304 | version = "0.6.4" 305 | 306 | [[deps.LibCURL_jll]] 307 | deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] 308 | uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" 309 | version = "8.6.0+0" 310 | 311 | [[deps.LibGit2]] 312 | deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] 313 | uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" 314 | version = "1.11.0" 315 | 316 | [[deps.LibGit2_jll]] 317 | deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] 318 | uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" 319 | version = "1.7.2+0" 320 | 321 | [[deps.LibSSH2_jll]] 322 | deps = ["Artifacts", "Libdl", "MbedTLS_jll"] 323 | uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" 324 | version = "1.11.0+1" 325 | 326 | [[deps.Libdl]] 327 | uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" 328 | version = "1.11.0" 329 | 330 | [[deps.LinearAlgebra]] 331 | deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] 332 | uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" 333 | version = "1.11.0" 334 | 335 | [[deps.Logging]] 336 | uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" 337 | version = "1.11.0" 338 | 339 | [[deps.LoweredCodeUtils]] 340 | deps = ["JuliaInterpreter"] 341 | git-tree-sha1 = "4ef1c538614e3ec30cb6383b9eb0326a5c3a9763" 342 | uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" 343 | version = "3.3.0" 344 | 345 | [[deps.MIMEs]] 346 | git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691" 347 | uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" 348 | version = "1.1.0" 349 | 350 | [[deps.MacroTools]] 351 | git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" 352 | uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" 353 | version = "0.5.16" 354 | 355 | [[deps.Markdown]] 356 | deps = ["Base64"] 357 | uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" 358 | version = "1.11.0" 359 | 360 | [[deps.MbedTLS_jll]] 361 | deps = ["Artifacts", "Libdl"] 362 | uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" 363 | version = "2.28.6+0" 364 | 365 | [[deps.Mmap]] 366 | uuid = "a63ad114-7e13-5084-954f-fe012c677804" 367 | version = "1.11.0" 368 | 369 | [[deps.MozillaCACerts_jll]] 370 | uuid = "14a3606d-f60d-562e-9121-12d972cd8159" 371 | version = "2023.12.12" 372 | 373 | [[deps.NetworkOptions]] 374 | uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" 375 | version = "1.2.0" 376 | 377 | [[deps.OpenBLAS_jll]] 378 | deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] 379 | uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" 380 | version = "0.3.27+1" 381 | 382 | [[deps.OrderedCollections]] 383 | git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" 384 | uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" 385 | version = "1.8.1" 386 | 387 | [[deps.Parsers]] 388 | deps = ["Dates", "PrecompileTools", "UUIDs"] 389 | git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" 390 | uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" 391 | version = "2.8.3" 392 | 393 | [[deps.Pkg]] 394 | deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] 395 | uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" 396 | version = "1.11.0" 397 | weakdeps = ["REPL"] 398 | 399 | [deps.Pkg.extensions] 400 | REPLExt = "REPL" 401 | 402 | [[deps.PlutoHooks]] 403 | deps = ["InteractiveUtils", "Markdown", "UUIDs"] 404 | git-tree-sha1 = "072cdf20c9b0507fdd977d7d246d90030609674b" 405 | uuid = "0ff47ea0-7a50-410d-8455-4348d5de0774" 406 | version = "0.0.5" 407 | 408 | [[deps.PlutoLinks]] 409 | deps = ["FileWatching", "InteractiveUtils", "Markdown", "PlutoHooks", "Revise", "UUIDs"] 410 | git-tree-sha1 = "8f5fa7056e6dcfb23ac5211de38e6c03f6367794" 411 | uuid = "0ff47ea0-7a50-410d-8455-4348d5de0420" 412 | version = "0.1.6" 413 | 414 | [[deps.PlutoTeachingTools]] 415 | deps = ["Downloads", "HypertextLiteral", "LaTeXStrings", "Latexify", "Markdown", "PlutoLinks", "PlutoUI", "Random"] 416 | git-tree-sha1 = "5d9ab1a4faf25a62bb9d07ef0003396ac258ef1c" 417 | uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" 418 | version = "0.2.15" 419 | 420 | [[deps.PlutoUI]] 421 | deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] 422 | git-tree-sha1 = "3151a0c8061cc3f887019beebf359e6c4b3daa08" 423 | uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" 424 | version = "0.7.65" 425 | 426 | [[deps.PrecompileTools]] 427 | deps = ["Preferences"] 428 | git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" 429 | uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" 430 | version = "1.2.1" 431 | 432 | [[deps.Preferences]] 433 | deps = ["TOML"] 434 | git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" 435 | uuid = "21216c6a-2e73-6563-6e65-726566657250" 436 | version = "1.4.3" 437 | 438 | [[deps.Printf]] 439 | deps = ["Unicode"] 440 | uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" 441 | version = "1.11.0" 442 | 443 | [[deps.Profile]] 444 | uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" 445 | version = "1.11.0" 446 | 447 | [[deps.REPL]] 448 | deps = ["InteractiveUtils", "Markdown", "Sockets", "StyledStrings", "Unicode"] 449 | uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" 450 | version = "1.11.0" 451 | 452 | [[deps.Random]] 453 | deps = ["SHA"] 454 | uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" 455 | version = "1.11.0" 456 | 457 | [[deps.Reexport]] 458 | git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" 459 | uuid = "189a3867-3050-52da-a836-e630ba90ab69" 460 | version = "1.2.2" 461 | 462 | [[deps.Requires]] 463 | deps = ["UUIDs"] 464 | git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" 465 | uuid = "ae029012-a4dd-5104-9daa-d747884805df" 466 | version = "1.3.1" 467 | 468 | [[deps.Revise]] 469 | deps = ["CodeTracking", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "REPL", "Requires", "UUIDs", "Unicode"] 470 | git-tree-sha1 = "f6f7d30fb0d61c64d0cfe56cf085a7c9e7d5bc80" 471 | uuid = "295af30f-e4ad-537b-8983-00126c2a3abe" 472 | version = "3.8.0" 473 | 474 | [deps.Revise.extensions] 475 | DistributedExt = "Distributed" 476 | 477 | [deps.Revise.weakdeps] 478 | Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b" 479 | 480 | [[deps.SHA]] 481 | uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" 482 | version = "0.7.0" 483 | 484 | [[deps.Serialization]] 485 | uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" 486 | version = "1.11.0" 487 | 488 | [[deps.Sockets]] 489 | uuid = "6462fe0b-24de-5631-8697-dd941f90decc" 490 | version = "1.11.0" 491 | 492 | [[deps.Statistics]] 493 | deps = ["LinearAlgebra"] 494 | git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" 495 | uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" 496 | version = "1.11.1" 497 | 498 | [deps.Statistics.extensions] 499 | SparseArraysExt = ["SparseArrays"] 500 | 501 | [deps.Statistics.weakdeps] 502 | SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" 503 | 504 | [[deps.StyledStrings]] 505 | uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" 506 | version = "1.11.0" 507 | 508 | [[deps.TOML]] 509 | deps = ["Dates"] 510 | uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" 511 | version = "1.0.3" 512 | 513 | [[deps.Tar]] 514 | deps = ["ArgTools", "SHA"] 515 | uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" 516 | version = "1.10.0" 517 | 518 | [[deps.Test]] 519 | deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] 520 | uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" 521 | version = "1.11.0" 522 | 523 | [[deps.Tricks]] 524 | git-tree-sha1 = "6cae795a5a9313bbb4f60683f7263318fc7d1505" 525 | uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" 526 | version = "0.1.10" 527 | 528 | [[deps.URIs]] 529 | git-tree-sha1 = "24c1c558881564e2217dcf7840a8b2e10caeb0f9" 530 | uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" 531 | version = "1.6.0" 532 | 533 | [[deps.UUIDs]] 534 | deps = ["Random", "SHA"] 535 | uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" 536 | version = "1.11.0" 537 | 538 | [[deps.Unicode]] 539 | uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" 540 | version = "1.11.0" 541 | 542 | [[deps.Zlib_jll]] 543 | deps = ["Libdl"] 544 | uuid = "83775a58-1f1d-513f-b197-d71354ab007a" 545 | version = "1.2.13+1" 546 | 547 | [[deps.libblastrampoline_jll]] 548 | deps = ["Artifacts", "Libdl"] 549 | uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" 550 | version = "5.11.0+0" 551 | 552 | [[deps.nghttp2_jll]] 553 | deps = ["Artifacts", "Libdl"] 554 | uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" 555 | version = "1.59.0+0" 556 | 557 | [[deps.p7zip_jll]] 558 | deps = ["Artifacts", "Libdl"] 559 | uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" 560 | version = "17.4.0+2" 561 | """ 562 | 563 | # ╔═╡ Cell order: 564 | # ╟─75b9bee9-7d03-4c90-b828-43e9e946517b 565 | # ╟─8577787d-d72d-4d92-8c69-9e516a85b779 566 | # ╟─3e5c3c97-4401-41d4-a701-d9b24f9acdc6 567 | # ╟─19f63d1f-99e5-4063-9af1-9c457c1cbda5 568 | # ╟─64e33738-e7b0-4a7a-893c-69b0b48b6215 569 | # ╟─2d039f15-fe74-4296-8e26-53cce9dde7c6 570 | # ╠═cbbfe10c-2131-42a0-8db7-06e7518508d9 571 | # ╠═89858748-ebe6-4d00-b09c-6cb1064e101f 572 | # ╠═03228a70-2298-4dcd-96e8-2be48603b860 573 | # ╟─031dc47b-8a1c-48a2-abe6-de88050ae1c7 574 | # ╟─4e54a79b-4eb5-4f2d-adb4-cc4545a7930d 575 | # ╟─5d888f29-0204-4388-ab81-53aefafd5092 576 | # ╠═0331dc20-fa0b-4b7f-badc-a2040795f15a 577 | # ╠═91f3684d-ed56-4ee2-b914-79ab4b6ed87a 578 | # ╠═0c8cfee6-5edb-4400-b7cd-753c2975a1e4 579 | # ╠═b2aecd04-115e-4aef-90d9-077aa886e70e 580 | # ╠═4297ac26-de6b-4041-940e-531184860d84 581 | # ╠═1fe0391a-7cee-4b9a-a775-3b78335f475c 582 | # ╠═cb042477-6a3e-4940-b3e6-38511936d370 583 | # ╠═3923ae23-1000-49ab-b5a2-c31567822e5d 584 | # ╟─c88229ac-c421-41e5-8db8-c62afdb54322 585 | # ╟─00000000-0000-0000-0000-000000000001 586 | # ╟─00000000-0000-0000-0000-000000000002 587 | -------------------------------------------------------------------------------- /src/exercises/exercise_13_reverse.jl: -------------------------------------------------------------------------------- 1 | ### A Pluto.jl notebook ### 2 | # v0.20.13 3 | 4 | #> [frontmatter] 5 | #> order = "11.1" 6 | #> exercise_number = "13" 7 | #> chapter = "4" 8 | #> section = "1" 9 | #> title = "Reverse mode AD" 10 | #> tags = ["module4", "track_ad", "exercises"] 11 | #> license = "MIT" 12 | #> layout = "layout.jlhtml" 13 | #> description = "sample exercise" 14 | #> 15 | #> [[frontmatter.author]] 16 | #> name = "Valentin Churavy" 17 | #> image = "https://avatars.githubusercontent.com/u/145258?v=4" 18 | #> url = "https://vchuravy.dev" 19 | 20 | using Markdown 21 | using InteractiveUtils 22 | 23 | # ╔═╡ 55ab2408-f966-4a3a-b5a7-7e73f5b52614 24 | using PlutoTeachingTools 25 | 26 | # ╔═╡ f8c6ade2-5196-11f0-34f7-7fa61b2cb26c 27 | using Enzyme 28 | 29 | # ╔═╡ b037fd65-0e30-41c1-ac39-7befc25dc37e 30 | function f1(x, y) 31 | x*exp(y) 32 | end 33 | 34 | # ╔═╡ 459dbd3f-8264-4882-960f-4350441ba4fb 35 | autodiff(Reverse, f1, Active(2.0), Active(1.0)) 36 | 37 | # ╔═╡ b489235d-1ed0-42e3-becb-708824cc30be 38 | md""" 39 | #### Exercise: 40 | - Manually write the reverse mode implementation for `f1`. 41 | """ 42 | 43 | # ╔═╡ 5884427b-1949-4d23-9c58-c1236c0e04d0 44 | function df1(x, y) 45 | # ... 46 | return (dx, dy) 47 | end 48 | 49 | # ╔═╡ 229f18d4-cb66-498c-9d43-07eb59bc711a 50 | md""" 51 | Enzyme allows for a selection of arguments to be "active". 52 | How would your implementation change if you knew that you didn't need the gradient of an argument? 53 | """ |> question_box 54 | 55 | # ╔═╡ e2c54f1f-6f73-4405-afeb-015bb5c9b446 56 | autodiff(Reverse, f1, Active(2.0), Const(1.0)) 57 | 58 | # ╔═╡ 3a1abfdf-abaa-4cc5-a1a0-3fc1ac3c2509 59 | autodiff(Reverse, f1, Const(2.0), Active(1.0)) 60 | 61 | # ╔═╡ 0fcfdd04-6e44-4d8e-9fff-cdb5e86ed368 62 | function f2(x::Array{Float64}, y::Array{Float64}) 63 | y[1] = x[1] * x[1] + x[2] * x[1] 64 | return nothing 65 | end 66 | 67 | # ╔═╡ 1bc8ae1b-8de1-4be0-9e7d-5034a20648d7 68 | let 69 | x = [2.0, 2.0] 70 | dx = [0.0, 0.0] 71 | y = [0.0] 72 | dy = [1.0] 73 | 74 | Enzyme.autodiff(Reverse, f2, Duplicated(x, dx), Duplicated(y, dy)) 75 | 76 | dx, dy 77 | end 78 | 79 | # ╔═╡ 4dcaf2e1-f217-4744-ba1e-46dd3aca37d2 80 | md""" 81 | #### Exercise: 82 | - Manually write the reverse mode implementation for `f2`. 83 | 84 | !!! note 85 | It might be very helpful to "desugar" the implementation as much as possible. 86 | """ 87 | 88 | # ╔═╡ 7fedda9a-bad0-448e-b4fe-924cd0b7f0a6 89 | md""" 90 | Note that Enzyme zeros out the `dy` memory. What would happen if it didn't? 91 | """ |> question_box 92 | 93 | # ╔═╡ fd5aadad-2522-41b1-8e95-b06eb10f804e 94 | f3(x) = exp(sin(x))^2 95 | 96 | # ╔═╡ 693eb763-0a8a-4a72-8106-fc6688916b3a 97 | 98 | 99 | # ╔═╡ 00000000-0000-0000-0000-000000000001 100 | PLUTO_PROJECT_TOML_CONTENTS = """ 101 | [deps] 102 | Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" 103 | PlutoTeachingTools = "661c6b06-c737-4d37-b85c-46df65de6f69" 104 | 105 | [compat] 106 | Enzyme = "~0.13.51" 107 | PlutoTeachingTools = "~0.4.1" 108 | """ 109 | 110 | # ╔═╡ 00000000-0000-0000-0000-000000000002 111 | PLUTO_MANIFEST_TOML_CONTENTS = """ 112 | # This file is machine-generated - editing it directly is not advised 113 | 114 | julia_version = "1.11.5" 115 | manifest_format = "2.0" 116 | project_hash = "fb512d2cf8738db99499013645d5d5e34b13ebf4" 117 | 118 | [[deps.AbstractPlutoDingetjes]] 119 | deps = ["Pkg"] 120 | git-tree-sha1 = "6e1d2a35f2f90a4bc7c2ed98079b2ba09c35b83a" 121 | uuid = "6e696c72-6542-2067-7265-42206c756150" 122 | version = "1.3.2" 123 | 124 | [[deps.ArgTools]] 125 | uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" 126 | version = "1.1.2" 127 | 128 | [[deps.Artifacts]] 129 | uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" 130 | version = "1.11.0" 131 | 132 | [[deps.Base64]] 133 | uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" 134 | version = "1.11.0" 135 | 136 | [[deps.CEnum]] 137 | git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" 138 | uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" 139 | version = "0.5.0" 140 | 141 | [[deps.ColorTypes]] 142 | deps = ["FixedPointNumbers", "Random"] 143 | git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" 144 | uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" 145 | version = "0.12.1" 146 | 147 | [deps.ColorTypes.extensions] 148 | StyledStringsExt = "StyledStrings" 149 | 150 | [deps.ColorTypes.weakdeps] 151 | StyledStrings = "f489334b-da3d-4c2e-b8f0-e476e12c162b" 152 | 153 | [[deps.CompilerSupportLibraries_jll]] 154 | deps = ["Artifacts", "Libdl"] 155 | uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" 156 | version = "1.1.1+0" 157 | 158 | [[deps.Dates]] 159 | deps = ["Printf"] 160 | uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" 161 | version = "1.11.0" 162 | 163 | [[deps.Downloads]] 164 | deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] 165 | uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" 166 | version = "1.6.0" 167 | 168 | [[deps.Enzyme]] 169 | deps = ["CEnum", "EnzymeCore", "Enzyme_jll", "GPUCompiler", "InteractiveUtils", "LLVM", "Libdl", "LinearAlgebra", "ObjectFile", "PrecompileTools", "Preferences", "Printf", "Random", "SparseArrays"] 170 | git-tree-sha1 = "de7f70d73805f4e1a32395afc9d580e4ffc62924" 171 | uuid = "7da242da-08ed-463a-9acd-ee780be4f1d9" 172 | version = "0.13.51" 173 | 174 | [deps.Enzyme.extensions] 175 | EnzymeBFloat16sExt = "BFloat16s" 176 | EnzymeChainRulesCoreExt = "ChainRulesCore" 177 | EnzymeGPUArraysCoreExt = "GPUArraysCore" 178 | EnzymeLogExpFunctionsExt = "LogExpFunctions" 179 | EnzymeSpecialFunctionsExt = "SpecialFunctions" 180 | EnzymeStaticArraysExt = "StaticArrays" 181 | 182 | [deps.Enzyme.weakdeps] 183 | BFloat16s = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" 184 | ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" 185 | GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" 186 | LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688" 187 | SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" 188 | StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" 189 | 190 | [[deps.EnzymeCore]] 191 | git-tree-sha1 = "8272a687bca7b5c601c0c24fc0c71bff10aafdfd" 192 | uuid = "f151be2c-9106-41f4-ab19-57ee4f262869" 193 | version = "0.8.12" 194 | 195 | [deps.EnzymeCore.extensions] 196 | AdaptExt = "Adapt" 197 | 198 | [deps.EnzymeCore.weakdeps] 199 | Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" 200 | 201 | [[deps.Enzyme_jll]] 202 | deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] 203 | git-tree-sha1 = "97e0a9a3fa1c51ebd94dd076dd847c037b79fd79" 204 | uuid = "7cc45869-7501-5eee-bdea-0790c847d4ef" 205 | version = "0.0.183+0" 206 | 207 | [[deps.ExprTools]] 208 | git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" 209 | uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" 210 | version = "0.1.10" 211 | 212 | [[deps.FileWatching]] 213 | uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" 214 | version = "1.11.0" 215 | 216 | [[deps.FixedPointNumbers]] 217 | deps = ["Statistics"] 218 | git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" 219 | uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" 220 | version = "0.8.5" 221 | 222 | [[deps.Format]] 223 | git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" 224 | uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" 225 | version = "1.3.7" 226 | 227 | [[deps.GPUCompiler]] 228 | deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "PrecompileTools", "Preferences", "Scratch", "Serialization", "TOML", "Tracy", "UUIDs"] 229 | git-tree-sha1 = "bbb7004345fb6141989835fc9f2f9e93bba3c806" 230 | uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" 231 | version = "1.5.3" 232 | 233 | [[deps.Hyperscript]] 234 | deps = ["Test"] 235 | git-tree-sha1 = "179267cfa5e712760cd43dcae385d7ea90cc25a4" 236 | uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91" 237 | version = "0.0.5" 238 | 239 | [[deps.HypertextLiteral]] 240 | deps = ["Tricks"] 241 | git-tree-sha1 = "7134810b1afce04bbc1045ca1985fbe81ce17653" 242 | uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2" 243 | version = "0.9.5" 244 | 245 | [[deps.IOCapture]] 246 | deps = ["Logging", "Random"] 247 | git-tree-sha1 = "b6d6bfdd7ce25b0f9b2f6b3dd56b2673a66c8770" 248 | uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" 249 | version = "0.2.5" 250 | 251 | [[deps.InteractiveUtils]] 252 | deps = ["Markdown"] 253 | uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" 254 | version = "1.11.0" 255 | 256 | [[deps.JLLWrappers]] 257 | deps = ["Artifacts", "Preferences"] 258 | git-tree-sha1 = "a007feb38b422fbdab534406aeca1b86823cb4d6" 259 | uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" 260 | version = "1.7.0" 261 | 262 | [[deps.JSON]] 263 | deps = ["Dates", "Mmap", "Parsers", "Unicode"] 264 | git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" 265 | uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" 266 | version = "0.21.4" 267 | 268 | [[deps.LLVM]] 269 | deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Preferences", "Printf", "Unicode"] 270 | git-tree-sha1 = "cfedf80c59000507cc8115a0281931253f4a33cd" 271 | uuid = "929cbde3-209d-540e-8aea-75f648917ca0" 272 | version = "9.4.1" 273 | 274 | [deps.LLVM.extensions] 275 | BFloat16sExt = "BFloat16s" 276 | 277 | [deps.LLVM.weakdeps] 278 | BFloat16s = "ab4f0b2a-ad5b-11e8-123f-65d77653426b" 279 | 280 | [[deps.LLVMExtra_jll]] 281 | deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] 282 | git-tree-sha1 = "2ea068aac1e7f0337d381b0eae3110581e3f3216" 283 | uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" 284 | version = "0.0.37+2" 285 | 286 | [[deps.LaTeXStrings]] 287 | git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" 288 | uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" 289 | version = "1.4.0" 290 | 291 | [[deps.Latexify]] 292 | deps = ["Format", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] 293 | git-tree-sha1 = "4f34eaabe49ecb3fb0d58d6015e32fd31a733199" 294 | uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" 295 | version = "0.16.8" 296 | 297 | [deps.Latexify.extensions] 298 | DataFramesExt = "DataFrames" 299 | SparseArraysExt = "SparseArrays" 300 | SymEngineExt = "SymEngine" 301 | TectonicExt = "tectonic_jll" 302 | 303 | [deps.Latexify.weakdeps] 304 | DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" 305 | SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" 306 | SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" 307 | tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" 308 | 309 | [[deps.LazyArtifacts]] 310 | deps = ["Artifacts", "Pkg"] 311 | uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" 312 | version = "1.11.0" 313 | 314 | [[deps.LibCURL]] 315 | deps = ["LibCURL_jll", "MozillaCACerts_jll"] 316 | uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" 317 | version = "0.6.4" 318 | 319 | [[deps.LibCURL_jll]] 320 | deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] 321 | uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" 322 | version = "8.6.0+0" 323 | 324 | [[deps.LibGit2]] 325 | deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] 326 | uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" 327 | version = "1.11.0" 328 | 329 | [[deps.LibGit2_jll]] 330 | deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] 331 | uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" 332 | version = "1.7.2+0" 333 | 334 | [[deps.LibSSH2_jll]] 335 | deps = ["Artifacts", "Libdl", "MbedTLS_jll"] 336 | uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" 337 | version = "1.11.0+1" 338 | 339 | [[deps.LibTracyClient_jll]] 340 | deps = ["Artifacts", "JLLWrappers", "Libdl"] 341 | git-tree-sha1 = "d2bc4e1034b2d43076b50f0e34ea094c2cb0a717" 342 | uuid = "ad6e5548-8b26-5c9f-8ef3-ef0ad883f3a5" 343 | version = "0.9.1+6" 344 | 345 | [[deps.Libdl]] 346 | uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" 347 | version = "1.11.0" 348 | 349 | [[deps.LinearAlgebra]] 350 | deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] 351 | uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" 352 | version = "1.11.0" 353 | 354 | [[deps.Logging]] 355 | uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" 356 | version = "1.11.0" 357 | 358 | [[deps.MIMEs]] 359 | git-tree-sha1 = "c64d943587f7187e751162b3b84445bbbd79f691" 360 | uuid = "6c6e2e6c-3030-632d-7369-2d6c69616d65" 361 | version = "1.1.0" 362 | 363 | [[deps.MacroTools]] 364 | git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" 365 | uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" 366 | version = "0.5.16" 367 | 368 | [[deps.Markdown]] 369 | deps = ["Base64"] 370 | uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" 371 | version = "1.11.0" 372 | 373 | [[deps.MbedTLS_jll]] 374 | deps = ["Artifacts", "Libdl"] 375 | uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" 376 | version = "2.28.6+0" 377 | 378 | [[deps.Mmap]] 379 | uuid = "a63ad114-7e13-5084-954f-fe012c677804" 380 | version = "1.11.0" 381 | 382 | [[deps.MozillaCACerts_jll]] 383 | uuid = "14a3606d-f60d-562e-9121-12d972cd8159" 384 | version = "2023.12.12" 385 | 386 | [[deps.NetworkOptions]] 387 | uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" 388 | version = "1.2.0" 389 | 390 | [[deps.ObjectFile]] 391 | deps = ["Reexport", "StructIO"] 392 | git-tree-sha1 = "09b1fe6ff16e6587fa240c165347474322e77cf1" 393 | uuid = "d8793406-e978-5875-9003-1fc021f44a92" 394 | version = "0.4.4" 395 | 396 | [[deps.OpenBLAS_jll]] 397 | deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] 398 | uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" 399 | version = "0.3.27+1" 400 | 401 | [[deps.OrderedCollections]] 402 | git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" 403 | uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" 404 | version = "1.8.1" 405 | 406 | [[deps.Parsers]] 407 | deps = ["Dates", "PrecompileTools", "UUIDs"] 408 | git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" 409 | uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" 410 | version = "2.8.3" 411 | 412 | [[deps.Pkg]] 413 | deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] 414 | uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" 415 | version = "1.11.0" 416 | 417 | [deps.Pkg.extensions] 418 | REPLExt = "REPL" 419 | 420 | [deps.Pkg.weakdeps] 421 | REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" 422 | 423 | [[deps.PlutoTeachingTools]] 424 | deps = ["Downloads", "HypertextLiteral", "Latexify", "Markdown", "PlutoUI"] 425 | git-tree-sha1 = "537c439831c0f8d37265efe850ee5c0d9c7efbe4" 426 | uuid = "661c6b06-c737-4d37-b85c-46df65de6f69" 427 | version = "0.4.1" 428 | 429 | [[deps.PlutoUI]] 430 | deps = ["AbstractPlutoDingetjes", "Base64", "ColorTypes", "Dates", "Downloads", "FixedPointNumbers", "Hyperscript", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "MIMEs", "Markdown", "Random", "Reexport", "URIs", "UUIDs"] 431 | git-tree-sha1 = "3151a0c8061cc3f887019beebf359e6c4b3daa08" 432 | uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8" 433 | version = "0.7.65" 434 | 435 | [[deps.PrecompileTools]] 436 | deps = ["Preferences"] 437 | git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" 438 | uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" 439 | version = "1.2.1" 440 | 441 | [[deps.Preferences]] 442 | deps = ["TOML"] 443 | git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" 444 | uuid = "21216c6a-2e73-6563-6e65-726566657250" 445 | version = "1.4.3" 446 | 447 | [[deps.Printf]] 448 | deps = ["Unicode"] 449 | uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" 450 | version = "1.11.0" 451 | 452 | [[deps.Random]] 453 | deps = ["SHA"] 454 | uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" 455 | version = "1.11.0" 456 | 457 | [[deps.Reexport]] 458 | git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" 459 | uuid = "189a3867-3050-52da-a836-e630ba90ab69" 460 | version = "1.2.2" 461 | 462 | [[deps.Requires]] 463 | deps = ["UUIDs"] 464 | git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" 465 | uuid = "ae029012-a4dd-5104-9daa-d747884805df" 466 | version = "1.3.1" 467 | 468 | [[deps.SHA]] 469 | uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" 470 | version = "0.7.0" 471 | 472 | [[deps.Scratch]] 473 | deps = ["Dates"] 474 | git-tree-sha1 = "9b81b8393e50b7d4e6d0a9f14e192294d3b7c109" 475 | uuid = "6c6a2e73-6563-6170-7368-637461726353" 476 | version = "1.3.0" 477 | 478 | [[deps.Serialization]] 479 | uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" 480 | version = "1.11.0" 481 | 482 | [[deps.SparseArrays]] 483 | deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] 484 | uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" 485 | version = "1.11.0" 486 | 487 | [[deps.Statistics]] 488 | deps = ["LinearAlgebra"] 489 | git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" 490 | uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" 491 | version = "1.11.1" 492 | weakdeps = ["SparseArrays"] 493 | 494 | [deps.Statistics.extensions] 495 | SparseArraysExt = ["SparseArrays"] 496 | 497 | [[deps.StructIO]] 498 | git-tree-sha1 = "c581be48ae1cbf83e899b14c07a807e1787512cc" 499 | uuid = "53d494c1-5632-5724-8f4c-31dff12d585f" 500 | version = "0.3.1" 501 | 502 | [[deps.SuiteSparse_jll]] 503 | deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] 504 | uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" 505 | version = "7.7.0+0" 506 | 507 | [[deps.TOML]] 508 | deps = ["Dates"] 509 | uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" 510 | version = "1.0.3" 511 | 512 | [[deps.Tar]] 513 | deps = ["ArgTools", "SHA"] 514 | uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" 515 | version = "1.10.0" 516 | 517 | [[deps.Test]] 518 | deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] 519 | uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" 520 | version = "1.11.0" 521 | 522 | [[deps.Tracy]] 523 | deps = ["ExprTools", "LibTracyClient_jll", "Libdl"] 524 | git-tree-sha1 = "16439d004690d4086da35528f0c6b4d7006d6dae" 525 | uuid = "e689c965-62c8-4b79-b2c5-8359227902fd" 526 | version = "0.1.4" 527 | 528 | [deps.Tracy.extensions] 529 | TracyProfilerExt = "TracyProfiler_jll" 530 | 531 | [deps.Tracy.weakdeps] 532 | TracyProfiler_jll = "0c351ed6-8a68-550e-8b79-de6f926da83c" 533 | 534 | [[deps.Tricks]] 535 | git-tree-sha1 = "6cae795a5a9313bbb4f60683f7263318fc7d1505" 536 | uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" 537 | version = "0.1.10" 538 | 539 | [[deps.URIs]] 540 | git-tree-sha1 = "24c1c558881564e2217dcf7840a8b2e10caeb0f9" 541 | uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" 542 | version = "1.6.0" 543 | 544 | [[deps.UUIDs]] 545 | deps = ["Random", "SHA"] 546 | uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" 547 | version = "1.11.0" 548 | 549 | [[deps.Unicode]] 550 | uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" 551 | version = "1.11.0" 552 | 553 | [[deps.Zlib_jll]] 554 | deps = ["Libdl"] 555 | uuid = "83775a58-1f1d-513f-b197-d71354ab007a" 556 | version = "1.2.13+1" 557 | 558 | [[deps.libblastrampoline_jll]] 559 | deps = ["Artifacts", "Libdl"] 560 | uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" 561 | version = "5.11.0+0" 562 | 563 | [[deps.nghttp2_jll]] 564 | deps = ["Artifacts", "Libdl"] 565 | uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" 566 | version = "1.59.0+0" 567 | 568 | [[deps.p7zip_jll]] 569 | deps = ["Artifacts", "Libdl"] 570 | uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" 571 | version = "17.4.0+2" 572 | """ 573 | 574 | # ╔═╡ Cell order: 575 | # ╠═55ab2408-f966-4a3a-b5a7-7e73f5b52614 576 | # ╠═f8c6ade2-5196-11f0-34f7-7fa61b2cb26c 577 | # ╠═b037fd65-0e30-41c1-ac39-7befc25dc37e 578 | # ╠═459dbd3f-8264-4882-960f-4350441ba4fb 579 | # ╟─b489235d-1ed0-42e3-becb-708824cc30be 580 | # ╠═5884427b-1949-4d23-9c58-c1236c0e04d0 581 | # ╟─229f18d4-cb66-498c-9d43-07eb59bc711a 582 | # ╠═e2c54f1f-6f73-4405-afeb-015bb5c9b446 583 | # ╠═3a1abfdf-abaa-4cc5-a1a0-3fc1ac3c2509 584 | # ╠═0fcfdd04-6e44-4d8e-9fff-cdb5e86ed368 585 | # ╠═1bc8ae1b-8de1-4be0-9e7d-5034a20648d7 586 | # ╟─4dcaf2e1-f217-4744-ba1e-46dd3aca37d2 587 | # ╟─7fedda9a-bad0-448e-b4fe-924cd0b7f0a6 588 | # ╠═fd5aadad-2522-41b1-8e95-b06eb10f804e 589 | # ╠═693eb763-0a8a-4a72-8106-fc6688916b3a 590 | # ╟─00000000-0000-0000-0000-000000000001 591 | # ╟─00000000-0000-0000-0000-000000000002 592 | -------------------------------------------------------------------------------- /src/mod2_principles_of_rse/recordings/gdb.cast: -------------------------------------------------------------------------------- 1 | {"version":2,"width":106,"height":52,"timestamp":1748423150,"env":{"TERM":"alacritty","SHELL":"/usr/bin/fish"},"theme":{"fg":"#d8d8d8","bg":"#181818","palette":"#181818:#ac4242:#90a959:#f4bf75:#6a9fb5:#aa759f:#75b5aa:#d8d8d8:#6b6b6b:#c55555:#aac474:#feca88:#82b8c8:#c28cb8:#93d3c3:#f8f8f8"}} 2 | [0.015809, "o", "Welcome to fish, the friendly interactive shell\r\nType \u001b[32mhelp\u001b(B\u001b[m for instructions on how to use fish\r\n"] 3 | [0.017258, "o", "\u001b]7;file://loki/home/vchuravy/src/rse-course/src/mod2_principles_of_rse\u0007"] 4 | [0.025657, "o", "\u001b]0;~/s/r/s/mod2_principles_of_rse\u0007\u001b[30m\u001b(B\u001b[m"] 5 | [0.025659, "o", "\r"] 6 | [0.025795, "o", "\u001b]133;A;special_key=1\u0007\u001b[92mvchuravy\u001b(B\u001b[m@\u001b(B\u001b[mloki\u001b(B\u001b[m \u001b[32m~/s/r/s/mod2_principles_of_rse\u001b(B\u001b[m (main)\u001b(B\u001b[m> \u001b[K\r\u001b[53C\u001b[?2004h\u001b[>4;1m\u001b[=5u\u001b="] 7 | [0.620423, "o", "\u001b[?2004l\u001b[>4;0m\u001b[=0u\u001b>"] 8 | [0.621372, "o", "asciinema rec --overwrite recordings/gdb.cast\r\u001b[98C\u001b[?2004h\u001b[>4;1m\u001b[=5u\u001b="] 9 | [0.621486, "o", "\u001b[45D\u001b[38;2;178;148;187masciinema \u001b[38;2;129;162;190mrec --overwrite \u001b[38;2;129;162;190m\u001b[4mrecordings/gdb.cast\u001b[30m\u001b(B\u001b[m\r\u001b[98C"] 10 | [1.1486, "o", "\u001b[?2004l\u001b[>4;0m\u001b[=0u\u001b>"] 11 | [1.148786, "o", "\u001b[45DENABLE_GDBLISTENER=1 gdb --args julia -g2\u001b[K\r\u001b[94C\u001b[?2004h\u001b[>4;1m\u001b[=5u\u001b="] 12 | [1.14891, "o", "\u001b[41D\u001b[38;2;129;162;190mENABLE_GDBLISTENER\u001b[38;2;0;166;178m=\u001b[38;2;129;162;190m1 \u001b[38;2;178;148;187mgdb \u001b[38;2;129;162;190m--args julia -g2\u001b[30m\u001b(B\u001b[m\r\u001b[94C"] 13 | [3.532688, "o", "\r\u001b[94C\r\n"] 14 | [3.532703, "o", "\u001b[30m\u001b(B\u001b[m\u001b]133;C;cmdline_url=ENABLE_GDBLISTENER%3D1%20gdb%20--args%20julia%20-g2\u0007"] 15 | [3.532759, "o", "\u001b[?2004l\u001b[>4;0m\u001b[=0u\u001b>"] 16 | [3.533303, "o", "\u001b]0;ENABLE_GDBLISTENER=1 ~/s/r/s/mod2_principles_of_rse\u0007\u001b[30m\u001b(B\u001b[m\r"] 17 | [3.596105, "o", "\u001b[35;1mGNU gdb (GDB) 16.3\u001b[m\r\nCopyright (C) 2024 Free Software Foundation, Inc.\r\nLicense GPLv3+: GNU GPL version 3 or later <\u001b[32mhttp://gnu.org/licenses/gpl.html\u001b[m>\r\nThis is free software: you are free to change and redistribute it.\r\nThere is NO WARRANTY, to the extent permitted by law.\r\nType \"\u001b[1mshow copying\u001b[m\" and \"\u001b[1mshow warranty\u001b[m\" for details.\r\n"] 18 | [3.596111, "o", "This GDB was configured as \"x86_64-pc-linux-gnu\".\r\nType \"\u001b[1mshow configuration\u001b[m\" for configuration details.\r\nFor bug reporting instructions, please see:\r\n"] 19 | [3.596119, "o", "\u001b[32m\u001b[m.\r\n"] 20 | [3.59612, "o", "Find the GDB manual and other documentation resources online at:\r\n"] 21 | [3.596129, "o", " <\u001b[32mhttp://www.gnu.org/software/gdb/documentation/\u001b[m>.\r\n\r\n"] 22 | [3.596137, "o", "For help, type \"\u001b[1mhelp\u001b[m\".\r\nType \"\u001b[1mapropos word\u001b[m\" to search for commands related to \"word\"...\r\n"] 23 | [3.596367, "o", "Reading symbols from \u001b[32mjulia\u001b[m...\r\n"] 24 | [3.597191, "o", "Reading symbols from \u001b[32m/usr/lib/debug/usr/bin/julia.debug\u001b[m...\r\n"] 25 | [3.598746, "o", "(No debugging symbols found in \u001b[32m/usr/lib/debug/usr/bin/julia.debug\u001b[m)\r\n"] 26 | [3.598865, "o", "\u001b[?2004h"] 27 | [3.598877, "o", "(gdb) "] 28 | [5.828475, "o", "b"] 29 | [5.988406, "o", "r"] 30 | [6.180523, "o", "e"] 31 | [6.268709, "o", "a"] 32 | [6.428593, "o", "k"] 33 | [6.55638, "o", " "] 34 | [6.724817, "o", "j"] 35 | [6.924403, "o", "l"] 36 | [7.356475, "o", "_"] 37 | [7.524454, "o", "b"] 38 | [7.692514, "o", "r"] 39 | [7.853347, "o", "e"] 40 | [7.972523, "o", "a"] 41 | [8.116838, "o", "k"] 42 | [8.324816, "o", "p"] 43 | [8.51643, "o", "o"] 44 | [8.72455, "o", "i"] 45 | [8.828396, "o", "n"] 46 | [8.932475, "o", "t"] 47 | [9.516775, "o", "\r\n\u001b[?2004l\r"] 48 | [9.517999, "o", "Function \"jl_breakpoint\" not defined.\r\n"] 49 | [9.518016, "o", "\u001b[?2004hMake breakpoint pending on future shared library load? (y or [n]) "] 50 | [10.98038, "o", "y"] 51 | [11.1967, "o", "\r\n\u001b[?2004l\rBreakpoint 1 (jl_breakpoint) pending.\r\n"] 52 | [11.196735, "o", "\u001b[?2004h"] 53 | [11.196736, "o", "(gdb) "] 54 | [13.612557, "o", "c"] 55 | [13.996739, "o", "\r\n\u001b[?2004l\r"] 56 | [13.996805, "o", "The program is not being run.\r\n"] 57 | [13.996833, "o", "\u001b[?2004h(gdb) "] 58 | [14.788644, "o", "r"] 59 | [15.540503, "o", "u"] 60 | [15.65261, "o", "n"] 61 | [15.909373, "o", "\r\n\u001b[?2004l\r"] 62 | [15.909477, "o", "Starting program: \u001b[32m/usr/bin/julia\u001b[m -g2\r\n"] 63 | [15.930435, "o", "[Detaching after fork from child process 426768]\r\n"] 64 | [15.930713, "o", "\u001b]0;Julia\u0007"] 65 | [15.930906, "o", "\u001b]0;Julia\u0007"] 66 | [15.931008, "o", "process 426762 is executing new program: /home/vchuravy/.julia/juliaup/julia-1.11.5+0.x64.linux.gnu/bin/julia\r\n"] 67 | [15.960271, "o", "[Thread debugging using libthread_db enabled]\r\nUsing host libthread_db library \"\u001b[32m/usr/lib/libthread_db.so.1\u001b[m\".\r\n"] 68 | [15.966952, "o", "[Detaching after fork from child process 426771]\r\n"] 69 | [15.987062, "o", "Function(s) ^std::(move|forward|as_const|(__)?addressof) will be skipped when stepping.\r\nFunction(s) ^std::(shared|unique)_ptr<.*>::(get|operator) will be skipped when stepping.\r\nFunction(s) ^std::(basic_string|vector|array|deque|(forward_)?list|(unordered_|flat_)?(multi)?(map|set)|span)<.*>::(c?r?(begin|end)|front|back|data|size|empty) will be skipped when stepping.\r\n"] 70 | [15.987068, "o", "Function(s) ^std::(basic_string|vector|array|deque|span)<.*>::operator.] will be skipped when stepping.\r\n"] 71 | [16.207099, "o", "[New Thread 0x7ffff0bff6c0 (LWP 426773)]\r\n"] 72 | [16.395267, "o", "[New Thread 0x7fffdd5ff6c0 (LWP 426774)]\r\n"] 73 | [16.39541, "o", "[New Thread 0x7fffdcdfe6c0 (LWP 426775)]\r\n"] 74 | [16.39555, "o", "[New Thread 0x7fffd43ff6c0 (LWP 426776)]\r\n"] 75 | [16.395639, "o", "[New Thread 0x7fffcb9ff6c0 (LWP 426777)]\r\n"] 76 | [16.395744, "o", "[New Thread 0x7fffc2fff6c0 (LWP 426778)]\r\n"] 77 | [16.395849, "o", "[New Thread 0x7fffba5ff6c0 (LWP 426779)]\r\n"] 78 | [16.395954, "o", "[New Thread 0x7fffb1bff6c0 (LWP 426780)]\r\n"] 79 | [16.607407, "o", " \u001b[1m\u001b[32m_\u001b[0m\r\n \u001b[1m\u001b[34m_\u001b[0m \u001b[0m_\u001b[0m \u001b[1m\u001b[31m_\u001b[1m\u001b[32m(_)\u001b[1m\u001b[35m_\u001b[0m | Documentation: https://docs.julialang.org\r\n \u001b[1m\u001b[34m(_)\u001b[0m | \u001b[1m\u001b[31m(_)\u001b[0m \u001b[1m\u001b[35m(_)\u001b[0m |\r\n \u001b[0m_ _ _| |_ __ _\u001b[0m | Type \"?\" for help, \"]?\" for Pkg help.\r\n \u001b[0m| | | | | | |/ _` |\u001b[0m |\r\n \u001b[0m| | |_| | | | (_| |\u001b[0m | Version 1.11.5 (2025-04-14)\r\n \u001b[0m_/ |\\__'_|_|_|\\__'_|\u001b[0m | Official https://julialang.org/ release\r\n\u001b[0m|__/\u001b[0m |\r\n\r\n"] 80 | [16.611648, "o", "\u001b[?2004h"] 81 | [16.611872, "o", "\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7C\r\u001b[7C"] 82 | [18.284735, "o", "\r\u001b[0K\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7C\r\u001b[7C"] 83 | [18.284855, "o", "\r\u001b[0K\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7C\r\u001b[7C"] 84 | [18.284881, "o", "\r\u001b[0K\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7Cexample()\r\u001b[16C"] 85 | [18.2849, "o", "\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7Cexample()\r\u001b[16C"] 86 | [18.470093, "o", "\r\u001b[0K\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7C\r\u001b[7C"] 87 | [18.470108, "o", "\r\u001b[0K\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7Cfunction example()\r\n\r\u001b[7C r = Ref(0)\r\n\r\u001b[7C @ccall jl_breakpoint(r::Any)::Cvoid\r\n\r\u001b[7C for i in 1:10\r\n\r\u001b[7C r[] += i\r\n\r\u001b[7C end\r\n\r\u001b[7C return r\r\n\r\u001b[7Cend\r\u001b[10C"] 88 | [18.473043, "o", "\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7Cfunction example()\r\n\r\u001b[7C r = Ref(0)\r\n\r\u001b[7C @ccall jl_breakpoint(r::Any)::Cvoid\r\n\r\u001b[7C for i in 1:10\r\n\r\u001b[7C r[] += i\r\n\r\u001b[7C end\r\n\r\u001b[7C return r\r\n\r\u001b[7Cend\r\u001b[10C"] 89 | [19.800989, "o", "\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7Cfunction example()\r\n\r\u001b[7C r = Ref(0)\r\n\r\u001b[7C @ccall jl_breakpoint(r::Any)::Cvoid\r\n\r\u001b[7C for i in 1:10\r\n\r\u001b[7C r[] += i\r\n\r\u001b[7C end\r\n\r\u001b[7C return r\r\n\r\u001b[7Cend\r\u001b[10C"] 90 | [19.801191, "o", "\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7Cfunction example()\r\n\r\u001b[7C r = Ref(0)\r\n\r\u001b[7C @ccall jl_breakpoint(r::Any)::Cvoid\r\n\r\u001b[7C for i in 1:10\r\n\r\u001b[7C r[] += i\r\n\r\u001b[7C end\r\n\r\u001b[7C return r\r\n\r\u001b[7Cend\r\u001b[10C"] 91 | [19.801214, "o", "\r\n"] 92 | [19.801389, "o", "\u001b[?2004l"] 93 | [19.801419, "o", "\u001b[0m"] 94 | [19.807468, "o", "\u001b[1m\u001b[0m\u001b[0m"] 95 | [19.807589, "o", "example (generic function"] 96 | [19.807591, "o", " with 1 method)"] 97 | [19.807602, "o", "\r\n"] 98 | [19.807608, "o", "\r\n"] 99 | [19.807662, "o", "\r\u001b[0K\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7C\r\u001b[7C"] 100 | [19.807675, "o", "\u001b[?2004h"] 101 | [19.807689, "o", "\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7C\r\u001b[7C"] 102 | [20.140532, "o", "\r\u001b[0K\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7C\r\u001b[7C"] 103 | [20.14055, "o", "\r\u001b[0K\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7C\r\u001b[7C"] 104 | [20.140584, "o", "\r\u001b[0K\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7Cfunction example()\r\n\r\u001b[7C r = Ref(0)\r\n\r\u001b[7C @ccall jl_breakpoint(r::Any)::Cvoid\r\n\r\u001b[7C for i in 1:10\r\n\r\u001b[7C r[] += i\r\n\r\u001b[7C end\r\n\r\u001b[7C return r\r\n\r\u001b[7Cend\r\u001b[10C"] 105 | [20.140597, "o", "\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7Cfunction example()\r\n\r\u001b[7C r = Ref(0)\r\n\r\u001b[7C @ccall jl_breakpoint(r::Any)::Cvoid\r\n\r\u001b[7C for i in 1:10\r\n\r\u001b[7C r[] += i\r\n\r\u001b[7C end\r\n\r\u001b[7C return r\r\n\r\u001b[7Cend\r\u001b[10C"] 106 | [20.284981, "o", "\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\u001b[1A\r\u001b[0K\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7C\r\u001b[7C"] 107 | [20.284995, "o", "\r\u001b[0K\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7Cexample()\r\u001b[16C"] 108 | [20.285032, "o", "\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7Cexample()\r\u001b[16C"] 109 | [20.788538, "o", "\r\u001b[0K\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7Cexample()\r\u001b[16C"] 110 | [20.788621, "o", "\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7Cexample()\r\u001b[16C"] 111 | [20.78863, "o", "\r\n"] 112 | [20.788697, "o", "\u001b[?2004l"] 113 | [20.788705, "o", "\u001b[0m"] 114 | [20.810451, "o", "\r\nThread 1 \"julia\" hit Breakpoint 1, \u001b[33mjl_breakpoint\u001b[m (\u001b[36mv\u001b[m=0x7fffeec5c6a0)\r\n at \u001b[32m/cache/build/tester-amdci5-12/julialang/julia-release-1-dot-11/src/rtutils.c\u001b[m:\u001b[2m1475\u001b[m\r\nwarning: 1475\t\u001b[32m/cache/build/tester-amdci5-12/julialang/julia-release-1-dot-11/src/rtutils.c\u001b[m: No such file or directory\r\n"] 115 | [20.810493, "o", "\u001b[?2004h"] 116 | [20.810534, "o", "\u001b[?2004l\r\u001b[?2004h(gdb) "] 117 | [25.501318, "o", "p"] 118 | [25.676976, "o", " "] 119 | [25.90095, "o", "j"] 120 | [26.148652, "o", "l"] 121 | [26.60462, "o", "_"] 122 | [27.108385, "o", "("] 123 | [27.156513, "o", ")"] 124 | [27.340734, "o", "\b"] 125 | [28.156622, "o", "v)\b"] 126 | [28.501108, "o", "\r\n\u001b[?2004l\r"] 127 | [28.502804, "o", "Base.RefValue{Int64}"] 128 | [28.502807, "o", "("] 129 | [28.502838, "o", "x=0)\r\n"] 130 | [28.503648, "o", "\u001b[36m$1\u001b[m = void\r\n"] 131 | [28.503683, "o", "\u001b[?2004h"] 132 | [28.503695, "o", "(gdb) "] 133 | [31.501253, "o", "b"] 134 | [31.716538, "o", "t"] 135 | [31.924398, "o", " "] 136 | [33.12451, "o", "3"] 137 | [33.732825, "o", "\r\n\u001b[?2004l\r"] 138 | [33.734524, "o", "#0 \u001b[33mjl_breakpoint\u001b[m (\u001b[36mv\u001b[m=0x7fffeec5c6a0)\r\n at \u001b[32m/cache/build/tester-amdci5-12/julialang/julia-release-1-dot-11/src/rtutils.c\u001b[m:\u001b[2m1475\u001b[m\r\n"] 139 | [33.734539, "o", "#1 \u001b[34m0x00007fffebcfc514\u001b[m in \u001b[33mjulia_example_43\u001b[m () at \u001b[32mREPL[1]\u001b[m:\u001b[2m3\u001b[m\r\n"] 140 | [33.740859, "o", "#2 \u001b[34m0x00007fffebcfc550\u001b[m in \u001b[33mjfptr_example_44\u001b[m ()\r\n"] 141 | [33.74093, "o", "(More stack frames follow...)\r\n"] 142 | [33.740958, "o", "\u001b[?2004h"] 143 | [33.740959, "o", "(gdb) "] 144 | [40.517024, "o", "p"] 145 | [40.900841, "o", " "] 146 | [42.580551, "o", "*"] 147 | [42.844552, "o", "("] 148 | [42.908842, "o", ")"] 149 | [43.180567, "o", "\b"] 150 | [44.036489, "o", "i)\b"] 151 | [44.140375, "o", "n)\b"] 152 | [44.308795, "o", "t)\b"] 153 | [45.452527, "o", "6)\b"] 154 | [45.69243, "o", "4)\b"] 155 | [46.236622, "o", "_)\b"] 156 | [46.388609, "o", "t)\b"] 157 | [47.428473, "o", "*)\b"] 158 | [47.692764, "o", "\u001b[C"] 159 | [50.476885, "o", "v"] 160 | [51.236868, "o", "\r\n\u001b[?2004l\r"] 161 | [51.238556, "o", "\u001b[36m$2\u001b[m = 0\r\n"] 162 | [51.238595, "o", "\u001b[?2004h(gdb) "] 163 | [53.80455, "o", "w"] 164 | [53.908349, "o", "a"] 165 | [54.124864, "o", "t"] 166 | [54.332526, "o", "c"] 167 | [54.780733, "o", "h"] 168 | [54.916643, "o", " "] 169 | [55.21253, "o", " "] 170 | [56.364664, "o", "\b\u001b[K"] 171 | [57.95641, "o", "*"] 172 | [58.260811, "o", "("] 173 | [58.324488, "o", ")"] 174 | [58.564444, "o", "\b"] 175 | [59.236639, "o", "i)\b"] 176 | [59.324467, "o", "n)\b"] 177 | [59.460358, "o", "t)\b"] 178 | [60.429258, "o", "6)\b"] 179 | [60.981029, "o", "4)\b"] 180 | [61.349004, "o", "_)\b"] 181 | [61.66089, "o", "t)\b"] 182 | [61.884638, "o", "\u001b[C"] 183 | [62.740906, "o", "\b"] 184 | [63.668666, "o", "*)\b"] 185 | [63.844527, "o", "\u001b[C"] 186 | [67.389645, "o", "\u001b[7m0x7fffeec5c6a0\u001b[27m"] 187 | [68.484891, "o", "\b\b\b\b\b\b\b\b\b\b\b\b\b\b0x7fffeec5c6a0\u0007"] 188 | [69.732502, "o", "\r\n\u001b[?2004l\r"] 189 | [69.732713, "o", "Hardware watchpoint 2: *(int64_t*)0x7fffeec5c6a0\r\n"] 190 | [69.732732, "o", "\u001b[?2004h"] 191 | [69.732744, "o", "(gdb) "] 192 | [70.996399, "o", "p"] 193 | [71.460781, "o", "/"] 194 | [71.620503, "o", "x"] 195 | [71.76481, "o", " "] 196 | [71.908558, "o", "v"] 197 | [72.036382, "o", "\r\n\u001b[?2004l\r"] 198 | [72.036489, "o", "\u001b[36m$3\u001b[m = 0x7fffeec5c6a0\r\n"] 199 | [72.036511, "o", "\u001b[?2004h(gdb) "] 200 | [74.956587, "o", "c"] 201 | [75.196573, "o", "o"] 202 | [75.556407, "o", "n"] 203 | [75.756489, "o", "t"] 204 | [75.876434, "o", "i"] 205 | [75.948786, "o", "n"] 206 | [76.100927, "o", "ue "] 207 | [76.532477, "o", "\r\n\u001b[?2004l\r"] 208 | [76.532521, "o", "Continuing.\r\n"] 209 | [76.533674, "o", "\r\nThread 1 \"julia\" hit Hardware watchpoint 2: *(int64_t*)0x7fffeec5c6a0\r\n\r\nOld value = 0\r\nNew value = 55\r\n"] 210 | [76.533689, "o", "\u001b[34m0x00007fffebcfc518\u001b[m in \u001b[33mjulia_example_43\u001b[m () at \u001b[32mREPL[1]\u001b[m:\u001b[2m5\u001b[m\r\nwarning: 5\t\u001b[32mREPL[1]\u001b[m: No such file or directory\r\n"] 211 | [76.533698, "o", "\u001b[?2004h"] 212 | [76.533699, "o", "\u001b[?2004l\r"] 213 | [76.533712, "o", "\u001b[?2004h(gdb) "] 214 | [79.284609, "o", "b"] 215 | [79.540369, "o", "t"] 216 | [79.676613, "o", " "] 217 | [79.900372, "o", "3"] 218 | [80.604338, "o", "\r\n\u001b[?2004l\r"] 219 | [80.604727, "o", "#0 \u001b[34m0x00007fffebcfc518\u001b[m in \u001b[33mjulia_example_43\u001b[m () at \u001b[32mREPL[1]\u001b[m:\u001b[2m5\u001b[m\r\n"] 220 | [80.604755, "o", "#1 \u001b[34m0x00007fffebcfc550\u001b[m in \u001b[33mjfptr_example_44\u001b[m ()\r\n"] 221 | [80.60491, "o", "#2 \u001b[34m0x00007ffff7270385\u001b[m in \u001b[33mjl_apply\u001b[m (\u001b[36mnargs\u001b[m=1, \u001b[36margs\u001b[m=0x7fffffffc7f0)\r\n at \u001b[32m/cache/build/tester-amdci5-12/julialang/julia-release-1-dot-11/src/julia.h\u001b[m:\u001b[2m2157\u001b[m\r\n"] 222 | [80.604913, "o", "(More stack frames follow...)\r\n"] 223 | [80.604967, "o", "\u001b[?2004h(gdb) "] 224 | [87.940708, "o", "c"] 225 | [88.108789, "o", "o"] 226 | [88.236868, "o", "n"] 227 | [88.348875, "o", "t"] 228 | [88.460371, "o", "i"] 229 | [88.588375, "o", "n"] 230 | [88.716367, "o", "u"] 231 | [88.844656, "o", "e"] 232 | [89.052548, "o", "\r\n\u001b[?2004l\rContinuing.\r\n"] 233 | [89.052926, "o", "\u001b[1m\u001b[0m\u001b[0m"] 234 | [89.084794, "o", "Base.RefValue{Int64}"] 235 | [89.0848, "o", "("] 236 | [89.090861, "o", "55"] 237 | [89.090869, "o", ")"] 238 | [89.09087, "o", "\r\n"] 239 | [89.090908, "o", "\r\n"] 240 | [89.091019, "o", "\r\u001b[0K\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7C\r\u001b[7C"] 241 | [89.091037, "o", "\u001b[?2004h"] 242 | [89.091057, "o", "\r\u001b[0K\u001b[32m\u001b[1mjulia> \u001b[0m\u001b[0m\r\u001b[7C\r\u001b[7C"] 243 | [93.229043, "o", "\r\n"] 244 | [93.229062, "o", "\u001b[?2004l"] 245 | [93.235519, "o", "\u001b[0m"] 246 | [93.238768, "o", "[Thread 0x7fffb1bff6c0 (LWP 426780) exited]\r\n"] 247 | [93.238771, "o", "[Thread 0x7fffba5ff6c0 (LWP 426779) exited]\r\n"] 248 | [93.23879, "o", "[Thread 0x7fffc2fff6c0 (LWP 426778) exited]\r\n[Thread 0x7fffd43ff6c0 (LWP 426776) exited]\r\n"] 249 | [93.238805, "o", "[Thread 0x7fffdcdfe6c0 (LWP 426775) exited]\r\n[Thread 0x7fffdd5ff6c0 (LWP 426774) exited]\r\n"] 250 | [93.238816, "o", "[Thread 0x7ffff0bff6c0 (LWP 426773) exited]\r\n"] 251 | [93.238829, "o", "[Thread 0x7ffff7d6e180 (LWP 426762) exited]\r\n"] 252 | [93.246249, "o", "[Thread 0x7fffcb9ff6c0 (LWP 426777) exited]\r\n"] 253 | [93.24631, "o", "[New process 426762]\r\n"] 254 | [93.246347, "o", "[Inferior 1 (process 426762) exited normally]\r\n"] 255 | [93.246455, "o", "\u001b[?2004h"] 256 | [93.246464, "o", "\u001b[?2004l\r"] 257 | [93.246472, "o", "\u001b[?2004h(gdb) "] 258 | [94.300939, "o", "quit\r\n\u001b[?2004l\r"] 259 | [94.329598, "o", "\u001b]133;D;0\u0007\u001b[?25h"] 260 | [94.32963, "o", "\u001b[2m⏎\u001b(B\u001b[m \r⏎ \r\u001b[K"] 261 | [94.334733, "o", "\u001b]0;~/s/r/s/mod2_principles_of_rse\u0007\u001b[30m\u001b(B\u001b[m"] 262 | [94.334741, "o", "\u001b]133;A;special_key=1\u0007\u001b[92mvchuravy\u001b(B\u001b[m@\u001b(B\u001b[mloki\u001b(B\u001b[m \u001b[32m~/s/r/s/mod2_principles_of_rse\u001b(B\u001b[m (main)\u001b(B\u001b[m> \u001b[K\r\u001b[53C"] 263 | [94.334742, "o", "\u001b[?2004h\u001b[>4;1m\u001b[=5u\u001b="] 264 | [95.204792, "o", "\r\n"] 265 | [95.204806, "o", "\u001b[30m\u001b(B\u001b[m"] 266 | [95.204818, "o", "\u001b[30m\u001b(B\u001b[m"] 267 | [95.204869, "o", "\u001b[?2004l\u001b[>4;0m\u001b[=0u\u001b>"] 268 | --------------------------------------------------------------------------------