在这里插入图片描述

很多开发者在接触昇腾时,最大的痛点不是“不会写代码”,而是**“不知道从哪开始看代码”**。文档虽然详尽,但往往缺乏一个连贯的、可运行的参考路径。

cann-samples 就是为了解决这个问题而生的——它是昇腾CANN的官方样例仓库,汇集了各个功能模块的完整示例代码。从最简单的“Hello World”到复杂的分布式大模型训练,这里都有可以直接运行、拿来即用的参考代码。

一句话总结:如果你想知道“如何在昇腾上跑通一个程序”,直接去 cann-samples 找对应的文件夹,复制粘贴改改就能跑。


一、cann-samples 是什么?

cann-samples 是昇腾CANN开源生态中的核心导航站。它不是一个单一的库,而是一个包含多个子项目的集合,覆盖了昇腾开发的完整生命周期。

  • 仓库地址:https://atomgit.com/cann/cann-samples
  • 核心价值
    • 零门槛入门:提供从环境搭建到复杂算子开发的全流程示例。
    • 版本配套:每个示例都明确标注了对应的CANN版本,避免环境不兼容。
    • 多语言支持:同时提供 C++ (ACL) 和 Python 接口实现。
    • 场景全覆盖:涵盖基础API、算子开发、模型部署、分布式训练等。

覆盖领域一览

类别 示例数量 典型内容 适用人群
基础入门 10+ 环境搭建、设备查询、第一个程序 新手小白
AscendCL 30+ 设备管理、内存分配、模型加载、算子调用 ACL开发者
Ascend C 20+ 算子开发基础、融合算子、自定义算子 算子工程师
模型部署 15+ PyTorch/TF/ONNX模型转换与推理 算法部署工程师
分布式 10+ 多卡训练、HCCL通信、MindSpore/PyTorch适配 大模型训练专家
性能优化 10+ Profiling分析、调优技巧、混合精度 性能优化专家

二、仓库结构解析

克隆仓库后,你会看到清晰的目录结构,这本身就是最好的学习地图:

git clone https://atomgit.com/cann/cann-samples.git
cd cann-samples
ls -la

主要目录说明:

  • acl-samples/: AscendCL 基础示例(最常用)。
  • operator-samples/: Ascend C 算子开发示例。
  • model-samples/: 各类框架模型的部署示例。
  • distributed-samples/: 分布式训练与通信示例。
  • tools-samples/: 工具链使用示例(如ATC命令行)。

深入 acl-samples 目录

这是新手的必经之路:

cd acl-samples
ls
# 101-ascendcl-device/      # 设备管理 (查询设备、设置设备)
# 102-ascendcl-memory/     # 内存管理 (malloc, memcpy, free)
# 103-ascendcl-model/      # 模型加载执行 (加载OM模型并推理)
# 104-ascendcl-op/         # 算子调用 (调用内置算子)
# 105-ascendcl-data/       # 数据处理 (数据预处理、格式转换)
# ...

深入 operator-samples 目录

如果你想自己写算子:

cd operator-samples
ls
# vector-add/        # 矢量加法 (最简单)
# matrix-multiply/   # 矩阵乘法 (经典案例)
# conv2d/           # 卷积操作
# transformer/      # 完整的 Transformer 块
# ...

三、快速开始:你的第一个昇腾程序

让我们从最简单的“Hello World”开始:查询可用设备

步骤 1: 进入示例目录

cd acl-samples/101-ascendcl-device/device-info/
ls
# README.md         # 说明文档
# src/              # C++ 源码
#   └── main.cpp
# src_python/       # Python 源码 (推荐先看这个)
#   └── main.py

步骤 2: 运行 Python 版本

python src_python/main.py

预期输出

[INFO] Initialize success.
[INFO] Set device 0 successfully.
[INFO] Query device info: 
  Device ID: 0
  Device Name: Ascend 910B
  Vendor: Huawei
  ...
[INFO] Finalize success.

成功! 你已经完成了在昇腾上的第一个程序。如果报错,请检查是否安装了正确的CANN Toolkit并配置了环境变量。


四、进阶实战:内存管理与数据搬运

理解内存管理是掌握昇腾开发的关键。NPU的显存(Device Memory)和CPU的主存(Host Memory)是分离的,必须手动拷贝。

示例:内存分配与拷贝

cd acl-samples/102-ascendcl-memory/memory-malloc/
cat src_python/main.py

核心逻辑解析

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import acl
import numpy as np

def memory_demo():
    # 1. 初始化环境
    acl.init()
    
    # 2. 分配设备显存 (1MB)
    size = 1024 * 1024
    device_ptr = acl.rt.malloc(size)
    print(f"[INFO] Allocate memory: {size} bytes at {device_ptr}")
    
    # 3. Host -> Device 数据拷贝
    host_data = np.arange(1024, dtype=np.float32)
    acl.rt.memcpy_host_to_device(device_ptr, host_data, size)
    print(f"[INFO] Copy data to device")
    
    # 4. (此处通常会有计算操作,例如调用算子)
    # acl.rt.run_kernel(...) 
    
    # 5. Device -> Host 数据拷贝
    result = np.zeros(1024, dtype=np.float32)
    acl.rt.memcpy_device_to_host(result, device_ptr, size)
    print(f"[INFO] Copy result to host: {result[:10]}")
    
    # 6. 释放显存
    acl.rt.free(device_ptr)
    print(f"[INFO] Free memory")
    
    acl.finalize()
    print("[INFO] Done!")

if __name__ == "__main__":
    memory_demo()

运行结果

[INFO] Allocate memory: 1048576 bytes at 0x7f8a000000
[INFO] Copy data to device
[INFO] Copy result to host: [ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
[INFO] Free memory
[INFO] Done!

关键点

  1. Init/Finalize: 所有程序的入口和出口。
  2. Malloc/Free: 显存必须手动管理,忘记释放会导致显存泄漏。
  3. Memcpy: 数据必须在Host和Device之间显式拷贝。

五、硬核挑战:从零写一个 MatMul 算子 (Ascend C)

想成为昇腾内核工程师?从这里开始。Ascend C 允许你编写高性能的底层算子。

步骤 1: 进入矩阵乘法示例

cd operator-samples/matrix-multiply/
ls
# README.md
# src/
#   ├── kernel_operator.h    # 算子头文件
#   └── kernel_operator.cpp   # 算子实现
# scripts/
#   ├── build.sh             # 编译脚本
#   └── run.sh               # 运行脚本
# test/
#   └── ut_test.cpp          # 单元测试

步骤 2: 核心实现 (简化版)

// kernel_operator.cpp
#include "kernel_operator.h"
#include "op_tiling.h"

// 模板参数:数据类型、模板大小
template <typename T>
void MatrixMultiplyKernel(T *output, const T *inputA, const T *inputB, 
                          int M, int N, int K) {
    // 1. 获取 Cube Unit 指针 (矩阵计算单元)
    auto cube_unit = GetCubeUnit();
    
    // 2. 配置 Cube Unit (设置输入输出维度、步长等)
    // ... (省略具体配置代码)
    
    // 3. 执行矩阵乘法指令
    // cube_unit->matmul(inputA, inputB, output, M, N, K);
    
    // 注意:实际代码中需要处理分块、流水线调度等优化细节
}

// 主函数入口
extern "C" __global__ void MatrixMultiplyKernelLauncher(
    float *output, const float *inputA, const float *inputB,
    int M, int N, int K) {
    MatrixMultiplyKernel<float>(output, inputA, inputB, M, N, K);
}

步骤 3: 编译与运行

chmod +x scripts/build.sh
./scripts/build.sh

chmod +x scripts/run.sh
./scripts/run.sh

产出:生成 .so 动态库,你可以将其注册到CANN中,供上层应用调用。


六、如何高效利用 cann-samples?

1. 按图索骥,不要盲目搜索

遇到需求先查目录:

  • “我想跑个ResNet?” -> 搜 model-samples/
  • “我想自己写个激活函数?” -> 搜 operator-samples/
  • “我想搞多机多卡?” -> 搜 distributed-samples/

2. 善用 README.md

每个示例目录下的 README.md 都是微型教程,包含:

  • 功能描述
  • 依赖环境
  • 编译命令
  • 运行步骤
  • 常见问题

3. 对比 C++ 与 Python

每个示例通常都有两套代码:

  • Python版:语法简洁,适合快速验证逻辑。
  • C++版:性能更高,适合生产环境或底层开发。
  • 建议:先用Python看懂逻辑,再对照C++学习底层API。

4. 关注版本匹配

CANN更新频繁,务必确认示例代码的版本与你安装的CANN版本一致。仓库根目录通常有 version.txt 或分支说明。


七、常见问题排查

Q1: 编译报错 “acl/acl.h not found”

  • A: 未正确配置CANN环境变量。确保执行了 source /usr/local/Ascend/ascend-toolkit/set_env.sh

Q2: 运行时 “Device not found”

  • A: 检查 npu-smi info 是否有NPU在线;检查代码中 acl.rt.set_device 的设备ID是否正确。

Q3: 显存溢出 (OOM)

  • A: 检查是否忘记 free 显存;尝试减小Batch Size;检查是否有内存泄漏。

Q4: 找不到某个特定功能的示例?

  • A: 尝试在AtomGit上搜索相关Issue,或者联系社区SIG组,他们可能会补充新的示例。

八、总结与建议

cann-samples 是昇腾开发的“百宝箱”和“教科书”。

  • 对于新手:它是你的第一本教材。跟着例子跑一遍,胜过读十遍文档。
  • 对于老手:它是你的灵感来源。遇到瓶颈时,看看别人是怎么优化的。
  • 对于架构师:它是你的最佳实践库。里面的代码代表了华为官方的推荐写法。

行动建议

  1. 今天:克隆 cann-samples,运行 101-ascendcl-device
  2. 本周:跑通 memory-mallocmodel-load,理解数据流。
  3. 本月:尝试修改一个算子示例,或者跑通一个分布式训练Demo。

不要等待完美,先跑通Demo。 昇腾的开发体验,就从这一行 git clone 开始。

cann-samples之上,万物可跑;cann-samples之下,算力无界。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐