File size: 5,085 Bytes
14a799a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
import ctypes
import os
import platform
def check_error(code: int) -> None:
if code != 0:
raise Exception(f"API้่ฏฏ: {code}")
base_dir = os.path.dirname(__file__)
arch = platform.machine()
if arch == 'x86_64':
arch_dir = 'x86_64'
elif arch in ('aarch64', 'arm64'):
arch_dir = 'aarch64'
else:
raise RuntimeError(f"Unsupported architecture: {arch}")
lib_paths = [
os.path.join(base_dir, arch_dir, 'libclip.so'),
os.path.join(base_dir, 'libclip.so')
]
last_error = None
diagnostic_shown = set()
for lib_path in lib_paths:
try:
print(f"Trying to load: {lib_path}")
_lib = ctypes.CDLL(lib_path)
print(f"โ
Successfully loaded: {lib_path}")
break
except OSError as e:
last_error = e
err_str = str(e)
print(f"\nโ Failed to load: {lib_path}")
print(f" {err_str}")
# Only show GLIBCXX tip once
if "GLIBCXX" in err_str and "not found" in err_str:
if "missing_glibcxx" not in diagnostic_shown:
diagnostic_shown.add("missing_glibcxx")
print("๐ Detected missing GLIBCXX version in libstdc++.so.6")
print("๐ก This usually happens when your environment (like Conda) uses an older libstdc++")
print(f"๐ Try running with system libstdc++ preloaded:")
print(f" export LD_PRELOAD=/usr/lib/{arch_dir}-linux-gnu/libstdc++.so.6\n")
elif "No such file" in err_str:
if "file_not_found" not in diagnostic_shown:
diagnostic_shown.add("file_not_found")
print("๐ File not found. Please verify that libclip.so exists and the path is correct.\n")
elif "wrong ELF class" in err_str:
if "elf_mismatch" not in diagnostic_shown:
diagnostic_shown.add("elf_mismatch")
print("๐ ELF class mismatch โ likely due to architecture conflict (e.g., loading x86_64 .so on aarch64).")
print(f"๐ Run `file {lib_path}` to verify the binary architecture.\n")
else:
if "generic_error" not in diagnostic_shown:
diagnostic_shown.add("generic_error")
print("๐ Tip: Use `ldd` to inspect missing dependencies:")
print(f" ldd {lib_path}\n")
else:
raise RuntimeError(f"\nโ Failed to load libclip.so.\nLast error:\n{last_error}")
# ๅฎไนๆไธพ็ฑปๅ
class AxDeviceType(ctypes.c_int):
unknown_device = 0
host_device = 1
axcl_device = 2
# ๅฎไน็ปๆไฝ
class AxMemInfo(ctypes.Structure):
_fields_ = [
('remain', ctypes.c_int),
('total', ctypes.c_int)
]
class AxHostInfo(ctypes.Structure):
_fields_ = [
('available', ctypes.c_char),
('version', ctypes.c_char * 32),
('mem_info', AxMemInfo)
]
class AxDeviceInfo(ctypes.Structure):
_fields_ = [
('temp', ctypes.c_int),
('cpu_usage', ctypes.c_int),
('npu_usage', ctypes.c_int),
('mem_info', AxMemInfo)
]
class AxDevices(ctypes.Structure):
_fields_ = [
('host', AxHostInfo),
('host_version', ctypes.c_char * 32),
('dev_version', ctypes.c_char * 32),
('count', ctypes.c_ubyte),
('devices_info', AxDeviceInfo * 16)
]
_lib.ax_dev_enum_devices.argtypes = [ctypes.POINTER(AxDevices)]
_lib.ax_dev_enum_devices.restype = ctypes.c_int
_lib.ax_dev_sys_init.argtypes = [AxDeviceType, ctypes.c_char]
_lib.ax_dev_sys_init.restype = ctypes.c_int
_lib.ax_dev_sys_deinit.argtypes = [AxDeviceType, ctypes.c_char]
_lib.ax_dev_sys_deinit.restype = ctypes.c_int
def enum_devices() -> dict:
devices = AxDevices()
check_error(_lib.ax_dev_enum_devices(ctypes.byref(devices)))
return {
'host': {
'available': bool(devices.host.available[0]),
'version': devices.host.version.decode('utf-8'),
'mem_info': {
'remain': devices.host.mem_info.remain,
'total': devices.host.mem_info.total
}
},
'devices': {
'host_version': devices.host_version.decode('utf-8'),
'dev_version': devices.dev_version.decode('utf-8'),
'count': devices.count,
'devices_info': [{
'temp': dev.temp,
'cpu_usage': dev.cpu_usage,
'npu_usage': dev.npu_usage,
'mem_info': {
'remain': dev.mem_info.remain,
'total': dev.mem_info.total
}
} for dev in devices.devices_info[:devices.count]]
}
}
def sys_init(dev_type: AxDeviceType = AxDeviceType.axcl_device, devid: int = 0) -> None:
check_error(_lib.ax_dev_sys_init(dev_type, devid))
def sys_deinit(dev_type: AxDeviceType = AxDeviceType.axcl_device, devid: int = 0) -> None:
check_error(_lib.ax_dev_sys_deinit(dev_type, devid)) |