{"record":{"id":"2f7ab6b5e0644056","repo":"sgl-project/sglang","slug":"mamba-storage-zero-copy-requires-page-first-layout","errorCode":null,"errorMessage":"Mamba storage zero-copy requires page_first layout, got {self.layout}","messagePattern":"Mamba storage zero-copy requires page_first layout, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/sglang/srt/mem_cache/pool_host/mamba.py","lineNumber":542,"sourceCode":"    ) -> None:\n        flat_bytes = data_page.contiguous().view(torch.uint8).reshape(-1)\n        start = 0\n        for tensor in self._iter_page_tensors(index):\n            num_bytes = tensor.numel() * tensor.element_size()\n            tensor_bytes = flat_bytes[start : start + num_bytes]\n            start += num_bytes\n            restored = tensor_bytes.view(dtype=tensor.dtype).reshape(tensor.shape)\n            tensor.copy_(restored)\n\n    def get_page_buffer_meta(self, indices):\n        \"\"\"Meta data for zero-copy storage I/O.\n\n        Only page-first layouts are supported for mamba storage zero-copy because\n        each page slot in temporal/conv buffers is directly addressable.\n        \"\"\"\n        assert len(indices) % self.page_size == 0\n        if self.layout not in [\"page_first\", \"page_first_direct\"]:\n            raise ValueError(\n                f\"Mamba storage zero-copy requires page_first layout, got {self.layout}\"\n            )\n        indices = indices.tolist()\n        ptr_list = []\n        element_size_list = []\n\n        # Compute base pointers once; each page pointer is offset from these bases.\n        temporal_base_ptr = self.temporal_buffer.data_ptr()\n        conv_base_ptrs = [buf.data_ptr() for buf in self.conv_buffer]\n        # Component sizes are constant across pages, so precompute once as well.\n        temporal_element_size = (\n            self.page_size\n            * self.num_mamba_layers\n            * self.temporal_dtype.itemsize\n            * self.temporal_state_elem_size\n        )\n        conv_element_sizes = [\n            (","sourceCodeStart":524,"sourceCodeEnd":560,"githubUrl":"https://github.com/sgl-project/sglang/blob/0132848349585cfe6aae51c4941cbae872505f8a/python/sglang/srt/mem_cache/pool_host/mamba.py#L524-L560","documentation":"The Mamba host storage's zero-copy page-buffer metadata API only works when the host pool was allocated in a page-first layout, because only then is each page slot in the temporal/conv state buffers directly addressable as contiguous memory. If the pool was created with layer_first layout, per-page pointers cannot be computed, so the API refuses.","triggerScenarios":"Calling MambaHostStorage.get_page_buffer_meta(indices) while self.layout is not 'page_first' or 'page_first_direct' — typically when the hierarchical cache was configured without the page-first host layout option (e.g. hierarchical cache for Mamba with layer-first host allocation).","commonSituations":"Enabling hierarchical cache / zero-copy offload on a hybrid Mamba model without setting the host pool layout to page-first; older configs that defaulted Mamba host pools to layer_first; custom code calling the zero-copy transfer API directly.","solutions":["Configure the host pool / hierarchical cache so the Mamba host storage uses page_first layout (enable the page-first host layout option in ServerArgs or the pool constructor)","If using a transfer API that requires get_page_buffer_meta, switch to the non-zero-copy path that works with layer_first","Upgrade SGLang if your version defaulted Mamba host layout incorrectly for zero-copy offload","Ensure indices length is a multiple of page_size as well, since the same API asserts on that"],"exampleFix":"# before\nhost_pool = MambaHostStorage(..., layout=\"layer_first\")\nmeta = host_pool.get_page_buffer_meta(indices)  # ValueError\n# after\nhost_pool = MambaHostStorage(..., layout=\"page_first\")\nmeta = host_pool.get_page_buffer_meta(indices)","handlingStrategy":"validation","validationCode":"assert host_storage.layout in (\"page_first\", \"page_first_direct\"), (\n    f\"get_page_buffer_meta requires page_first layout, got {host_storage.layout}\")\nassert len(indices) % host_storage.page_size == 0","typeGuard":"def supports_zero_copy(storage) -> bool:\n    return getattr(storage, \"layout\", \"\") in (\"page_first\", \"page_first_direct\")","tryCatchPattern":null,"preventionTips":["Construct Mamba host storage with page_first layout whenever zero-copy transfer is intended","Centralize layout constants instead of passing raw strings","Assert page-size-aligned indices before calling"],"tags":["sglang","mamba","layout","zero-copy","hierarchical-cache"],"backgroundTag":"unsupported-layout-value","analyzedSha":"0132848349585cfe6aae51c4941cbae872505f8a","analyzedAt":"2026-08-28T05:10:05.995Z","schemaVersion":2},"datasetVersion":"2026-08-28T06:17:29.519Z"}