Skip to content

Upgrade Mojo starters to 26.2#238

Merged
kunal-mansukhani merged 1 commit intomainfrom
kunal/mojo-26.2-uprev
Apr 5, 2026
Merged

Upgrade Mojo starters to 26.2#238
kunal-mansukhani merged 1 commit intomainfrom
kunal/mojo-26.2-uprev

Conversation

@kunal-mansukhani
Copy link
Copy Markdown
Contributor

@kunal-mansukhani kunal-mansukhani commented Apr 5, 2026

Summary

  • Mojo 26.2 introduced several breaking changes to imports, UnsafePointer, GPU kernel launch, and raising semantics. All existing starter.mojo files were broken under 26.2; this updates them so they compile cleanly again.
  • Companion change in leetgpu-infra bumps modular==26.2.0 in Dockerfile.accelerated and MOJO: "26.2" in language_version.go.

Breaking changes addressed

  1. Stdlib imports must be fully qualifiedfrom gpu.host import …from std.gpu.host import …, and similarly for memory, math.
  2. gpu.id module removedblock_dim, block_idx, thread_idx now import from std.gpu directly.
  3. UnsafePointer requires an originUnsafePointer[Float32]UnsafePointer[Float32, MutAnyOrigin]. MutAnyOrigin is a builtin (no import needed). This is required because @export can't be applied to parametric functions, so we can't ...-unbind the origin parameter.
  4. Parametric enqueue_function[kernel](...) removed — kernels must be compiled first via ctx.compile_function[kernel, kernel]() and then passed as a runtime arg to ctx.enqueue_function(kernel, …). The kernel is passed twice as a comptime parameter (once as func, once as signature_func).
  5. def no longer auto-raises in Mojo 26DeviceContext(), enqueue_function, and synchronize all raise, so solve is now declared as fn solve(...) raises instead of def solve(...). @export + raises is allowed and propagates exceptions across the C ABI as expected.

Example diff (vector_add)

# before
from gpu.host import DeviceContext
from gpu.id import block_dim, block_idx, thread_idx
from memory import UnsafePointer
from math import ceildiv

fn vector_add_kernel(A: UnsafePointer[Float32], B: UnsafePointer[Float32], C: UnsafePointer[Float32], N: Int32):
    pass

@export
def solve(A: UnsafePointer[Float32], B: UnsafePointer[Float32], C: UnsafePointer[Float32], N: Int32):
    var BLOCK_SIZE: Int32 = 256
    var ctx = DeviceContext()
    var num_blocks = ceildiv(N, BLOCK_SIZE)
    ctx.enqueue_function[vector_add_kernel](
        A, B, C, N,
        grid_dim  = num_blocks,
        block_dim = BLOCK_SIZE
    )
    ctx.synchronize()

# after
from std.gpu.host import DeviceContext
from std.gpu import block_dim, block_idx, thread_idx
from std.memory import UnsafePointer
from std.math import ceildiv

fn vector_add_kernel(A: UnsafePointer[Float32, MutAnyOrigin], B: UnsafePointer[Float32, MutAnyOrigin], C: UnsafePointer[Float32, MutAnyOrigin], N: Int32):
    pass

@export
fn solve(A: UnsafePointer[Float32, MutAnyOrigin], B: UnsafePointer[Float32, MutAnyOrigin], C: UnsafePointer[Float32, MutAnyOrigin], N: Int32) raises:
    var BLOCK_SIZE: Int32 = 256
    var ctx = DeviceContext()
    var num_blocks = ceildiv(N, BLOCK_SIZE)
    var _kernel = ctx.compile_function[vector_add_kernel, vector_add_kernel]()
    ctx.enqueue_function(_kernel,
        A, B, C, N,
        grid_dim  = num_blocks,
        block_dim = BLOCK_SIZE
    )
    ctx.synchronize()

Test plan

  • Build vector_add starter against Mojo 26.2 via accelerated runner on Tesla T4 — compiles, test-case-failed as expected for an empty-kernel starter.
  • Build 9_1d_convolution starter (multi-line def solve(...) signature, parameter named kernel) — compiles.
  • Build medium/4_reduction starter (pass-only body, no kernel scaffold) — compiles.
  • CI lint / pre-commit passes.

🤖 Generated with Claude Code

Breaking changes in Mojo 26 require updates across all starter.mojo files:

- stdlib imports must be fully qualified (std.gpu, std.memory, std.math)
- gpu.id module removed; block_dim/block_idx/thread_idx now live in std.gpu
- UnsafePointer requires an explicit origin; use MutAnyOrigin for pointers
  crossing the @export C ABI boundary
- ctx.enqueue_function[kernel](...) parametric form removed; kernels must
  first be compiled via ctx.compile_function[kernel, kernel]() and then
  passed as a runtime arg to ctx.enqueue_function(kernel, ...)
- def no longer auto-raises in Mojo 26, so @export functions that call
  raising APIs (DeviceContext, enqueue_function, synchronize) are now
  declared as `fn solve(...) raises` instead of `def solve(...)`

Verified by compiling several starters (vector_add, 1d_convolution,
reduction) against Mojo 26.2 on a Tesla T4 via the accelerated runner.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@kunal-mansukhani kunal-mansukhani merged commit 9a9c134 into main Apr 5, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant