# Ascend 910 AI处理器上推理
## 概述
用户可以创建C++应用程序,调用MindSpore的C++接口推理MindIR模型。
## 推理目录结构介绍
创建目录放置推理代码工程,例如`/home/HwHiAiUser/mindspore_sample/ascend910_resnet50_preprocess_sample`,可以从官网示例下载[样例代码](https://gitee.com/mindspore/docs/tree/r2.0.0-alpha/docs/sample_code/ascend910_resnet50_preprocess_sample),`model`目录用于存放`MindIR`[模型文件](https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/sample_resources/ascend310_resnet50_preprocess_sample/resnet50_imagenet.mindir),`test_data`目录用于存放待分类的图片,推理代码工程目录结构如下:
```text
└─ascend910_resnet50_preprocess_sample
├── CMakeLists.txt // 构建脚本
├── README.md // 使用说明
├── main.cc // 主函数
├── model
│ └── resnet50_imagenet.mindir // MindIR模型文件
└── test_data
├── ILSVRC2012_val_00002138.JPEG // 输入样本图片1
├── ILSVRC2012_val_00003014.JPEG // 输入样本图片2
├── ... // 输入样本图片n
```
## 推理代码介绍
推理代码样例:[ascend910_resnet50_preprocess_sample](https://gitee.com/mindspore/docs/blob/r2.0.0-alpha/docs/sample_code/ascend910_resnet50_preprocess_sample/main.cc)。
引用`mindspore`和`mindspore::dataset`的名字空间。
```c++
namespace ms = mindspore;
namespace ds = mindspore::dataset;
```
环境初始化,指定硬件为Ascend 910,DeviceID为0:
```c++
auto context = std::make_shared();
auto ascend910_info = std::make_shared();
ascend910_info->SetDeviceID(0);
context->MutableDeviceInfo().push_back(ascend910_info);
```
加载模型文件:
```c++
// Load MindIR model
ms::Graph graph;
ms::Status ret = ms::Serialization::Load(resnet_file, ms::ModelType::kMindIR, &graph);
// Build model with graph object
ms::Model resnet50;
ret = resnet50.Build(ms::GraphCell(graph), context);
```
获取模型所需输入信息:
```c++
std::vector model_inputs = resnet50.GetInputs();
```
加载图片文件:
```c++
// Readfile is a function to read images
ms::MSTensor ReadFile(const std::string &file);
auto image = ReadFile(image_file);
```
图片预处理:
```c++
// Create the CPU operation provided by MindData to get the function object
// Decode the input to RGB format
std::shared_ptr decode(new ds::vision::Decode());
// Resize the image to the given size
std::shared_ptr resize(new ds::vision::Resize({256}));
// Normalize the input
std::shared_ptr normalize(new ds::vision::Normalize(
{0.485 * 255, 0.456 * 255, 0.406 * 255}, {0.229 * 255, 0.224 * 255, 0.225 * 255}));
// Crop the input image at the center
std::shared_ptr center_crop(new ds::vision::CenterCrop({224, 224}));
// shape (H, W, C) to shape (C, H, W)
std::shared_ptr hwc2chw(new ds::vision::HWC2CHW());
// // Define a MindData preprocessor
ds::Execute preprocessor({decode, resize, normalize, center_crop, hwc2chw});
// Call the function object to get the processed image
ret = preprocessor(image, &image);
```
执行推理:
```c++
// Create outputs vector
std::vector outputs;
// Create inputs vector
std::vector inputs;
inputs.emplace_back(model_inputs[0].Name(), model_inputs[0].DataType(), model_inputs[0].Shape(),
image.Data().get(), image.DataSize());
// Call the Predict function of Model for inference
ret = resnet50.Predict(inputs, &outputs);
```
获取推理结果:
```c++
// Output the maximum probability to the screen
std::cout << "Image: " << image_file << " infer result: " << GetMax(outputs[0]) << std::endl;
```
## 构建脚本介绍
构建脚本用于构建用户程序,样例来自于 [CMakeLists.txt](https://gitee.com/mindspore/docs/blob/r2.0.0-alpha/docs/sample_code/ascend910_resnet50_preprocess_sample/CMakeLists.txt) 。
为编译器添加头文件搜索路径:
```cmake
option(MINDSPORE_PATH "mindspore install path" "")
include_directories(${MINDSPORE_PATH})
include_directories(${MINDSPORE_PATH}/include)
```
在MindSpore中查找所需动态库:
```cmake
find_library(MS_LIB libmindspore.so ${MINDSPORE_PATH}/lib)
file(GLOB_RECURSE MD_LIB ${MINDSPORE_PATH}/_c_dataengine*)
```
使用指定的源文件生成目标可执行文件,并为目标文件链接MindSpore库:
```cmake
add_executable(resnet50_sample main.cc)
target_link_libraries(resnet50_sample ${MS_LIB} ${MD_LIB})
```
## 编译推理代码
进入工程目录`ascend910_resnet50_preprocess_sample`,设置如下环境变量:
```bash
# control log level. 0-DEBUG, 1-INFO, 2-WARNING, 3-ERROR, 4-CRITICAL, default level is WARNING.
export GLOG_v=2
# Conda environmental options
LOCAL_ASCEND=/usr/local/Ascend # the root directory of run package
# lib libraries that the run package depends on
export LD_LIBRARY_PATH=${LOCAL_ASCEND}/ascend-toolkit/latest/lib64:${LOCAL_ASCEND}/driver/lib64/common:${LOCAL_ASCEND}/driver/lib64/driver:${LOCAL_ASCEND}/ascend-toolkit/latest/opp/op_impl/built-in/ai_core/tbe/op_tiling:${LD_LIBRARY_PATH}
# lib libraries that the mindspore depends on, modify "pip3" according to the actual situation
export LD_LIBRARY_PATH=`pip3 show mindspore | grep Location | awk '{print $2"/mindspore/lib"}' | xargs realpath`:${LD_LIBRARY_PATH}
# Environment variables that must be configured
export TBE_IMPL_PATH=${LOCAL_ASCEND}/ascend-toolkit/latest/opp/op_impl/built-in/ai_core/tbe # TBE operator implementation tool path
export ASCEND_OPP_PATH=${LOCAL_ASCEND}/ascend-toolkit/latest/opp # OPP path
export PATH=${LOCAL_ASCEND}/ascend-toolkit/latest/compiler/ccec_compiler/bin/:${PATH} # TBE operator compilation tool path
export PYTHONPATH=${TBE_IMPL_PATH}:${PYTHONPATH} # Python library that TBE implementation depends on
```
执行`cmake`命令,其中`pip3`需要按照实际情况修改:
```bash
cmake . -DMINDSPORE_PATH=`pip3 show mindspore | grep Location | awk '{print $2"/mindspore"}' | xargs realpath`
```
再执行`make`命令编译即可。
```bash
make
```
编译完成后,在`ascend910_resnet50_preprocess_sample`下会生成可执行文件。
## 执行推理并查看结果
登录Ascend 910环境,创建`model`目录放置MindIR文件`resnet50_imagenet.mindir`,例如`/home/HwHiAiUser/mindspore_sample/ascend910_resnet50_preprocess_sample/model`。
创建`test_data`目录放置图片,例如`/home/HwHiAiUser/mindspore_sample/ascend910_resnet50_preprocess_sample/test_data`。
就可以开始执行推理了:
```bash
./resnet50_sample
```
执行后,会对`test_data`目录下放置的所有图片进行推理,比如放置了9张[ImageNet2012](http://image-net.org/download-images)验证集中label为0的图片,可以看到推理结果如下。
```text
Image: ./test_data/ILSVRC2012_val_00002138.JPEG infer result: 0
Image: ./test_data/ILSVRC2012_val_00003014.JPEG infer result: 0
Image: ./test_data/ILSVRC2012_val_00006697.JPEG infer result: 0
Image: ./test_data/ILSVRC2012_val_00007197.JPEG infer result: 0
Image: ./test_data/ILSVRC2012_val_00009111.JPEG infer result: 0
Image: ./test_data/ILSVRC2012_val_00009191.JPEG infer result: 0
Image: ./test_data/ILSVRC2012_val_00009346.JPEG infer result: 0
Image: ./test_data/ILSVRC2012_val_00009379.JPEG infer result: 0
Image: ./test_data/ILSVRC2012_val_00009396.JPEG infer result: 0
```