Skip to main content
Glama
Sunye1213106

ascendc-codemap-mcp

by Sunye1213106
README.md
# AscendC CodeMap MCP

![CodeMap:面向 AscendC 算子的语义索引与查询服务](docs/codemap-overview.jpg)

按 operator + architecture 编译得到的、自包含 AscendC 语义索引。构建把 C++ / CANN DSL 编成唯一、可信、可追溯的语义事实;`.uo` 是唯一产品真值;Query 把这些事实压缩成面向 AI 的上下文。Agent 只负责理解任务和使用事实。

架构合约见 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)。两条根约束:**Build for truth. Project for usefulness.** Query 是 semantic projection / compression,不重新分析代码,也不读工作区源码。内部 identity(entity id、USR、provenance)默认不出现在 Agent 卡片上。

这不是通用代码记忆。Agent 的计划、review、ADR 留在会话或调用方(例如 AscendC-Pilot)。

对 SFAG 算子的本地实测:


| 操作           | 耗时      |
| ------------ | ------- |
| 首次构建 CodeMap | 约 1 分钟  |
| 单次查询         | 约 20 ms |


一次构建,之后反复查询,避免每次重新 grep 和通读源码。

构建需要 CANN Toolkit 头文件和 LLVM clang。查询已有 `.uo` 不依赖 CANN。环境不会自动配好:先 `codemap_doctor`,按 `next_steps` 下载 `.run` 并用 `cann-extract` 解包。



## 它解决什么

AscendC 算子逻辑通常跨多层传递:

```text
Host → TilingData → TilingKey / Template → Kernel → AscendC API
```

Kernel 里看到的行为,往往由 Host 条件决定,再经 TilingData、TilingKey 和模板参数一路传下来。普通搜索能回答「这个名字出现在哪」,很难直接回答:

- 谁写入了这个 TilingData 字段?哪个 Kernel 读取了它?
- 哪条 TilingKey / Template 控制这条路径?某个模板组合是否合法?
- 这段 Kernel 最终落到哪个 AscendC API?
- Buffer、Queue、Pipe、Event 之间是什么关系?

CodeMap 把这些关系提前提取进图,让 agent 按标识符、Dim、证据位点查询。

## 和 Codebase Memory / CodeGraph

Codebase Memory 与 CodeGraph 是通用代码图:多语言、通用导航。CodeMap 只做 **AscendC 算子领域语义**。


|                               | Codebase Memory / CodeGraph | AscendC CodeMap    |
| ----------------------------- | --------------------------- | ------------------ |
| 目标                            | 通用代码理解                      | AscendC 算子理解       |
| 解析                            | 主要 Tree-sitter              | Clang + CANN 编译上下文 |
| 语言                            | 多语言                         | C++ / AscendC      |
| Call graph                    | 有                           | 有                  |
| Template 语义                   | 通用                          | 重点建模               |
| TilingData / TilingKey        | —                           | 有                  |
| Host → Kernel 数据流             | —                           | 有                  |
| Buffer / Queue / Pipe / Event | —                           | 有                  |
| Architecture / 编译条件           | 通用                          | 按 arch 产品槽         |


他们更擅长「代码在哪、谁调用谁」。CodeMap 更希望回答:**这个算子为什么走到这个 Kernel,以及这个值怎么从 Host 传下来。**

本仓库不把 memory / ADR / 文档检索、默认 Cypher/SQL 或可视化做成产品功能。公开查询只有 `search`、`trace`、`source`。

## 为什么用 Clang

Tree-sitter 适合快速、多语言的语法树。AscendC 大量依赖 C++ 编译语义,例如:

```cpp
template <bool IsPse, typename T>
__aicore__ inline void Process(...)
```

只看语法很难完整恢复模板参数与实例化、类型、宏、architecture 分支、Host 字段写入、TilingKey 选择和 Kernel specialization。因此构建路径是 **libclang + 实际 CANN 环境**,再叠加 AscendC 专用分析。

## 当前建模的语义

**Host / Tiling:** Function、Method、Branch、Predicate、Input、Output、TilingData、Field、Host READ/WRITE、Compile Macro / Variable。

**Template / TilingKey:** TilingKey、Template、Template Argument / Instance、Build Variant、Binding / Specialization / Selection。

**Kernel:** Kernel、Operation、Buffer、Register、Queue、Pipe、Event、AscendC API。

边上常见:

```text
READS / WRITES    CALLS    BINDS    SELECTS    LAUNCHES
GUARDED_BY        FLOWS_TO    SIGNALS / AWAITS
```

串起来仍是:Host 条件 → TilingData 字段 → TilingKey / Template → Kernel → AscendC API。

## 身份与新鲜度

索引之后用稳定 id,不要每次贴绝对路径:

```text
codemap_id   = p:<workspace>::op_name@arch     例如 p:a91f42::flash_attention_score_grad@arch35
alias        = op_name@arch                    本进程内唯一时可用;撞车返回 AMBIGUOUS_CODEMAP_ID
snapshot_id  = cm:<digest 前缀>                已提交图的内容身份,不是 path/mtime
```

`codemap_status` 看的是相对当前源码的 **freshness**,不是「磁盘上有没有 `.uo`」:

`fresh` / `dirty` / `stale` / `building` / `blocked` / `incompatible` / `unknown`

读写契约:

- `ok` 只表示这次调用在协议层成功。更新是否发生看 `state` 和 `updated`。
- `codemap_update` 得到 `state=needs_confirmation` 时图**没有**前进,需用户确认后再 `confirm_scope=true`。
- 已有 `.uo` 时再调 `codemap_index` 会 `ALREADY_INDEXED`(`updated=false`),应改用 `codemap_update`。
- 正在构建时,查询返回 `freshness=building`,不会读半写文件。

## 构建环境(Clang + CANN)

查询已有 `.uo` **不需要** CANN / Clang。冷构建(`codemap_index`)需要三者齐备:

1. Python ≥ 3.10 与本仓库(`pip install -e .`)
2. **LLVM 18 clang 可执行文件** + pip `libclang`(只有 Python 绑定不够,TPL 预处理要跑 `clang -E`)
3. **CANN Toolkit 头文件**(解包 `.run` 即可,不必在本机完整安装 Toolkit,也不需要 NPU)

Agent 先跑 doctor,再按返回的 `next_steps` 配环境,不要猜路径:

```bash
pip install -e .
python -m ascendc_codemap_mcp doctor --project <算子目录> --architecture arch35
```

`ok=false` 时执行 `next_steps`,再跑一次 doctor。不要执行 `.run` 安装脚本。

### Clang / libclang

Ubuntu / Debian:

```bash
sudo apt-get update
sudo apt-get install -y clang
python -c "import clang.cindex as c; print(c.__file__)"
clang --version
```

Windows(LLVM 18 与 pip `libclang` 18.x 对齐):

```powershell
winget install --id LLVM.LLVM --version 18.1.8 -e
python -c "import clang.cindex as c; print(c.__file__)"
clang --version
```

`clang` 不在 PATH 时:

```powershell
$env:CLANG_EXE = "C:\Program Files\LLVM\bin\clang.exe"
```

也可设 `UO_CLANG` / `LLVM_HOME`。

### 下载 CANN Toolkit `.run`

CodeMap 只要 **Toolkit 开发套件**里的头文件。不要下 kernels / nnal 来代替 Toolkit。

1. **先搜本机**,避免重复下载(包很大):

```powershell
Get-ChildItem -Path "$HOME\Downloads","D:\Downloads","$HOME" -Filter "Ascend-cann-toolkit_*.run" -ErrorAction SilentlyContinue
```

```bash
ls ~/Downloads/Ascend-cann-toolkit_*.run 2>/dev/null
```

1. 没有文件时,打开昇腾社区下载中心(**需要华为账号登录**;社区包的直链通常带签名,**未登录 wget 会失败**):

- 社区版 CANN:[https://www.hiascend.com/developer/download/community/result?module=cann](https://www.hiascend.com/developer/download/community/result?module=cann)
- 软件页:[https://www.hiascend.com/software/cann](https://www.hiascend.com/software/cann)
- 入口:[https://www.hiascend.com/developer/download](https://www.hiascend.com/developer/download)

1. 页面上选 **CANN Toolkit**,操作系统 **Linux**,架构:


| 本机                     | 下载哪个 `.run`                                       |
| ---------------------- | ------------------------------------------------- |
| Windows / Linux x86_64 | `Ascend-cann-toolkit_<version>_linux-x86_64.run`  |
| Linux aarch64          | `Ascend-cann-toolkit_<version>_linux-aarch64.run` |


Windows 也下 **linux-x86_64** 包:`cann-extract` 只解出文件树,**不会执行** installer。

版本尽量与算子真实编译环境一致。部分社区版安装文档会给出 `ascend-repo.obs.cn-east-2.myhuaweicloud.com` 的 wget;仅当该版本文档写明 URL 时再用,不要随便抓一个旧包。

已有官方安装(`source set_env.sh`)则把 `ASCEND_HOME_PATH` 指到安装前缀,不必再解 `.run`。

### 解包 CANN(不要跑 installer)

推荐解到本仓库 `_cann/pkg`,doctor 会自动发现,不必设环境变量:

```powershell
$pkg = Join-Path (Get-Location) "_cann\pkg"
python -m ascendc_codemap_mcp cann-extract `
  "D:\Downloads\Ascend-cann-toolkit_<version>_linux-x86_64.run" `
  --dest $pkg
python -m ascendc_codemap_mcp cann-extract --fixup --dest $pkg
```

Linux:

```bash
pkg="$(pwd)/_cann/pkg"
python -m ascendc_codemap_mcp cann-extract \
  ~/Downloads/Ascend-cann-toolkit_<version>_linux-x86_64.run \
  --dest "$pkg"
python -m ascendc_codemap_mcp cann-extract --fixup --dest "$pkg"
```

等价写法:`python scripts/cann_extract.py ...`(checkout 内、尚未 `pip install` 时)。

解完应能看到:

```text
_cann/pkg/
├── cann-metadef/
├── cann-asc-devkit/
├── cann-opbase/
├── cann-npu-runtime/
├── cann-ge-compiler/
└── bisheng/          # 若包内有
```

`ASCENDC_CODEMAP_CANN_ROOT` 指 package **根**(上面这一层),不要指到某个 `include/`。解到别处时设用户级环境变量,只写当前会话会丢。

Windows:

```powershell
[Environment]::SetEnvironmentVariable("ASCENDC_CODEMAP_CANN_ROOT", "<abs-pkg>", "User")
```

Linux:

```bash
echo 'export ASCENDC_CODEMAP_CANN_ROOT=/abs/path/to/_cann/pkg' >> ~/.bashrc
```

`--fixup` 会补 `asc/impl/include` → `asc/include`(官方包不带这个目录,vanilla clang 需要这个 junction)。

## 安装 MCP

```bash
pip install -e .
python -m ascendc_codemap_mcp doctor --project <算子目录> --architecture arch35
python -m ascendc_codemap_mcp install
```

Windows:

```powershell
pip install -e .
python -m ascendc_codemap_mcp install
```

`install` 为已检测到的客户端写入本产品的 MCP 条目和 skills,不改无关 server、不打开 YOLO。`uninstall` 只删除本产品写入的内容。装完后重启 coding agent。工具出现在 MCP server `ascendc-codemap-mcp`。

协议是官方 Python SDK 的 **2026-07-28**(含 stateless `server/discover`),同一进程仍服务握手期客户端。

不要在 MCP 连接时自动 index。冷构建可能要几分钟。

## 构建与更新

```bash
ascendc-codemap-mcp index --project <算子目录> --architecture arch35
```

产物:

```text
<operator>/.ascendc-codemap/<arch>/<op>.<arch>.uo
```

源码变化后增量刷新(优先 `codemap_id`):

```bash
ascendc-codemap-mcp update --codemap-id <id>
ascendc-codemap-mcp status --codemap-id <id>
```

`index` 在 prepare / extract / analyze / commit 之间可取消。`update` 在 detect / plan / 各层 rebuild / commit 之间可取消。某一步内部的 Clang 会跑完该步。取消是**每次调用一份 token**,不是按 CodeMap 共享。

## 查询

Query 只读已提交的 `.uo`(`source_line` / 图),不打开工作区文件。

三个工具按**你手上有什么**分,参数不重叠,所以没有「该传哪个」的判断:

| 你手上有             | 用                | 必填              |
| ---------------- | ---------------- | --------------- |
| 一个字符串,还不知道在哪     | `codemap_search` | `pattern`       |
| 一个名字             | `codemap_trace`  | `symbol`        |
| 一个 `file:line`   | `codemap_source` | `file` + `line` |

`trace` 的形态由参数在不在决定,不用声明模式:

- 只传 `symbol`:那个名字的全部语义事实(定义体、每个写入点及其取值/守卫/被谁调用、读者、kernel 消费者、调用图、编译期合法键)。这是默认 80% 工作量。
- 再给 `to_symbol`:两点之间的**有向四族菜单**(call / data / control / compile,每族最多两条短路径)。这是关系菜单,不是全路径导出,也不是「最短一条 = 完整答案」。写链仍用 `trace symbol=` 看 Writes。
- 给 `dim` + `value`:编译期合法键空间;`dim=*` 列出本算子全部 dim。

`relation=` 可选收窄到 `call` / `data` / `control` / `compile`(逗号分隔)。省略则四族都给;指定一族只跑该族。一条 1 跳 READS 不是写链;某个族 `no path` 只表示图上没建那类边。

`source` 不收 `symbol`,`trace` 不收 `file` / `line`:混着传会**丢掉非法参数、保留合法的**(`trace` 留 `symbol`,`source` 留 `file`/`line`),不会去猜你要哪个。`source` 的标题是覆盖所问窗口**主体**的包围函数:`line` 已在函数体内则保持该函数;`line` 落在上一函数尾巴、窗口主体已是下一函数时改挂新身份,`Called by` 跟着走。`line_end=` 裁 snippet。

CLI:

```bash
ascendc-codemap-mcp discover --project <算子目录>
ascendc-codemap-mcp query --codemap-id <id> --operation trace --symbol IsPse
ascendc-codemap-mcp query --codemap-id <id> --operation trace --symbol DoOpTiling --to-symbol DoSparse
ascendc-codemap-mcp query --codemap-id <id> --operation search --pattern BufferNum
ascendc-codemap-mcp query --codemap-id <id> --operation source --file op_host/x.cpp --line 1673
```

`symbol` 必须是一个标识符;自然语言句子返回 `INVALID_QUERY`(合法 filter 清单 + 已解析 token),不会模糊排名。

| 意图                        | 工具                                                         |
| ------------------------- | ---------------------------------------------------------- |
| 扫目录、拿到 `codemap.id`       | `codemap_discover`                                         |
| 新鲜度                       | `codemap://map/{codemap_id}`(CLI 仍可用 `status`)            |
| 构建前检查                     | `codemap_doctor`                                           |
| 冷构建                       | `codemap_index`                                            |
| 增量刷新                      | `codemap_update`                                           |

兼容别名:`index_operator`、`update_operator`;`codemap_query`(旧的单工具形态)仍然接受,但不在默认工具集里。只读工具带 `readOnlyHint`。查询结果走统一 envelope(`ok`、`codemap`、`verdict`、`layer`、`data`、`coverage`、`next_cursor`)和 `structuredContent`。 `codemap_evidence` 不在默认工具集,可用 `ASCENDC_CODEMAP_MCP_TOOLS` 打开。

每节都自带完整性:`Writes 3 of 3, complete` 是「算完了,就是 3 个」,`not computed here` 是「这张卡没算这个」。**后者永远不会渲染成「没有」**——那正是上一版把 17 个有 caller 的函数报成 `no resolved caller` 的原因。

跟 `evidence[].id`(`span:...`)走,并把当时的 `snapshot_id` 当作 `expected_snapshot_id`;对不上是 `SNAPSHOT_CHANGED`。`coverage.truncated` 且带了 `next_cursor` 再翻页。`count: 0` 不等于「图上没有」,跟 `hint`。

回答所问的层:Host 写出 ≠ 模板可编译 ≠ Kernel 消费。不要把 LLM 补丁写进 `.uo`,不要对产品图跑原始 SQL/Cypher。

## 资源与传输


| 类型                | 名称               | URI / 参数                     |
| ----------------- | ---------------- | ---------------------------- |
| Resource          | runtime          | `codemap://runtime`          |
| Resource template | 一张图的身份与新鲜度       | `codemap://map/{codemap_id}` |
| Prompt            | `query_operator` | `codemap_id`,可选 `focus`      |
| Prompt            | `build_codemap`  | `project`、`architecture`     |


`codemap_id` / `architecture` 的补全来自本进程 registry 和常见 arch 名。

默认 stdio。同一 SDK server 也可 HTTP(这是传输,不是远程图服务):

```bash
ascendc-codemap-mcp serve --transport streamable-http --host 127.0.0.1 --port 8765
```

`install` 覆盖 Cursor、Claude Code、Codex、OpenCode。Cursor / Claude Code 只写 skills;Codex / OpenCode 另写 `AGENTS.md` 片段。

## 环境变量


| 变量                                                         | 作用                                                                                                         |
| ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `ASCENDC_CODEMAP_CANN_ROOT`                                | 解包后的 CANN 根(还可回退 `ASCEND_CANN_PACKAGE_PATH`、`ASCEND_HOME_PATH`、`CANN_ROOT`)。解到 `<checkout>/_cann/pkg` 时不必设 |
| `CLANG_EXE` / `UO_CLANG` / `LLVM_HOME`                     | clang 可执行文件;仅 pip `libclang` 不够                                                                            |
| `ASCENDC_CODEMAP_CACHE_DIR`                                | 缓存目录,默认 `~/.cache/ascendc-codemap-mcp`                                                                     |
| `ASCENDC_CODEMAP_PROJECT` / `ASCENDC_CODEMAP_ARCHITECTURE` | 本进程 discover 之后的默认身份;也作 CLI 默认                                                                             |
| `ASCENDC_CODEMAP_MAX_OPEN`                                 | 打开的查询句柄 LRU 上限,默认 4                                                                                        |


Codex 子进程只转发 `env_vars` 里列出的名字;`install` 会带上 CANN / cache 相关变量。

Windows 可以解 linux-x86_64 `.run` 再构建;查询已有 `.uo` 不依赖 CANN。

## License

MIT

TDQS

A4/5.0

Scored across 5 tools

Disambiguation5/5

Each tool maps to a distinct action: environment check, full build, incremental update, status check, and read-only query. The overlapping index/update pair is explicitly disambiguated by whether a .uo already exists.

Naming Consistency3/5

The names are readable and domain-consistent, but they do not follow one pattern: codemap_doctor/codemap_status use noun-first style, query_codemap is verb-first, and index_operator/update_operator use _operator suffix. This makes the naming less predictable across the set.

Tool Count5/5

Five tools is well-scoped for an operator CodeMap lifecycle: preflight, full index, incremental update, status, and query. No tool feels redundant at this granularity.

Completeness4/5

The surface covers the core lifecycle: build/rebuild, update, status, and query, plus environment validation. An explicit delete/cleanup tool is absent, but rebuild and update cover most recovery workflows.

Maintenance

ActivityMaintained
ResponsivenessNo issues