Skip to content
Volume M · The TensorCore.si Library

Mojo

Python syntax, systems speed, built for AI.

Mojo is a language from Modular that looks like Python but compiles to fast native code for CPUs and GPUs. It was created by Chris Lattner (who also created LLVM and Swift) to write AI kernels and models without switching between Python and C++ or CUDA.

Prologue

Why learn Mojo?

Mojo targets the exact problem AI engineers face: Python is easy but slow, while CUDA and C++ are fast but hard.

  • Familiar: Python-like syntax with types where you need speed.
  • Fast: SIMD, parallelism and GPU kernels written in one language.
  • AI-native: powers Modular's MAX inference engine and custom GPU kernels.
Prologue

Set up and run your first program

Install the Pixi package manager, then create a project with Mojo. Mojo runs on Linux and macOS (Apple silicon).

terminal
curl -fsSL https://pixi.sh/install.sh | sh
pixi init hello-mojo -c https://conda.modular.com/max-nightly/ -c conda-forge
cd hello-mojo && pixi add mojo
pixi run mojo hello.mojo
hello.mojo
fn main():
    var name = "Ada"
    print("Hello, AI! Welcome to Mojo,", name + ".")
TipMojo is young and changes quickly; install steps and syntax may differ in newer releases.
Chapter 1

Variables and types

Declare variables with var, optionally with a type. Types such as Int, Float64 and String let the compiler produce fast code.

variables.mojo
fn main():
    var layers: Int = 32
    var lr: Float64 = 3e-4
    var model: String = "llama3.1"
    var params = 8.03e9
    print(model, layers, lr)
    print("FP16 GB:", params * 2 / 1e9)
Chapter 2

fn and def

fn functions are strict: arguments need types and errors must be declared with raises. def functions behave more like Python.

functions.mojo
fn params(layers: Int, width: Int = 4096) -> Int:
    return 12 * layers * width * width

def greet(name):
    return "Hi " + String(name)

fn main() raises:
    print(params(32))
    print(greet("Mojo"))
Chapter 3

Control flow and collections

Loops and conditions look like Python. List and Dict come from the standard library.

collections.mojo
from collections import Dict

fn main() raises:
    var gpus = List[String]("H100", "H200", "B200")
    for g in gpus:
        print(g)
    var vram = Dict[String, Int]()
    vram["H100"] = 80
    vram["H200"] = 141
    for e in vram.items():
        if e.value > 100:
            print(e.key, "has", e.value, "GB")
Chapter 4

Structs and traits

Structs are like classes but fixed at compile time, which makes them fast. Traits describe shared behaviour.

structs.mojo
@fieldwise_init
struct Gpu(Copyable, Movable):
    var name: String
    var vram: Int

    fn fits(self, gb: Int) -> Bool:
        return gb <= self.vram

fn main():
    var g = Gpu("RTX 5090", 32)
    print(g.name, "fits 16 GB:", g.fits(16))
Chapter 5

SIMD and parallelism

SIMD is a built-in type that maps to the CPU's vector registers. parallelize spreads work across cores.

simd.mojo
from algorithm import parallelize

fn main():
    var a = SIMD[DType.float32, 8](1.0)
    var b = SIMD[DType.float32, 8](0.5)
    print((a * b).reduce_add())        # 4.0

    @parameter
    fn work(i: Int):
        print("chunk", i)
    parallelize[work](4)
Part II · AI with Mojo

AI with Mojo

Mojo's main job is AI performance: writing fast kernels for matrix multiplication and attention, custom operations for Modular's MAX engine, and GPU code without CUDA. You can also import Python modules, so NumPy and other libraries remain available.

The essential libraries

MAXModular inference engine and model serving.
gpu packageWrite GPU kernels directly in Mojo.
Python interopImport NumPy or any Python module.
layout / LayoutTensorTensor layouts for fast kernels.

Use Python libraries from Mojo

Mojo can call into Python, so you can mix NumPy with fast Mojo code.

gradient.mojo
from python import Python

fn main() raises:
    var np = Python.import_module("numpy")
    var x = np.linspace(-1, 1, 100)
    var y = 3 * x + 0.5
    var w: Float64 = 0
    var b: Float64 = 0
    for _ in range(500):
        var err = w * x + b - y
        w -= 0.1 * Float64(py=(2 * (err * x).mean()))
        b -= 0.1 * Float64(py=(2 * err.mean()))
    print("w =", w, "b =", b)
Part III · Build an AI agent

Build an AI agent with Mojo

Mojo has no mature HTTP library yet, so the practical way to build an agent is to call Python's requests through interop while keeping your fast tools in Mojo.

Your goal→Model plans→Tool call→Your code runs the tool→Result back to model→Final answer
agent.mojo
from python import Python

fn get_weather(city: String) -> String:
    return "It is 24°C and sunny in " + city + "."

fn main() raises:
    var requests = Python.import_module("requests")
    var json = Python.import_module("json")
    var url = "http://localhost:11434/v1/chat/completions"
    var tools = json.loads('[{"type":"function","function":{"name":"get_weather","description":"Weather for a city","parameters":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}}}]')
    var messages = Python.list()
    messages.append(Python.dict(role="user", content="Should I take an umbrella in Lahore today?"))

    for _ in range(5):
        var body = Python.dict(model="llama3.1", messages=messages, tools=tools)
        var msg = requests.post(url, json=body).json()["choices"][0]["message"]
        messages.append(msg)
        var calls = msg.get("tool_calls")
        if not calls:
            print(msg["content"])
            break
        for call in calls:
            var args = json.loads(call["function"]["arguments"])
            var result = get_weather(String(args["city"]))
            messages.append(Python.dict(role="tool", tool_call_id=call["id"], content=result))

Mojo's Python interop API is still evolving; check the current docs if a call has been renamed.

Run it locallyInstall Ollama, run ollama pull llama3.1, and keep it running. The code talks to its OpenAI-compatible API at http://localhost:11434/v1, so the same program also works with vLLM, llama.cpp server or a cloud API by changing the URL, model name and adding an API key.
Part IV · Your path

Mojo learning roadmap

Tick items off as you go. Your progress is saved in this browser.

Beginner

Intermediate

Advanced

Part IV · Your path

Projects to build

MandelbrotCompare Python and Mojo speed on a fractal.
Fast matmulTile and vectorize matrix multiplication.
MAX modelServe an open model with Modular MAX.
Reference

Mojo cheat sheet

TaskSyntax
Variablevar x: Int = 5
Strict functionfn f(x: Int) -> Int:
Python-styledef g(x):
Structstruct P: var x: Int
SIMDSIMD[DType.float32, 4](1.0)
Python modulePython.import_module("numpy")
Reference

Common mistakes

  • Mojo is not a full Python superset yet; many Python features are missing.
  • Syntax and library names change between releases.
  • fn functions need types and raises if they can throw.
Reference

Where to go next

On TensorCore.si: Python volume, CUDA volume.

Keyboard: [ previous language · ] next language · / search the library