Coverage for /opt/cloud/slavespace/usr1/096471637100f3de0fcfc01072822a80/dttest/api/python/ge/ge/_capi/pyes_graph_builder_wrapper.py: 95%

148 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-07-27 10:03 +0800

1#!/usr/bin/env python3 

2# -*- coding: utf-8 -*- 

3# ------------------------------------------------------------------- 

4# ----------------------------------------------------------------------------------------------------------- 

5# Copyright (c) 2025 Huawei Technologies Co., Ltd. 

6# This program is free software, you can redistribute it and/or modify it under the terms and conditions of 

7# CANN Open Software License Agreement Version 2.0 (the "License"). 

8# Please refer to the License for details. You may not use this file except in compliance with the License. 

9# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, 

10# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE. 

11# See LICENSE in the root of the software repository for the full text of the License. 

12# ----------------------------------------------------------------------------------------------------------- 

13 

14import ctypes 

15import os 

16from typing import Dict 

17 

18from ._lib_loader import load_lib_from_path 

19 

20# 常用C类型别名 

21c_void_p = ctypes.c_void_p 

22c_char_p = ctypes.c_char_p 

23c_int = ctypes.c_int 

24c_int32 = ctypes.c_int32 

25c_int64 = ctypes.c_int64 

26c_float = ctypes.c_float 

27c_bool = ctypes.c_bool 

28c_uint32 = ctypes.c_uint32 

29c_uint64 = ctypes.c_uint64 

30c_double = ctypes.c_double 

31 

32 

33# C结构体定义 

34class EsCTensorHolder(ctypes.Structure): 

35 """C层 struct EsCTensorHolder""" 

36 

37 pass 

38 

39 

40class EsCGraphBuilder(ctypes.Structure): 

41 """C层 struct EsCGraphBuilder""" 

42 

43 pass 

44 

45 

46class EsCGraph(ctypes.Structure): 

47 """C层 struct EsCGraph""" 

48 

49 pass 

50 

51 

52class EsCTensor(ctypes.Structure): 

53 """C层 struct EsCTensor""" 

54 

55 pass 

56 

57 

58# 指针类型定义 

59EsCTensorHolderPtr = ctypes.POINTER(EsCTensorHolder) 

60EsCGraphBuilderPtr = ctypes.POINTER(EsCGraphBuilder) 

61EsCTensorPtr = ctypes.POINTER(EsCTensor) 

62 

63# 基础库 

64BASE_LIB_NAME = "libeager_style_graph_builder_base.so" 

65# 默认生成的es api的全量库 

66DEFAULT_GENERATED_LIB_NAME = "libes_all.so" 

67# 生成的数学库 

68MATH_LIB_NAME = "libes_math.so" 

69 

70# 优先使用 GLOBAL|NOW,确保符号可见并尽早完成重定位 

71_dir = os.path.dirname(os.path.abspath(__file__)) 

72_dlopen_mode = getattr(os, "RTLD_GLOBAL", 0) | getattr(os, "RTLD_NOW", 0) 

73 

74# 尝试在当前py的安装路径下,加载生成的es api的C库 

75_lib_cache: Dict[str, ctypes.CDLL] = {} 

76_configured_lib_ids = set() 

77_default_lib_available = False 

78_default_lib = None 

79esb_lib = None 

80 

81 

82def _configure_generated_lib(lib: ctypes.CDLL) -> None: 

83 lib_id = id(lib) 

84 if lib_id in _configured_lib_ids: 

85 return 

86 

87 # 二元操作符:加减乘除(仅在符号存在时配置) 

88 for op_name in ["EsAdd", "EsSub", "EsMul", "EsDiv"]: 

89 if hasattr(lib, op_name): 

90 getattr(lib, op_name).restype = EsCTensorHolderPtr 

91 getattr(lib, op_name).argtypes = [EsCTensorHolderPtr, EsCTensorHolderPtr] 

92 

93 _configured_lib_ids.add(lib_id) 

94 

95 

96# Try to load generated libraries first so base weak-symbol calls can bind to strong impls. 

97for lib_name in [DEFAULT_GENERATED_LIB_NAME, MATH_LIB_NAME]: 

98 try: 

99 lib = load_lib_from_path(lib_name, _dir, mode=_dlopen_mode) 

100 _configure_generated_lib(lib) 

101 _lib_cache[lib_name] = lib 

102 if lib_name == DEFAULT_GENERATED_LIB_NAME: 

103 _default_lib = lib 

104 _default_lib_available = True 

105 except OSError: 

106 continue 

107 

108# Load base library after generated libraries. 

109esb_lib = load_lib_from_path(BASE_LIB_NAME, _dir, mode=_dlopen_mode) 

110if esb_lib is None: 

111 raise RuntimeError(f"Failed to load {BASE_LIB_NAME}") 

112 

113 

114def is_generated_lib_available(): 

115 """Check if default generated operator library is available""" 

116 return _default_lib_available 

117 

118 

119def get_loaded_lib_names(): 

120 """Get list of currently loaded library names. 

121 

122 Returns: 

123 List of library names that have been loaded and cached. 

124 """ 

125 return list(_lib_cache.keys()) 

126 

127 

128def clear_lib_cache(): 

129 """Clear the library cache. 

130 

131 Warning: This only clears Python references. The actual shared libraries 

132 remain loaded in the process memory and cannot be unloaded. 

133 """ 

134 _lib_cache.clear() 

135 

136 

137def get_generated_lib(lib_name: str = None): 

138 """Get specified generated operator library. 

139 

140 Args: 

141 lib_name: Library name. If None, returns default library. 

142 

143 Returns: 

144 Loaded ctypes.CDLL object. 

145 

146 Raises: 

147 RuntimeError: If library is not available. 

148 """ 

149 global _default_lib, _default_lib_available 

150 target = lib_name or DEFAULT_GENERATED_LIB_NAME 

151 

152 # Return cached default library if available 

153 if target == DEFAULT_GENERATED_LIB_NAME and _default_lib_available and _default_lib is not None: 

154 return _default_lib 

155 

156 # Return cached library if already loaded 

157 if target in _lib_cache: 

158 return _lib_cache[target] 

159 

160 # Load library from file system 

161 try: 

162 lib = load_lib_from_path(target, _dir, mode=_dlopen_mode) 

163 _configure_generated_lib(lib) 

164 _lib_cache[target] = lib 

165 except OSError as exc: 

166 raise RuntimeError(f"Generated library {target} is not available: {exc}") from exc 

167 

168 # Update default library reference if loading default lib name 

169 if target == DEFAULT_GENERATED_LIB_NAME: 

170 _default_lib, _default_lib_available = lib, True 

171 

172 return lib 

173 

174 

175# ============ GraphBuilder C API ============ 

176# 创建/销毁 

177esb_lib.EsCreateGraphBuilder.restype = EsCGraphBuilderPtr 

178esb_lib.EsCreateGraphBuilder.argtypes = [c_char_p] 

179 

180esb_lib.EsDestroyGraphBuilder.restype = None 

181esb_lib.EsDestroyGraphBuilder.argtypes = [EsCGraphBuilderPtr] 

182 

183# 图输入创建 

184esb_lib.EsCreateGraphInputWithDetails.restype = EsCTensorHolderPtr 

185esb_lib.EsCreateGraphInputWithDetails.argtypes = [ 

186 EsCGraphBuilderPtr, 

187 c_int64, 

188 c_char_p, 

189 c_char_p, 

190 c_int, 

191 c_int, 

192 ctypes.POINTER(c_int64), 

193 c_int64, 

194] 

195 

196esb_lib.EsCreateGraphInput.restype = EsCTensorHolderPtr 

197esb_lib.EsCreateGraphInput.argtypes = [EsCGraphBuilderPtr, c_int64] 

198 

199# 常量创建 - 根据 esb_funcs.h 中的实际接口定义 

200esb_lib.EsCreateConstInt64.restype = EsCTensorHolderPtr 

201esb_lib.EsCreateConstInt64.argtypes = [ 

202 EsCGraphBuilderPtr, 

203 ctypes.POINTER(c_int64), 

204 ctypes.POINTER(c_int64), 

205 c_int64, 

206] 

207 

208esb_lib.EsCreateConstFloat.restype = EsCTensorHolderPtr 

209esb_lib.EsCreateConstFloat.argtypes = [ 

210 EsCGraphBuilderPtr, 

211 ctypes.POINTER(c_float), 

212 ctypes.POINTER(c_int64), 

213 c_int64, 

214] 

215 

216esb_lib.EsCreateConstUInt64.restype = EsCTensorHolderPtr 

217esb_lib.EsCreateConstUInt64.argtypes = [ 

218 EsCGraphBuilderPtr, 

219 ctypes.POINTER(c_uint64), 

220 ctypes.POINTER(c_int64), 

221 c_int64, 

222] 

223 

224esb_lib.EsCreateConstInt32.restype = EsCTensorHolderPtr 

225esb_lib.EsCreateConstInt32.argtypes = [ 

226 EsCGraphBuilderPtr, 

227 ctypes.POINTER(c_int32), 

228 ctypes.POINTER(c_int64), 

229 c_int64, 

230] 

231 

232esb_lib.EsCreateConstUInt32.restype = EsCTensorHolderPtr 

233esb_lib.EsCreateConstUInt32.argtypes = [ 

234 EsCGraphBuilderPtr, 

235 ctypes.POINTER(c_uint32), 

236 ctypes.POINTER(c_int64), 

237 c_int64, 

238] 

239 

240# 向量和标量创建 

241esb_lib.EsCreateVectorInt64.restype = EsCTensorHolderPtr 

242esb_lib.EsCreateVectorInt64.argtypes = [ 

243 EsCGraphBuilderPtr, 

244 ctypes.POINTER(c_int64), 

245 c_int64, 

246] 

247 

248esb_lib.EsCreateScalarInt64.restype = EsCTensorHolderPtr 

249esb_lib.EsCreateScalarInt64.argtypes = [EsCGraphBuilderPtr, c_int64] 

250 

251esb_lib.EsCreateScalarInt32.restype = EsCTensorHolderPtr 

252esb_lib.EsCreateScalarInt32.argtypes = [EsCGraphBuilderPtr, c_int32] 

253 

254esb_lib.EsCreateScalarFloat.restype = EsCTensorHolderPtr 

255esb_lib.EsCreateScalarFloat.argtypes = [EsCGraphBuilderPtr, c_float] 

256 

257esb_lib.EsCreateScalarUInt64.restype = EsCTensorHolderPtr 

258esb_lib.EsCreateScalarUInt64.argtypes = [EsCGraphBuilderPtr, c_uint64] 

259 

260esb_lib.EsCreateScalarUInt32.restype = EsCTensorHolderPtr 

261esb_lib.EsCreateScalarUInt32.argtypes = [EsCGraphBuilderPtr, c_uint32] 

262 

263# 变量创建 

264esb_lib.EsCreateVariable.restype = EsCTensorHolderPtr 

265esb_lib.EsCreateVariable.argtypes = [EsCGraphBuilderPtr, c_int32, c_char_p] 

266 

267# 图构建 

268esb_lib.EsBuildGraphAndReset.restype = c_void_p 

269esb_lib.EsBuildGraphAndReset.argtypes = [EsCGraphBuilderPtr] 

270 

271# 获取拥有者 

272esb_lib.EsGetProducer.restype = c_void_p 

273esb_lib.EsGetProducer.argtypes = [EsCTensorHolderPtr] 

274 

275# 获取构建器 

276esb_lib.EsGetOwnerBuilder.restype = EsCGraphBuilderPtr 

277esb_lib.EsGetOwnerBuilder.argtypes = [EsCTensorHolderPtr] 

278 

279# ============ TensorHolder C API ============ 

280# 数据类型和格式设置 

281esb_lib.EsSetDataType.restype = c_uint32 

282esb_lib.EsSetDataType.argtypes = [EsCTensorHolderPtr, c_int] 

283 

284esb_lib.EsSetFormat.restype = c_uint32 

285esb_lib.EsSetFormat.argtypes = [EsCTensorHolderPtr, c_int] 

286 

287# 形状设置 

288esb_lib.EsSetShape.restype = c_uint32 

289esb_lib.EsSetShape.argtypes = [EsCTensorHolderPtr, ctypes.POINTER(c_int64), c_int64] 

290 

291# 图输出设置 

292esb_lib.EsSetGraphOutput.restype = c_uint32 

293esb_lib.EsSetGraphOutput.argtypes = [EsCTensorHolderPtr, c_int64] 

294 

295# ============ 属性设置 API ============ 

296# 图属性设置 

297esb_lib.EsSetInt64AttrForGraph.restype = c_uint32 

298esb_lib.EsSetInt64AttrForGraph.argtypes = [EsCGraphBuilderPtr, c_char_p, c_int64] 

299 

300esb_lib.EsSetStringAttrForGraph.restype = c_uint32 

301esb_lib.EsSetStringAttrForGraph.argtypes = [EsCGraphBuilderPtr, c_char_p, c_char_p] 

302 

303esb_lib.EsSetBoolAttrForGraph.restype = c_uint32 

304esb_lib.EsSetBoolAttrForGraph.argtypes = [EsCGraphBuilderPtr, c_char_p, c_bool] 

305 

306# Tensor属性设置 

307esb_lib.EsSetInt64AttrForTensor.restype = c_uint32 

308esb_lib.EsSetInt64AttrForTensor.argtypes = [EsCTensorHolderPtr, c_char_p, c_int64] 

309 

310esb_lib.EsSetStringAttrForTensor.restype = c_uint32 

311esb_lib.EsSetStringAttrForTensor.argtypes = [EsCTensorHolderPtr, c_char_p, c_char_p] 

312 

313esb_lib.EsSetBoolAttrForTensor.restype = c_uint32 

314esb_lib.EsSetBoolAttrForTensor.argtypes = [EsCTensorHolderPtr, c_char_p, c_bool] 

315 

316# 节点属性设置 

317esb_lib.EsSetInt64AttrForNode.restype = c_uint32 

318esb_lib.EsSetInt64AttrForNode.argtypes = [EsCTensorHolderPtr, c_char_p, c_int64] 

319 

320esb_lib.EsSetStringAttrForNode.restype = c_uint32 

321esb_lib.EsSetStringAttrForNode.argtypes = [EsCTensorHolderPtr, c_char_p, c_char_p] 

322 

323esb_lib.EsSetBoolAttrForNode.restype = c_uint32 

324esb_lib.EsSetBoolAttrForNode.argtypes = [EsCTensorHolderPtr, c_char_p, c_bool] 

325 

326# 控制边设置 

327esb_lib.EsAddControlEdge.restype = c_uint32 

328esb_lib.EsAddControlEdge.argtypes = [ 

329 EsCTensorHolderPtr, 

330 ctypes.POINTER(EsCTensorHolderPtr), 

331 c_int64, 

332] 

333 

334# ============ Tensor C API ============ 

335esb_lib.EsCreateEsCTensor.restype = EsCTensorPtr 

336esb_lib.EsCreateEsCTensor.argtypes = [ 

337 c_void_p, 

338 ctypes.POINTER(c_int64), 

339 c_int64, 

340 c_int, 

341 c_int, 

342] 

343 

344esb_lib.EsCreateEsCTensorFromFile.restype = EsCTensorPtr 

345esb_lib.EsCreateEsCTensorFromFile.argtypes = [ 

346 c_char_p, 

347 ctypes.POINTER(c_int64), 

348 c_int64, 

349 c_int, 

350 c_int, 

351]