📦 WP-087b — perf(ptl): batched mask-loss gather, one sync not 64¶
Research log · Phase 7 — Instance segmentation, v0.2.0
🔗 Depends on WP-087 · Needed by none
WP-087b — batched mask-loss gather¶
Wiring the segmentation path made it trainable and slow: 1.59 s a step against detection's 0.39 on an RTX PRO 6000, GPU idle, main process on CPU.
Cause was not volume — ~2,340 masks, 0.24 GB. _branch_mask_loss selected each image's positives with a boolean mask index, whose output shape is data-dependent, so the device had to report the surviving count back to the host before the next op could be built. Inside a loop over the batch, run per branch, that is 2×B forced syncs a step — 64 at batch 32.
Padding to the batch's largest positive count and selecting once costs two syncs a branch at any batch size. Positives keep ascending anchor order within an image and image order across the batch, so summation order — and therefore the value — is the loop's own.
Padding is where a perf change turns numerical, and it did: padded rows carry gt_index = -1, the unassigned sentinel, which is a legal negative index in Python and out of bounds in a gather. The existing gradient test caught it before any of the perf work ran.