{"record":{"id":"de9a5ff2192cedcc","repo":"sgl-project/sglang","slug":"graph-capture-input-at-ptr-is-outside-vmm-alloca","errorCode":null,"errorMessage":"graph capture input at {ptr} is outside VMM allocation [base={base}, size={size}]","messagePattern":"graph capture input at (.+?) is outside VMM allocation \\[base=(.+?), size=(.+?)\\]","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/utils/cuda_vmm_utils.py","lineNumber":135,"sourceCode":"    input_chunk_indices: List[List[int]] = []\n    input_offsets: List[int] = []\n    for ptr, nbytes in graph_inputs:\n        ptr, remaining = int(ptr), int(nbytes)\n        if remaining <= 0:\n            raise RuntimeError(f\"Invalid graph capture input size: {nbytes}\")\n        cursor = ptr\n        first_base = None\n        chunks: List[int] = []\n        while remaining > 0:\n            err, base, size = drv.cuMemGetAddressRange(cursor)\n            if err != drv.CUresult.CUDA_SUCCESS:\n                raise RuntimeError(f\"cuMemGetAddressRange: {err}\")\n            base, size = int(base), int(size)\n            if first_base is None:\n                first_base = base\n            byte_offset = cursor - base\n            if not 0 <= byte_offset < size:\n                raise RuntimeError(\n                    f\"graph capture input at {ptr} is outside VMM allocation \"\n                    f\"[base={base}, size={size}]\"\n                )\n            idx = base_to_idx.setdefault(base, len(bases_info))\n            if idx == len(bases_info):\n                bases_info.append((base, size))\n            chunks.append(idx)\n            advance = min(remaining, size - byte_offset)\n            assert advance > 0, \"Failed to advance VMM graph capture span\"\n            remaining -= advance\n            cursor += advance\n        input_chunk_indices.append(chunks)\n        input_offsets.append(ptr - first_base)\n    return bases_info, input_chunk_indices, input_offsets\n\n\ndef make_rw_access_desc(device_id: int):\n    \"\"\"A read-write, device-local ``CUmemAccessDesc`` for ``device_id``.\"\"\"","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/utils/cuda_vmm_utils.py#L117-L153","documentation":"After querying an allocation's base/size, the code verifies the cursor address actually lies within that allocation range; if the computed byte offset is outside [0, size) the pointer is outside the VMM allocation and the invariant is broken. This catches inconsistent address-range results or corrupted pointer arithmetic before chunk indices are built.","triggerScenarios":"A graph input pointer that doesn't fall inside any cuMem allocation returned by the driver; integer/pointer arithmetic bugs producing a cursor past the region end; non-contiguous spanning inputs where the walk goes past the last chunk.","commonSituations":"Corrupted capture input lists; buffers straddling allocations freed mid-walk; pointer truncation on 32-bit builds.","solutions":["Recompute the graph input list from live tensors and retry capture","Ensure inputs are allocated from the VMM pool (not foreign allocations) when using capture bases","Check for 32-bit/64-bit pointer truncation in code building the ptr/nbytes pairs"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"err, base, size = drv.cuMemGetAddressRange(ptr)\nif not (base <= ptr < base + size):\n    raise ValueError(\"pointer outside its VMM allocation\")","typeGuard":"def pointer_in_allocation(ptr: int, base: int, size: int) -> bool:\n    return base <= ptr < base + size","tryCatchPattern":null,"preventionTips":["Allocate capture inputs from the VMM pool","Recompute capture bases after any reallocation"],"tags":["cuda","vmm","cuda-graph","pointer-range"],"backgroundTag":"pointer-out-of-range","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}