diff --git a/AGENTS.md b/AGENTS.md index 7250b65..5cb77d0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,7 +4,7 @@ **pymtml** is Python bindings for the Moore Threads Management Library (MTML) - a C-based API for monitoring and managing Moore Threads GPU devices. It provides: -1. **Native MTML bindings** - Direct Python wrappers for libmtml.so C library functions +1. **Native MTML bindings** - Direct Python wrappers for MTML C library functions (Linux: libmtml.so, Windows: mtml.dll) 2. **NVML compatibility layer** - Drop-in replacement for NVIDIA's pynvml library Moore Threads GPUs use **MUSA** (Meta-computing Unified System Architecture) as their compute platform, analogous to NVIDIA's CUDA. @@ -93,13 +93,13 @@ def mtmlDeviceGetSomething(device): ## Testing Instructions - **Always run tests before committing**: `python test_pymtml.py && python test_pynvml.py` -- **Tests require Moore Threads GPU hardware** with driver and libmtml.so installed +- **Tests require Moore Threads GPU hardware** with driver and MTML library installed (Linux: libmtml.so, Windows: mtml.dll) - **Test init/shutdown cycles**: The library supports multiple init/shutdown cycles - **Check for segfaults**: Library shutdown must not cause crashes ## Security Considerations -- This library loads `libmtml.so` dynamically via ctypes +- This library loads MTML library dynamically via ctypes (Linux: libmtml.so, Windows: mtml.dll) - No network operations or external data fetching - GPU operations require appropriate system permissions - Handle device handles carefully - don't use after shutdown diff --git a/MANUAL.md b/MANUAL.md index 2e50c44..ce45d4a 100644 --- a/MANUAL.md +++ b/MANUAL.md @@ -23,14 +23,14 @@ Python Bindings for Moore Threads Management Library (MTML) ## 1. 项目简介 -**pymtml** 是摩尔线程 GPU 管理库 (MTML) 的 Python 绑定,通过 ctypes 动态加载 `libmtml.so` 共享库,提供对摩尔线程 GPU 设备的监控与管理能力。 +**pymtml** 是摩尔线程 GPU 管理库 (MTML) 的 Python 绑定,通过 ctypes 动态加载 MTML 共享库(Linux: `libmtml.so`, Windows: `mtml.dll`),提供对摩尔线程 GPU 设备的监控与管理能力。 ### 核心特性 | 特性 | 说明 | | --- | --- | -| **原生 MTML API** | 直接封装 libmtml.so C 库函数 | +| **原生 MTML API** | 直接封装 MTML C 库函数(Linux: libmtml.so, Windows: mtml.dll) | | **NVML 兼容层** | 提供 pynvml 的替代接口,支持一行替换 | | **上下文管理器** | 提供 `with` 语句管理 GPU/Memory/VPU 子组件生命周期 | | **多 GPU 支持** | 支持多卡拓扑查询、P2P 状态检测、MtLink 互连检测 | @@ -67,7 +67,7 @@ mthreads-ml-py/ 验证驱动是否安装: ```bash -# 检查 libmtml.so 是否可用 +# 检查 MTML 库是否可用 ldconfig -p | grep libmtml # 检查 GPU 设备 @@ -193,7 +193,7 @@ pynvml.nvmlShutdown() | 函数 | 说明 | | --- | --- | -| `mtmlLibraryInit()` | 初始化 MTML 库,加载 `libmtml.so` | +| `mtmlLibraryInit()` | 初始化 MTML 库,加载 MTML 共享库(Linux: libmtml.so, Windows: mtml.dll) | | `mtmlLibraryShutDown()` | 关闭库接口(库本身保持加载) | | `mtmlLibraryGetVersion()` | 获取 MTML 库版本号 | | `mtmlLibraryCountDevice()` | 获取 GPU 设备数量 | @@ -999,7 +999,7 @@ pymtml.MTMLError_DriverNotLoaded: Driver Not Loaded **原因**:摩尔线程 GPU 驱动未加载或不在当前环境中可用(例如在沙箱、容器中运行时)。 -**解决**:确认 GPU 驱动已安装,`libmtml.so` 在 `LD_LIBRARY_PATH` 中。 +**解决**:确认 GPU 驱动已安装,MTML 库在系统路径中(Linux: `libmtml.so` 在 `LD_LIBRARY_PATH` 中,Windows: `mtml.dll` 在 `PATH` 中或 `mtml/` 目录下)。 ### Q: `nvmlDeviceGetCudaComputeCapability()` 返回 `(0, 0)` diff --git a/README.md b/README.md index 71178d7..fa78a40 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,8 @@ Moore Threads GPUs use MUSA (Meta-computing Unified System Architecture) as thei - Python 3.7+ - Moore Threads GPU driver with MTML library installed -- The `libmtml.so` shared library must be in the library path +- **Linux**: The `libmtml.so` shared library must be in the library path +- **Windows**: The `mtml.dll` library must be in the system PATH or in the `mtml/` directory relative to the script ## Installation diff --git a/pymtml.py b/pymtml.py index 949ddd6..ea5e7de 100644 --- a/pymtml.py +++ b/pymtml.py @@ -647,13 +647,42 @@ def _LoadMtmlLibrary(): try: # ensure the library still isn't loaded if mtmlLib == None: - try: - # assume linux - mtmlLib = CDLL("libmtml.so") - except OSError as ose: - _mtmlCheckReturn(MTML_ERROR_FUNCTION_NOT_FOUND) + # Platform-specific library loading + platform = sys.platform + + if platform.startswith("win32") or platform.startswith("cygwin"): + # Windows platform + lib_names = ["mtml.dll", "libmtml.dll"] + lib_loader = WinDLL + else: + # Linux/Unix platform + lib_names = ["libmtml.so"] + lib_loader = CDLL + + # Try loading the library with different names + last_error = None + for lib_name in lib_names: + try: + mtmlLib = lib_loader(lib_name) + break + except OSError as ose: + last_error = ose + continue + + # If all attempts failed, try with full path to mtml/mtml.dll + if mtmlLib is None and (platform.startswith("win32") or platform.startswith("cygwin")): + try: + import os + dll_path = os.path.join(os.path.dirname(__file__), "mtml", "mtml.dll") + mtmlLib = WinDLL(dll_path) + except OSError as ose: + last_error = ose + if mtmlLib == None: - _mtmlCheckReturn(MTML_ERROR_FUNCTION_NOT_FOUND) + error_msg = f"Failed to load MTML library. Tried: {', '.join(lib_names)}" + if last_error: + error_msg += f"\nLast error: {last_error}" + raise OSError(error_msg) finally: # lock is always freed libLoadLock.release() diff --git a/setup.py b/setup.py index 2b89143..788a5aa 100644 --- a/setup.py +++ b/setup.py @@ -1,10 +1,15 @@ -from distutils.core import setup +try: + from setuptools import setup + from setuptools.dist import DistributionMetadata +except ImportError: + from distutils.core import setup + from distutils.dist import DistributionMetadata + from sys import version from sys import exit # earlier versions don't support all classifiers if version < '2.2.3': - from distutils.dist import DistributionMetadata DistributionMetadata.classifiers = None DistributionMetadata.download_url = None diff --git a/test_win.py b/test_win.py new file mode 100644 index 0000000..0cf4905 --- /dev/null +++ b/test_win.py @@ -0,0 +1,32 @@ +from pymtml import * + +#init +mtmlLibraryInit() + +#get device count +device_count = mtmlLibraryCountDevice() +print(f"Found {device_count} GPU(s)") + +#query devices +for i in range(device_count): + device = mtmlLibraryInitDeviceByIndex(i) + + #Basic info + name = mtmlDeviceGetName(device) + uuid = mtmlDeviceGetUUID(device) + print(f"Device {i}: {name} (UUID: {uuid})") + + #Memory info + with mtmlMemoryContext(device) as mem_ctx: + total = mtmlMemoryGetTotal(mem_ctx) + used = mtmlMemoryGetUsed(mem_ctx) + print(f" Memory: {used / (1024**3):.2f} GB used / {total / (1024**3):.2f} GB total") + + #GPU1 utilization + with mtmlGpuContext(device) as gpu_ctx: + utilization = mtmlGpuGetUtilization(gpu_ctx) + temp = mtmlGpuGetTemperature(gpu_ctx) + print(f" GPU Utilization: {utilization}%, Temperature: {temp}°C") + +#cleanup +mtmlLibraryShutDown() \ No newline at end of file