{"id":61637,"url":"https://github.com/ego/awesome-mojo","name":"awesome-mojo","description":"Awesome Mojo🔥","projects_count":152,"last_synced_at":"2026-08-03T01:00:28.606Z","repository":{"id":165623531,"uuid":"640977678","full_name":"ego/awesome-mojo","owner":"ego","description":"Awesome Mojo🔥","archived":false,"fork":false,"pushed_at":"2025-11-01T21:51:35.000Z","size":7742,"stargazers_count":229,"open_issues_count":1,"forks_count":10,"subscribers_count":10,"default_branch":"main","last_synced_at":"2026-07-14T21:03:59.994Z","etag":null,"topics":["artificial-intelligence","awesome","awesome-mojo","benchmark","compilers","cpp","future-ai","future-technologies","hacktoberfest","hardware-acceleration","llvm","machine-learning","mlir","mojo","mojo-lang","mojo-language","mojolang","performance","programming-language","python"],"latest_commit_sha":null,"homepage":"https://ego.systemdef.com/awesome-mojo/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ego.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-05-15T14:16:19.000Z","updated_at":"2026-07-14T08:03:43.000Z","dependencies_parsed_at":"2026-07-08T14:03:47.034Z","dependency_job_id":null,"html_url":"https://github.com/ego/awesome-mojo","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ego/awesome-mojo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ego%2Fawesome-mojo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ego%2Fawesome-mojo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ego%2Fawesome-mojo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ego%2Fawesome-mojo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ego","download_url":"https://codeload.github.com/ego/awesome-mojo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ego%2Fawesome-mojo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":36213603,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-08-02T02:00:06.915Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"created_at":"2024-06-11T16:09:45.606Z","updated_at":"2026-08-03T01:00:28.608Z","primary_language":null,"list_of_lists":false,"displayable":true,"categories":["AI","Why is it called Mojo?","Python / C++","Modular and Mojo🔥 history and etymology","Summary Mandelbrot Set","[Mojo🔥 Merge sort](algorithm/MergeSort_Mojo.mojo)","[Bonus V Breadth First Search Path](algorithm/bfs_V.v)","[Mojo🔥Fizz buzz](algorithm/fizz_buzz_Mojo.mojo)","Parameterization[]: compile time meta-programming","Data Type Model and alias","String","Advanced Mojo🔥features and Intrinsics module","Mojo🔥TCP Socket Server with PythonInterface","Radiative transfer","IDEA","Code share from Mojo Playground","MLIR and low-level implementation","Python hints","Tools","Mojo🔥FastAPI with PythonInterface","`VariadicList` for destructuring/unpacking/accessing arguments","MLIR libc gethostname","Pointer","Instant and DateTimeLocal"],"sub_categories":["Mojo🔥FastAPI Client","[Codon Mandelbrot Set](benchmarks/multibrot_set/multibrot.codon)","String and builtin slice","Decorators combination","Syscalls"],"readme":"# Awesome Mojo🔥\n\n![Mojo](img/mojo.png) \n\nMojo 🔥 — a new programming language for all developers, AI/ML scientists and software engineers.\n\nA curated list of awesome Mojo🔥 code, problem-solving, solution, and in future libraries, frameworks, software and\nresources.\n\nLet's accumulate here very new technology knowledge and best practices.\n\n* [Awesome Mojo🔥](https://github.com/ego/awesome-mojo)\n* [Mojo 🔥Driven Community](https://mojo-lang.dev)\n* [Official Mojo docs](https://docs.modular.com/mojo/)\n\nMojo is a programming language that combines the user-friendliness of Python with the performance capabilities of C++\nand Rust. Additionally, Mojo enables users to harness the vast ecosystem of Python libraries.\n\nIn a brief\n\n* Mojo allows you to leverage the entire Python ecosystem.\n* Mojo is designed to become a superset of Python.\n* Make Mojo compatible with existing Python programs.\n* Mojo as a member of the Python family.\n* Applied for AI systems and AI field.\n* Scalable programming for heterogeneous systems.\n* Building unify the world’s ML/AI infrastructure.\n* Innovations in compiler internals.\n* Support for current and emerging hardware accelerators.\n* Systems programming features.\n* Leverage the existing MLIR compiler ecosystem.\n\n# Hello Mojo🔥\n\nMojo is a new programming language that bridges the gap between research and production by combining the best of Python\nsyntax with systems programming and metaprogramming.\n\n`hello.mojo` or `hello.🔥` the file extension can be an emoji!\n\n* [Hello Mojo 🔥](algorithm/HelloMojo.🔥)\n\nYou can read more about why Modular doing this [Why Mojo🔥](https://docs.modular.com/mojo/why-mojo.html)\n\n\u003e What we wanted was an innovative and scalable programming model that could target accelerators and other heterogeneous\n\u003e systems that are pervasive in the AI field.\n\u003e ...\n\u003e Applied AI systems need to address all these issues, and we decided there was no reason it couldn’t be done with just\n\u003e one language. Thus, Mojo was born.\n\nBut Python has done its job very well =)\n\n\u003e We didn’t see any need to innovate in language syntax or community.\n\u003e So we chose to embrace the Python ecosystem because it is so widely used, it is loved by the AI ecosystem, and because\n\u003e we believe it is a really nice language.\n\n## Why is it called Mojo?\n\n\u003e Mojo🔥 means “a magical charm” or “magical powers.”\n\u003e We thought this was a fitting name for a language that brings magical powers to Python :python:,\n\u003e including unlocking an innovative programming model for accelerators and other heterogeneous systems pervasive in AI today.\n\n**Guido van Rossum** [benevolent dictator for life](https://en.wikipedia.org/wiki/Guido_van_Rossum) and **Christopher Arthur Lattner** [distinguished inventor, creator and well-known leader](https://en.wikipedia.org/wiki/Chris_Lattner) about Mojo🔥pronunciation =)\n\n\u003cimg src=\"img/guido-chris.png\" width=\"300\" /\u003e\n\u003cimg src=\"img/gvanrossum.png\" height=\"200\" /\u003e\n\nAccording to the description\n\n* [Mojo word definition](https://duckduckgo.com/?q=mojo\u0026ia=definition\u0026iax=definition)\n* [Mojo sound](mojo_American_English_pronunciation.mp3)\n\n\n# Background and influenced by\n\nWho knows that these programming languages will be very happy, because Mojo benefits from tremendous lessons learned from\nother [languages](https://en.wikipedia.org/wiki/History_of_programming_languages) Rust, Swift, Julia, Zig, Nim, etc.\n\n* Rust starts the C revolution and now [Rust in the Linux kernel](https://docs.kernel.org/rust/index.html).\n* [Swift](https://www.swift.org) makes [Apple beautiful](https://developer.apple.com/swift/) from a technical\n  perspective.\n* [Julia](https://julialang.org) high performance.\n* [Nim](https://nim-lang.org) systems programming language.\n* [Zig](https://ziglang.org) general-purpose programming language. We are like and following it =)\n\n![Mojo](img/speed.png)\n\n# News\n\n[new]\n\n* Github now auto-detects Mojo code 🔥!\n\n  \u003cimg src=\"img/mojo_lang_github.png\" width=\"300\" /\u003e\n\n* [Simple and fast HTTP framework for Mojo! 🔥 Perfect for building web services and simple APIs. For Mojicians](https://github.com/saviorand/lightbug_http)\n* [LLama implementations benchmarking framework](https://github.com/tairov/lamatune)\n* [Automated Python to Mojo code translation](https://github.com/msaelices/py2mojo)\n* [Programming Language DataBase Research](lang/pldb.pub.md)\n* October 19, 2023 [Mojo🔥 is now available on Mac!](https://www.modular.com/blog/mojo-is-now-available-on-mac)\n[Use developer console](https://developer.modular.com/download)\n* [Chris Lattner: Future of Programming and AI | Lex Fridman Podcast #381](https://www.youtube.com/watch?v=pdJQ8iVTwj8)\n* [Mojo and Python type system explained | Chris Lattner and Lex Fridman](https://www.youtube.com/watch?v=0VCq8jJjAPc)\n* [Can Mojo run Python code? | Chris Lattner and Lex Fridman](https://www.youtube.com/watch?v=99hRAvk3wIk)\n* [Switching from Python to Mojo programming language | Chris Lattner and Lex Fridman](https://www.youtube.com/watch?v=7wo4vyB7l3s)\n* New [GitHub Topic mojo-lang](https://github.com/topics/mojo-lang). So you can follow it.\n\n  \u003cimg src=\"img/GitHub-Topic-Mojo-Lang.png\" height=\"200\" /\u003e\n\n* [Guido van Rossum about Mojo = Python with C++/GPU performance?](https://discuss.python.org/t/mojo-python-with-c-gpu-performance/26993/6)\n  \u003cimg src=\"img/guido-cpython-mojo.png\" height=\"200\" /\u003e\n* [Tensor struct with some basic ops #251](https://github.com/modularml/mojo/discussions/251)\n* [Matrix fn with numpy #267](https://github.com/modularml/mojo/discussions/267)\n* Updates about `lambda` and `parameter` [Closures and higer order functions in mojo #244](https://github.com/modularml/mojo/discussions/244#discussioncomment-6008071)\n* May-25-2023, Guido van Rossum (gvanrossum#8415), creator and emeritus BDFL of Python, visit the Mojo🔥 public [Discord Chat](https://www.discord.gg/modular)\n* [Waiting for a Mojo🔥 syntax highlighting at GitHub](https://github.com/github-linguist/linguist/pull/6400)\n* [New Mojo🔥release 2023-05-24](https://docs.modular.com/mojo/changelog.html#section)\n\n[old]\n\nMojo🔥\n\n* [Changelog](https://docs.modular.com/mojo/changelog.html)\n* [Discussions](https://github.com/modularml/mojo/discussions?discussions_q=is%3Aopen)\n* [Issues](https://github.com/modularml/mojo/issues)\n\n\n# Benchmarks\n\n## Tools\n\n* [hyperfine](https://github.com/sharkdp/hyperfine) a command-line benchmarking tool\n\n```shell\nbrew install hyperfine\n```\n\n* [macchina](https://github.com/Macchina-CLI/macchina) a system information frontend with an emphasis on performance.\n\n```shell\nbrew install macchina\n```\n\n* Python3 libs for plots\n\n```shell\npip3 install numpy matplotlib scipy\n```\n\n* Code to image PNG\n\n```shell\nbrew install silicon\n```\n\n\n## Benchmarking environment\n\n\u003cimg src=\"benchmarks/macchina-sys-info.png\" width=\"800\" /\u003e\n\nPython / Mojo / Codon / Rust  versions\n\n```shell\n\u003e python3 --version\nPython 3.11.6\n\n\u003e mojo --version\nmojo 0.4.0 (9e33b013)\n\n\u003e codon --version\n0.16.3\n\n\u003e rustc --version\nrustc 1.65.0-nightly (9243168fa 2022-08-31)\n```\n\n## [Fibonacci Sequence](https://en.wikipedia.org/wiki/Fibonacci_sequence)\n\nLets find Fibonacci Sequence where\n\n**N = 100**\n\n### [Python Fibonacci Sequence Recursion](benchmarks/fibonacci_sequence/python_recursion.py)\n\n```python\ndef fibonacci_recursion(n):\n    return n if n \u003c 2 else fibonacci_recursion(n - 1) + fibonacci_recursion(n - 2)\nfibonacci_recursion(100)\n```\n\n```shell\nhyperfine --warmup 10 -r 100 --time-unit=microsecond --export-json python_recursion.json 'python3 benchmarks/fibonacci_sequence/python_recursion.py'\n```\n\n**RESULT: TIMEOUT, I canceled computation after 1m**\n\n\n### [Python Fibonacci Sequence Iteration](benchmarks/fibonacci_sequence/python_iteration.py)\n\n```python\ndef fibonacci_iteration(n):\n    a, b = 0, 1\n    for _ in range(n):\n        a, b = b, a+b\n    return a\nfibonacci_iteration(100)\n```\n\n```shell\nhyperfine --warmup 10 -r 100 --time-unit=microsecond --export-json benchmarks/fibonacci_sequence/python_iteration.json 'python3 benchmarks/fibonacci_sequence/python_iteration.py'\n```\n\n**RESULT**:\\\nBenchmark 1: python3 benchmarks/fibonacci_sequence/python_iteration.py\\\n  Time (mean ± σ):     16374.7 µs ± 904.0 µs    [User: 11483.5 µs, System: 3680.0 µs]\\\n  Range (min … max):   15361.0 µs … 22863.3 µs    100 runs\n\n\n### Compile Python byte code\n\n```shell\npython3 -m compileall benchmarks/fibonacci_sequence/python_recursion.py\npython3 -m compileall benchmarks/fibonacci_sequence/python_iteration.py\n```\n\n```shell\nhyperfine --warmup 10 -r 100 --time-unit=microsecond --export-json benchmarks/fibonacci_sequence/python_recursion.cpython-311.json 'python3 benchmarks/fibonacci_sequence/__pycache__/python_recursion.cpython-311.pyc'\n# TIMEOUT!\n\nhyperfine --warmup 10 -r 100 --time-unit=microsecond --export-json benchmarks/fibonacci_sequence/python_iteration.cpython-311.json 'python3 benchmarks/fibonacci_sequence/__pycache__/python_iteration.cpython-311.pyc'\n```\n\n**RESULT**:\\\nBenchmark 1: python3 benchmarks/fibonacci_sequence/__pycache__/python_iteration.cpython-311.pyc\\\n  Time (mean ± σ):     16584.6 µs ± 761.5 µs    [User: 11451.8 µs, System: 3813.3 µs]\\\n  Range (min … max):   15592.0 µs … 20953.2 µs    100 runs\n\n\n### [Mojo Fibonacci Sequence Recursion](benchmarks/fibonacci_sequence/mojo_recursion.mojo)\n\n```mojo\nfn fibonacci_recursion(n: Int) -\u003e Int:\n    return n if n \u003c 2 else fibonacci_recursion(n - 1) + fibonacci_recursion(n - 2)\nfn main():\n    _ = fibonacci_recursion(100)\n```\n\n```shell\nhyperfine --warmup 10 -r 100 --time-unit=microsecond --export-json benchmarks/fibonacci_sequence/mojo_recursion.json 'mojo run benchmarks/fibonacci_sequence/mojo_recursion.mojo'\n```\n\n**RESULT: TIMEOUT, I canceled computation after 1m**\n\n\n### [Mojo Fibonacci Sequence Iteration](benchmarks/fibonacci_sequence/mojo_iteration.mojo)\n\n```mojo\nfn fibonacci_iteration(n: Int) -\u003e Int:\n    var a: Int = 0\n    var b: Int = 1\n    for _ in range(n):\n        a = b\n        b = a+b\n    return a\nfn main():\n    _ = fibonacci_iteration(100)\n```\n\n```shell\nhyperfine --warmup 10 -r 100 --time-unit=microsecond --export-json benchmarks/fibonacci_sequence/mojo_iteration.json 'mojo run benchmarks/fibonacci_sequence/mojo_iteration.mojo'\n```\n\n**RESULT**:\\\nBenchmark 1: mojo run benchmarks/fibonacci_sequence/mojo_iteration.mojo\\\n  Time (mean ± σ):     43852.7 µs ± 1353.5 µs    [User: 38156.0 µs, System: 10407.3 µs]\\\n  Range (min … max):   42033.6 µs … 49357.3 µs    100 runs\n\n\n### Compile Mojo code\n\n```shell\nmojo build benchmarks/fibonacci_sequence/mojo_recursion.mojo\nmojo build benchmarks/fibonacci_sequence/mojo_iteration.mojo\n```\n\n```shell\nhyperfine --warmup 10 -r 100 --time-unit=microsecond --export-json benchmarks/fibonacci_sequence/mojo_recursion.exe.json './benchmarks/fibonacci_sequence/mojo_recursion'\n# TIMEOUT!\n\nhyperfine --warmup 10 -r 100 --time-unit=microsecond --export-json benchmarks/fibonacci_sequence/mojo_iteration.exe.json './benchmarks/fibonacci_sequence/mojo_iteration'\n```\n\n**RESULT**:\\\nBenchmark 1: ./benchmarks/fibonacci_sequence/mojo_iteration\\\n  Time (mean ± σ):     934.6 µs ± 468.9 µs    [User: 409.8 µs, System: 247.8 µs]\\\n  Range (min … max):   552.7 µs … 4522.9 µs    100 runs\n\n\n### [Codon Fibonacci Sequence Recursion](benchmarks/fibonacci_sequence/codon_recursion.codon)\n\n```codon\ndef fibonacci_recursion(n):\n    return n if n \u003c 2 else fibonacci_recursion(n - 1) + fibonacci_recursion(n - 2)\nfibonacci_recursion(100)\n```\n\n```shell\nhyperfine --warmup 10 -r 100 --time-unit=microsecond --export-json benchmarks/fibonacci_sequence/codon_recursion.json 'codon run --release benchmarks/fibonacci_sequence/codon_recursion.codon'\n```\n\n**RESULT: TIMEOUT, I canceled computation after 1m**\n\n\n### [Codon Fibonacci Sequence Iteration](benchmarks/fibonacci_sequence/codon_iteration.codon)\n\n```codon\ndef fibonacci_iteration(n):\n    a, b = 0, 1\n    for _ in range(n):\n        a, b = b, a+b\n    return a\nfibonacci_iteration(100)\n```\n\n```shell\nhyperfine --warmup 10 -r 100 --time-unit=microsecond --export-json benchmarks/fibonacci_sequence/codon_iteration.json 'codon run --release benchmarks/fibonacci_sequence/codon_iteration.codon'\n```\n\n**RESULT**:\\\nBenchmark 1: codon run --release benchmarks/fibonacci_sequence/codon_iteration.codon\\\n  Time (mean ± σ):     628060.1 µs ± 10430.5 µs    [User: 584524.3 µs, System: 39358.5 µs]\\\n  Range (min … max):   612742.5 µs … 662716.9 µs    100 runs\n\n\n### Compile Codon code\n\n```shell\ncodon build --release -exe benchmarks/fibonacci_sequence/codon_recursion.codon\ncodon build --release -exe benchmarks/fibonacci_sequence/codon_iteration.codon\n```\n\n```shell\nhyperfine --warmup 10 -r 100 --time-unit=microsecond --export-json codon_recursion.exe.json './benchmarks/fibonacci_sequence/codon_recursion'\n# TIMEOUT!\n\nhyperfine --warmup 10 -r 100 --time-unit=microsecond --export-json benchmarks/fibonacci_sequence/codon_iteration.exe.json './benchmarks/fibonacci_sequence/codon_iteration'\n```\n\n**RESULT**:\\\nBenchmark 1: ./benchmarks/fibonacci_sequence/codon_iteration\\\n  Time (mean ± σ):     2732.7 µs ± 1145.5 µs    [User: 1466.0 µs, System: 1061.5 µs]\\\n  Range (min … max):   2036.6 µs … 13236.3 µs    100 runs\n\n\n### [Rust Fibonacci Sequence Recursion](benchmarks/fibonacci_sequence/rust/main.rs)\n\n```rust\nfn fibonacci_recursive(n: i64) -\u003e i64 {\n    if n \u003c 2 {\n        return n;\n    }\n    return fibonacci_recursive(n - 1) + fibonacci_recursive( n - 2);\n}\nfn main() {\n    let _ = fibonacci_recursive(100);\n}\n```\n\n```shell\nrustc -C opt-level=3 benchmarks/fibonacci_sequence/rust_recursion.rs -o benchmarks/fibonacci_sequence/rust_recursion\n\nhyperfine --warmup 10 -r 100 --time-unit=microsecond --export-json benchmarks/fibonacci_sequence/rust_recursion.json './benchmarks/fibonacci_sequence/rust_recursion'\n```\n\n**RESULT: TIMEOUT, I canceled computation after 1m**\n\n\n### [Rust Fibonacci Sequence Iteration](benchmarks/fibonacci_sequence/rust_iteration.rs)\n\n```rust\nfn fibonacci_iteration(n: usize) -\u003e usize {\n    let mut a = 1;\n    let mut b = 1;\n    for _ in 1..n {\n        let old = a;\n        a = b;\n        b += old;\n    }\n    b\n}\nfn main() {\n    let _ = fibonacci_iteration(100);\n}\n```\n\n```shell\nrustc -C opt-level=3 benchmarks/fibonacci_sequence/rust_iteration.rs -o benchmarks/fibonacci_sequence/rust_iteration\n\nhyperfine --warmup 10 -r 100 --time-unit=microsecond --export-json benchmarks/fibonacci_sequence/rust_iteration.json './benchmarks/fibonacci_sequence/rust_iteration'\n```\n\n**RESULT**:\\\nBenchmark 1: ./benchmarks/fibonacci_sequence/rust_iteration\\\n  Time (mean ± σ):     848.9 µs ± 283.2 µs    [User: 371.8 µs, System: 261.4 µs]\\\n  Range (min … max):   525.9 µs … 2607.3 µs    100 runs\n\n\n## Summary Fibonacci Sequence\n\n```shell\n# Merge all JSON files into benchmarks.json\npython3 benchmarks/hyperfine-scripts/merge_jsons.py benchmarks/fibonacci_sequence/ benchmarks/fibonacci_sequence/benchmarks.json\n\npython3 benchmarks/hyperfine-scripts/plot2.py benchmarks/fibonacci_sequence/benchmarks.json\n\npython3 benchmarks/hyperfine-scripts/plot3.py benchmarks/fibonacci_sequence/benchmarks.json\n\npython3 benchmarks/hyperfine-scripts/advanced_statistics.py benchmarks/fibonacci_sequence/benchmarks.json \u003e benchmarks/fibonacci_sequence/benchmarks.json.md\n\nsilicon benchmarks/fibonacci_sequence/benchmarks.json.md -l python -o benchmarks/fibonacci_sequence/benchmarks.json.md.png\n```\n\nAdvanced statistics\n\n\u003cimg src=\"benchmarks/fibonacci_sequence/benchmarks.json.md.png\" width=\"800\" /\u003e\n\nAll together\n\n\u003cimg src=\"benchmarks/fibonacci_sequence/benchmarks.json.all.png\" width=\"800\" /\u003e\n\nZoomed\n\n\u003cimg src=\"benchmarks/fibonacci_sequence/benchmarks.json.all2.png\" width=\"800\" /\u003e\n\nDetailed one by one\n\n\u003cimg src=\"benchmarks/fibonacci_sequence/benchmarks.json.combined.png\" width=\"800\" /\u003e\n\nPlaces\n\n1. Rust\n1. Mojo\n2. Codon\n3. Python\n\nBut here a lot of questions:\n\n* How to optimize code/build/run?\n* Why `mojo run` so slow?\n* Why `codon run --release` so slow?\n* Why compiled Python byte code +/- equals Python interpreter?\n* Why Python interpreter faster than Mojo/Codon `run`?\n\n\nSo, we can say that Mojo🔥 is as fast as Rust on Mac!\n\n\n## [Mandelbrot Set](https://en.wikipedia.org/wiki/Mandelbrot_set)\n\nLets find Mandelbrot Set where\n\nWIDTH = 960\\\nHEIGHT = 960\\\nMAX_ITERS = 200\n\nMIN_X = -2.0\\\nMAX_X = 0.6\\\nMIN_Y = -1.5\\\nMAX_Y = 1.5\n\n\n### [Python Mandelbrot Set](benchmarks/multibrot_set/multibrot.py)\n```python\ndef mandelbrot_kernel(c):\n    z = c\n    for i in range(MAX_ITERS):\n        z = z * z + c  # Change this for different Multibrot sets (e.g., 2 for Mandelbrot)\n        if z.real * z.real + z.imag * z.imag \u003e 4:\n            return i\n    return MAX_ITERS\n\n\ndef compute_mandelbrot():\n    t = [[0 for _ in range(WIDTH)] for _ in range(HEIGHT)] # Pixel matrix\n    dx = (MAX_X - MIN_X) / WIDTH\n    dy = (MAX_Y - MIN_Y) / HEIGHT\n    for row in range(HEIGHT):\n        for col in range(WIDTH):\n            t[row][col] = mandelbrot_kernel(complex(MIN_X + col * dx, MIN_Y + row * dy))\n    return t\n\n\ncompute_mandelbrot()\n```\n\n```shell\npython3 -m compileall benchmarks/multibrot_set/multibrot.py\n\nhyperfine --warmup 10 -r 10 --time-unit=microsecond --export-json benchmarks/multibrot_set/multibrot.cpython-311.json 'python3 benchmarks/multibrot_set/__pycache__/multibrot.cpython-311.pyc'\n```\n\n**RESULT**:\\\nBenchmark 1: python3 benchmarks/multibrot_set/__pycache__/multibrot.cpython-311.pyc\\\n  Time (mean ± σ):     5444155.4 µs ± 23059.7 µs    [User: 5419790.1 µs, System: 18131.3 µs]\\\n  Range (min … max):   5408155.3 µs … 5490548.4 µs    10 runs\\\n\n\n### [Mojo Mandelbrot Set](benchmarks/multibrot_set/multibrot.mojo)\n\nMojo version with no optimization.\n\n```mojo\n# Compute the number of steps to escape.\ndef multibrot_kernel(c: ComplexFloat64) -\u003e Int:\n    z = c\n    for i in range(MAX_ITERS):\n        z = z * z + c  # Change this for different Multibrot sets (e.g., 2 for Mandelbrot)\n        if z.squared_norm() \u003e 4:\n            return i\n    return MAX_ITERS\n\n\ndef compute_multibrot() -\u003e Tensor[FloatType]:\n    # create a matrix. Each element of the matrix corresponds to a pixel\n    t = Tensor[FloatType](HEIGHT, WIDTH)\n\n    dx = (MAX_X - MIN_X) / WIDTH\n    dy = (MAX_Y - MIN_Y) / HEIGHT\n\n    y = MIN_Y\n    for row in range(HEIGHT):\n        x = MIN_X\n        for col in range(WIDTH):\n            t[Index(row, col)] = multibrot_kernel(ComplexFloat64(x, y))\n            x += dx\n        y += dy\n    return t\n\n\n_ = compute_multibrot()\n```\n\n```shell\nmojo build benchmarks/multibrot_set/multibrot.mojo\n\nhyperfine --warmup 10 -r 10 --time-unit=microsecond --export-json benchmarks/multibrot_set/multibrot.exe.json './benchmarks/multibrot_set/multibrot'\n```\n\n**RESULT**:\\\nBenchmark 1: ./benchmarks/multibrot_set/multibrot\\\n  Time (mean ± σ):     135880.5 µs ± 1175.4 µs    [User: 133309.3 µs, System: 1700.1 µs]\\\n  Range (min … max):   134639.9 µs … 137621.4 µs    10 runs\n\n\n### [Mojo Parallelized Mandelbrot Set](benchmarks/multibrot_set/multibrot_mojo_parallelize.mojo)\n\n```mojo\nfn mandelbrot_kernel_SIMD[\n    simd_width: Int\n](c: ComplexSIMD[float_type, simd_width]) -\u003e SIMD[float_type, simd_width]:\n    \"\"\"A vectorized implementation of the inner mandelbrot computation.\"\"\"\n    let cx = c.re\n    let cy = c.im\n    var x = SIMD[float_type, simd_width](0)\n    var y = SIMD[float_type, simd_width](0)\n    var y2 = SIMD[float_type, simd_width](0)\n    var iters = SIMD[float_type, simd_width](0)\n\n    var t: SIMD[DType.bool, simd_width] = True\n    for i in range(MAX_ITERS):\n        if not t.reduce_or():\n            break\n        y2 = y * y\n        y = x.fma(y + y, cy)\n        t = x.fma(x, y2) \u003c= 4\n        x = x.fma(x, cx - y2)\n        iters = t.select(iters + 1, iters)\n    return iters\n\n\nfn compute_multibrot_parallelized() -\u003e Tensor[float_type]:\n    let t = Tensor[float_type](height, width)\n\n    @parameter\n    fn worker(row: Int):\n        let scale_x = (max_x - min_x) / width\n        let scale_y = (max_y - min_y) / height\n\n        @parameter\n        fn compute_vector[simd_width: Int](col: Int):\n            \"\"\"Each time we operate on a `simd_width` vector of pixels.\"\"\"\n            let cx = min_x + (col + iota[float_type, simd_width]()) * scale_x\n            let cy = min_y + row * scale_y\n            let c = ComplexSIMD[float_type, simd_width](cx, cy)\n            t.data().simd_store[simd_width](\n                row * width + col, mandelbrot_kernel_SIMD[simd_width](c)\n            )\n\n        # Vectorize the call to compute_vector where call gets a chunk of pixels.\n        vectorize[simd_width, compute_vector](width)\n\n    # Parallelized\n    parallelize[worker](height, height)\n    return t\n\n\ndef main():\n    _ = compute_multibrot_parallelized()\n```\n\n```shell\nmojo build benchmarks/multibrot_set/multibrot_mojo_parallelize.mojo\n\nhyperfine --warmup 10 -r 10 --time-unit=microsecond --export-json benchmarks/multibrot_set/multibrot_mojo_parallelize.exe.json './benchmarks/multibrot_set/multibrot_mojo_parallelize'\n```\n\n**RESULT**:\\\nBenchmark 1: ./benchmarks/multibrot_set/multibrot_mojo_parallelize\\\n  Time (mean ± σ):     7139.4 µs ± 596.4 µs    [User: 36535.2 µs, System: 6670.1 µs]\\\n  Range (min … max):   6222.6 µs … 8269.7 µs    10 runs\n\n\n### [Codon Mandelbrot Set](benchmarks/multibrot_set/multibrot.codon)\n```codon\ndef mandelbrot_kernel(c):\n    z = c\n    for i in range(MAX_ITERS):\n        z = z * z + c  # Change this for different Multibrot sets (e.g., 2 for Mandelbrot)\n        if z.real * z.real + z.imag * z.imag \u003e 4:\n            return i\n    return MAX_ITERS\n\n\ndef compute_mandelbrot():\n    t = [[0 for _ in range(WIDTH)] for _ in range(HEIGHT)]  # Pixel matrix\n\n    dx = (MAX_X - MIN_X) / WIDTH\n    dy = (MAX_Y - MIN_Y) / HEIGHT\n\n    @par(collapse=2)\n    for row in range(HEIGHT):\n        for col in range(WIDTH):\n            t[row][col] = mandelbrot_kernel(complex(MIN_X + col * dx, MIN_Y + row * dy))\n    return t\n\n\ncompute_mandelbrot()\n```\n\nFor test run or plot (uncomment code in the file)\n\n```shell\nCODON_PYTHON=/opt/homebrew/opt/python@3.11/Frameworks/Python.framework/Versions/3.11/lib/libpython3.11.dylib codon run --release benchmarks/multibrot_set/multibrot.codon\n```\n\nBuild and run\n\n```shell\ncodon build --release -exe benchmarks/multibrot_set/multibrot.codon -o benchmarks/multibrot_set/multibrot_codon\n\nhyperfine --warmup 10 -r 10 --time-unit=microsecond --export-json benchmarks/multibrot_set/multibrot_codon.json './benchmarks/multibrot_set/multibrot_codon'\n```\n\n**RESULT**:\\\nBenchmark 1: ./benchmarks/multibrot_set/multibrot_codon\\\n  Time (mean ± σ):     44184.7 µs ± 1142.0 µs    [User: 248773.9 µs, System: 72935.3 µs]\\\n  Range (min … max):   42963.8 µs … 46456.2 µs    10 runs\n\n\n```shell\ncodon build --release -exe benchmarks/multibrot_set/multibrot_codon_par.codon -o benchmarks/multibrot_set/multibrot_codon_par\n\nhyperfine --warmup 10 -r 10 --time-unit=microsecond --export-json benchmarks/multibrot_set/multibrot_codon_par.json './benchmarks/multibrot_set/multibrot_codon_par'\n```\n\n\n## Summary Mandelbrot Set\n\n```shell\n# Merge all JSON files into benchmarks.json\npython3 benchmarks/hyperfine-scripts/merge_jsons.py benchmarks/multibrot_set/ benchmarks/multibrot_set/benchmarks.json\n\npython3 benchmarks/hyperfine-scripts/plot2.py benchmarks/multibrot_set/benchmarks.json\n\npython3 benchmarks/hyperfine-scripts/plot3.py benchmarks/multibrot_set/benchmarks.json\n\npython3 benchmarks/hyperfine-scripts/advanced_statistics.py benchmarks/multibrot_set/benchmarks.json \u003e benchmarks/multibrot_set/benchmarks.json.md\n\nsilicon benchmarks/multibrot_set/benchmarks.json.md -l python -o benchmarks/multibrot_set/benchmarks.json.md.png\n```\n\nAdvanced statistics\n\n\u003cimg src=\"benchmarks/multibrot_set/benchmarks.json.md.png\" width=\"800\" /\u003e\n\nAll together\n\n\u003cimg src=\"benchmarks/multibrot_set/benchmarks.json.all.png\" width=\"800\" /\u003e\n\nZoomed\n\n\u003cimg src=\"benchmarks/multibrot_set/benchmarks.json.all2.png\" width=\"800\" /\u003e\n\nDetailed one by one\n\n\u003cimg src=\"benchmarks/multibrot_set/benchmarks.json.combined.png\" width=\"800\" /\u003e\n\nPlaces\n\n1. Mojo (parallelize)\n2. Codon\n3. Mojo\n4. Python\n\n\nLinks:\n\n* [Multibrot Set](https://en.wikipedia.org/wiki/Multibrot_set)\n\nMandelbrot = Multibrot with `power = 2`\n\n```python\nz = z**power + c  # You can change this for different set\n```\n\n* [Pillow built-in ImagingEffectMandelbrot](https://github.com/python-pillow/Pillow/blob/10.1.0/src/libImaging/Effects.c#L23)\n\n* [Exaloop Codon version of Mandelbrot](https://github.com/exaloop/codon/blob/develop/bench/mandelbrot/mandelbrot.codon)\n\n* [Modular Mojo version of Mandelbrot](https://github.com/modularml/mojo/blob/main/examples/mandelbrot.mojo)\n\n* [Mojo Complex squared_norm](https://docs.modular.com/mojo/stdlib/complex/complex.html#squared_norm)\n\n* [Matplotlib Mandelbrot](https://matplotlib.org/stable/gallery/showcase/mandelbrot.html)\n\n\n# Awesome Mojo🔥 code\n\n\n# Binary Search Algorithm\n\nIn computer science, [binary search algorithm](https://en.wikipedia.org/wiki/Binary_search_algorithm), also known as\nhalf-interval search, logarithmic search, or binary chop, is a search algorithm that finds the position of a target\nvalue within a sorted array.\n\nLet's do some code with Python, Mojo🔥, Swift, V, Julia, Nim, Zig.\n\nNote:\nFor **Python** and **Mojo** versions,\nI leave some optimization and make the code similar for measurement and comparison.\n\n## [Python Binary Search](algorithm/binary_search_Python.py)\n\n```python\nfrom typing import List\nimport timeit\n\nSIZE = 1000000\nMAX_ITERS = 100\nCOLLECTION = tuple(i for i in range(SIZE))  # Make it aka at compile-time.\n\n\ndef python_binary_search(element: int, array: List[int]) -\u003e int:\n    start = 0\n    stop = len(array) - 1\n    while start \u003c= stop:\n        index = (start + stop) // 2\n        pivot = array[index]\n        if pivot == element:\n            return index\n        elif pivot \u003e element:\n            stop = index - 1\n        elif pivot \u003c element:\n            start = index + 1\n    return -1\n\n\ndef test_python_binary_search():\n    _ = python_binary_search(SIZE - 1, COLLECTION)\n\n\nprint(\n    \"Average execution time of func in sec\",\n    timeit.timeit(lambda: test_python_binary_search(), number=MAX_ITERS),\n)\n```\n\n## [Mojo🔥 Binary Search](algorithm/BinarySearch_Mojo.mojo)\n\n```python\n\"\"\"Implements basic binary search.\"\"\"\n\nfrom Benchmark import Benchmark\nfrom Vector import DynamicVector\n\n\nalias SIZE = 1000000\nalias NUM_WARMUP = 0\nalias MAX_ITERS = 100\n\n\nfn mojo_binary_search(element: Int, array: DynamicVector[Int]) -\u003e Int:\n    var start = 0\n    var stop = len(array) - 1\n    while start \u003c= stop:\n        let index = (start + stop) // 2\n        let pivot = array[index]\n        if pivot == element:\n            return index\n        elif pivot \u003e element:\n            stop = index - 1\n        elif pivot \u003c element:\n            start = index + 1\n    return -1\n\n\n@parameter  # statement runs at compile-time.\nfn get_collection() -\u003e DynamicVector[Int]:\n    var v = DynamicVector[Int](SIZE)\n    for i in range(SIZE):\n        v.push_back(i)\n    return v\n\n\nfn test_mojo_binary_search() -\u003e F64:\n    fn test_closure():\n        _ = mojo_binary_search(SIZE - 1, get_collection())\n    return F64(Benchmark(NUM_WARMUP, MAX_ITERS).run[test_closure]()) / 1e9\n\n\nprint(\n    \"Average execution time of func in sec \",\n    test_mojo_binary_search(),\n)\n```\n\n**It is the first binary search written in Mojo🔥by community (@ego) and posted in mojo-chat.**\n\n\u003cimg src=\"img/python_binary_search_05.15.2023.png\" height=\"300\" /\u003e\n\u003cimg src=\"img/mojo_binary_search_05.15.2023.png\" height=\"300\" /\u003e\n\n## [Swift Binary Search](algorithm/binarySearch_Swift.swift)\n\n```swift\nfunc binarySearch(items: [Int], elem: Int) -\u003e Int {\n    var low = 0\n    var high = items.count - 1\n    var mid = 0\n    while low \u003c= high {\n        mid = Int((high + low) / 2)\n        if items[mid] \u003c elem {\n            low = mid + 1\n        } else if items[mid] \u003e elem {\n            high = mid - 1\n        } else {\n            return mid\n        }\n    }\n    return -1\n}\n\nlet items = [1, 2, 3, 4, 0].sorted()\nlet res = binarySearch(items: items, elem: 4)\nprint(res)\n```\n\n## [Julia Binary Search](algorithm/binarysearch_Julia.jl)\n\n```julia\nfunction binarysearch(lst::Vector{T}, val::T) where T\n    low = 1\n    high = length(lst)\n    while low ≤ high\n        mid = (low + high) ÷ 2\n        if lst[mid] \u003e val\n            high = mid - 1\n        elseif lst[mid] \u003c val\n            low = mid + 1\n        else\n            return mid\n        end\n    end\n    return 0\nend\n```\n\n## [Nim Binary Search](algorithm/binarySearch_Nim.nim)\n\n```nim\nproc binarySearch[T](a: openArray[T], key: T): int =\n  var b = len(a)\n  while result \u003c b:\n    var mid = (result + b) div 2\n    if a[mid] \u003c key: result = mid + 1\n    else: b = mid\n  if result \u003e= len(a) or a[result] != key: result = -1\n\n\nlet res = @[2,3,4,5,6,7,8,9,10,12,14,16,18,20,22,25,27,30]\necho binarySearch(res, 10)\n```\n\n## [Zig Binary Search](algorithm/BinarySearch_Zig.zig)\n\n```zig\nconst std = @import(\"std\");\n\nfn binarySearch(comptime T: type, arr: []const T, target: T) ?usize {\n    var lo: usize = 0;\n    var hi: usize = arr.len - 1;\n\n    while (lo \u003c= hi) {\n        var mid: usize = (lo + hi) / 2;\n\n        if (arr[mid] == target) {\n            return mid;\n        } else if (arr[mid] \u003c target) {\n            lo = mid + 1;\n        } else {\n            hi = mid - 1;\n        }\n    }\n\n    return null;\n}\n```\n\n## [V Binary Search](algorithm/binary_search_V.v)\n\n```v\nfn binary_search(a []int, value int) int {\n    mut low := 0\n    mut high := a.len - 1\n    for low \u003c= high {\n        mid := (low + high) / 2\n        if a[mid] \u003e value {\n            high = mid - 1\n        } else if a[mid] \u003c value {\n            low = mid + 1\n        } else {\n            return mid\n        }\n    }\n    return -1\n}\n\nfn main() {\n    search_list := [1, 2, 3, 5, 6, 7, 8, 9, 10]\n    println(binary_search(search_list, 9))\n}\n```\n\n## [Bonus V Breadth First Search Path](algorithm/bfs_V.v)\n    \n* [BFS at vlang examples](https://github.com/vlang/v/blob/master/examples/graphs/bfs.v)\n* [BFS original PR](https://github.com/ego/v/blob/e13474757bee0afa00e8c4dd013b14e2f4fbc428/examples/bfs.v)\n\n```v\nfn breadth_first_search_path(graph map[string][]string, vertex string, target string) []string {\n    mut path := []string{}\n    mut visited := []string{init: vertex}\n    mut queue := [][][]string{}\n    queue \u003c\u003c [[vertex], path]\n    for queue.len \u003e 0 {\n        mut idx := queue.len - 1\n        node := queue[idx][0][0]\n        path = queue[idx][1]\n        queue.delete(idx)\n        if node == target {\n            path \u003c\u003c node\n            return path\n        }\n        for child in graph[node] {\n            mut tmp := path.clone()\n            if child !in visited {\n                visited \u003c\u003c child\n                tmp \u003c\u003c node\n                queue \u003c\u003c [[child], tmp]\n            }\n        }\n    }\n    return path\n}\n\nfn main() {\n    graph := map{\n        'A': ['B', 'C']\n        'B': ['A', 'D', 'E']\n        'C': ['A', 'F']\n        'D': ['B']\n        'E': ['B', 'F']\n        'F': ['C', 'E']\n    }\n    println('Graph: $graph')\n    path := breadth_first_search_path(graph, 'A', 'F')\n    println('The shortest path from node A to node F is: $path')\n    assert path == ['A', 'C', 'F']\n}\n```\n\n# Fizz buzz\n\n* [Leetcode Fizz buzz problem](https://leetcode.com/problems/fizz-buzz/)\n* [Wikipedia Fizz buzz](https://en.wikipedia.org/wiki/Fizz_buzz)\n* Add some optimisation, according to a Wikipedia problem statement.\n\n## [Python Fizz buzz](algorithm/fizz_buzz_Python.py)\n\n```python\nimport timeit\n\nSIZE = 100\nMAX_ITERS = 100\n\n\ndef _fizz_buzz():  # Make it aka at compile-time.\n  res = []\n  for n in range(1, SIZE+1):\n    if (n % 3 == 0) and (n % 5 == 0):\n      s = \"FizzBuzz\"\n    elif n % 3 == 0:\n      s = \"Fizz\"\n    elif n % 5 == 0:\n      s = \"Buzz\"\n    else:\n      s = str(n)\n    res.append(s)\n  return res\n\n\nDATA = _fizz_buzz()\n\n\ndef fizz_buzz():\n  print(\"\\n\".join(DATA))\n\n\nprint(\n  \"Average execution time of Python func in sec\",\n  timeit.timeit(lambda: fizz_buzz(), number=MAX_ITERS),\n)\n\n# Average execution time of Python func in sec 0.005334990004485007\n```\n\n## [Clojure Fizz buzz](algorithm/fizz_buzz_Clojure.clj)\n\n```clojure\n(import '[java.io OutputStream])\n(require '[clojure.java.io :as io])\n\n(def devnull (io/writer (OutputStream/nullOutputStream)))\n\n(defmacro timeit [n expr]\n  `(with-out-str (time\n                   (dotimes [_# ~(Math/pow 1 n)]\n                     (binding [*out* devnull]\n                       ~expr)))))\n\n(defmacro macro-fizz-buzz [n]\n  `(fn []\n    (print\n      ~(apply str\n        (for [i (range 1 (inc n))]\n          (cond\n            (zero? (mod i 15)) \"FizzBuzz\\n\"\n            (zero? (mod i 5))  \"Buzz\\n\"\n            (zero? (mod i 3))  \"Fizz\\n\"\n            :else              (str i \"\\n\")))))))\n\n(print (timeit 100 (macro-fizz-buzz 100)))\n\n;; \"Elapsed time: 0.175486 msecs\"\n;; Average execution time of Clojure func in sec 0.000175486 seconds\n```\n\n## [Mojo🔥Fizz buzz](algorithm/fizz_buzz_Mojo.mojo)\n\n```python\nfrom String import String\nfrom Benchmark import Benchmark\n\nalias SIZE = 100\nalias NUM_WARMUP = 0\nalias MAX_ITERS = 100\n\n\n@parameter  # statement runs at compile-time.\nfn _fizz_buzz() -\u003e String:\n    var res: String = \"\"\n    for n in range(1, SIZE+1):\n      if (n % 3 == 0) and (n % 5 == 0):\n        res += \"FizzBuzz\"\n      elif n % 3 == 0:\n        res += \"Fizz\"\n      elif n % 5 == 0:\n        res += \"Buzz\"\n      else:\n        res += String(n)\n      res += \"\\n\"\n    return res\n\n\nfn fizz_buzz():\n    print(_fizz_buzz())\n\nfn run_benchmark() -\u003e F64:\n    fn _closure():\n        _ = fizz_buzz()\n    return F64(Benchmark(NUM_WARMUP, MAX_ITERS).run[_closure]()) / 1e9\n\n\nprint(\n    \"Average execution time of func in sec \",\n    run_benchmark(),\n)\n\n# Average execution time of func in sec  0.000104 🔥\n```\n**It is the first Fizz buzz written in Mojo🔥 ever by community (@Ego).**\n\n# [Merge sort](https://en.wikipedia.org/wiki/Merge_sort)\n\nWe will use algorithm from vell-known [reference](https://en.wikipedia.org/wiki/Introduction_to_Algorithms) for algorithms book [Introduction to Algorithms A3](https://mitpress.mit.edu/9780262046305/introduction-to-algorithms/)\n\nIts fame has led to the common use of the abbreviation \"**CLRS**\" (Cormen, Leiserson, Rivest, Stein), or, in the first edition, \"**CLR**\" (Cormen, Leiserson, Rivest).\n\n**Chapter 2** \"2.3.1 The divide-and-conquer approach\".\n\n## [Python Merge sort](algorithm/merge_sort_Python.py)\n\n```python\n%%python\n\nimport timeit\n\nMAX_ITERS = 100\n\n\ndef merge(A, p, q, r):\n    n1 = q - p + 1\n    n2 = r - q\n    L = [None] * n1\n    R = [None] * n2\n    for i in range(n1):\n        L[i] = A[p + i]\n    for j in range(n2):\n        R[j] = A[q + 1 + j]\n    i = 0\n    j = 0\n    k = p\n\n    while i \u003c n1 and j \u003c n2:\n        if L[i] \u003c= R[j]:\n            A[k] = L[i]\n            i += 1\n        else:\n            A[k] = R[j]\n            j += 1\n        k += 1\n\n    while i \u003c n1:\n        A[k] = L[i]\n        i += 1\n        k += 1\n\n    while j \u003c n2:\n        A[k] = R[j]\n        j += 1\n        k += 1\n\n\ndef merge_sort(A, p, r):\n    if p \u003c r:\n        q = (p + r) // 2\n        merge_sort(A, p, q)\n        merge_sort(A, q + 1, r)\n        merge(A, p, q, r)\n\n\ndef run_benchmark_merge_sort():\n    A = [14, 72, 50, 83, 18, 20, 13, 30, 17, 87, 94, 65, 24, 99, 70, 44, 5, 12, 74, 6, 32, 63, 91, 88, 43, 54, 27, 39, 64, 78, 29, 62, 58, 59, 61, 89, 2, 15, 41, 9, 93, 90, 23, 96, 73, 14, 8, 28, 11, 42, 77, 34, 52, 80, 57, 84, 21, 60, 66, 40, 7, 85, 47, 98, 97, 35, 82, 36, 49, 3, 68, 22, 67, 81, 56, 71, 4, 38, 69, 95, 16, 48, 1, 31, 75, 19, 10, 25, 79, 45, 76, 33, 53, 55, 46, 37, 26, 51, 92, 86]\n    merge_sort(A, 0, len(A)-1)\n\nprint(\n  \"Average execution time of Python `merge_sort` in sec\",\n  timeit.timeit(lambda: run_benchmark_merge_sort(), number=MAX_ITERS),\n)\n# Average execution time of Python `merge_sort` in sec 0.019136679999064654\n\n\ndef run_benchmark_sort():\n    A = [14, 72, 50, 83, 18, 20, 13, 30, 17, 87, 94, 65, 24, 99, 70, 44, 5, 12, 74, 6, 32, 63, 91, 88, 43, 54, 27, 39, 64, 78, 29, 62, 58, 59, 61, 89, 2, 15, 41, 9, 93, 90, 23, 96, 73, 14, 8, 28, 11, 42, 77, 34, 52, 80, 57, 84, 21, 60, 66, 40, 7, 85, 47, 98, 97, 35, 82, 36, 49, 3, 68, 22, 67, 81, 56, 71, 4, 38, 69, 95, 16, 48, 1, 31, 75, 19, 10, 25, 79, 45, 76, 33, 53, 55, 46, 37, 26, 51, 92, 86]\n    A.sort()\n\nprint(\n    \"Average execution time of Python builtin `sort` in sec\",\n    timeit.timeit(lambda: run_benchmark_sort(), number=MAX_ITERS),\n)\n# Average execution time of Python builtin `sort` in sec 0.00019922800129279494\n```\n\n## [Mojo🔥 Merge sort](algorithm/MergeSort_Mojo.mojo)\n\n```python\nfrom Benchmark import Benchmark\nfrom Vector import DynamicVector\nfrom StaticTuple import StaticTuple\nfrom Sort import sort\n\nalias NUM_WARMUP = 0\nalias MAX_ITERS = 100\n\n\nfn merge(inout A: DynamicVector[Int], p: Int, q: Int, r: Int):\n    let n1 = q - p + 1\n    let n2 = r - q\n\n    var L = DynamicVector[Int](n1)\n    var R = DynamicVector[Int](n2)\n\n    for i in range(n1):\n        L[i] = A[p + i]\n    for j in range(n2):\n        R[j] = A[q + 1 + j]\n\n    var i = 0\n    var j = 0\n    var k = p\n\n    while i \u003c n1 and j \u003c n2:\n        if L[i] \u003c= R[j]:\n            A[k] = L[i]\n            i += 1\n        else:\n            A[k] = R[j]\n            j += 1\n        k += 1\n\n    while i \u003c n1:\n        A[k] = L[i]\n        i += 1\n        k += 1\n\n    while j \u003c n2:\n        A[k] = R[j]\n        j += 1\n        k += 1\n\n\nfn merge_sort(inout A: DynamicVector[Int], p: Int, r: Int):\n    if p \u003c r:\n        let q = (p + r) // 2\n        merge_sort(A, p, q)\n        merge_sort(A, q + 1, r)\n        merge(A, p, q, r)\n\n\n@parameter\nfn create_vertor() -\u003e DynamicVector[Int]:\n    let st = StaticTuple[MAX_ITERS, Int](14, 72, 50, 83, 18, 20, 13, 30, 17, 87, 94, 65, 24, 99, 70, 44, 5, 12, 74, 6, 32, 63, 91, 88, 43, 54, 27, 39, 64, 78, 29, 62, 58, 59, 61, 89, 2, 15, 41, 9, 93, 90, 23, 96, 73, 14, 8, 28, 11, 42, 77, 34, 52, 80, 57, 84, 21, 60, 66, 40, 7, 85, 47, 98, 97, 35, 82, 36, 49, 3, 68, 22, 67, 81, 56, 71, 4, 38, 69, 95, 16, 48, 1, 31, 75, 19, 10, 25, 79, 45, 76, 33, 53, 55, 46, 37, 26, 51, 92, 86)\n    var v = DynamicVector[Int](st.__len__())\n    for i in range(st.__len__()):\n        v.push_back(st[i])\n    return v\n\n\nfn run_benchmark_merge_sort() -\u003e F64:\n    fn _closure():\n        var A = create_vertor()\n        merge_sort(A, 0, len(A)-1)\n    return F64(Benchmark(NUM_WARMUP, MAX_ITERS).run[_closure]()) / 1e9\n\nprint(\n    \"Average execution time of Mojo🔥 `merge_sort` in sec \",\n    run_benchmark_merge_sort(),\n)\n# Average execution time of Mojo🔥 `merge_sort` in sec 1.1345999999999999e-05\n\n\nfn run_benchmark_sort() -\u003e F64:\n    fn _closure():\n        var A = create_vertor()\n        sort(A)\n    return F64(Benchmark(NUM_WARMUP, MAX_ITERS).run[_closure]()) / 1e9\n\nprint(\n    \"Average execution time of Mojo🔥 builtin `sort` in sec \",\n    run_benchmark_sort(),\n)\n# Average execution time of Mojo🔥 builtin `sort` in sec 2.988e-06\n```\n\nYou can use it like:\n\n```python\n# Usage: merge_sort\n\nvar A = create_vertor()\nmerge_sort(A, 0, len(A)-1)\n\nprint(len(A))\nprint(A[0], A[99])\n```\n\nBuiltin `from Sort import sort` [quicksort](https://en.wikipedia.org/wiki/Quicksort) a little bit [faster](https://en.wikipedia.org/wiki/Sorting_algorithm#Comparison_of_algorithms) than our implementation,\nbut we can optimize it during deep in language and as usual with algorithms =) and programming paradigms.\n\n- Multithreaded Algorithms, Multithreaded merge sort at pages 797, 803 of the book **CLRS** above\n- Three Hungarians' Algorithm\n- Use insertion sort for small subarrays, hybrid merge sort\n- Merge in a different direction\n- Use an adaptive approach\n- Implement in-place merging\n- Optimize memory access\n- [Mojo Stdlib Functional](https://docs.modular.com/mojo/MojoStdlib/Functional.html)\n- **Tiled merge sort** like in [Tiling Matmul](https://docs.modular.com/mojo/notebooks/Matmul.html#tiling-matmul)\n- Parallel multiway merge sort\n\n## Summary for sorting algorithms merge sort and quicksort\n\n| Lang                | sec             |\n|---------------------|-----------------|\n| Python merge_sort   | **0.019136679** |\n| Python builtin sort | **0.000199228** |\n| Mojo merge_sort     | **0.000011346** |\n| Mojo builtin sort   | **0.000002988** |\n\nLet's build a plot for this table.\n\n```python\n#%%python\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nlanguages = ['Python merge_sort', 'Python builtin sort', 'Mojo merge_sort', 'Mojo builtin sort']\nseconds = [0.019136679, 0.000199228, 0.000011346, 0.000002988]\n\n# Apply a custom transformation to the values\ntransformed_seconds = [np.sqrt(1 / x) for x in seconds]\n\nplt.barh(languages, transformed_seconds)\nplt.xlabel('Custom Transformation')\nplt.ylabel('Language and Sort Type')\nplt.title('Comparison of Sorting Algorithms (Custom Transformation)')\n\nplt.show()\n```\n\nPlot notes, more is better and faster.\n\n\u003cimg src=\"img/comparison_sorting.png\" /\u003e\n\n\n# Programming manual\n\n## Parameterization[]: compile time meta-programming\n\nI strongly recommended start from here [HelloMojo](https://docs.modular.com/mojo/notebooks/HelloMojo.html)\nand understand **[parameter]** and **[parameter expressions]** [parameterization here](https://docs.modular.com/mojo/notebooks/HelloMojo.html#parameterization-compile-time-meta-programming).\nLike in this example:\n\n```python\nfn concat[len1: Int, len2: Int](lhs: MySIMD[len1], rhs: MySIMD[len2]) -\u003e MySIMD[len1+len2]:\n    let result = MySIMD[len1 + len2]()\n    for i in range(len1):\n        result[i] = lhs[i]\n    for j in range(len2):\n        result[len1 + j] = rhs[j]\n    return result\n\n\nlet a = MySIMD[2](1, 2)\nlet x = concat[2,2](a, a)\nx.dump()\n```\n\nCompile time **[Parameters]:** `fn concat[len1: Int, len2: Int]`.\n\nRun time **(Args)**: `fn concat(lhs: MySIMD, rhs: MySIMD)`.\n\nParameters [PEP695](https://peps.python.org/pep-0695/) syntax in square `[]` brackets.\n\nNow in Python:\n\n```python\ndef func(a: _T, b: _T) -\u003e _T:\n    ...\n```\n\nNow in Mojo🔥:\n\n```python\ndef func[T](a: T, b: T) -\u003e T:\n    ...\n```\n\n**[Parameters]** are named and have types **like normal values** in a Mojo program, but `parameters[]` are evaluated at **compile time**.\n\nThe runtime program may use the value of **[parameters]** - because the parameters are resolved at compile time\nbefore they are needed by the runtime program - but the compile time parameter expressions may not use runtime values.\n\n`Self` type from [PEP673](https://peps.python.org/pep-0673/)\n\n```python\nfn __sub__(self, rhs: Self) -\u003e Self:\n    let result = MySIMD[size]()\n    for i in range(size):\n        result[i] = self[i] - rhs[i]\n    return result\n```\n\nIn the docs you can find word **Fields** it is aka class **Attributes** in the Python.\n\nSo, you call them with `dot`.\n\n```python\nfrom DType import DType\nlet bool_type = DType.bool\n```\n\n## Data Type Model and alias\n\n* The base construct block is [DType](https://docs.modular.com/mojo/MojoStdlib/DType.html).\n  Some analogies:\n  - [NumPy dtype](https://numpy.org/doc/stable/reference/generated/numpy.dtype.html#numpy-dtype)\n  - [Jax dtype](https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.dtype.html#jax-numpy-dtype)\n  - [TensorFlow DType](https://www.tensorflow.org/api_docs/python/tf/dtypes/DType)\n\n```python\nfrom DType import DType\nDType.si8\n```\n\n* Then you can wrap it with **SIMD struct** aka container.\n* SIMD [Single Instruction, Multiple Data](https://docs.modular.com/mojo/MojoStdlib/SIMD.html) and [SIMD at wikipedia](https://en.wikipedia.org/wiki/Single_instruction,_multiple_data)\n\n```python\nfrom DType import DType\nfrom SIMD import SIMD, SI8\n\nalias MY_SIMD_DType_si8 = SIMD[DType.si8, 1]\nalias MY_SI8 = SI8\nprint(MY_SIMD_DType_si8 == MY_SI8)\n# true\n```\n\n* Then a sequence of these types you can wrap with a container [DynamicVector](https://docs.modular.com/mojo/MojoStdlib/Vector.html) or similar.\n\n```python\nfrom DType import DType\nfrom SIMD import SIMD, SI8\nfrom Vector import DynamicVector\nfrom String import String\n\nalias a = DynamicVector[SIMD[DType.si8, 1]]\nalias b = DynamicVector[SI8]\nprint(a == b)\nprint(a == String)\nprint(b == String)\n# all true\n```\n\nSo the `String` is only alias for a something like `DynamicVector[SIMD[DType.si8, 1]]`.\n\n## `VariadicList` for destructuring/unpacking/accessing arguments\n\n```python\nfrom List import VariadicList\n\nfn destructuring_arguments(*args: Int):\n    let my_var_list = VariadicList(args)\n    for i in range(len(my_var_list)):\n        print(\"argument\", i, \":\", my_var_list[i])\n\ndestructuring_arguments(1, 2, 3, 4)\n```\n\nIt is very useful for creating initial collections.\nWe can write like this:\n\n```python\nfrom Vector import DynamicVector\nfrom StaticTuple import StaticTuple\n\nfn create_vertor() -\u003e DynamicVector[Int]:\n    let st = StaticTuple[4, Int](1, 2, 3, 4)\n    var v = DynamicVector[Int](st.__len__())\n    for i in range(st.__len__()):\n    v.push_back(st[i])\n    return v\n\nv = create_vertor()\nprint(v[0], v[3])\n\n# or\nfrom List import VariadicList\n\nfn create_vertor() -\u003e DynamicVector[Int]:\n  let var_list = VariadicList(1, 2, 3, 4)\n  var v = DynamicVector[Int](len(var_list))\n  for i in range(len(var_list)):\n    v.push_back(var_list[i])\n  return v\n\nv = create_vertor()\nprint(v[0], v[3])\n```\n\nRead more about function [def](https://docs.modular.com/mojo/notebooks/HelloMojo.html#fn-definitions) and [fn](https://docs.modular.com/mojo/programming-manual.html#fn-definitions)\n\n## String\n\n```python\nfrom String import String\n# String concatenation\nprint(String(\"'\") + String(1) + \"'\\n\")\n\n# Python's join\nprint(String(\"|\").join(\"a\", \"b\", \"c\"))\n\n# String format\nfrom IO import _printf as print\nlet x: Int = 1\nprint(\"'%i'\\n\", x.value)\n```\n\n### String and builtin slice\n\nFor a string you can use [Builtin Slice](https://docs.modular.com/mojo/MojoBuiltin/BuiltinSlice.html) with format string slice[start:end:step].\n\n```python\nfrom String import String\n\nlet hello_mojo = String(\"Hello Mojo!\")\nprint(\"Till the end:\", hello_mojo[0::])\nprint(\"Before last 2 chars:\", hello_mojo[0:-2])\nprint(\"From start to the end with step 2:\", hello_mojo[0::2])\nprint(\"From start to the before last with step 3:\", hello_mojo[0:-1:3])\n```\n\n\u003cimg src=\"img/string_slice.png\" height=\"200\" /\u003e\n\nThere is some problem with unicode, when slicing 🔥:\n\n```python\nlet hello_mojo_unicode = String(\"Hello Mojo🔥!\")\nprint(\"Unicode efore last 2 chars:\", hello_mojo_unicode[0:-2])\n# no result, silents\n```\n\nHere is an [explanation](https://mzaks.medium.com/counting-chars-with-simd-in-mojo-140ee730bd4d) and some [discussion](https://github.com/modularml/mojo/discussions/270).\n\n[mbstowcs - convert a multibyte string to a wide-character string](https://man7.org/linux/man-pages/man3/mbstowcs.3.html)\n\n## Mojo🔥decorators\n\n### @value\n`struct` decorator aka Python `@dataclass`.\nIt will generate methods `__init__`, `__copyinit__`, `__moveinit__` for you automatically.\n\n```python\n@value\nstruct dataclass:\n    var name: String\n    var age: Int\n```\nNote that the `@value` decorator only works on types whose members are `copyable` and/or `movable`.\n\n### @value(\"trivial\")\n\n### @register_passable(\"trivial\")\nTrivial types. This decorator tells Mojo that the type should be copyable `__copyinit__` and movable `__moveinit__`.\nIt also tells Mojo to prefer to pass the value in CPU registers.\nAllows `structs` to opt-in to being passed in a `register` instead of passing through `memory`.\n\n```python\n@register_passable(\"trivial\")\nstruct Int:\n    var value: __mlir_type.`!pop.scalar\u003cindex\u003e`\n```\n\n### @always_inline\nDecorators that provide full **control** over **compiler optimizations**.\nInstructs compiler to always **inline** this function when it’s called.\n\n```python\n@always_inline\nfn foo(x: Int, y: Int) -\u003e Int:\n    return x + y\n\nfn bar(z: Int):\n    let r = foo(z, z) # This call will be inlined\n```\n\n### @parameter\nIt can be placed on nested functions that capture runtime values to create “parametric” capturing closures.\nIt allows closures that capture runtime values to be passed as parameter values.\n\n### Decorators combination\n```python\n@always_inline\n@parameter\nfn test(): return\n```\n\n## Casting\n\nSome casting examples\n\n```python\ns: StringLiteral\nlet p = DTypePointer[DType.si8](s.data()).bitcast[DType.ui8]()\nvar result = 0\nresult += ((p.simd_load[64](offset) \u003e\u003e 6) != 0b10).cast[DType.ui8]().reduce_add().to_int()\nlet rest_p: DTypePointer[DType.ui8] = stack_allocation[simd_width, UI8, 1]()\n\nfrom Bit import ctlz\ns: String\ni: Int\nlet code = s.buffer.data.load(i)\nlet byte_length_code = ctlz(~code).to_int()\n```\n\n## Stack, Mem, Pointer, Allocation, Free\n\n## DTypePointer, Heap and Stack\n\n**DTypePointer** - store an address with a given DType, allowing you to allocate, load and modify data with convenient access to SIMD operations.\n\n```python\nfrom Pointer import DTypePointer\nfrom DType import DType\nfrom Random import rand\nfrom Memory import memset_zero\n\n# `heap`\nvar my_pointer_on_heap = DTypePointer[DType.ui8].alloc(8)\nmemset_zero(my_pointer_on_heap, 8)\n\n# `stack or register`\nvar data = my_pointer_on_heap.simd_load[8](0)\nprint(data)\n\nrand(my_pointer_on_heap, 4)\n\n# `data` does not contain a reference to the `heap`, so load the data again\ndata = my_pointer_on_heap.simd_load[8](0)\nprint(data)\n\n# simd_load and simd_store\nvar half = my_pointer_on_heap.simd_load[4](0)\nhalf = half + 1\nmy_pointer_on_heap.simd_store[4](4, half)\nprint(my_pointer_on_heap.simd_load[8](0))\n\n# Pointer move back\nmy_pointer_on_heap -= 1\nprint(my_pointer_on_heap.simd_load[8](0))\n\n# Mast free memory\nmy_pointer_on_heap.free()\n```\n\nStruct can minimaze potential dangerous of pointers by limiting scoup.\n\nExcellent article on Mojo Dojo blog about [DTypePointer here](https://mojodojo.dev/guides/modules/Pointer/DTypePointer.html#storing-and-loading-simd-data)\n\nPlus his example [Matrix Struct and DTypePointer](algorithm/MatrixStruct.mojo)\n\n## Pointer\n\n[Pointer](https://docs.modular.com/mojo/MojoStdlib/Pointer.html) store an address to any `register_passable type`, and allocate `n` amount of them to the `heap`.\n\n```python\nfrom Pointer import Pointer\nfrom Memory import memset_zero\nfrom String import String\n\n@register_passable  # for syntaxt like `let coord = p1[0]` and let it be passed through registers.\nstruct Coord:  # memory-only type\n    var x: UI8\n    var y: UI8\n\nvar p1 = Pointer[Coord].alloc(2)\n\nmemset_zero(p1, 2)\nvar coord = p1[0]  # is an identifier to memory on the stack or in a register\nprint(coord.x)\n\n# Store the value\n\ncoord.x = 5\ncoord.y = 5\nprint(coord.x)\n\n# We need to store the data.\np1.store(0, coord)\nprint(p1[0].x)\n\n# Mast free memory\np1.free()\n```\n\nFull article about [Pointer](https://mojodojo.dev/guides/modules/Pointer/Pointer.html)\n\nPlus exemple [Pointer and Struct](algorithm/Pointer.mojo)\n\n## Advanced Mojo🔥features and Intrinsics module\nModular [Intrinsics](https://docs.modular.com/mojo/MojoStdlib/Intrinsics.html) it is some kind of **execution backends**:\n\n- Mojo🔥**compiler** features\n- **LLVM intrinsic** maybe [this one](https://libc.llvm.org/stdio.html)\n- **External call** like [libc](https://www.gnu.org/software/libc/manual/html_node/Function-Index.html)\n- [MLIR Multi-Level Intermediate Representation](https://docs.modular.com/mojo/notebooks/BoolMLIR.html)\n\nMojo🔥-\u003e [MLIR Dialects](https://mlir.llvm.org/docs/Dialects/) -\u003e execution backends with optimization code and architectures.\n\n[MLIR](https://mlir.llvm.org/docs) is a compiler infrastructure witch implementing various transformation and optimization passes for different **programming languages** and **architectures**.\n\n### Syscalls\nMLIR itself does not directly provide functionality for interacting with operating system [syscalls](https://en.wikipedia.org/wiki/System_call).\n\nWhich are low-level interfaces to operating system services, are typically handled at the level of the target programming language or the operating system itself.\nMLIR is designed to be language-and-target-agnostic, and its primary focus is on providing an intermediate representation for performing optimizations.\nTo perform operating system syscalls in MLIR, we need to use a target-specific **backend**.\n\nBut with these `execution backends`, basically, we have access to OS syscalls.\nAnd we have the whole world of C/LLVM/Python stuff under the hood.\n\nLets have same quick look on it in practice:\n\n```python\nfrom OS import getenv\n\nprint(getenv(\"PATH\"))\nprint(getenv(StringRef(\"PATH\")))\n\n# or like this\nfrom SIMD import SI8\nfrom Intrinsics import external_call\n\nvar path1 = external_call[\"getenv\", StringRef](StringRef(\"PATH\"))\nprint(path1.data)\n\nvar path2 = external_call[\"getenv\", StringRef](\"PATH\")\nprint(path2.data)\n\nlet abs_10 = external_call[\"abs\", SI8, Int](-10)\nprint(abs_10)\n```\n\nIn this simple example we used `external_call` to get OS environment variable with a casting type between Mojo and libc functions.\nPretty cool, yeah!\n\nI have a lot of ideas from this topic and I am eagerly awaiting the opportunity to implement them soon.\nTaking action can lead to amazing outcomes =)\n\n## MLIR libc gethostname\n\nLet's do something interesting - call `libc function` [gethostname](https://www.gnu.org/software/libc/manual/html_node/Host-Identification.html#index-gethostname).\n\nFunction has this interface `int gethostname (char *name, size_t size)`.\n\nFor that we can use helper function [external_call](https://docs.modular.com/mojo/MojoStdlib/Intrinsics.html#external_call) from **Intrinsics** module or write own [MLIR](https://docs.modular.com/mojo/notebooks/HelloMojo.html#direct-access-to-mlir).\n\nLet's go code:\n\n```python\nfrom Intrinsics import external_call\nfrom SIMD import SIMD, SI8\nfrom DType import DType\nfrom Vector import DynamicVector\nfrom DType import DType\nfrom Pointer import DTypePointer, Pointer\n\n# We can use `from String import String` but for clarification we will use a full form.\n# DynamicVector[SIMD[DType.si8, 1]] == DynamicVector[SI8] == String\n\n# Compile time stuff.\nalias cArrayOfStrings = DynamicVector[SIMD[DType.si8, 1]]\nalias capacity = 1024\n\nvar c_pointer_to_array_of_strings = DTypePointer[DType.si8](cArrayOfStrings(capacity).data)\nvar c_int_result = external_call[\"gethostname\", Int, DTypePointer[DType.si8], Int](c_pointer_to_array_of_strings, capacity)\nlet mojo_string_result = String(c_pointer_to_array_of_strings.address)\n\nprint(\"C function gethostname result code:\", c_int_result)\nprint(\"C function gethostname result value:\", star_hostname(mojo_string_result))\n\n\n@always_inline\nfn star_hostname(hostname: String) -\u003e String:\n    # [Builtin Slice](https://docs.modular.com/mojo/MojoBuiltin/BuiltinSlice.html)\n    # string slice[start:end:step]\n    return hostname[0:-1:2]\n```\n\n\u003cimg src=\"img/gethostname.png\" height=\"200\" /\u003e\n\n\n## Mojo🔥TCP Socket Server with PythonInterface\n\nLet's do some things for a WEB with Mojo🔥.\nWe do not have Internet access at playground.modular.com\nBut we can steal do some interesting stuff like TCP on one machine.\n\nLet's write the first TCP client-server code in Mojo🔥 with [PythonInterface](https://docs.modular.com/mojo/MojoPython/PythonInterface.html)\n\n\u003cimg src=\"img/TCPSocketServer.png\" width=\"600\" /\u003e\n\u003cimg src=\"img/TCPSocketClient.png\" width=\"600\" /\u003e\n\n* [Mojo TCP Socket Server](algorithm/TCPSocketServer.mojo)\n* [Mojo TCP Client Server](algorithm/TCPSocketClient.mojo)\n\nYou should create two separate notebooks, and run **TCPSocketServer** first then **TCPSocketClient**.\n\n**Python version** of this code almost the same, except:\n\n- `with` syntax\n- `let` assigning\n- and destructuring like `a, b = (1, 2)`\n\n* [Pytohn socket low-level networking interface](https://docs.python.org/3/library/socket.html)\n* [Pytohn socketserver framework for network servers](https://docs.python.org/3/library/socketserver.html#module-socketserver)\n\n\n## Mojo🔥FastAPI with PythonInterface\n\nAfter TCP Server in Mojo🔥 we are going forward =)\n\nIt's crazy, but let's try to run modern Python web server [FastAPI](https://fastapi.tiangolo.com) with Mojo🔥!\n\n### Preparation\nWe need to upload FastAPI code to playground.\nSo, on your local machine do\n\n```shell\npip install --target=web fastapi uvicorn\ntar -czPf web.tar.gz web\n```\nand upload `web.tar.gz` to playground via web interface.\n\nThen we need to `install` it, just put into proper folder:\n\n```python\n%%python\nimport os\nimport site\n\nsite_packages_path = site.getsitepackages()[0]\n# install fastapi\nos.system(f\"tar xzf web.tar.gz -C {site_packages_path}\")\nos.system(f\"cp -r {site_packages_path}/web/* {site_packages_path}/\")\nos.system(f\"ls {site_packages_path} | grep fastapi\")\n# clean packages\nos.system(f\"rm -rf {site_packages_path}/web\")\nos.system(f\"rm web.tar.gz\")\n```\n\n### Mojo🔥FastAPI Server\n\n```python\nfrom PythonInterface import Python\n\n# Python fastapi\nlet fastapi = Python.import_module(\"fastapi\")\nlet uvicorn = Python.import_module(\"uvicorn\")\n\nvar app = fastapi.FastAPI()\nvar router = fastapi.APIRouter()\n\n# tricky part\nlet py = Python()\nlet py_code = \"\"\"lambda: 'Hello Mojo🔥!'\"\"\"\nlet py_obj = py.evaluate(py_code)\nprint(py_obj)\n\nrouter.add_api_route(\"/mojo\", py_obj)\napp.include_router(router)\n\nprint(\"Start FastAPI WEB Server\")\nuvicorn.run(app)\nprint(\"Done\")\n```\n\n### Mojo🔥FastAPI Client\n\n```python\nfrom PythonInterface import Python\nlet http_client = Python.import_module(\"http.client\")\n\nlet conn = http_client.HTTPConnection(\"localhost\", 8000)\nconn.request(\"GET\", \"/mojo\")\nlet response = conn.getresponse()\nprint(response.status, response.reason, response.read())\n```\n\nAs usual, you should create two separate notebooks, and run **FastAPI** first then **FastAPIClient**.\n\n* [Mojo🔥FastAPI Server](algorithm/MojoFastAPI.mojo)\n* [Mojo🔥FastAPI Server Jupyter Notebook](notebooks/MojoFastAPI.ipynb)\n* [Mojo🔥FastAPI Client](algorithm/MojoFastAPIClient.mojo)\n* [Mojo🔥FastAPI Client Jupyter Notebook](notebooks/MojoFastAPIClient.ipynb)\n\nThere are a lot of open questions, but basically we achieve the goal.\n\n\u003cimg src=\"img/MojoFastAPI.png\" width=\"600\" /\u003e\n\u003cimg src=\"img/MojoFastAPIClient.png\" width=\"600\" /\u003e\n\nMojo🔥 well done!\n\nSome open questions:\n\n- Lack of Python syntax sugar\n- Lack of Mojo types implicitly converted into Python objects\n- How to pass Mojo function into Python space/function\n\n```python\nfrom PythonInterface import Python\n\nlet pyfn = Python.evaluate(\"lambda x, y: x+y\")\nlet functools = Python.import_module(\"functools\")\nprint(functools.reduce(pyfn, [1, 2, 3, 4]))\n\n# How to, without Mojo pyfn.so?\ndef pyfn(x, y):\n    retyrn x+y\n```\n\nThe future looks very optimistic!\n\nLinks:\n\n* [Mojo types in Python](https://docs.modular.com/mojo/programming-manual.html#mojo-types-in-python)\n* [Mandelbrot in Mojo with Python plots](https://docs.modular.com/mojo/notebooks/Mandelbrot.html)\n\n\n# Code implementation\n\n## Radiative transfer\n[Benchmark Mojo vs Numba by Nick Wogan](https://gist.github.com/Nicholaswogan/ca156adb065cb598bd3903b3eaab2381)\n\n## Instant and DateTimeLocal\n[Time utils by Samay Kapadia @Zalando](https://github.com/modularml/mojo/issues/156)\n\n## IDEA\n[Connecting to your mojo playground from VSCode or DataSpell](https://github.com/modularml/mojo/discussions/277)\n\n## Python Interface and reading files\nby Maxim Zaks\n\n```python\nfrom String import String\nfrom PythonInterface import Python\n\nlet pathlib = Python.import_module('pathlib')\nlet txt = pathlib.Path('nfl.csv').read_text()\nlet s: String = txt.to_string()\n```\n\n\n[libc implementation](https://github.com/crisadamo/mojo-libc/blob/main/Libc.mojo)\n\n## Pointer data\n\n```python\nfrom DType import DType\nfrom Buffer import Buffer\nfrom Pointer import Pointer\nfrom String import String, chr\n\nlet hello = \"hello\"\nlet pointer = Pointer(hello.data())\n\nprint(\"variant 1\")\nvar result = String()\nfor i in range(len(hello)):\n    result += chr(pointer.bitcast[Int8]().offset(i).load().to_int())\nprint(result)\n\nprint(\"variant 2\")\nprint(StringRef(hello.data()))\n\nprint(\"variant 3\")\nprint(StringRef(pointer.address))\n\nprint(\"variant 4\")\nlet pm: Pointer[__mlir_type.`!pop.scalar\u003csi8\u003e`] = Pointer(hello.data())\nprint(StringRef(pm.address))\n\nprint(\"variant 5\")\nprint(String(pointer.address))\n\nprint(\"variant 6\")\nlet x = Buffer[8, DType.int8](pointer)\nlet array = x.simd_load[10](0)\nvar result = String()\nfor i in range(len(array)):\n    result += chr(array[i].to_int())\nprint(result)\n```\n\n\n## Code share from Mojo Playground\n\n1. From the Mojo Playground, `right click` the file in the explorer and press `Open With \u003e Editor`\n2. Right click in the editor, `select all` and `copy`\n3. Create a new [GitHub gist](https://gist.github.com) or put Jupyter notebook file into yor GitHub repository\n4. Paste in the contents and name the file with the Jupyter extension like test`.ipynb`\n5. Paste the link to the gist in the Discord chat\n\nGithub renders it properly, and then if someone wants to try out the code in their playground they can copy paste the raw code.\n\n\n# The Zen of Mojo🔥\n\n* [Style Guide for Mojo Code. Zen of Mojo #141](https://github.com/modularml/mojo/discussions/141)\n\n# Space for improvements\n\nIt is my personal view, so don't judge me too harshly.\n\nI can't say that Mojo🔥 is an easy programming language for learning, like a Python as an example.\n\nIt requires a lot of understanding, patience and experience in any other programming languages.\n\nIf you want to build something not trivial, it will be hard but funny!\n\nIt has been **2 weeks** since I embarked on this **journey**, and I am thrilled to share that I have now become **well-acquainted** with the Mojo🔥.\n\nThe intricacies of its **structure and syntax** have started to **unravel before my eyes**, and I am filled with a newfound **understanding**.\n\nI am proud to say that I can now confidently **craft code** in this language, allowing me to bring to life a **diverse** range of **ideas**.\n\n## Major things to improve:\n\n1. Weak and unclear **documentation**.\n2. Lack of **code examples**.\n   A good example is [clojuredocs](https://clojuredocs.org) website.\n3. More **explanation** to the language **paradigms**\n4. Lack **comparison** to Python base things datatypes/functions/classes/expressions.\n5. Even though Mojo is superset of Python, the **threshold** of language entry is **not so simple**.\n6. A little bit raw, need some time for **stabilizing** language. Production release 1.0.\n7. **Bugs**, like in any one.\n8. Small **standard library**.\n9. Project Jupyter and **notebooks environment**.\n   I understand that Jupyter plugin and custom kernel are a good solution, but it is makes development so slow.\n10. Not **open-sourced** yet.\n   The community is waiting for open source compiler and REPL to start developing and producing libraries and applications.\n   I think the community will easily rewrite the (bootstrapping) compiler from C++ to itself Mojo🔥.\n\n## Good and nice for win\n\n1. **Modular team** easily responds to requests/questions/letters/ideas\n2. **Friendly** and very smart **community**\n3. **Problem-solving** programming language with an idea to not create new syntax but deal with real word challenges.\n4. I don't know about you, but I was waiting and researching a long time for a Mojo🔥.\n   I have been tried a hundred of programming languages.\n   The World is ready for the revolution and the future of computation and AI.\n   I'm really into Mojo🔥, it excites, fascinates me, and I hope it does the same for you.\n5. I believe that a well-known distinguished leader Ph.D. Computer Science Chris Lattner can build things, systems, teams and change the future.\n\n## Modular and Mojo🔥 history and etymology\n\nMojo🔥 is a [Modular Inc](https://www.modular.com) programming language. Why **Mojo** we [discussed here](https://github.com/ego/awesome-mojo#why-is-it-called-mojo).\nAbout [Company](https://www.modular.com/about) we know less, but it has a very cool name `Modular`,\nwhich can be referred to:\n\n* [Modular arithmetic](https://en.wikipedia.org/wiki/Modular_arithmetic)\n* [Modulo](https://en.wikipedia.org/wiki/Modulo)\n* [Modular programming](https://en.wikipedia.org/wiki/Modular_programming)\n* [Modularity](https://en.wikipedia.org/wiki/Modularity)\n\n\u003e [\"In other words: Mojo isn’t magic, it’s modular.\"](https://docs.modular.com/mojo/notebooks/BoolMLIR.html)\n\nAll about computing, programming, AI/ML.\nA very good domain name that accurately describes the meaning of the Company.\n\nThere are some additional materials about [Modular's Brand Story](https://www.modular.com/blog/modulars-brand-story)\nand [Helping Modular Humanize AI Through Brand](https://www.metalab.com/blog/helping-modular-humanize-ai-through-brand)\n\n# Additional materials\n\n* [Chris Lattner](https://nondot.org/sabre/)\n* [LLVM](https://llvm.org)\n* [MLIR](https://mlir.llvm.org)\n* [Circuit IR Compilers and Tools](https://circt.llvm.org)\n* [Cross Compile Compiler-rt](https://releases.llvm.org/8.0.1/docs/HowToCrossCompileBuiltinsOnArm.html)\n* [The future of AI depends on Modularity](https://www.modular.com/blog/the-future-of-ai-depends-on-modularity)\n* [The Architecture of Open Source Applications LLVM](https://aosabook.org/en/v1/llvm.html)\n* [The Golden Age of Compiler Design in an Era of HW/SW Co-design by Dr. Chris Lattner](https://youtu.be/4HgShra-KnY)\n* [LLVM in 100 Seconds](https://youtu.be/BT2Cv-Tjq7Q)\n* [Mojo Dojo](https://mojodojo.dev/mojo_team_answers.html)\n* [Mojo Cheatsheet](https://github.com/czheo/mojo-cheatsheet/tree/main)\n* [Counting chars with SIMD in Mojo](https://mzaks.medium.com/counting-chars-with-simd-in-mojo-140ee730bd4d)\n* [History of programming languages](https://en.wikipedia.org/wiki/History_of_programming_languages)\n\n## MLIR and low-level implementation\n\n* [Doxygen mlir](https://mlir.llvm.org/doxygen/index.html)\n* [IndexOps](https://mlir.llvm.org/docs/Dialects/IndexOps/)\n* [LLVM libc](https://libc.llvm.org/)\n* [GNU libc](https://www.gnu.org/software/libc/manual/html_mono/libc.html)\n* [GNU libc Index](https://www.gnu.org/software/libc/manual/html_node/Function-Index.html)\n\n## Python / C++\n\n* [Numpy](https://numpy.org/doc/stable/user/whatisnumpy.html)\n* [Numba](https://numba.pydata.org/numba-doc/latest/user/5minguide.html) based on (LLVM)\n* [PyPy](https://www.pypy.org/)\n* [Google JAX](https://github.com/google/jax) based on (XLA)\n  * [Autograd](https://github.com/hips/autograd)\n  * [XLA](https://www.tensorflow.org/xla)\n* [Ray](https://github.com/ray-project/ray)\n* [Taichi Lang](https://github.com/taichi-dev/taichi)\n  * [Taichi compared to cub cupy numba](https://docs.taichi-lang.org/blog/taichi-compared-to-cub-cupy-numba)\n* [Codon](https://github.com/exaloop/codon)\n  * [Codon benchmarks](https://exaloop.io/benchmarks)\n* [CuPy](https://github.com/cupy/cupy)\n* [Cython](https://github.com/cython/cython)\n* [Pythran](https://github.com/serge-sans-paille/pythran)\n* [Mypyc](https://mypyc.readthedocs.io/en/latest/introduction.html)\n* [Nuitka](https://github.com/Nuitka/Nuitka)\n* [DeepSpeed](https://github.com/microsoft/DeepSpeed)\n* [Benchmarks for CPU and GPU performance high-performance Python libs](https://github.com/dionhaefner/pyhpc-benchmarks)\n* [Metaflow](https://metaflow.org)\n* [Accelerating experimentation with mlops](https://www.rea-group.com/about-us/news-and-insights/blog/accelerating-experimentation-with-mlops/)\n* [nebuly-ai](https://github.com/nebuly-ai/nebuly/tree/v0.9.0)\n* [Numba compiler for Python bytecode, Numba IR into LLVM IR, Compile LLVM IR to machine code](https://numba.readthedocs.io/en/stable/developer/architecture.html)\n\n## AI\n\n* [Accelerated Computing](https://blogs.nvidia.com/blog/2021/09/01/what-is-accelerated-computing/)\n* [ONNX open standard for machine learning](https://github.com/onnx/onnx)\n* [ONNX Runtime: cross-platform, high performance ML inferencing and training accelerator](https://github.com/microsoft/onnxruntime)\n* [CUDA](https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html)\n* [OpenCL](https://www.khronos.org/opencl/)\n* [SYCL](https://www.khronos.org/api/index_2017/sycl)\n* [Google Brain TensorFlow](https://github.com/tensorflow/tensorflow)\n* [PyTorch](https://github.com/pytorch/pytorch)\n* [TensorRT](https://github.com/NVIDIA/TensorRT)\n* [OpenaAI Triton language and compiler](https://github.com/openai/triton)\n* [Made With ML](https://madewithml.com)\n* [Vertex AI](https://cloud.google.com/vertex-ai)\n* [Google TPU](https://cloud.google.com/tpu)\n* [Sagemaker](https://aws.amazon.com/sagemaker/)\n* [MLIR: accelerating AI with open-source infrastructure](https://www.blog.google/technology/ai/mlir-accelerating-ai-open-source-infrastructure/)\n* [Apache TVM](https://tvm.apache.org)\n\n\n## Python hints\n\nTodat I would like to tell story about Python Enum problem.\nAs a software engineers we often meet it in a WEB.\nAssume we have this DataBase Schema (PostgreSQL) with status `enum`:\n\n```SQL\nCREATE TYPE public.status_type AS ENUM (\n    'FIRST',\n    'SECOND'\n);\n```\n\nIn a Python code we need names and values as strings (assume we use GraphQL with some ENUM type for our frontend side), and we need to maintain their order and have ability to compare these enums:\n\n`order2.status \u003e order1.status \u003e 'FIRST'`\n\nSo it's a problem for most of common languages =) but we can use a `little-known` Python feature and override enum class method: `__new__`.\n\n- But Why?\n- Hm..\n  To assosiate each enum value with its INDEX! `MALE -\u003e 1`, `FEMALE -\u003e 2`, like PostgreSQL do.\n- and How?\n- Just COUNT its members with the `len` function!\n\n```Python\nimport enum\nfrom functools import total_ordering\n\n\n@total_ordering\n@enum.unique\nclass BaseUniqueSortedEnum(enum.Enum):\n    \"\"\"Base unique enum class with ordering.\"\"\"\n\n    def __new__(cls, *args, **kwargs):\n        obj = object.__new__(cls)\n        obj.index = len(cls.__members__) + 1  # This code line is a piece of advice, an insight and a tip!\n        return obj\n\n    # and then boring Python's magic methods as usual...\n\n    def __hash__(self) -\u003e int:\n        return hash(\n          f\"{self.__module__}_{self.__class__.__name__}_{self.name}_{self.value}\"\n        )\n\n    def __eq__(self, other) -\u003e bool:\n        self._check_type(other)\n        return super().__eq__(other)\n\n    def __lt__(self, other) -\u003e bool:\n        self._check_type(other)\n        return self.index \u003c other.index\n\n    def _check_type(self, other) -\u003e None:\n        if type(self) != type(other):\n            raise TypeError(f\"Different types of Enum: {self} != {other}\")\n\n\nclass Dog(BaseUniqueSortedEnum):\n    # THIS ORDER MATTERS!\n    BLOODHOUND = \"BLOODHOUND\"\n    WEIMARANER = \"WEIMARANER\"\n    SAME = \"SAME\"\n\n\nclass Cat(BaseUniqueSortedEnum)\n    # THIS ORDER MATTERS!\n    BRITISH = \"BRITISH\"\n    SCOTTISH = \"SCOTTISH\"\n    SAME = \"SAME\"\n\n\n# and some tests\nassert Dog.BLOODHOUND \u003c Dog.WEIMARANER\nassert Dog.BLOODHOUND \u003c= Dog.WEIMARANER\nassert Dog.BLOODHOUND != Dog.WEIMARANER\nassert Dog.BLOODHOUND == Dog.BLOODHOUND\nassert Dog.WEIMARANER == Dog.WEIMARANER\nassert Dog.WEIMARANER \u003e Dog.BLOODHOUND\nassert Dog.WEIMARANER \u003e= Dog.BLOODHOUND\n\nassert Cat.BRITISH \u003c Cat.SCOTTISH\nassert Cat.BRITISH \u003c= Cat.SCOTTISH\nassert Cat.BRITISH != Cat.SCOTTISH\nassert Cat.BRITISH == Cat.BRITISH\nassert Cat.SCOTTISH == Cat.SCOTTISH\nassert Cat.SCOTTISH \u003e Cat.BRITISH\nassert Cat.SCOTTISH \u003e= Cat.BRITISH\n\nassert hash(Dog.BLOODHOUND) == hash(Dog.BLOODHOUND)\nassert hash(Dog.WEIMARANER) == hash(Dog.WEIMARANER)\nassert hash(Dog.BLOODHOUND) != hash(Dog.WEIMARANER)\nassert hash(Dog.SAME) != hash(Cat.SAME)\n\n# raise TypeError\nDog.SAME \u003c= Cat.SAME\nDog.SAME \u003c Cat.SAME\nDog.SAME \u003e Cat.SAME\nDog.SAME \u003e= Cat.SAME\nDog.SAME != Cat.SAME\n```\n\nThe end of the story.\nand use this `Python ENUM` **insight** for your well-codding!\n\n\n# Contributing\n\n* Your contributions are always welcome!\n* If you have any **question**, do not hesitate to contact me.\n* If you would like to participate in the initiative [Mojo🔥Driven Community](https://mojo-lang.dev), please contact me.\n* [Your help supporting this repository](https://github.com/ego/awesome-mojo/issues/1)\n","projects_url":"https://awesome.ecosyste.ms/api/v1/lists/ego%2Fawesome-mojo/projects"}