Coverage for / home / jenkins / .local / lib / python3.10 / site-packages / hyper_multicore / shmem / _runtime.py: 85%
46 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"""Lazy access to the private Torch SHMEM Runtime binding."""
17from __future__ import annotations
19__all__ = [
20 "_load_native",
21 "_torch_modules",
22]
24import ctypes
25import importlib.util
26import sys
27from pathlib import Path
28from typing import Any, Final
30from hyper_multicore._loader import (
31 NativeComponentUnavailableError, load_torch_npu, native_loading, native_context, native_ready,
32 require_multicore_environment, validate_native_compatibility,
33 select_native_shmem,
34)
35from hyper_multicore._native_manifest import SHMEM_DEPENDENCIES, resource_path
38_NATIVE_MODULE: Final = "hyper_multicore_shmem_torch"
40_native: Any | None = None
41_native_libraries: list[Any] = []
44def _load_native() -> Any:
45 """Import and cache the private binding after the first successful load."""
46 global _native # pylint: disable=global-statement
48 if native_ready("shmem"):
49 return _native
50 require_multicore_environment()
51 load_torch_npu()
52 selected = validate_native_compatibility()
53 backend, resources = select_native_shmem(selected)
54 path = resource_path(selected["root"], selected["variant"]["shmem_so"][backend])
55 with native_loading("shmem") as needed:
56 if needed:
57 for dependency in SHMEM_DEPENDENCIES:
58 library = resource_path(selected["root"], f"{resources['shmem_root']}/{dependency}")
59 _native_libraries.append(ctypes.CDLL(str(library), mode=ctypes.RTLD_LOCAL))
60 cached = sys.modules.get(_NATIVE_MODULE)
61 if cached is not None:
62 if Path(getattr(cached, "__file__", "")).resolve() != path:
63 raise NativeComponentUnavailableError(f"Unexpected SHMEM module already loaded: {cached!r}")
64 _native = cached
65 else:
66 try:
67 spec = importlib.util.spec_from_file_location(_NATIVE_MODULE, path)
68 if spec is None or spec.loader is None:
69 raise ImportError(f"No extension loader for {path}")
70 native = importlib.util.module_from_spec(spec)
71 sys.modules[_NATIVE_MODULE] = native
72 spec.loader.exec_module(native)
73 _native = native
74 except BaseException as error:
75 sys.modules.pop(_NATIVE_MODULE, None)
76 raise NativeComponentUnavailableError(
77 f"[HYPER-MULTICORE-SHMEM-LOAD-FAILED] path={path} {native_context()}: {error}"
78 ) from error
79 return _native
82def _torch_modules() -> tuple[Any, Any]:
83 """Load Torch only when the internal SHMEM boundary is used."""
84 import torch # pylint: disable=C0415
85 import torch.distributed as dist # pylint: disable=C0415
87 return torch, dist