Magic:Mojo 的包管理器
Magic 的设计理念
Magic 是 Modular 专为 Mojo 和 MAX 生态设计的包管理和环境管理工具,底层基于 conda 生态(兼容 conda-forge 和 PyPI 仓库)。这意味着你可以通过 Magic 同时管理 Mojo 包和 Python 包,在一个工具中统一两个生态。
Magic 核心命令
# ─── 项目创建 ───
magic init my-project --format mojoproject
cd my-project
# ─── 依赖管理 ───
magic add max # 添加 MAX Engine(含 Mojo)
magic add numpy # 添加 Python 包(conda-forge)
magic add "pytorch>=2.0" # 指定版本约束
magic remove numpy # 移除依赖
# ─── 环境管理 ───
magic install # 根据 mojoproject.toml 安装所有依赖
magic update # 更新所有依赖到兼容最新版
magic clean # 清理缓存
# ─── 运行命令 ───
magic run mojo hello.mojo # 在虚拟环境中运行
magic run mojo build hello.mojo # 编译
magic run python train.py # 运行 Python 脚本
# ─── 环境信息 ───
magic list # 列出已安装的包
magic info # 显示环境信息
mojoproject.toml 格式
[project]
name = "my-mojo-project"
version = "0.1.0"
description = "A high-performance AI module"
authors = ["Your Name <you@example.com>"]
[dependencies]
max = ">=24.0,<25" # MAX Engine(含 Mojo)
python = ">=3.9,<3.12" # Python 版本约束
numpy = ">=1.24"
torch = ">=2.0"
[dev-dependencies] # 仅开发时使用
pytest = ">=7.0"
[tasks] # 自定义任务(类似 Makefile)
test = "mojo test tests/"
bench = "mojo bench.mojo"
build = "mojo build src/main.mojo -o dist/main"
创建 Mojo 包(mojopkg)
包结构规范
# Mojo 包结构
my_package/
├── __init__.mojo # 包入口,导出公共 API
├── core.mojo # 核心功能
├── utils.mojo # 工具函数
└── tests/
├── test_core.mojo
└── test_utils.mojo
# 编译为 .mojopkg(二进制分发格式)
mojo package my_package -o my_package.mojopkg
# 在其他项目中使用
# 将 my_package.mojopkg 放入项目目录或 MOJO_PATH
__init__.mojo:公共 API 导出
# my_package/__init__.mojo
# 控制哪些符号对外可见
from .core import Matrix, vector_add, dot_product
from .utils import Timer, format_size
# 使用方:
# from my_package import Matrix, Timer
单元测试
testing 模块
Mojo 内置 testing 模块,提供断言函数用于单元测试。测试函数以 test_ 开头,测试文件以 test_ 开头。
# tests/test_math.mojo
from testing import assert_equal, assert_almost_equal, assert_true, assert_false
from my_package import dot_product
fn test_dot_product_basic() raises:
var a = List[Float64](1.0, 2.0, 3.0)
var b = List[Float64](4.0, 5.0, 6.0)
let result = dot_product(a, b)
# 1*4 + 2*5 + 3*6 = 32
assert_equal(result, 32.0)
fn test_dot_product_zero() raises:
var a = List[Float64](1.0, 2.0)
var b = List[Float64](0.0, 0.0)
assert_equal(dot_product(a, b), 0.0)
fn test_floating_point() raises:
# 浮点数比较用 assert_almost_equal(容忍误差)
assert_almost_equal(3.14159, 3.14, atol=0.01)
fn test_bool_assertions() raises:
assert_true(5 > 3)
assert_false(2 > 10)
# 运行测试(单文件)
mojo test tests/test_math.mojo
# 运行所有测试
mojo test tests/
# 输出示例:
# test_dot_product_basic ... OK
# test_dot_product_zero ... OK
# test_floating_point ... OK
# test_bool_assertions ... OK
# 4 passed in 0.023s
编译为可执行文件
# 基本编译
mojo build src/main.mojo -o dist/my_app
# 指定优化级别(默认 -O2)
mojo build src/main.mojo -O3 -o dist/my_app_fast
# 查看生成的 LLVM IR(调试编译问题)
mojo build src/main.mojo --emit-llvm -o out.ll
# 交叉编译(编译到不同平台)
mojo build src/main.mojo --target-triple aarch64-apple-macosx -o app_arm64
# 运行编译产物(静态链接,可直接分发)
./dist/my_app
mojo run vs mojo build 的区别
mojo run file.mojo:解释执行,有 JIT 编译开销(首次运行略慢),适合开发调试。
mojo build file.mojo -o app:完整 AOT(Ahead-of-Time)编译,生成独立可执行文件,无运行时依赖(除动态库外),性能最优,适合生产部署。
Benchmark 性能分析
from benchmark import Benchmark, run
from algorithm import vectorize
from sys.info import simdwidthof
alias SIMD_W = simdwidthof[DType.float32]()
fn scalar_sum(n: Int) -> Float32:
var result: Float32 = 0.0
for i in range(n):
result += Float32(i)
return result
fn vector_sum(data: UnsafePointer[Float32], n: Int) -> Float32:
var acc = SIMD[DType.float32, SIMD_W](0.0)
@parameter
fn add_chunk[sw: Int](i: Int):
acc += SIMD[DType.float32, sw].load(data + i)
vectorize[add_chunk, SIMD_W](n)
return acc.reduce_add()
fn main():
alias N = 10_000_000
# 方法 1:使用 Benchmark 模块
@parameter
fn bench_scalar():
_ = scalar_sum(N)
var report_s = run[bench_scalar](max_runtime_secs=1)
print("标量求和:")
report_s.print_full()
# 方法 2:手动计时
from time import now
var data = UnsafePointer[Float32].alloc(N)
let t0 = now()
for _ in range(100):
_ = vector_sum(data, N)
print("向量化求和平均:", (now() - t0) // 100 // 1000, "μs")
data.free()
VS Code 开发环境配置
Mojo 扩展安装
在 VS Code 扩展市场搜索「Mojo」,安装 Modular 官方发布的扩展(ID:
modular-mojotools.vscode-mojo)。提供语法高亮、代码补全、实时错误检查、跳转定义、悬停文档。settings.json 配置
设置
"mojo.mojoPath" 指向 Mojo 可执行文件路径,设置 "mojo.modularHomePath" 指向 Modular 安装目录,确保 LSP 服务器能找到标准库。调试配置
在
.vscode/launch.json 中配置 "type": "mojo",设置程序路径和参数,按 F5 即可启动调试,支持断点、单步执行、变量查看。Jupyter 集成
安装
jupyter 后,VS Code 的 Jupyter 扩展可以选择 Mojo 内核,在 .ipynb 文件中交互式运行 Mojo 代码,方便探索性开发。本章小结
Magic:基于 conda 的包管理器,统一管理 Mojo 和 Python 依赖,mojoproject.toml 声明项目配置。
mojopkg:将 Mojo 模块打包为二进制 .mojopkg,通过 __init__.mojo 控制公共 API。
testing 模块:内置断言函数(assert_equal、assert_almost_equal等),测试文件和函数以 test_ 开头,mojo test 运行。
编译部署:mojo build 生成独立可执行文件,AOT 编译获得最优性能,适合生产部署。
Benchmark:内置 benchmark 模块提供统计性能分析,run[] 自动重复运行并给出中位数/方差。