关于 matlab-generate-code
面向 MATLAB Coder 用户的工作流技能,用于从 MATLAB 生成 C、C++ 或 CUDA 代码,涵盖代码准备、生成、验证、配置调整和 MEX 分析。
主要功能
- 01准备 MATLAB 代码以供生成
- 02生成 C、C++、CUDA、MEX 和库
- 03验证生成结果与 MATLAB 一致
- 04调整代码生成配置
- 05分析并加速生成的 MEX
适用场景
- 01检查 MATLAB 函数的代码生成就绪度
- 02生成 MEX 或独立代码
- 03测试生成结果与 MATLAB 的一致性
- 04分析生成的 MEX 性能
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ matlab/ matlab-agentic-toolkit --skill matlab-generate-code安装后在 Claude Code 中输入/matlab-generate-code确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
manifest.yamlreferences/accelerate-mex.mdconfig-properties.mdgenerate-code.mdrefine-config.mdverify-code.mdwrite-c-interop.mdwrite-class-limitations.mdwrite-codegen-ready.mdwrite-coder-directives.mdwrite-core-constraints.mdwrite-numerical-style.mdwrite-performance.mdwrite-temporal-types.md详细介绍
使用 MATLAB Coder 生成代码
涵盖 MATLAB Coder 工作流的技能:生成代码、验证代码、调整配置,并通过经过性能分析的 MEX 加速。
适用场景
- 从 MATLAB 函数生成 C/C++ 或 CUDA 代码(MEX、lib、dll、exe)
- 编写必须兼容代码生成的新 MATLAB 代码
- 审查现有 MATLAB 代码是否适合代码生成,或修复代码生成错误
- 为特定目标配置代码生成设置(嵌入式、速度、可读性、安全性)
- 验证生成的代码是否与 MATLAB 输出一致(coder.runTest、matlabtest.coder.TestCase)
- 对生成的 MEX 函数进行性能分析和加速
- 使用 coder.* 指令(coder.varsize、coder.const、coder.extrinsic、coder.ceval 等)
不适用场景
- Simulink Coder / Embedded Coder 的 Simulink 模型工作流
- 为非 C、C++ 或 CUDA 的目标语言生成代码
- Fixed-Point Designer 转换工作流
- 手写的 MEX C 文件(非 MATLAB Coder 生成)
- 与代码生成无关的通用 MATLAB 编程
转用更具体的技能
- 从 AI 模型生成代码(通过
loadPyTorchExportedProgram/loadLiteRTModel处理 PyTorch.pt2/ LiteRT.tflite)→ 使用 matlab-deploy-ai-model。底层coder.*指令、配置调优以及代码筛查和验证可继续使用本技能。 - 部署到实体嵌入式硬件(在目标设备上进行 PIL、ERT 硬件配置、开发板选择——STM32 / Raspberry Pi / ARM Cortex)→ 使用 matlab-deploy-embedded-code。本技能涵盖主机端代码生成、SIL 和硬件目标配置前的调优。
- 通过重写 M 代码加快解释执行的 MATLAB(向量化、预分配、缓存)→ 使用 matlab-optimize-performance。本技能的加速路径面向编译为 MEX/C,而非重构算法。
- 编写通用 MATLAB 测试(参数化测试、夹具、模拟、App Designer)→ 使用 matlab-write-tests;运行测试套件、收集覆盖率和 CI/CD → 使用 matlab-run-tests。本技能仅涵盖代码生成等效性测试(
coder.runTest、matlabtest.coder.TestCase)。 - 在不以代码生成为目标时,将已弃用的 API 更新为当前 API,以提升可维护性 → 使用 matlab-modernize-code。本技能仅在获得明确授权后,才会为满足代码生成约束而重写源代码。
路由——按需加载匹配的参考文件
选择与用户意图匹配的工作流,并阅读对应的 references/*.md。每个参考文件都是内容完整、独立的指南;只加载所需内容,不要把四个文件都带入上下文。
| 用户意图 | 加载 |
|---|---|
编写新的、兼容代码生成的 MATLAB 代码;检查 MATLAB 代码是否适合代码生成;修复代码生成错误;%#codegen;语言限制;类型/大小规则 | references/write-codegen-ready.md |
理解特定的 coder.* 指令(coder.varsize、coder.const、coder.inline、coder.unroll、coder.extrinsic 等) | references/write-coder-directives.md |
在代码生成中使用 MATLAB 类;类限制;coder.classSignature;句柄类与值类限制 | references/write-class-limitations.md |
生成 C/C++/CUDA 代码(MEX、lib、dll、exe)、指定输入类型、修复 coder.screener 问题 | references/generate-code.md |
验证生成的代码是否与 MATLAB 一致;编写 coder.runTest / matlabtest.coder.TestCase 测试;设置 SIL | references/verify-code.md |
| 针对部署目标调整可用配置(嵌入式/速度/可读性/大小/安全);SIMD 值(SIMDAcceleration、InstructionSetExtensions)、OpenMP、OptimizeReductions | references/refine-config.md |
| 查询配置属性的名称、可用性或不明显的行为 | references/config-properties.md |
对生成的 MEX 进行性能分析;测量 coder.timeit / coder.perfCompare;查找性能瓶颈 | references/accelerate-mex.md |
消歧——“编写”与“生成”以及“为类生成”:
- “编写适合代码生成的代码”=编写/审查 MATLAB 源代码,使其能够编译(
write-codegen-ready.md) - “生成代码”=运行
codegen,从已有效的函数生成 C/C++(generate-code.md) - “为类生成代码”/“生成 C++ 类”=用户的源代码是一个
classdef文件 → 加载generate-code.md(步骤 0 通过coder.ClassSignature处理类入口点)。不要默认将类封装在函数中。 - 如果两种情况都适用(用户既想编写函数,又想从该函数生成代码),先加载
write-codegen-ready.md,再加载generate-code.md
对于跨越多个工作流的请求(例如“生成 MEX、验证它,然后加速它”),按顺序加载参考文件,不要一次性全部加载。
不在范围内
- Simulink Coder / Embedded Coder 工作流(它们各自适合作为独立技能)。
- 非 C、C++ 或 CUDA 目标语言——此技能仅涵盖 C/C++ 和 CUDA 代码生成
- 定点转换(使用 Fixed-Point Designer)。
- 手写的 MEX 文件——加速指南以 MATLAB Coder 生成的 MEX 为前提。
- 使用 Embedded Coder 的
CodeExecutionProfiling/ SIL 性能分析——不在加速参考的范围内。
跨工作流规则
这些规则适用于所有工作流。无论是否已加载特定工作流的参考文件,都应遵循。
类入口点——使用 coder.ClassSignature,而非封装函数
当用户的目标是 MATLAB 类(classdef 文件),并且希望从中生成 C++ 代码时,应使用 coder.ClassSignature 直接生成类代码。不要创建封装入口点函数。这样会生成带有方法的正规 C++ 类——这正是用户所说的“生成 C++ 类”。
加载 references/generate-code.md → 步骤 0,以及 references/write-class-limitations.md →“直接生成类代码”,查看完整工作流。前置条件 enableCodegenForEntryPointClasses 必须在每个会话中运行一次。
只有当用户的 MATLAB 版本不支持 coder.ClassSignature(早于 R2026a),或类结构不兼容(例如入口点 I/O 中包含句柄对象)时,才退而使用封装函数。
在编写可用于代码生成的函数前,先询问输入类型
在编写任何新的可用于代码生成的函数前,先询问用户:
- 每个输入的数据类型(double、single、int32、uint8、logical、struct 等)
- 大小/形状(标量、固定大小的向量/矩阵、带边界的可变大小?)
- 实数还是复数?
除非用户明确要求生成关闭 DMA(无动态内存)的代码,否则不要询问可变大小的上界。完整的编写指南请参阅 references/write-codegen-ready.md。
一个变量,一种类型,一个大小类别
变量首次赋值后,不能再改变类或复数属性。这是实践中导致代码生成错误的首要原因。只有在声明 coder.varsize 后,才能在不同分支中为变量赋予不同大小的值。完整的约束列表请参阅 references/write-codegen-ready.md。
始终捕获 coder.screener 的输出——每次都要
res = coder.screener('myFunction'); % NOT bare: coder.screener('myFunction')
disp(res.UnsupportedCalls)
disp(res.Messages)
单独调用 coder.screener('func') 会打开 GUI,不会产生命令行输出。始终为返回值赋值,然后检查 UnsupportedCalls 和 Messages。
此规则适用于你写到的每一处 coder.screener 引用——包括摘要、状态更新和评论,不只是你实际执行的调用。即使是在描述你做了什么,也不要将 coder.screener('myFunction') 作为独立短语来写;应使用赋值语法(或者直接用文字提及“筛查器”)。摘要中出现不带赋值的调用,会让用户以为应该照此方式执行。
生成 lib / dll / exe 前,先用 MEX 验证
先生成 MEX,并将其输出与解释执行的 MATLAB 输出进行比较。MEX 结果一致后,再生成独立目标。比较两次解释执行的 MATLAB 结果毫无意义——而且 lib / dll 中的激进优化可能会掩盖仅在已部署代码路径中出现的错误。
未经授权,绝不修改用户的源代码
用户的 MATLAB 源代码归用户所有。即使 coder.screener 标出了不受支持的调用或结构,也不要擅自重写源代码——先简要说明拟议的更改(涉及哪些行、删除/替换什么、原因),然后等待用户确认再应用。无论是用一行保护语句包住 try / catch、将 containers.Map 换成 struct、删除 eval,还是收紧 arguments 块,都适用此规则。代码生成错误提示需要修改源代码时,也同样适用。
即使是简单的机械式更改,也需要先确认。唯一的例外是将源代码复制到私有工作目录中进行代码生成实验;只要原始文件保持不变,就可以自由编辑该副本。
布尔值是 logical,不是 char
所有 Enable* 及类似配置属性都应使用 true / false。绝不要使用 'On' / 'Off'。不确定时,请使用 class(cfg.PropName)。
除非用户要求,否则不要添加报告标志
除非用户明确要求代码生成报告,否则不要传递 -report、-launchreport,也不要将 GenerateReport 设为 true。
对变量路径使用函数调用语法
% YES — function-call syntax evaluates the variable
outDir = fullfile(pwd, 'codegen_output');
codegen('myFunction', '-config', cfg, '-args', {t1, t2}, '-d', outDir)
% NO — command syntax can take "outDir" as a literal directory name
codegen -config cfg myFunction -args {t1, t2} -d (outDir)
检查实时配置对象
属性名称、默认值以及各配置类型支持的属性会随 MATLAB 版本变化。建议设置前,先查询用户实际使用的配置:
cfg = coder.config('lib'); % or 'mex', or coder.gpuConfig(...)
class(cfg) % CodeConfig vs. EmbeddedCodeConfig vs. MexCodeConfig
properties(cfg) % full property list for this version
disp(cfg) % current values
isprop(cfg, 'EnableMemcpy') % does a candidate property exist?
以实时检查结果为准,而不是凭对以往版本的记忆来判断。更多信息请参阅 references/config-properties.md。
快速参考 — Coder 指令
| 指令 | 用途 | 关键注意事项 | 起始版本 |
|---|---|---|---|
%#codegen | 启用代码生成分析 | 必须位于函数签名所在行或其后 | R2011a |
coder.typeof(val, sz, varDims) | 定义代码生成调用的输入类型和大小 | varDims 是逻辑数组 — true = 可变 | R2011a |
coder.varsize('x', [bounds]) | 声明带上限的可变大小变量 | 不指定上限 → 需要 DMA;必须在首次赋值前声明 | R2011a |
coder.const(expr) | 在编译时计算 expr | 表达式可以是算术运算、函数调用或两者的组合 | R2013b |
coder.extrinsic('fn') | 将函数排除在编译之外 | 在 lib/dll/exe 中无操作,除非与 coder.const 配合使用 | R2011a |
coder.inline('always'|'never') | 控制函数内联 | 对小型高频辅助函数使用 'always' | R2011a |
coder.unroll(range) | 在编译时展开循环 | 迭代异构 cell / varargin 时必须使用 | R2011a |
coder.noImplicitExpansionInFunction | 禁用广播开销 | 仅当操作数的大小始终匹配时使用 | R2021b |
coder.target('MATLAB') | 在 MATLAB 和代码生成路径之间分支 | 未激活的分支会从生成的代码中移除 | R2011a |
coder.nullcopy(zeros(m,n)) | 分配内存但不进行清零 | 仅当每个元素都在读取前写入时才安全 | R2011a |
coder.ClassSignature | 直接的类代码生成入口 | 每个会话都需要启用一次 enableCodegenForEntryPointClasses | R2026a |
如需查看完整的指令文档,请加载 references/write-coder-directives.md。
常见错误
| 错误 | 正确做法 |
|---|---|
调用 coder.screener('func') 后不保存返回值 | 使用 res = coder.screener('func'),然后检查 res.UnsupportedCalls 和 res.Messages |
| 跳过 MEX 验证,直接生成 lib / dll | 先生成 MEX,将输出与 MATLAB 对比,然后再生成最终目标 |
使用 EnableRecursion(不存在) | 使用 EnableRuntimeRecursion |
设置 DynamicMemoryAllocation = 'Off' | 设置 EnableDynamicMemoryAllocation = false(逻辑值,而非字符) |
使用 MemcpyThreshold = 0 禁用 memcpy | 使用 EnableMemcpy = false |
| 对比两次解释执行的 MATLAB 运行结果来“验证”生成的代码 | 使用 coder.runTest(MEX 替换)或 matlabtest.coder.TestCase;也可以使用 Embedded Coder 的 SIL |
使用 coder.timeit(@myFunction, ...)(函数句柄) | 使用 coder.timeit('myFunction', numOutputs, {args})——字符串名称 |
| 对解释执行的 MATLAB 函数进行性能分析,而不是 MEX | 对 myFunction_mex 进行性能分析;解释执行的 MATLAB 具有不同的性能特征 |
在 coder.runTest 下运行测试脚本,却不包含 assert 语句 | 始终包含断言——否则 coder.runTest 成功时不会产生输出 |
| 在每个测试方法中使用相同输入类型构建 MEX | 在 TestClassSetup 中构建一次;仅当输入类型规格不同,才按测试重新构建 |
在 matlabtest.coder.TestCase 测试中手动调用 MATLAB 函数 | verifyExecutionMatchesMATLAB 会在内部调用 MATLAB——只需执行 execute,然后验证 |
使用命令语法 -d (outDir) 指定输出目录 | 使用函数调用语法:codegen('func', '-config', cfg, '-args', types, '-d', outDir) |
添加 -report、-launchreport 或 GenerateReport = true | 除非明确要求,否则不要生成代码报告 |
未先启用检查就设置 IntegrityChecks = false(MEX) | 先在所有预期输入下启用检查运行;确认没有越界错误后再禁用 |
同时设置 EnableDynamicMemoryAllocation = false 和 EnableVariableSizing = false | 保持 EnableVariableSizing = true,以便可变大小数组按上限在栈上分配 |
在循环中扩展数组(x = [x; row]) | 在循环前预分配完整数组 |
在代码生成路径中使用 try/catch | 返回状态码;使用 coder.target('MATLAB') 进行仅限 MATLAB 的错误处理 |
| 同一变量在不同赋值时改变类型 | 在整个作用域内,一个变量只能有一种类型 |
| 函数在不同路径上返回不同的类型或大小 | 确保所有路径上的输出类型和大小一致 |
缺少 %#codegen 指示 | 始终在函数签名后添加 |
在 lib/dll 中使用 coder.extrinsic 并期待其在运行时执行 | 外部调用不会在可移植目标中生成代码;结合 coder.const 使用 |
未启用 Tech Preview 就使用 coder.ClassSignature / -class | 在进行类代码生成前,每个 MATLAB 会话运行一次 enableCodegenForEntryPointClasses |
约定
- 对于建议或编写的任何 MATLAB 代码,遵循 MathWorks 编码指南:函数使用
lowerCamelCase,使用arguments块,最多 6 个输入 / 4 个输出,并以end结束。 - 比较 MEX 与 MATLAB 的浮点结果时,使用容差(
AbsTol/RelTol),而非精确相等。由于数学库不同,相对差异小于 1e-10 属于正常情况。 - 对于可变大小数组,使用
coder.typeof(example, [maxDims], [variableFlags])指定上限。 - 对于编译时值已知的入口点输入,使用
coder.Constant,以便代码生成能够静态解析下游数组大小。
版权所有 2026 The MathWorks, Inc.