# HelloDSP

HelloDSP 是一个简单的MindSpore Signal+平台开发示例，展示如何开发一个矩阵乘程序。主要流程分为两部分操作，分别为MindSpore Python端和MindSpore Lite端。MindSpore Python端在本地运行，用于生成模型；MindSpore Lite端在本地交叉编译，编译产物拷贝到MT7004板卡上运行。以下是HelloDSP矩阵乘例子介绍：

## 1.MindSpore Python端

### 1.1 新建Python文件

打开`YHFT-IDE`，新建`test_matmul.py`文件

### 1.2 编写Python代码

    import mindspore as ms
    import numpy as np
    from mindspore import nn, ops

    class Matmul(nn.Cell):
        def __init__(self):
            super(Matmul, self).__init__()
            self.matmul = ops.MatMul()

        def construct(self, x1, x2):
            out = self.matmul(x1, x2)
            return out

    x1 = np.ones((2, 2), dtype=np.float32)
    x2 = np.ones((2, 2), dtype=np.float32)
    x1_tensor = ms.Tensor(x1)
    x2_tensor = ms.Tensor(x2)

    model = Matmul()
    out = model(x1_tensor, x2_tensor)
    print(out)

    ms.export(model, x1_tensor, x2_tensor, file_name="matmul", file_format="MINDIR")

以上代码的作用说明如下：

- 导入库：`mindspore` 用于构建与导出模型；`numpy` 用于生成示例数据；从 `mindspore` 引入 `nn` 与 `ops` 以定义网络与调用算子。

- 定义网络 `Matmul`：继承 `nn.Cell`，在 `__init__` 中实例化矩阵乘算子 `ops.MatMul()`；在 `construct` 中实现前向计算，将输入 `x1`、`x2` 进行矩阵乘法并返回结果。

- 准备数据：使用 `numpy.ones` 生成两个形状为 `(2, 2)`、类型为 `float32` 的数组，全为 1。

- 张量转换：用 `ms.Tensor` 将 `numpy` 数组转换为 MindSpore 张量，作为模型输入。

- 构建与执行模型：实例化 `Matmul` 模型，传入张量执行前向推理，打印结果。对于两个全 1 的 `2x2` 矩阵，输出为一个元素均为 2 的 `2x2` 张量。

- 导出模型：调用 `ms.export` 将模型导出为 `MINDIR` 格式：

  - `file_name`: 保存的基础文件名为 `matmul`；

  - `file_format`: 指定为 `MINDIR`（MindSpore IR 格式），用于后续在 MindSpore Lite 端加载与推理；

  - 传入的输入张量 `x1_tensor` 与 `x2_tensor` 用于固化输入`shape`和`dtype`，确保在部署端可正确构建模型输入。

### 1.3 运行Python代码

在`YHFT-IDE`中运行`test_matmul.py`文件，会生成一个`matmul.mindir`模型文件，要在MindSpore Lite端运行则需要转成 `ms` 模型文件。mindir转ms的converter工具也已经集成到vscode，使用converter工具方式：

选择模型文件直接右键，找到模型转换选项，点击即可。

## MindSpore Lite端

### 1. 新建工程

打开`YHFT-IDE`，新建工程。输入工程名、路径，工程类型选择`Heterogeneous`，输入交叉编译工具路径，参照配置交叉编译工具链，然后点确定。会生成一个异构模板工程。

### 2. 工程目录结构

生成的异构模板工程具有以下目录结构：

    test_matmul/
    ├── model/
    │   └── matmul.ms
    ├── arm_toolchain.cmake
    ├── build.bat
    ├── CMakeLists.txt
    ├── data_handler.cc
    ├── data_handler.h
    └── main.cc

文件说明：

文件名 | 类型 | 作用
--- | --- | ---
`model/matmul.ms` | 模型文件 | MindSpore 导出的模型权重和结构文件
`arm_toolchain.cmake` | 配置文件 | 指定 ARM 交叉编译工具链路径和参数
`build.bat` | 脚本文件 | Windows 环境下的编译构建脚本
`CMakeLists.txt` | 构建文件 | CMake 构建系统的主配置文件
`data_handler.h/.cc` | 源码文件 | 数据预处理和结果处理的实现
`main.cc` | 源码文件 | 程序主入口，包含模型加载和推理逻辑

### 3. 更改输入数据

通过修改 `data_handler.cc` 文件中的函数来调整输入输出数据：

- 修改输入数据：编辑 `GetInputData` 函数内容

- 查看输出结果：编辑 `GetOutputData` 函数内容

默认配置：

- 输入数据填充为 1

- 输出结果打印输出地址

### 4. main.cc 功能介绍

`main` 函数主要包含 6 个核心步骤，实现完整的模型推理流程：

#### 4.1 读取模型文件

通过 `ReadFile` 接口读取 `.ms` 模型文件，将数据保存到 `model_buf` 中。

#### 4.2 设置运行后端

通过 `context` 的 `MutableDeviceInfo` 添加一个或多个后端：

- 默认后端：`MT7004`

- 可选后端：`CPU`、`FT78NE`

#### 4.3 编译模型图

通过 MindSpore 的 `Model` 类的 `Build` 方法编译模型图：

编译规则：按设置顺序查找后端算子，都没找到则编译失败

Build 方法参数：

参数 | 类型 | 说明
--- | --- | ---
`model_data` | `const void *` | 模型数据
`data_size` | `size_t` | 模型数据大小
`model_type` | `ModeType` | 模型类型
`model_context` | `const std::shared_ptr<Context> &` | 模型上下文（主要传递设备信息）

#### 4.4 获取模型输入

通过 `Model` 类的 `GetInputs` 方法获取所有模型输入的 `Tensor` 地址，通过修改 `GetInputData` 函数传递输入值。

#### 4.5 执行模型推理

通过 `Model` 类的 `Predict` 方法进行模型推理：

Predict 方法参数：

参数 | 类型 | 说明
--- | --- | ---
`inputs` | `const std::vector<MSTensor> &` | 模型的输入
`output` | `const std::vector<MSTensor> *` | 模型的输出地址

#### 4.6 获取模型结果

通过 `Model` 类的 `GetOutputs` 方法获取所有模型输出，通过修改 `GetOutputData` 函数查看输出值。

### 5. 编译工程

提供多种编译方式，选择其中一种即可：

编译方式：

- 方式一：在 `YHFT-IDE` 集成终端运行 `build.bat` 脚本

- 方式二：点击调试按钮 → 编译

- 方式三：直接点击编译图标

### 6. 运行工程

编译生成的可执行文件位于 `build` 目录下，默认文件名为 `main`。需要将可执行文件拷贝到 MT7004 板卡上运行。

#### 6.1 连接 MT7004 板卡

步骤 1： 打开远程窗口

- 在 `YHFT-IDE` 左下角找到远程窗口功能

- 点击打开远程窗口按钮

步骤 2： 选择连接方式

- 在弹出的选项中选择第一个选项进行远程连接

步骤 3： 输入连接信息

- 输入 MT7004 板卡的用户名和 IP 地址

- 按回车键后会弹出新的窗口界面

> 注意：确保本机和 MT7004 板卡在同一网段，或使用网线直接连接并修改本机 IP 地址与板卡在同一网段

连接成功标志： 新界面左下角出现 `SSH:xxx` 表示连接成功

#### 6.2 部署和运行程序

步骤 4： 部署程序文件

- 在 MT7004 板卡上新建目录存放程序

- 通过拖拽方式将可执行文件和模型文件传输到板卡

- 使用 `chmod` 命令赋予可执行文件执行权限