--- name: matlab-generate-code description: > Generate, verify, refine, and accelerate C/C++ or CUDA code from MATLAB with MATLAB Coder, Embedded Coder, GPU Coder, or MATLAB Test. Also covers writing codegen-ready MATLAB code: language constraints, coder.* directives, and optimization patterns. Triggers on: codegen, MEX, deploy MATLAB as C/C++, GPU Coder, coder.screener, coder.config, coder.gpuConfig, coder.typeof, coder.runTest, matlabtest.coder.TestCase, SIL, embedded config, no dynamic memory, EnableMexProfiling, coder.timeit, coder.perfCompare, %#codegen, writing codegen-ready MATLAB, code generation readiness, coder.varsize, coder.unroll, coder.noImplicitExpansionInFunction, coder.ceval, coder.inline, coder.extrinsic, coder.const, coder.classSignature, class codegen limitations, temporal types codegen, DMA-off, stack-only, host-target InstructionSetExtensions, SIMDAcceleration, OptimizeReductions, host SIMD tuning, host OpenMP, codegen performance. license: https://www.mathworks.com/content/dam/mathworks/license/pmrl/license.md metadata: author: MathWorks version: "1.1" --- # Generate Code with MATLAB Coder Umbrella skill for the MATLAB Coder workflow: generate code, verify it, refine the config, and accelerate with profiled MEX. ## When to Use - Generating C/C++ or CUDA code from MATLAB functions (MEX, lib, dll, exe) - Writing new MATLAB code that must be compatible with code generation - Reviewing existing MATLAB code for codegen readiness or fixing codegen errors - Configuring codegen settings for specific targets (embedded, speed, readability, safety) - Verifying generated code matches MATLAB output (coder.runTest, matlabtest.coder.TestCase) - Profiling and accelerating generated MEX functions - Using coder.* directives (coder.varsize, coder.const, coder.extrinsic, coder.ceval, etc.) ## When NOT to Use - Simulink Coder / Embedded Coder Simulink-model workflows - Generating code for target languages that are not C, C++, or CUDA - Fixed-Point Designer conversion workflows - Hand-written MEX C files (not generated by MATLAB Coder) - General MATLAB programming unrelated to code generation ### Route to a more specific skill - **Generating code from an AI model** (PyTorch `.pt2` / LiteRT `.tflite` via `loadPyTorchExportedProgram` / `loadLiteRTModel`) → use **matlab-deploy-ai-model**. Return here for the underlying `coder.*` directives, config tuning, and screener/verification. - **Deploying to physical embedded hardware** (on-target PIL, ERT hardware configs, board selection — STM32 / Raspberry Pi / ARM Cortex) → use **matlab-deploy-embedded-code**. This skill covers host-side codegen, SIL, and config tuning up to hardware targeting. - **Speeding up interpreted MATLAB by rewriting the M-code** (vectorization, preallocation, caching) → use **matlab-optimize-performance**. This skill's acceleration path assumes you want to compile to MEX/C, not restructure the algorithm. - **General MATLAB test authoring** (parameterized tests, fixtures, mocking, coverage, CI/CD, App Designer) → use **matlab-write-test**. This skill covers only codegen-equivalence tests (`coder.runTest`, `matlabtest.coder.TestCase`). - **Modernizing deprecated APIs for currency/maintainability** when code generation is not the goal → use **matlab-modernize-code**. This skill rewrites source only to satisfy codegen constraints, with explicit authorization. ## Routing — load the matching reference file on demand Pick the workflow that matches the user's intent and read the corresponding `references/*.md`. Each reference file is a deep, self-contained guide; load only what you need rather than carrying all four in context. | User intent | Load | |---|---| | Writing new codegen-compatible MATLAB; reviewing MATLAB for codegen readiness; fixing codegen errors; `%#codegen`; language constraints; type/size rules | `references/write-codegen-ready.md` | | Understanding a specific `coder.*` directive (coder.varsize, coder.const, coder.inline, coder.unroll, coder.extrinsic, etc.) | `references/write-coder-directives.md` | | Using MATLAB classes in codegen; class limitations; `coder.classSignature`; handle vs value class restrictions | `references/write-class-limitations.md` | | Generate C/C++/CUDA code (MEX, lib, dll, exe), specify input types, fix `coder.screener` issues | `references/generate-code.md` | | Verify generated code matches MATLAB; write `coder.runTest` / `matlabtest.coder.TestCase` tests; SIL setup | `references/verify-code.md` | | Tune a working config for a deployment goal (embedded / speed / readability / size / safety); SIMD values (SIMDAcceleration, InstructionSetExtensions), OpenMP, OptimizeReductions | `references/refine-config.md` | | Profile generated MEX, measure `coder.timeit` / `coder.perfCompare`, find hotspots | `references/accelerate-mex.md` | | Look up a config property's name, availability, or non-obvious behavior | `references/config-properties.md` | **Disambiguation — "write" vs. "generate" vs. "generate for a class":** - "Write codegen-ready code" = authoring/reviewing the MATLAB source so it *can* be compiled (`write-codegen-ready.md`) - "Generate code" = running `codegen` to produce C/C++ from an already-valid function (`generate-code.md`) - "Generate code for a class" / "generate C++ class" = the user's source is a `classdef` file → load `generate-code.md` (Step 0 handles class entry points via `coder.ClassSignature`). Do NOT default to wrapping the class in a function. - If both apply (user wants to write a function AND generate code from it), load `write-codegen-ready.md` first, then `generate-code.md` For requests that span workflows (e.g., "generate MEX, verify it, then speed it up"), load the references in order rather than all at once. ## Out of scope - **Simulink** Coder / Embedded Coder workflows (these are skill candidates of their own). - **Non-C, C++, or CUDA target languages** — this skill covers C/C++ and CUDA code generation only - **Fixed-point conversion** (use Fixed-Point Designer). - **Hand-written MEX files** — the acceleration guidance assumes MATLAB Coder-generated MEX. - **`CodeExecutionProfiling` / SIL profiling** with Embedded Coder — out of scope for the acceleration reference. ## Cross-cutting rules These apply across every workflow. Apply them whether or not you've loaded a per-workflow reference yet. ### Class entry point — use `coder.ClassSignature`, not a wrapper function When the user's target is a MATLAB class (classdef file) and they want to generate C++ code from it, use `coder.ClassSignature` for direct class code generation. Do NOT create a wrapper entry-point function. This produces a proper C++ class with methods — which is what users mean when they say "generate C++ class." Load `references/generate-code.md` → Step 0 and `references/write-class-limitations.md` → "Direct class code generation" for the full workflow. The prerequisite `enableCodegenForEntryPointClasses` must run once per session. Only fall back to a wrapper function if the user's MATLAB version lacks `coder.ClassSignature` (pre-R2026a) or the class structure is incompatible (e.g., handle objects in entry-point I/O). ### Ask for input types before writing codegen-ready functions Before writing any new codegen-ready function, ask the user: - Data type of each input (double, single, int32, uint8, logical, struct, etc.) - Size/shape (scalar, fixed-size vector/matrix, variable-size with bounds?) - Real or complex? Do NOT ask about variable-size upper bounds unless the user has explicitly requested DMA-off (no dynamic memory) code generation. See `references/write-codegen-ready.md` for full authoring guidance. ### One variable, one type, one size category A variable cannot change class or complexity after first assignment. This is the #1 source of codegen errors in practice. Assign different-sized values on different branches only after declaring `coder.varsize`. See `references/write-codegen-ready.md` for the full constraint list. ### Always capture `coder.screener` output — every time ```matlab res = coder.screener('myFunction'); % NOT bare: coder.screener('myFunction') disp(res.UnsupportedCalls) disp(res.Messages) ``` Bare `coder.screener('func')` opens the GUI with no command-line output. **Always** assign the return value, then inspect `UnsupportedCalls` and `Messages`. This rule applies to every reference to `coder.screener` you write — including summaries, status updates, and commentary, not just the actual call you execute. Don't write `coder.screener('myFunction')` as a bare phrase even when describing what you did; mirror the assignment-syntax form (or just refer to "the screener" prose-style). A bare call in a summary suggests the user should reproduce it that way. ### Verify with MEX before generating lib / dll / exe Generate MEX first and compare its output to the interpreted MATLAB. Once MEX matches, generate the standalone target. Comparing two interpreted MATLAB runs proves nothing — and aggressive optimizations on lib/dll can mask bugs that surface only in the deployed code path. ### Never modify the user's source without authorization The user's MATLAB source is theirs. Even when `coder.screener` flags an unsupported call or construct, do not silently rewrite the source — present a short summary of the proposed change (which lines, what's removed/replaced, why) and wait for the user to confirm before applying. This applies whether the change is a one-line guard around a `try`/`catch`, a swap of `containers.Map` for a struct, removal of an `eval`, or a tightened `arguments` block. The same rule applies when a codegen error suggests a source-level fix. Trivial mechanical changes still need the same confirmation step. The one exception is a copy of the source into a private working directory for codegen experiments; that copy may be edited freely as long as the original file is untouched. ### Booleans are `logical`, not char Every `Enable*` and similar config property takes `true` / `false`. Never `'On'` / `'Off'`. Use `class(cfg.PropName)` if unsure. ### Don't add report flags unless the user asks Do not pass `-report`, `-launchreport`, or set `GenerateReport = true` unless the user explicitly requests a code-generation report. ### Use function-call syntax for variable paths ```matlab % 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) ``` ### Introspect the live config object Property names, defaults, and per-config-type availability drift across MATLAB releases. Before recommending settings, query the user's actual config: ```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? ``` Treat the live introspection — not memory of past releases — as ground truth. See `references/config-properties.md` for more. ## Quick Reference — Coder Directives | Directive | Purpose | Key gotcha | Available From | |-----------|---------|-----------|---------------| | `%#codegen` | Enable codegen analysis | Must be on/after function signature | R2011a | | `coder.typeof(val, sz, varDims)` | Define input type+size for codegen call | `varDims` is logical array — `true` = variable | R2011a | | `coder.varsize('x', [bounds])` | Declare variable-size with upper bounds | Without bounds → requires DMA; declare before first assignment | R2011a | | `coder.const(expr)` | Evaluate expr at compile time | Expression can be arithmetic, a function call, or a combination | R2013b | | `coder.extrinsic('fn')` | Exclude function from compilation | No-op in lib/dll/exe unless paired with `coder.const` | R2011a | | `coder.inline('always'\|'never')` | Control function inlining | Use `'always'` for small hot helpers | R2011a | | `coder.unroll(range)` | Unroll loop at compile time | Required for heterogeneous cell / varargin iteration | R2011a | | `coder.noImplicitExpansionInFunction` | Disable broadcasting overhead | Only when operands always match in size | R2021b | | `coder.target('MATLAB')` | Branch between MATLAB and codegen paths | Inactive branch is eliminated from generated code | R2011a | | `coder.nullcopy(zeros(m,n))` | Allocate without zeroing | Only safe if every element is written before read | R2011a | | `coder.ClassSignature` | Direct class code generation entry point | Requires `enableCodegenForEntryPointClasses` once per session | R2026a | For full directive documentation, load `references/write-coder-directives.md`. ## Common Mistakes | Mistake | Correct Approach | |---------|-----------------| | `coder.screener('func')` without capturing return value | `res = coder.screener('func')` then inspect `res.UnsupportedCalls` and `res.Messages` | | Jumping straight to lib / dll without MEX verification | Generate MEX first, compare outputs to MATLAB, then generate the final target | | `EnableRecursion` (does not exist) | `EnableRuntimeRecursion` | | `DynamicMemoryAllocation = 'Off'` | `EnableDynamicMemoryAllocation = false` (logical, not char) | | `MemcpyThreshold = 0` to disable memcpy | `EnableMemcpy = false` | | Comparing two interpreted MATLAB runs to "verify" generated code | Use `coder.runTest` (MEX replacement) or `matlabtest.coder.TestCase`; or SIL with Embedded Coder | | `coder.timeit(@myFunction, ...)` (function handle) | `coder.timeit('myFunction', numOutputs, {args})` — string name | | Profiling the interpreted MATLAB function instead of the MEX | Profile `myFunction_mex`; interpreted MATLAB has different performance characteristics | | Test script run under `coder.runTest` without `assert` statements | Always include assertions — `coder.runTest` produces no output on success otherwise | | Building MEX in every test method with identical input types | Build once in `TestClassSetup`; rebuild per test only when input type specs differ | | Calling the MATLAB function manually in `matlabtest.coder.TestCase` tests | `verifyExecutionMatchesMATLAB` calls MATLAB internally — just `execute` then verify | | Command-syntax `-d (outDir)` for output directory | Function-call syntax: `codegen('func', '-config', cfg, '-args', types, '-d', outDir)` | | Adding `-report`, `-launchreport`, or `GenerateReport = true` | Don't generate code reports unless explicitly requested | | `IntegrityChecks = false` (MEX) without first running with checks on | Run with checks enabled across all expected inputs first; only disable after confirming no bounds errors | | `EnableDynamicMemoryAllocation = false` and `EnableVariableSizing = false` together | Keep `EnableVariableSizing = true` so variable-size arrays stack-allocate at the upper bound | | Growing array in loop (`x = [x; row]`) | Preallocate full array before loop | | Using `try`/`catch` in codegen path | Return status codes; use `coder.target('MATLAB')` for MATLAB-only error handling | | Variable changes type between assignments | One variable = one type throughout scope | | Function returns different types/sizes on different paths | Ensure consistent output type and size on all paths | | Missing `%#codegen` pragma | Always include after function signature | | `coder.extrinsic` expecting runtime behavior in lib/dll | Extrinsic calls produce no code in portable targets; combine with `coder.const` | | Using `coder.ClassSignature` / `-class` without enabling the Tech Preview | Run `enableCodegenForEntryPointClasses` once per MATLAB session before class code generation | ## Conventions - Follow MathWorks Coding Guidelines for any MATLAB code suggested or written: `lowerCamelCase` functions, `arguments` blocks, max 6 inputs / 4 outputs, `end` terminators. - For floating-point comparisons between MEX and MATLAB, use tolerances (`AbsTol` / `RelTol`) rather than exact equality. Differences < 1e-10 relative are normal due to different math libraries. - For variable-size arrays, specify upper bounds via `coder.typeof(example, [maxDims], [variableFlags])`. - Use `coder.Constant` for entrypoint inputs whose value is known at compile time so codegen can resolve downstream array sizes statically. ---- Copyright 2026 The MathWorks, Inc. ----