Coverage for / home / jenkins / .local / lib / python3.10 / site-packages / hyper_multicore / diagnostics / api.py: 92%
51 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-11-15 05:03 +0800
« prev ^ index » next coverage.py v7.13.1, created at 2026-11-15 05:03 +0800
1# Copyright 2026 Huawei Technologies Co., Ltd
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14# ============================================================================
15"""Generic MegaKernel integration without imports of concrete diagnostic tools."""
17from __future__ import annotations
19from collections.abc import Callable, Sequence
20from typing import Any
22import torch
24from hyper_multicore.diagnostics.common.call import DiagnosticCall, LaunchContext
25from hyper_multicore.diagnostics.common.graph import DiagnosticSpec, GraphDiagnosticMetadata
26from hyper_multicore.diagnostics.common.runtime import PreparedDiagnosticRuntime
27from hyper_multicore.diagnostics.common.session import _get_active_session
28from hyper_multicore.scheduler.config import RuntimeConfigC, TaskDescC
29from hyper_multicore.scheduler.graph import ComputeGraph, OperatorNode
32class MegaKernelDiagnostics:
33 """A reusable normal runtime and optional tool-independent launch boundary."""
35 def __init__(self, runtime: PreparedDiagnosticRuntime) -> None:
36 """Bind a normal runtime without evaluating diagnostic graph semantics."""
37 self._runtime = runtime
39 @property
40 def runtime_config(self) -> torch.Tensor:
41 """Return the original normal execution configuration."""
42 return self._runtime.normal_tensor
44 @property
45 def is_active(self) -> bool:
46 """Return whether an explicit diagnostic session is active."""
47 session = _get_active_session()
48 return session is not None and session.is_capture_enabled()
50 @property
51 def metadata(self) -> GraphDiagnosticMetadata:
52 """Resolve shared graph metadata explicitly for diagnostics or inspection."""
53 return self._runtime.metadata
55 def launch(
56 self, parameters: Sequence[torch.Tensor | None], *, direction: str,
57 fallback_event_counters: torch.Tensor | None = None,
58 ) -> DiagnosticCall:
59 """Select exactly one tool, or return an ordinary no-op context.
61 Kernel adapters should bypass this method when is_active is false so
62 ordinary execution need not create even a Host-side diagnostic call.
64 Args:
65 parameters: Complete native ABI bindings for this invocation.
66 direction: Forward or backward invocation direction.
67 fallback_event_counters: Existing execution-owned event counters, if any.
68 """
69 context = LaunchContext(self._runtime, parameters, direction, fallback_event_counters)
70 session = _get_active_session()
71 if session is None or not session.is_capture_enabled():
72 return DiagnosticCall(context.ordinary_arguments())
73 if len(parameters) != self._runtime.parameter_count:
74 raise ValueError(f"launch expects {self._runtime.parameter_count} ABI parameters, got {len(parameters)}")
75 if direction not in ("forward", "backward"):
76 raise ValueError(f"invalid MegaKernel direction {direction!r}")
77 return session.prepare_call(context)
80def prepare_mega_kernel_diagnostics(
81 graph: ComputeGraph | None, runtime_config: RuntimeConfigC, *, kernel_name: str,
82 parameter_count: int, device: torch.device | str, rank: int = 0, owner_label: str = "Owner",
83 owner_resolver: Callable[[OperatorNode, TaskDescC, Any], int | None] | None = None,
84 owner_context: Any = None,
85 execution_mode: str = "event_driven", vector_worker_stride: int = 2,
86 graph_adapter: Callable[[Any, RuntimeConfigC], ComputeGraph] | None = None,
87) -> MegaKernelDiagnostics:
88 """Prepare only normal execution storage and defer all diagnostic graph work.
90 Args:
91 graph: Completed scheduling graph; may be None if graph_adapter builds
92 the graph of a native broadcast pipeline on first capture.
93 runtime_config: Filled graph-sized Host configuration.
94 kernel_name: Stable name shared by both tools.
95 parameter_count: Number of launch binding entries. Device task positions
96 must match input_list exactly; zero-task Host boundary nodes may
97 describe results produced outside the MegaKernel.
98 device: Device receiving the ordinary runtime configuration.
99 rank: Distributed rank recorded by diagnostics.
100 owner_label: Business display label, such as Expert, Head or Block.
101 owner_resolver: Optional task-owner callback, never called on the normal path.
102 owner_context: Business context passed unchanged to the owner callback.
103 execution_mode: Event-driven queues or a broadcast ``aiv_pipeline``.
104 vector_worker_stride: Two for paired MoE workers, one for all AIV workers.
105 graph_adapter: Optional lazy business-owned binding of graph ports to the
106 real native ABI. It receives a private Host config; ordinary storage
107 and the caller's graph must remain unchanged.
109 Returns:
110 Adapter used by any MegaKernel; dynamic view resolvers remain dump-owned.
111 """
112 if graph is None and graph_adapter is None:
113 raise ValueError("a compute graph or graph_adapter is required")
114 if graph_adapter is not None and not callable(graph_adapter):
115 raise TypeError("graph_adapter must be callable or None")
116 resolved_device = torch.device(device)
117 device_id = resolved_device.index
118 if device_id is None:
119 device_id = 0 if resolved_device.type == "cpu" else torch.get_device_module(resolved_device).current_device()
120 resolved_device = torch.device(resolved_device.type, device_id)
122 def tensor_factory(data: bytes) -> torch.Tensor:
123 """Copy one runtime image onto the execution device.
125 Args:
126 data: Serialized runtime configuration bytes.
127 """
128 return torch.frombuffer(bytearray(data), dtype=torch.uint8).clone().to(device=resolved_device)
130 if execution_mode not in ("event_driven", "aiv_pipeline"):
131 raise ValueError(f"invalid execution mode: {execution_mode!r}")
132 if vector_worker_stride not in (1, 2):
133 raise ValueError("vector_worker_stride must be 1 or 2")
134 runtime = PreparedDiagnosticRuntime(
135 graph, runtime_config, DiagnosticSpec(
136 kernel_name, owner_label, owner_resolver, owner_context,
137 execution_mode, vector_worker_stride, graph_adapter,
138 ),
139 parameter_count=parameter_count, tensor_factory=tensor_factory, rank=rank, device_id=device_id,
140 )
141 return MegaKernelDiagnostics(runtime)