{"record":{"id":"ed2a2bca29ddd0da","repo":"huggingface/transformers","slug":"fused-kernel-kernel-cls-name-r-requires-a-co","errorCode":null,"errorMessage":"Fused kernel {kernel_cls.__name__!r} requires a companion layout class named '{kernel_cls.__name__}Layout' in the same module.","messagePattern":"Fused kernel (.+?) requires a companion layout class named '(.+?)Layout' in the same module\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/transformers/integrations/hub_kernels.py","lineNumber":946,"sourceCode":"\n        # Case 1: no fusion.\n        if isinstance(layer_name, str):\n            # No layout class: stateless kernel, leave for kernels.kernelize.\n            if layout_cls is None:\n                new_mapping[layer_name] = final_repo\n                continue\n\n            # Register the layout class as a monkey patch for the parent module containing the target layer.\n            layout_cls.kernel_layer_name = kernel_cls.__name__\n            patch_mapping[layer_name] = layout_cls\n\n            # Keep the original repo string so kernelize can replace the layout's forward.\n            new_mapping[kernel_cls.__name__] = final_repo\n\n        # Case 2: fusion.\n        elif isinstance(layer_name, tuple):\n            if layout_cls is None:\n                raise ValueError(\n                    f\"Fused kernel {kernel_cls.__name__!r} requires a companion layout class \"\n                    f\"named '{kernel_cls.__name__}Layout' in the same module.\"\n                )\n\n            layout_cls.kernel_layer_name = kernel_cls.__name__\n\n            glob_patterns = [item[1] for item in layer_name]\n            parent_patterns = [p.rsplit(\".\", 1)[0] for p in glob_patterns]\n\n            if len(set(parent_patterns)) != 1:\n                raise ValueError(\n                    f\"All patterns for a fused kernel must share the same parent module, got {glob_patterns}\"\n                )\n\n            parent_pattern = parent_patterns[0].replace(\"*\", r\"\\w+\")\n            child_names = [p.rsplit(\".\", 1)[1] for p in glob_patterns]\n\n            if meta_model is None:","sourceCodeStart":928,"sourceCodeEnd":964,"githubUrl":"https://github.com/huggingface/transformers/blob/a597f974857b3d92939971296bc0deb93d33d780/src/transformers/integrations/hub_kernels.py#L928-L964","documentation":"When a kernel_mapping key is a tuple (fusion mode: multiple child modules fused into one kernel), transformers looks for a class named '<KernelCls>Layout' in the same module as the loaded kernel class to use as the fused layer's new type. Fusion without a layout class is unsupported, so a None layout_cls raises this ValueError.","triggerScenarios":"A kernel_mapping entry whose key is a list/tuple of (index, 'parent.child') patterns (e.g. [[0, 'model.layers.*.mlp.gate_proj'], [1, 'model.layers.*.mlp.up_proj']]) while the kernel repo's module defines KernelCls but no KernelClsLayout class.","commonSituations":"Authoring or publishing a custom fused kernel and forgetting the companion Layout class; upgrading a kernel repo where the Layout class was renamed; copying a fusion mapping onto a kernel that only supports single-layer replacement.","solutions":["Add a class named exactly f'{kernel_cls.__name__}Layout' to the same Python module the kernel class lives in.","If the kernel is not meant to fuse multiple modules, change the kernel_mapping key from a tuple to a single dotted string.","Check the kernel repo's exports (dir(module)) to confirm whether the Layout class exists under a different name and update accordingly."],"exampleFix":"# before: kernel module defines only\nclass FuseMLP(nn.Module): ...\n\n# after\nclass FuseMLP(nn.Module): ...\nclass FuseMLPLayout(nn.Module):\n    conversion_mapping = ...\n    def forward(self, hidden_states): ...","handlingStrategy":"validation","validationCode":"import sys\n\ndef has_layout_class(kernel_cls) -> bool:\n    mod = sys.modules.get(kernel_cls.__module__)\n    return mod is not None and hasattr(mod, f\"{kernel_cls.__name__}Layout\")","typeGuard":null,"tryCatchPattern":"try:\n    register_kernel_replacements_and_fusions(cls, config, kernel_config)\nexcept ValueError as e:\n    if \"requires a companion layout class\" in str(e):\n        # kernel does not support fusion: demote entry to single-layer replacement\n        convert_key_to_string(kernel_config)\n    else:\n        raise","preventionTips":["When publishing fused kernels, always ship <Kernel>Layout next to <Kernel> in the same module.","Add a repo self-test that asserts the Layout class exists for every fusion-capable kernel."],"tags":["hub-kernels","fusion","kernel-authoring"],"backgroundTag":null,"analyzedSha":"a597f974857b3d92939971296bc0deb93d33d780","analyzedAt":"2026-08-14T18:24:08.354Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}