-
Notifications
You must be signed in to change notification settings - Fork 19
Expand file tree
/
Copy pathconf.py
More file actions
292 lines (246 loc) · 11 KB
/
conf.py
File metadata and controls
292 lines (246 loc) · 11 KB
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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = '昇腾开源'
copyright = '2024, Ascend'
author = 'Ascend'
# The full version, including alpha/beta/rc tags
release = ''
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinxext.remoteliteralinclude',
'sphinx_copybutton',
"sphinx_design",
'myst_parser',
]
# 这一行非常重要,它允许 MyST 处理复杂的标题层级
myst_heading_anchors = 3
# 允许在 RST 中嵌入 Markdown 内容
myst_enable_extensions = [
"colon_fence",
"html_image",
]
# conf.py
html_theme_options = {
# 仅显示当前页面所属的导航树,不显示全局无关节点
'collapse_navigation': True,
'navigation_depth': 4,
'includehidden': True,
'titles_only': False,
}
# 模板路径设置
templates_path = ['_templates']
autosummary_generate = True
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'zh_CN'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '.venv', 'README.md']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "sphinx_rtd_theme"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
def setup(app):
app.add_css_file('custom.css')
app.add_js_file('package_info.js')
app.add_js_file('statistics.js')
app.add_js_file('onnxruntime_quickstart.js')
# Generate ascend_config.json if it doesn't exist (for RTD/CI builds)
import os.path
ascend_config_path = os.path.join(os.path.dirname(__file__), '_static', 'ascend_config.json')
if not os.path.exists(ascend_config_path):
print("ascend_config.json not found, generating...")
fetch_script = os.path.join(os.path.dirname(__file__), 'scripts', 'fetch_ascend_data.py')
if os.path.exists(fetch_script):
import subprocess
try:
subprocess.run(['python3', fetch_script], check=True)
except Exception as e:
print(f"Warning: Failed to generate ascend_config.json: {e}")
else:
print(f"Warning: fetch script not found at {fetch_script}")
import os, re, importlib.util
from jinja2 import Environment, FileSystemLoader
def deal_before_example(before_example):
# 需要加黑的字段
fields = ["功能描述", "参数说明", "参数解释", "接口原型", "约束说明", "输出说明"]
# 正则匹配这些字段
pattern = re.compile(r'(' + '|'.join(fields) + r')')
# 匹配之后替换
result = pattern.sub(r'**\1**', before_example)
params_list = [param.strip() for param in result.split('\n') if param.strip()]
return params_list
def generate_api_doc():
# 查找 _op_plugin_docs 中所有的 add_torch_npu_docstr 调用
try:
# 获取插件文档路径
torch_npu_path = os.path.dirname(importlib.util.find_spec('torch_npu').origin)
plugin_docs_path = os.path.join(torch_npu_path, '_op_plugin_docs.py')
except AttributeError:
raise ImportError("_op_plugin_docs module not found")
with open(plugin_docs_path, 'r') as file:
plugin_docs_code = file.read()
# 查找所有add_torch_npu_docstr 函数调用
pattern = re.compile(r'add_torch_npu_docstr\(\s*"(.*?)"\s*,\s*"""(.*?)"""', re.DOTALL)
matches = pattern.findall(plugin_docs_code)
functions_data = []
for func, docstring in matches:
# 匹配 "调用示例" 或 "示例" 部分的位置
example_pattern = re.compile(r'\s*(调用示例|示例)\s*[::]?\s*\n(.*)', re.DOTALL)
example_match = example_pattern.search(docstring)
before_example = docstring.split(example_match.group(0))[0].strip() if example_match else docstring
params_list = deal_before_example(before_example)
formatted_example = ''
if example_match:
# 截取示例代码部分
after_example = example_match.group(2).strip()
# 对每一行进行检查,如果没有以 '>>>' 开头,添加 '>>> ' 前缀
formatted_example_lines = []
example_lines = after_example.split('\n')
for line in example_lines:
# 如果行以多个 '>' 开头,但没有 '>>> '(即没有空格),删除所有多余的 '>' 并添加 '>>> '
if re.match(r'^>+', line.strip()) and not line.lstrip().startswith('>>> '):
formatted_example_lines.append('>>> ' + line.lstrip('>').strip())
elif not line.strip().startswith('>>>'):
# 如果没有 '>>> ',则添加 '>>> '
formatted_example_lines.append('>>> ' + line.strip())
else:
# 如果已经以 '>>> ' 开头,保持原样
formatted_example_lines.append(line.strip())
# 将处理后的行重新组合成一个完整的示例
formatted_example = '\n'.join(formatted_example_lines)
functions_data.append({
'function': func,
'params': params_list,
'example': formatted_example
})
# 配置模板环境
template_dir = os.path.join(os.path.dirname(__file__), '_templates/pytorch')
env = Environment(
loader=FileSystemLoader(template_dir),
autoescape=False,
trim_blocks=True
)
# 渲染模板
template = env.get_template('api_doc.rst.jinja')
rendered_content = template.render(npu_functions=functions_data)
# 将渲染后的内容写入 .rst 文件
# 拼接成目标文件路径
rst_filename = os.path.join(os.getcwd(), 'sources', 'pytorch', 'api_doc.rst')
with open(rst_filename, 'w', encoding='utf-8') as f:
f.write(rendered_content)
# =========================================================
# 独立社区页面全局配置 (核心机制:高度可配置化)
# =========================================================
html_context = {
'independent_communities': {
'verl': {
'display_name': 'verl',
'sidebar_mapping': {
'quick_start': '🚀 快速入门',
'features': '📚 特性指南',
'profiling': '⚡ 调优指南',
'examples': '📊 应用与调优实践',
'faq': '🔆 故障排查(FAQ)',
'contribution_guide': '🔧 开源开发'
}
},
'vllm-ascend': {
'display_name': 'vllm-ascend',
'sidebar_mapping': {
'getting_started': 'Getting Started',
'user_guide': 'User Guide',
'developer_guide': 'Developer Guide',
'community': 'Community',
# __root_files__: 根目录下无子目录的文件需显式映射到所属分组
# 否则侧边栏无法按目录路径自动归类
'__root_files__': {
'quick_start': 'getting_started',
'installation': 'getting_started',
'faqs': 'getting_started',
},
}
},
'triton-ascend': {
'display_name': 'Triton-Ascend',
'sidebar_mapping': {
'migration_guide': 'Triton 算子迁移指南',
'examples': '典型算子样例',
'debug_guide': '算子调试与调优',
'triton_api': 'Triton API 接口说明',
'triton_api_extention': '昇腾扩展 API 接口说明',
'quick_start_group': '快速开始',
'install_group': '安装指南',
'arch_group': '架构设计与核心特性',
'dev_guide_group': 'Triton 算子开发指南',
'env_group': '环境变量',
'faq_group': '常见问题',
'__root_files__': {
'quick_start': 'quick_start_group',
'installation_guide': 'install_group',
'architecture_design_and_core_features': 'arch_group',
'programming_guide': 'dev_guide_group',
'environment_variable_reference': 'env_group',
'FAQ': 'faq_group',
'release_note': 'faq_group',
},
}
},
}
}
# 【新增核心代码】:Sphinx 页面上下文注入 Hook
def update_page_context(app, pagename, templatename, context, doctree):
"""
拦截页面渲染,判断当前路径是否属于独立社区。
如果是,向 Jinja 模板注入 is_independent 和对应的 comm_config 变量。
支持两种路径格式:
- sources/verl/... (手写页面)
- sources/_generated/sources/verl/... (从子模块拉取的页面)
"""
communities = context.get('independent_communities', {})
context['is_independent'] = False
for comm_id, comm_info in communities.items():
# 匹配两种路径格式
if pagename.startswith(f"sources/{comm_id}") or pagename.startswith(f"sources/_generated/sources/{comm_id}"):
context['is_independent'] = True
context['current_community_id'] = comm_id
context['comm_config'] = comm_info
break
def setup(app):
app.add_css_file('custom.css')
app.add_js_file('package_info.js')
app.add_js_file('statistics.js')
# 【新增 Hook 注册】
app.connect('html-page-context', update_page_context)
# 在 Sphinx 构建之前调用该函数生成 API 文档
try:
generate_api_doc()
except ImportError as e:
print(f"Warning: {e}. Skipping API documentation generation.")