Segment Anything Model 2 β Embedded Deployment via Manual C++ vs MATLAB Coder
Deploy SAM2 for embedded/edge use without the Python/PyTorch runtime. We compare two approaches
to generate C++ code from the .pt2 exported model.
317 tensors extracted to float32 binary files + manifest.json
150+ graph nodes traced: Hiera backbone, MUA attention, FPN neck, mask decoder
Full hand-written C++ inference engine (~1200 lines, Accelerate BLAS)
loadPyTorchExportedProgram β MLIR/TOSA β C++ (scripts ready)
Succeeded in 64.4 s β 12,598 C++ lines, 320 weight .bin files (125.3 MB)
Latency measured, PyTorch reference generated, numerical comparison
| Criterion | Manual C++ | MATLAB Coder |
|---|---|---|
| Code generation | Manual | Automatic |
| Effort | ~1200 lines C++ | ~100 lines MATLAB |
| Architecture knowledge | Full required | Not required |
| Portability | Any platform | MATLAB needed |
| Optimisation | Manual BLAS | Auto (MLIR) |
| Status | Running (debug) | Codegen complete |
| Runtime (invoke) | 8.3 s | 36.6 s (interpreted MLIR) |
sam2_1200x1800.pt2 export.
Manual C++ is reference quality; MATLAB Coder would produce optimised code.
| Stage | Channels | Res. | Blocks | Window | Heads | Lifted Tensors |
|---|---|---|---|---|---|---|
| Patch Embed | 96 | 256Β² | β | β | β | 0β5 |
| Stage 1 | 96 | 256Β² | 1 regular | 8Γ8 | 1 | 6β17 |
| S1βS2 proj | 96β192 | β | ds_proj | β | β | 18β19 |
| Stage 2 trans. | 96β192 | 256Β²β128Β² | MUA block | 8Γ8 | 2 | 20β31 |
| Stage 2 reg. | 192 | 128Β² | 1 regular | 4Γ4 | 2 | 32β43 |
| S2βS3 proj | 192β384 | β | ds_proj | β | β | 44β45 |
| Stage 3 trans. | 192β384 | 128Β²β64Β² | MUA block | 4Γ4 | 4 | 46β57 |
| Stage 3 reg. | 384 | 64Β² | 6 regular | 4Γ4 | 4 | 58β129 |
| S3βS4 proj | 384β768 | β | ds_proj | β | β | 130β131 |
| Stage 4 trans. | 384β768 | 64Β²β32Β² | MUA block | 4Γ4 | 8 | 132β143 |
| Stage 4 reg. | 768 | 32Β² | 1 (no norm2) | 4Γ4 | 8 | 144β153 |
| FPN Neck | β256 | 4 scales | 1Γ1 conv Γ4 | β | β | 154β161 |
Transition blocks spatially downsample by 2Γ using pooled Q tokens. Q tokens are 2Γ2 maxpooled within each window (TβT/4), while K/V remain at full window resolution. No pre-attention LayerNorm β applied post-add before MLP.
Precomputed bicubic index/weight tables stored as model buffers:
aa_idx_w[1024,4], aa_wt_w[1024,4] (width axis),
aa_idx_h[1024,3], aa_wt_h[1024,3] (height axis).
Saved as float32, must be cast to int64 for indexing.
162 Hiera backbone weights stored as graph constants
(c_sam2_lifted_tensor_0..161), distinct from
named parameters (p_sam2_*) and buffers (b_*).
2-layer transformer: self-attn (8h, 256d) + cross-attn tokenβimage (8h, 128d internal). Hypernetwork MLPs produce per-pixel mask weights. Output: 4 masks + IoU scores + obj_score.
aa_idx_w/h index buffers saved as float32 by extractor
but read as int64 bytes β reads 2Γ past EOF.ds_w_s2/s3/s4 fields.
<8 β <7.
blk.norm2 (offset 10-11 in block) for pre-MLP LayerNorm
in transition blocks. Graph shows the pre-MLP norm is at offset 4-5 (blk.norm1).blk.norm1 for MLP norm in transition blocks.
load_hiera_block set norm1.size = C_in always.
For transition blocks, norm1 operates on C_out-dim features (post-attention-add).norm1.size = is_transition ? C_out : C_in.
This approach uses loadPyTorchExportedProgram directly β the same
pattern as the Easy/repvit_deploy project. It does NOT use
importNetworkFromPyTorch (Deep Learning Toolbox) which requires
network graph parsing. Instead, the .pt2 ExportedProgram is consumed
directly by MATLAB Coder's MLIR/TOSA lowering path.
Blue bars = Manual C++ (5 runs). Orange bar = MATLAB invoke interpreted MLIR (mean of 3 runs). MATLAB compiled C++ (sam2_infer.a) expected β«10Γ faster than interpreted invoke.
| Metric | C++ (pre-fix) | C++ (post-fix) | MATLAB invoke | PyTorch |
|---|---|---|---|---|
| IoU[0] | 1.48 Γ 10ΒΉβ΅ | 5.975 | 0.9921 | 0.9803 |
| IoU[1] | β2.78 Γ 10ΒΉβ΅ | β17.26 | 0.6599 | 0.4820 |
| IoU[2] | β7.37 Γ 10ΒΉβ΅ | 5.532 | 0.0090 | 0.0048 |
| Masks RMSE | 2.77 Γ 10Β²β° | 4.849 | ~0.01 | 0.000 |
| Status | SIGBUS crash | Runs, wrong scale | β Correct | Reference |
Select a tensor from the list to view details.