Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions MANUAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 互连检测 |
Expand Down Expand Up @@ -67,7 +67,7 @@ mthreads-ml-py/
验证驱动是否安装:

```bash
# 检查 libmtml.so 是否可用
# 检查 MTML 库是否可用
ldconfig -p | grep libmtml

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Windows, there is no ldconfig mechanism like Linux, please add the checking command like: where mtml.dll


# 检查 GPU 设备
Expand Down Expand Up @@ -193,7 +193,7 @@ pynvml.nvmlShutdown()

| 函数 | 说明 |
| --- | --- |
| `mtmlLibraryInit()` | 初始化 MTML 库,加载 `libmtml.so` |
| `mtmlLibraryInit()` | 初始化 MTML 库,加载 MTML 共享库(Linux: libmtml.so, Windows: mtml.dll) |
| `mtmlLibraryShutDown()` | 关闭库接口(库本身保持加载) |
| `mtmlLibraryGetVersion()` | 获取 MTML 库版本号 |
| `mtmlLibraryCountDevice()` | 获取 GPU 设备数量 |
Expand Down Expand Up @@ -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)`

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
41 changes: 35 additions & 6 deletions pymtml.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest that we need to split up the windows and linux loader logic. Maybe refactoring the loader into smaller, well-defined helper functions with clearer responsibilities.

platform = sys.platform

if platform.startswith("win32") or platform.startswith("cygwin"):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We prefer using: os.name == "nt"

# 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")):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as os.name == "nt"

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()
Expand Down
9 changes: 7 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -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

Expand Down
32 changes: 32 additions & 0 deletions test_win.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from pymtml import *

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe no need to add this test file. It is the same as test_pymtml.py

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@xinye0123 You can run the tests under https://github.com/MooreThreads/mthreads-ml-py/tree/main/examples to verify that everything works properly on Windows.


#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()