diff --git a/official/cv/fastscnn/README_CN.md b/official/cv/fastscnn/README_CN.md
index 2dcf9dccc21c58a98aec7aeb39c308ee2d2734f0..105e39cdd36482881b9e836f22e86d06e3e90a43 100644
--- a/official/cv/fastscnn/README_CN.md
+++ b/official/cv/fastscnn/README_CN.md
@@ -80,7 +80,7 @@ python train.py \
 bash ./scripts/run_train.sh [train_code_path] [dataset] [epochs] [batch_size] [lr] [output_path]
 
 #Ascend多卡训练。
-bash ./scripts/run_distribute_train.sh [train_code_path] [dataset] [epochs] [batch_size] [lr] [output_path]
+bash ./scripts/run_distribute_train.sh [train_code_path] [dataset] [epochs] [batch_size] [lr] [output_path] [rank_table_file_path]
 
 # 通过 python 命令行运行推理脚本。
 # resume_path 指 ckpt 所在目录,为了兼容 modelarts,将其拆分为了 “路径” 与 “文件名”
@@ -116,16 +116,15 @@ Ascend训练:生成[RANK_TABLE_FILE](https://gitee.com/mindspore/models/tree/m
         │   ├──fusion_switch.cfg             // 配置文件
         ├──cal_mIoU.py                       // 310 推理时计算mIoU的脚本
         ├──preprocess.py                     // 310 推理时预处理验证集的脚本
-        ├──score.py                          // 310 推理时计算mIoU的脚本
         ├── README_CN.md                     // fastscnn 的说明文件
         ├── scripts
         │   ├──run_distribute_train.sh       // Ascend 8卡训练脚本
         │   ├──run_eval.sh                   // 推理启动脚本
         │   ├──run_train.sh                  // 训练启动脚本
         │   ├──run_infer_310.sh              // 启动310推理的脚本
+        │   ├──docker_start.sh               // 使用 MindX 推理时的 docker 启动脚本
         ├── src
         │   ├──dataloader.py                 // 数据集处理
-        │   ├──distributed_sampler.py        // 8卡并行时的数据集切分操作
         │   ├──fast_scnn.py                  // 模型结构
         │   ├──logger.py                     // 日志打印文件
         │   ├──loss.py                       // 损失函数
@@ -237,7 +236,7 @@ cal_mIoU.py 中的主要参数如下:
   #上述命令均会使脚本在后台运行,日志将输出到 log.txt,可通过查看该文件了解训练详情
 
   #Ascend多卡训练(2、4、8卡配置请自行修改run_distribute_train.sh,默认8卡)
-  bash ./scripts/run_distribute_train.sh [train_code_path] [dataset] [epochs] [batch_size] [lr] [output_path]
+  bash ./scripts/run_distribute_train.sh [train_code_path] [dataset] [epochs] [batch_size] [lr] [output_path] [rank_table_file_path]
   ```
 
   训练完成后,您可以在 --output_path 参数指定的目录下找到保存的权重文件,训练过程中的部分 loss 收敛情况如下(4卡并行):
@@ -349,7 +348,7 @@ FastSCNN on “Cityscapes ”
 | Accuracy                   | 55.48%                                                       |
 | Total time                 | 8p:8h20m                                                    |
 | Checkpoint for Fine tuning | 8p: 14.51MB(.ckpt file)                                      |
-| Scripts                    | https://gitee.com/mindspore/models/tree/master/official/cv/fastscnn |
+| Scripts                    | [FastSCNN脚本](https://gitee.com/mindspore/models/tree/master/official/cv/fastscnn) |
 
 ## 随机情况说明
 
diff --git a/official/cv/fastscnn/cal_mIoU.py b/official/cv/fastscnn/cal_mIoU.py
index 6d300e98ee7fc5017784e8376043358781fefcbf..ffb08edfd495c0c9fa31bd513b19a96a99959fa4 100644
--- a/official/cv/fastscnn/cal_mIoU.py
+++ b/official/cv/fastscnn/cal_mIoU.py
@@ -17,18 +17,20 @@ import os
 import time
 import glob
 import numpy as np
+import PIL.Image as Image
 from tabulate import tabulate
-from score import SegmentationMetric
 
 ## Params
 parser = argparse.ArgumentParser()
 parser.add_argument('--label_path', type=str
                     , help='directory of dataset label')
-parser.add_argument('--output_path', default='', type=str,
-                    help='path of the predict files that generated by the model')
-parser.add_argument('--image_width', default=768, type=int, help='image_width')
+parser.add_argument('--output_path', default=None, type=str
+                    , help='path of the predict files that generated by the model')
 parser.add_argument('--image_height', default=768, type=int, help='image_height')
+parser.add_argument('--image_width', default=768, type=int, help='image_width')
 parser.add_argument('--save_mask', default=0, type=int, help='0 for False, 1 for True')
+parser.add_argument('--mask_result_path', default='./mask_result', type=str
+                    , help='the folder to save the semantic mask images')
 
 args = parser.parse_args()
 
@@ -56,37 +58,114 @@ cityspallete = [
 classes = ('road', 'sidewalk', 'building', 'wall', 'fence', 'pole', 'traffic light',
            'traffic sign', 'vegetation', 'terrain', 'sky', 'person', 'rider', 'car',
            'truck', 'bus', 'train', 'motorcycle', 'bicycle')
-def cal_mIoU(label_path, output_path, image_width, image_height, save_mask):
-    file_list = glob.glob(label_path+'*') # label_path must end by '/'
 
+class SegmentationMetric():
+    """Computes pixAcc and mIoU metric scores
+    """
+    def __init__(self, nclass):
+        super(SegmentationMetric, self).__init__()
+        self.nclass = nclass
+        self.reset()
+
+    def update(self, preds, labels):
+        """Updates the internal evaluation result.
+        Parameters
+        ----------
+        labels : 'NumpyArray' or list of `NumpyArray`
+            The labels of the data.
+        preds : 'NumpyArray' or list of `NumpyArray`
+            Predicted values.
+        """
+        def evaluate_worker(self, pred, label):
+            correct, labeled = batch_pix_accuracy(pred, label)
+            inter, union = batch_intersection_union(pred, label, self.nclass)
+            self.total_correct += correct
+            self.total_label += labeled
+            self.total_inter += inter
+            self.total_union += union
+        evaluate_worker(self, preds, labels)
+
+    def get(self, return_category_iou=False):
+        """Gets the current evaluation result.
+        Returns
+        -------
+        metrics : tuple of float
+            pixAcc and mIoU
+        """
+        # remove np.spacing(1)
+        pixAcc = 1.0 * self.total_correct / (2.220446049250313e-16 + self.total_label)
+        IoU = 1.0 * self.total_inter / (2.220446049250313e-16 + self.total_union)
+        mIoU = IoU.mean().item()
+        if return_category_iou:
+            return pixAcc, mIoU, IoU
+        return pixAcc, mIoU
+
+    def reset(self):
+        """Resets the internal evaluation result to initial state."""
+        self.total_inter = np.zeros(self.nclass)
+        self.total_union = np.zeros(self.nclass)
+        self.total_correct = 0
+        self.total_label = 0
+
+def batch_pix_accuracy(output, target):
+    """PixAcc"""
+    # inputs are numpy array, output 4D NCHW where 'C' means label classes, target 3D NHW
+    predict = np.argmax(output.astype(np.int64), 1) + 1
+    target = target.astype(np.int64) + 1
+    pixel_labeled = (target > 0).sum()
+    pixel_correct = ((predict == target) * (target > 0)).sum()
+    assert pixel_correct <= pixel_labeled, "Correct area should be smaller than Labeled"
+    return pixel_correct, pixel_labeled
+
+def batch_intersection_union(output, target, nclass):
+    """mIoU"""
+    # inputs are numpy array, output 4D, target 3D
+    mini = 1
+    maxi = nclass
+    nbins = nclass
+    predict = np.argmax(output.astype(np.float32), 1) + 1
+    target = target.astype(np.float32) + 1
+
+    predict = predict.astype(np.float32) * (target > 0).astype(np.float32)
+    intersection = predict * (predict == target).astype(np.float32)
+    # areas of intersection and union
+    # element 0 in intersection occur the main difference from np.bincount. set boundary to -1 is necessary.
+    area_inter, _ = np.histogram(intersection, bins=nbins, range=(mini, maxi))
+    area_pred, _ = np.histogram(predict, bins=nbins, range=(mini, maxi))
+    area_lab, _ = np.histogram(target, bins=nbins, range=(mini, maxi))
+    area_union = area_pred + area_lab - area_inter
+    assert (area_inter > area_union).sum() == 0, "Intersection area should be smaller than Union area"
+    return area_inter.astype(np.float32), area_union.astype(np.float32)
+
+def cal_mIoU():
+    file_list = glob.glob(os.path.join(args.label_path, '*'))
     start_time = time.time()
     metric = SegmentationMetric(19)
     metric.reset()
-    index = 0
-    for file in file_list:
+    if args.save_mask and not os.path.exists(args.mask_result_path):
+        os.makedirs(args.mask_result_path)
+    for index, file in enumerate(sorted(file_list)):
         label = np.fromfile(file, dtype=np.int32)
-        label = label.reshape(image_height, image_width)
+        label = label.reshape(args.image_height, args.image_width)
 
-        filename = file.split(os.sep)[-1][:-10]    # get the name of image file
-        predict_path = os.path.join(output_path, filename+"_img_0.bin")
+        filename = file.split(os.sep)[-1][:-10]  # get the name of image file
+        predict_path = os.path.join(args.output_path, filename + "_img_0.bin")
         predict = np.fromfile(predict_path, dtype=np.float32)
-        predict = predict.reshape(1, 19, image_height, image_width)
+        predict = predict.reshape(1, 19, args.image_height, args.image_width)
         metric.update(predict, label)
         pixAcc, mIoU = metric.get()
         print("[EVAL] Sample: {:d}, pixAcc: {:.3f}, mIoU: {:.3f}".format(index + 1, pixAcc * 100, mIoU * 100))
-        index += 1
 
-        if save_mask == 1:
+        if args.save_mask:
             output = np.argmax(predict[0], axis=0)
             out_img = Image.fromarray(output.astype('uint8'))
             out_img.putpalette(cityspallete)
-            outname = str(index) + '.png'
-            out_img.save(os.path.join(output_path, outname))
-
+            outname = str(filename) + '.png'
+            out_img.save(os.path.join(args.mask_result_path, outname))
 
     pixAcc, mIoU, category_iou = metric.get(return_category_iou=True)
     print('End validation pixAcc: {:.3f}, mIoU: {:.3f}'.format(pixAcc * 100, mIoU * 100))
-    txtName = os.path.join(output_path, "eval_results.txt")
+    txtName = os.path.join(args.mask_result_path, "eval_results.txt")
     with open(txtName, "w") as f:
         string = 'validation pixAcc:' + str(pixAcc * 100) + ', mIoU:' + str(mIoU * 100)
         f.write(string)
@@ -103,4 +182,4 @@ def cal_mIoU(label_path, output_path, image_width, image_height, save_mask):
     print("Time cost:"+str(time_used)+" seconds!")
 
 if __name__ == '__main__':
-    cal_mIoU(args.label_path, args.output_path, args.image_width, args.image_height, args.save_mask)
+    cal_mIoU()
diff --git a/official/cv/fastscnn/export.py b/official/cv/fastscnn/export.py
index 719430f7f85fac1d0816796b8cfbafb2677cfecc..16da751390025b475c05feac83b807c080b20eee 100644
--- a/official/cv/fastscnn/export.py
+++ b/official/cv/fastscnn/export.py
@@ -1,17 +1,17 @@
-# Copyright 2021 Huawei Technologies Co., Ltd
+# Copyright 2021 Huawei Technologies Co., Ltd
 #
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
 #
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
 #
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ============================================================================
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============================================================================
 """
 ##############export checkpoint file into air, onnx, mindir models#################
 python export.py
diff --git a/official/cv/fastscnn/infer/Dockerfile b/official/cv/fastscnn/infer/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..053bf80cd2309a41b6033b3e8d5ab4f87d41bd5e
--- /dev/null
+++ b/official/cv/fastscnn/infer/Dockerfile
@@ -0,0 +1,5 @@
+ARG FROM_IMAGE_NAME
+FROM ${FROM_IMAGE_NAME}
+
+COPY requirements.txt .
+RUN pip3.7 install -r requirements.txt
\ No newline at end of file
diff --git a/official/cv/fastscnn/infer/README_CN.md b/official/cv/fastscnn/infer/README_CN.md
new file mode 100644
index 0000000000000000000000000000000000000000..e294cba022fa25b1619835a6f73d1feebe2e87b8
--- /dev/null
+++ b/official/cv/fastscnn/infer/README_CN.md
@@ -0,0 +1,314 @@
+# FastSCNN MindX推理及mx Base推理
+
+<!-- TOC -->
+
+- [脚本说明](#脚本说明)
+    - [脚本及样例代码](#脚本及样例代码)
+    - [模型转换](#模型转换)
+    - [MindX SDK 启动流程](#{mindx\quadsdk\quad启动流程})
+    - [mx Base 推理流程](#{mx\quadbase\quad推理流程})
+
+<!-- /TOC -->
+
+## 脚本说明
+
+### 脚本及样例代码
+
+```tex
+├── fastscnn
+    ├── README_CN.md                           // fastscnn 的说明文件
+    ├── infer
+        ├── README_CN.md                       // fastscnn 的 MindX SDK 推理及 mx Base 推理的说明文件
+        ├── convert
+        │   ├──ATC_AIR_2_OM.sh                 // 将 air 模型转换为 om 模型的脚本
+        ├── data
+        │   ├──config
+        │   │   ├──fastscnn.pipeline           // MindX SDK运行所需的 pipline 配置文件
+        ├── mxbase                             // mx Base 推理目录(C++)
+        │   ├──src
+        │   │   ├──FastSCNN.h                  // 头文件
+        │   │   ├──FastSCNN.cpp                // 详细实现
+        │   │   ├──main.cpp                    // mx Base 主函数
+        │   ├──build.sh                        // 代码编译脚本
+        │   ├──CMakeLists.txt                  // 代码编译设置
+        ├── sdk
+        │   ├──main.py                         // MindX SDK 运行脚本
+        │   ├──run.sh                          // 启动 main.py 的 sh 文件
+    ├── ......                                 // 其他代码文件
+```
+
+### 模型转换
+
+1、首先执行 fastscnn 目录下的 export.py 将准备好的权重文件转换为 air 模型文件。
+
+```python
+# 此处简要举例
+python export.py \
+--batch_size=1 \
+--image_height=768 \
+--image_width=768 \
+--ckpt_file=xxx/fastscnn.ckpt \
+--file_name=fastscnn \
+--file_format=AIR \
+--device_target=Ascend \
+--device_id=0 \
+
+#转换完成后请将生成的fastscnn.air文件移动至infer目录下。
+```
+
+2、然后执行 convert 目录下的 ATC_AIR_2_OM.sh 将刚刚转换好的 air 模型文件转换为 om 模型文件以备后续使用。
+
+```bash
+# bash ./ATC_AIR_2_OM.sh -h 或者 bash ./ATC_AIR_2_OM.sh --help 可以查看帮助信息
+bash ATC_AIR_2_OM.sh [--model --output]
+
+e.g.
+bash ATC_AIR_2_OM.sh --model=../fastscnn.air --output=../data/model/fastscnn
+#转换后的模型结果为fastscnn.om,将放在{fastscnn}/infer/data/model/目录下
+```
+
+### 数据集准备
+
+此处以原始数据集 Cityscapes 为例。
+
+1、在 infer 目录下或其他文件夹下创建数据集存放文件夹(记为“xxx/dataset/”),并将 Cityscapes 中的 gtFine、leftImg8bit 文件夹上传至此,gtFine 和 leftImg8bit 中的 train、test文件夹可不上传。“xxx/dataset/” 下的数据集组织结构如下:
+
+```tex
+├── xxx/dataset/                           // 数据集根目录
+    │   ├──gtFine                          // 标注内容
+    │   │   ├──val                         // 验证集
+    │   │   │   ├── ....
+    │   │   │   ├── ....
+    │   ├──leftImg8bit                     // 原始图片
+    │   │   ├──val                         // 验证集
+    │   │   │   ├── ....
+    │   │   │   ├── ....
+```
+
+2、MindX SDK 直接使用原始数据集,上述数据集准备好后即可执行 “MindX SDK 启动流程” 步骤。
+
+3、mx Base 推理并不直接处理图片和计算语义分割后的 mIoU 值。因此我们需要首先执行 fastscnn 目录下的 preprocess.py 对测试图片进行归一化、对 label 进行 class 映射等操作并以 "bin" 文件形式进行存储。
+
+```python
+# 此处简要举例,“xx/preprocess_data” 为处理后的数据存储路径,不存在时会自动创建
+python preprocess.py \
+--image_path=xx/dataset \
+--out_dir=xx/preprocess_data \
+--image_height=768 \
+--image_width=768
+```
+
+数据预处理完毕后即可执行 “mx Base 推理流程” 步骤。
+
+### MindX SDK 启动流程
+
+```shell
+# 通过 bash 脚本启动 MindX SDK 推理
+# bash ./run.sh -h 或者 bash ./run.sh --help 可以查看帮助信息
+bash ./run.sh [--pipeline --image_path --image_width --image_height --save_mask --mask_result_path]
+# 注意: data/config/fastscnn.pipeline 中默认 MindX SDK 推理所需的模型文件为 "fastscnn.om",且放在 data/model/ 目录下,具体可以修改该文件中的 "modelPath" 属性进行配置。
+
+# 通过 python 命令启动 MindX SDK 推理
+python main.py \
+--pipeline=../data/config/fastscnn.pipeline \
+--image_path=xxx/dataset/ \
+--image_width=768 \
+--image_height=768 \
+--save_mask=1 \
+--mask_result_path=./mask_result
+# 注意: data/config/fastscnn.pipeline 中默认 MindX SDK 推理所需的模型文件为 "fastscnn.om",且放在 data/model/ 目录下,具体可以修改该文件中的 "modelPath" 属性进行配置。
+```
+
+推理结果示例:
+
+```tex
+Begin to initialize Log.
+The output directory of logs file exist.
+Save logs information to specified directory.
+Found 500 images in the folder /home/data/FastSCNN/dataset/leftImg8bit/val
+Processing --->  frankfurt_000001_029086_leftImg8bit
+[EVAL] Sample: 1, pixAcc: 93.023, mIoU: 34.965
+Processing --->  frankfurt_000001_064651_leftImg8bit
+[EVAL] Sample: 2, pixAcc: 94.525, mIoU: 39.346
+Processing --->  frankfurt_000001_023235_leftImg8bit
+[EVAL] Sample: 3, pixAcc: 93.609, mIoU: 43.201
+........
+Processing --->  lindau_000030_000019_leftImg8bit
+[EVAL] Sample: 497, pixAcc: 93.535, mIoU: 55.196
+Processing --->  lindau_000001_000019_leftImg8bit
+[EVAL] Sample: 498, pixAcc: 93.543, mIoU: 55.501
+Processing --->  lindau_000025_000019_leftImg8bit
+[EVAL] Sample: 499, pixAcc: 93.539, mIoU: 55.485
+Processing --->  lindau_000040_000019_leftImg8bit
+[EVAL] Sample: 500, pixAcc: 93.546, mIoU: 55.487
+End validation pixAcc: 93.546, mIoU: 55.487
+Category iou:
+ +------------+---------------+----------+
+|  class id  |  class name   |   iou    |
++============+===============+==========+
+|     0      |     road      | 0.976416 |
++------------+---------------+----------+
+|     1      |   sidewalk    | 0.662959 |
++------------+---------------+----------+
+|     2      |   building    | 0.866088 |
++------------+---------------+----------+
+|     3      |     wall      | 0.320282 |
++------------+---------------+----------+
+|     4      |     fence     | 0.248646 |
++------------+---------------+----------+
+|     5      |     pole      | 0.31713  |
++------------+---------------+----------+
+|     6      | traffic light | 0.360871 |
++------------+---------------+----------+
+|     7      | traffic sign  | 0.485951 |
++------------+---------------+----------+
+|     8      |  vegetation   | 0.896945 |
++------------+---------------+----------+
+|     9      |    terrain    | 0.503119 |
++------------+---------------+----------+
+|     10     |      sky      | 0.928662 |
++------------+---------------+----------+
+|     11     |    person     | 0.632751 |
++------------+---------------+----------+
+|     12     |     rider     | 0.370751 |
++------------+---------------+----------+
+|     13     |      car      | 0.851971 |
++------------+---------------+----------+
+|     14     |     truck     | 0.496429 |
++------------+---------------+----------+
+|     15     |      bus      | 0.565111 |
++------------+---------------+----------+
+|     16     |     train     | 0.289486 |
++------------+---------------+----------+
+|     17     |  motorcycle   | 0.259988 |
++------------+---------------+----------+
+|     18     |    bicycle    | 0.508992 |
++------------+---------------+----------+
+Testing finished....
+=======================================
+The total time of inference is 412.33897733688354 s
+=======================================
+```
+
+### mx Base 推理流程
+
+1、编译 mx Base
+
+```shell
+bash ./build.sh
+# 编译后的可执行文件 "fastscnn" 将保存在当前目录下
+```
+
+2、执行 mx Base 推理
+
+```tex
+./fastscnn [model_path input_data_path output_data_path]
+# 按顺序传入模型路径、图像路径(“数据集准备” 中的图片保存路径 “xx/preprocess_data” 下的 images 目录,以"/"结尾)、输出路径(需要提前创建)
+例如:
+ ./fastscnn ../data/model/fastscnn.om xx/preprocess_data/images ./result/
+```
+
+mx Base 推理结果示例:
+
+```tex
+I1108 03:06:01.198787 86423 main.cpp:53] =======================================  !!!Parameters setting!!! ========================================
+I1108 03:06:01.198843 86423 main.cpp:55] ==========  loading model weights from: ../data/model/fastscnn.om
+I1108 03:06:01.198853 86423 main.cpp:58] ==========  input data path = ../preprocess_data/images/
+I1108 03:06:01.198858 86423 main.cpp:61] ==========  output data path = ./result/ WARNING: please make sure that this folder is created in advance!!!
+I1108 03:06:01.198861 86423 main.cpp:63] ========================================  !!!Parameters setting!!! ========================================
+I1108 03:06:01.552381 86423 ModelInferenceProcessor.cpp:22] Begin to ModelInferenceProcessor init
+I1108 03:06:01.661561 86423 ModelInferenceProcessor.cpp:69] End to ModelInferenceProcessor init
+I1108 03:06:01.661762 86423 main.cpp:82] Processing: 1/500 ---> frankfurt_000001_023769_leftImg8bit_img.bin
+I1108 03:06:02.280328 86423 main.cpp:82] Processing: 2/500 ---> frankfurt_000001_067295_leftImg8bit_img.bin
+I1108 03:06:02.903029 86423 main.cpp:82] Processing: 3/500 ---> frankfurt_000000_011074_leftImg8bit_img.bin
+I1108 03:06:03.528358 86423 main.cpp:82] Processing: 4/500 ---> frankfurt_000000_002196_leftImg8bit_img.bin
+I1108 03:06:04.150723 86423 main.cpp:82] Processing: 5/500 ---> frankfurt_000001_073243_leftImg8bit_img.bin
+I1108 03:06:04.769243 86423 main.cpp:82] Processing: 6/500 ---> frankfurt_000001_082087_leftImg8bit_img.bin
+I1108 03:06:05.391845 86423 main.cpp:82] Processing: 7/500 ---> frankfurt_000001_055172_leftImg8bit_img.bin
+........
+I1108 03:07:17.471393 86423 main.cpp:91] infer succeed and write the result data with binary file !
+I1108 03:07:17.758675 86423 DeviceManager.cpp:83] DestroyDevices begin
+I1108 03:07:17.758706 86423 DeviceManager.cpp:85] destroy device:0
+I1108 03:07:17.950556 86423 DeviceManager.cpp:91] aclrtDestroyContext successfully!
+I1108 03:07:18.839597 86423 DeviceManager.cpp:99] DestroyDevices successfully
+I1108 03:07:18.839629 86423 main.cpp:98] Infer images sum 500, cost total time: 256694.6 ms.
+I1108 03:07:18.839658 86423 main.cpp:99] The throughput: 1.94784 bin/sec.
+I1108 03:07:18.839663 86423 main.cpp:100] ==========  The infer result has been saved in ---> ./result/
+
+```
+
+mx Base 的推理结果为 "图片的语义分割表示",将以 "bin" 文件的形式存储在指定路径下。
+
+3、计算语义分割的 mIoU 值和将语义分割结果进行可视化展示
+
+如果需要计算语义分割的 mIoU 值和将语义分割结果进行可视化展示,请执行 fastscnn 目录下的 cal_mIoU.py 脚本
+
+```python
+# 此处简要举例
+python cal_mIoU.py \
+--label_path=xx/preprocess_data/labels \
+--output_path=xxx/infer/mxbase/result \
+--image_height=768 \
+--image_width=768 \
+--save_mask=1
+--mask_result_path=./mask_result
+label_path 指第1步处理后的label保存路径,output_path 指 mx Base 推理后的结果保存路径
+```
+
+mIoU 计算结果示例:
+
+```tex
+[EVAL] Sample: 1, pixAcc: 96.204, mIoU: 32.133
+[EVAL] Sample: 2, pixAcc: 96.826, mIoU: 37.931
+[EVAL] Sample: 3, pixAcc: 96.307, mIoU: 36.358
+[EVAL] Sample: 4, pixAcc: 95.621, mIoU: 39.828
+.......
+[EVAL] Sample: 497, pixAcc: 93.530, mIoU: 55.492
+[EVAL] Sample: 498, pixAcc: 93.536, mIoU: 55.489
+[EVAL] Sample: 499, pixAcc: 93.543, mIoU: 55.495
+[EVAL] Sample: 500, pixAcc: 93.546, mIoU: 55.487
+End validation pixAcc: 93.546, mIoU: 55.487
+Category iou:
+ +------------+---------------+----------+
+|  class id  |  class name   |   iou    |
++============+===============+==========+
+|     0      |     road      | 0.976416 |
++------------+---------------+----------+
+|     1      |   sidewalk    | 0.662959 |
++------------+---------------+----------+
+|     2      |   building    | 0.866088 |
++------------+---------------+----------+
+|     3      |     wall      | 0.320282 |
++------------+---------------+----------+
+|     4      |     fence     | 0.248646 |
++------------+---------------+----------+
+|     5      |     pole      | 0.31713  |
++------------+---------------+----------+
+|     6      | traffic light | 0.360871 |
++------------+---------------+----------+
+|     7      | traffic sign  | 0.485951 |
++------------+---------------+----------+
+|     8      |  vegetation   | 0.896945 |
++------------+---------------+----------+
+|     9      |    terrain    | 0.503119 |
++------------+---------------+----------+
+|     10     |      sky      | 0.928662 |
++------------+---------------+----------+
+|     11     |    person     | 0.632751 |
++------------+---------------+----------+
+|     12     |     rider     | 0.370751 |
++------------+---------------+----------+
+|     13     |      car      | 0.851971 |
++------------+---------------+----------+
+|     14     |     truck     | 0.496429 |
++------------+---------------+----------+
+|     15     |      bus      | 0.565111 |
++------------+---------------+----------+
+|     16     |     train     | 0.289486 |
++------------+---------------+----------+
+|     17     |  motorcycle   | 0.259988 |
++------------+---------------+----------+
+|     18     |    bicycle    | 0.508992 |
++------------+---------------+----------+
+Time cost:188.06731748580933 seconds!
+```
diff --git a/official/cv/fastscnn/infer/convert/ATC_AIR_2_OM.sh b/official/cv/fastscnn/infer/convert/ATC_AIR_2_OM.sh
new file mode 100644
index 0000000000000000000000000000000000000000..049f88542e3a73a25a18a021b66726368b88b0dd
--- /dev/null
+++ b/official/cv/fastscnn/infer/convert/ATC_AIR_2_OM.sh
@@ -0,0 +1,62 @@
+#!/bin/bash
+
+# Copyright 2021 Huawei Technologies Co., Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============================================================================
+
+soc_version=Ascend310
+input_shape="x:1,3,768,768"
+# help message
+if [[ $1 == --help || $1 == -h ]];then
+    echo "usage:bash ./ATC_AIR_2_OM.sh <args>"
+    echo "parameter explain:
+    --model                  set model place, e.g. --model=../fastscnn.air
+    --output                 set the name and place of OM model, e.g. --output=../data/model/fastscnn
+    --soc_version            set the soc_version, default: --soc_version=Ascend310
+    --input_shape            set the input node and shape, default: --input_shape='x:1,3,768,768'
+    -h/--help                show help message
+    "
+    exit 1
+fi
+
+for para in "$@"
+do
+    if [[ $para == --model* ]];then
+        model=`echo ${para#*=}`
+    elif [[ $para == --output* ]];then
+        output=`echo ${para#*=}`
+    elif [[ $para == --soc_version* ]];then
+        soc_version=`echo ${para#*=}`
+    elif [[ $para == --input_shape* ]];then
+        input_shape=`echo ${para#*=}`
+    fi
+done
+
+if [[ $model  == "" ]];then
+   echo "[Error] para \"model \" must be config"
+   exit 1
+fi
+
+if [[ $output  == "" ]];then
+   echo "[Error] para \"output \" must be config"
+   exit 1
+fi
+
+atc \
+    --model=${model} \
+    --output=${output} \
+    --soc_version=${soc_version} \
+    --input_shape=${input_shape} \
+    --framework=1 \
+    --input_format=NCHW
\ No newline at end of file
diff --git a/official/cv/fastscnn/infer/data/config/fastscnn.pipeline b/official/cv/fastscnn/infer/data/config/fastscnn.pipeline
new file mode 100644
index 0000000000000000000000000000000000000000..0be93150dfb56f5a81cd9ddc5d918a90a73b290c
--- /dev/null
+++ b/official/cv/fastscnn/infer/data/config/fastscnn.pipeline
@@ -0,0 +1,26 @@
+{
+"fastscnn": {
+    "appsrc0": {
+        "factory": "appsrc",
+        "next": "modelInfer"
+        },
+    "modelInfer": {
+        "props": {
+            "modelPath": "../data/model/fastscnn.om",
+            "dataSource": "appsrc0"
+        },
+        "factory": "mxpi_tensorinfer",
+        "next": "dataserialize"
+        },
+    "dataserialize": {
+        "props": {
+             "outputDataKeys": "modelInfer"
+        },
+        "factory": "mxpi_dataserialize",
+        "next": "appsink0"
+    },
+    "appsink0": {
+        "factory": "appsink"
+    }
+  }
+}
diff --git a/official/cv/fastscnn/infer/docker_start_infer.sh b/official/cv/fastscnn/infer/docker_start_infer.sh
new file mode 100644
index 0000000000000000000000000000000000000000..64cf90a2311bdfb21d68a4e90e08602670fdf632
--- /dev/null
+++ b/official/cv/fastscnn/infer/docker_start_infer.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+
+# Copyright 2021 Huawei Technologies Co., Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+docker_image=$1
+data_dir=$2
+
+function show_help() {
+    echo "Usage: docker_start.sh docker_image data_dir"
+}
+
+function param_check() {
+    if [ -z "${docker_image}" ]; then
+        echo "please input docker_image"
+        show_help
+        exit 1
+    fi
+
+    if [ -z "${data_dir}" ]; then
+        echo "please input data_dir"
+        show_help
+        exit 1
+    fi
+}
+
+param_check
+
+docker run -it \
+  --device=/dev/davinci0 \
+  --device=/dev/davinci_manager \
+  --device=/dev/devmm_svm \
+  --device=/dev/hisi_hdc \
+  -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
+  -v ${data_dir}:${data_dir} \
+  ${docker_image} \
+  /bin/bash
diff --git a/official/cv/fastscnn/infer/mxbase/CMakeLists.txt b/official/cv/fastscnn/infer/mxbase/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..37ef3af8de31b77bee12149bce40b3ccd2eea3e3
--- /dev/null
+++ b/official/cv/fastscnn/infer/mxbase/CMakeLists.txt
@@ -0,0 +1,49 @@
+cmake_minimum_required(VERSION 3.14.0)
+project(fastscnn)
+set(TARGET fastscnn)
+add_definitions(-DENABLE_DVPP_INTERFACE)
+add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
+add_definitions(-Dgoogle=mindxsdk_private)
+add_compile_options(-std=c++11 -fPIE -fstack-protector-all -fPIC -Wall)
+add_link_options(-Wl,-z,relro,-z,now,-z,noexecstack -s -pie)
+# Check environment variable
+if(NOT DEFINED ENV{ASCEND_HOME})
+    message(FATAL_ERROR "please define environment variable:ASCEND_HOME")
+endif()
+if(NOT DEFINED ENV{ASCEND_VERSION})
+    message(WARNING "please define environment variable:ASCEND_VERSION")
+endif()
+if(NOT DEFINED ENV{ARCH_PATTERN})
+    message(WARNING "please define environment variable:ARCH_PATTERN")
+endif()
+set(ACL_INC_DIR $ENV{ASCEND_HOME}/$ENV{ASCEND_VERSION}/$ENV{ARCH_PATTERN}/acllib/include)
+set(ACL_LIB_DIR $ENV{ASCEND_HOME}/$ENV{ASCEND_VERSION}/$ENV{ARCH_PATTERN}/acllib/lib64)
+set(MXBASE_ROOT_DIR $ENV{MX_SDK_HOME})
+set(MXBASE_INC ${MXBASE_ROOT_DIR}/include)
+set(MXBASE_LIB_DIR ${MXBASE_ROOT_DIR}/lib)
+set(MXBASE_POST_LIB_DIR ${MXBASE_ROOT_DIR}/lib/modelpostprocessors)
+set(MXBASE_POST_PROCESS_DIR ${MXBASE_ROOT_DIR}/include/MxBase/postprocess/include)
+
+if(NOT DEFINED ENV{MXSDK_OPENSOURCE_DIR})
+    message(WARNING "please define environment variable:MXSDK_OPENSOURCE_DIR")
+endif()
+
+set(OPENSOURCE_DIR $ENV{MXSDK_OPENSOURCE_DIR})
+
+include_directories(src)
+include_directories(${ACL_INC_DIR})
+include_directories(${OPENSOURCE_DIR}/include)
+include_directories(${OPENSOURCE_DIR}/include/opencv4)
+
+
+include_directories(${MXBASE_INC})
+include_directories(${MXBASE_POST_PROCESS_DIR})
+
+link_directories(${ACL_LIB_DIR})
+link_directories(${OPENSOURCE_DIR}/lib)
+link_directories(${MXBASE_LIB_DIR})
+link_directories(${MXBASE_POST_LIB_DIR})
+
+add_executable(${TARGET} src/main.cpp src/FastSCNN.cpp)
+target_link_libraries(${TARGET} glog cpprest mxbase opencv_world stdc++fs)
+install(TARGETS ${TARGET} RUNTIME DESTINATION ${PROJECT_SOURCE_DIR}/)
diff --git a/official/cv/fastscnn/infer/mxbase/build.sh b/official/cv/fastscnn/infer/mxbase/build.sh
new file mode 100644
index 0000000000000000000000000000000000000000..2a239241a5d82ada71d8e60852033b7c84d40566
--- /dev/null
+++ b/official/cv/fastscnn/infer/mxbase/build.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+
+# Copyright 2021 Huawei Technologies Co., Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============================================================================
+export ASCEND_HOME=/usr/local/Ascend
+export ASCEND_VERSION=nnrt/latest
+export ARCH_PATTERN=.
+export MXSDK_OPENSOURCE_DIR=/usr/local/sdk_home/mxManufacture/opensource
+export LD_LIBRARY_PATH="${MX_SDK_HOME}/lib/plugins:${MX_SDK_HOME}/opensource/lib64:${MX_SDK_HOME}/lib:${MX_SDK_HOME}/lib/modelpostprocessors:${MX_SDK_HOME}/opensource/lib:/usr/local/Ascend/nnae/latest/fwkacllib/lib64:${LD_LIBRARY_PATH}"
+export ASCEND_OPP_PATH="/usr/local/Ascend/nnae/latest/opp"
+export ASCEND_AICPU_PATH="/usr/local/Ascend/nnae/latest"
+
+function check_env()
+{
+    # set ASCEND_VERSION to ascend-toolkit/latest when it was not specified by user
+    if [ ! "${ASCEND_VERSION}" ]; then
+        export ASCEND_VERSION=ascend-toolkit/latest
+        echo "Set ASCEND_VERSION to the default value: ${ASCEND_VERSION}"
+    else
+        echo "ASCEND_VERSION is set to ${ASCEND_VERSION} by user"
+    fi
+
+    if [ ! "${ARCH_PATTERN}" ]; then
+        # set ARCH_PATTERN to ./ when it was not specified by user
+        export ARCH_PATTERN=./
+        echo "ARCH_PATTERN is set to the default value: ${ARCH_PATTERN}"
+    else
+        echo "ARCH_PATTERN is set to ${ARCH_PATTERN} by user"
+    fi
+}
+
+function build_fastscnn()
+{
+    cd .
+    rm -rf build
+    mkdir -p build
+    cd build
+    cmake ..
+    make
+    ret=$?
+    if [ ${ret} -ne 0 ]; then
+        echo "Failed to build brdnet."
+        exit ${ret}
+    fi
+    make install
+}
+
+rm -rf ./result
+mkdir -p ./result
+
+check_env
+build_fastscnn
diff --git a/official/cv/fastscnn/infer/mxbase/src/FastSCNN.cpp b/official/cv/fastscnn/infer/mxbase/src/FastSCNN.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ecdab3995b8a532fc09f0a7a2407a1a72d353176
--- /dev/null
+++ b/official/cv/fastscnn/infer/mxbase/src/FastSCNN.cpp
@@ -0,0 +1,177 @@
+/**
+ * Copyright 2021 Huawei Technologies Co., Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "FastSCNN.h"
+#include <unistd.h>
+#include <sys/stat.h>
+#include <map>
+#include <fstream>
+#include "MxBase/DeviceManager/DeviceManager.h"
+#include "MxBase/Log/Log.h"
+
+APP_ERROR FastSCNN::Init(const InitParam &initParam) {
+    this->deviceId_ = initParam.deviceId;
+    this->outputDataPath_ = initParam.outputDataPath;
+    APP_ERROR ret = MxBase::DeviceManager::GetInstance()->InitDevices();
+    if (ret != APP_ERR_OK) {
+        LogError << "Init devices failed, ret=" << ret << ".";
+        return ret;
+    }
+
+    ret = MxBase::TensorContext::GetInstance()->SetContext(initParam.deviceId);
+    if (ret != APP_ERR_OK) {
+        LogError << "Set context failed, ret=" << ret << ".";
+        return ret;
+    }
+
+    this->model_ = std::make_shared<MxBase::ModelInferenceProcessor>();
+    ret = this->model_->Init(initParam.modelPath, this->modelDesc_);
+    if (ret != APP_ERR_OK) {
+        LogError << "ModelInferenceProcessor init failed, ret=" << ret << ".";
+        return ret;
+    }
+    uint32_t input_data_size = 1;
+    for (size_t j = 0; j < this->modelDesc_.inputTensors[0].tensorDims.size(); ++j) {
+        this->inputDataShape_[j] = (uint32_t)this->modelDesc_.inputTensors[0].tensorDims[j];
+        input_data_size *= this->inputDataShape_[j];
+    }
+    this->inputDataSize_ = input_data_size;
+
+    return APP_ERR_OK;
+}
+
+APP_ERROR FastSCNN::DeInit() {
+    this->model_->DeInit();
+    MxBase::DeviceManager::GetInstance()->DestroyDevices();
+    return APP_ERR_OK;
+}
+
+APP_ERROR FastSCNN::ReadTensorFromFile(const std::string &file, float *data) {
+    if (data == NULL) {
+        LogError << "input data is invalid.";
+        return APP_ERR_COMM_INVALID_POINTER;
+    }
+
+    std::ifstream infile;
+    // open data file
+    infile.open(file, std::ios_base::in | std::ios_base::binary);
+    // check data file validity
+    if (infile.fail()) {
+        LogError << "Failed to open data file: " << file << ".";
+        return APP_ERR_COMM_OPEN_FAIL;
+    }
+    infile.read(reinterpret_cast<char*>(data), sizeof(float) * this->inputDataSize_);
+    infile.close();
+    return APP_ERR_OK;
+}
+
+APP_ERROR FastSCNN::ReadInputTensor(const std::string &fileName, std::vector<MxBase::TensorBase> *inputs) {
+    float data[this->inputDataSize_] = {0};
+    APP_ERROR ret = ReadTensorFromFile(fileName, data);
+    if (ret != APP_ERR_OK) {
+        LogError << "ReadTensorFromFile failed.";
+        return ret;
+    }
+    const uint32_t dataSize = this->modelDesc_.inputTensors[0].tensorSize;
+    MxBase::MemoryData memoryDataDst(dataSize, MxBase::MemoryData::MEMORY_DEVICE, this->deviceId_);
+    MxBase::MemoryData memoryDataSrc(reinterpret_cast<void*>(data), dataSize, MxBase::MemoryData::MEMORY_HOST_MALLOC);
+
+    ret = MxBase::MemoryHelper::MxbsMallocAndCopy(memoryDataDst, memoryDataSrc);
+    if (ret != APP_ERR_OK) {
+        LogError << GetError(ret) << "Memory malloc and copy failed.";
+        return ret;
+    }
+
+    inputs->push_back(MxBase::TensorBase(memoryDataDst, false, this->inputDataShape_, MxBase::TENSOR_DTYPE_FLOAT32));
+    return APP_ERR_OK;
+}
+
+
+APP_ERROR FastSCNN::Inference(const std::vector<MxBase::TensorBase> &inputs,
+                                 std::vector<MxBase::TensorBase> *outputs) {
+    auto dtypes = this->model_->GetOutputDataType();
+    for (size_t i = 0; i < this->modelDesc_.outputTensors.size(); ++i) {
+        std::vector<uint32_t> shape = {};
+        for (size_t j = 0; j < modelDesc_.outputTensors[i].tensorDims.size(); ++j) {
+            shape.push_back((uint32_t)this->modelDesc_.outputTensors[i].tensorDims[j]);
+        }
+        MxBase::TensorBase tensor(shape, dtypes[i], MxBase::MemoryData::MemoryType::MEMORY_DEVICE, this->deviceId_);
+        APP_ERROR ret = MxBase::TensorBase::TensorBaseMalloc(tensor);
+        if (ret != APP_ERR_OK) {
+            LogError << "TensorBaseMalloc failed, ret=" << ret << ".";
+            return ret;
+        }
+        outputs->push_back(tensor);
+    }
+
+    MxBase::DynamicInfo dynamicInfo = {};
+    dynamicInfo.dynamicType = MxBase::DynamicType::STATIC_BATCH;
+    auto startTime = std::chrono::high_resolution_clock::now();
+    APP_ERROR ret = this->model_->ModelInference(inputs, *outputs, dynamicInfo);
+    auto endTime = std::chrono::high_resolution_clock::now();
+    double costMs = std::chrono::duration<double, std::milli>(endTime - startTime).count();
+    g_inferCost.push_back(costMs);
+
+    if (ret != APP_ERR_OK) {
+        LogError << "ModelInference failed, ret=" << ret << ".";
+        return ret;
+    }
+    return APP_ERR_OK;
+}
+
+
+APP_ERROR  FastSCNN::WriteResult(const std::string &imageFile, std::vector<MxBase::TensorBase> outputs) {
+    for (size_t i = 0; i < 1; ++i) {  //  when model's aux==True, we don't use the other two outputs.
+        APP_ERROR ret = outputs[i].ToHost();
+        if (ret != APP_ERR_OK) {
+            LogError << GetError(ret) << "tohost fail.";
+            return ret;
+        }
+        void *netOutput = outputs[i].GetBuffer();
+        std::vector<uint32_t> out_shape = outputs[i].GetShape();
+        int pos = imageFile.rfind('/');
+        std::string fileName(imageFile, pos + 1);
+        fileName.replace(fileName.find('.'), fileName.size() - fileName.find('.'), "_0.bin");
+        std::string outFileName = this->outputDataPath_ + "/" + fileName;
+        FILE *outputFile_ = fopen(outFileName.c_str(), "wb");
+        fwrite(netOutput, out_shape[0]*out_shape[1]*out_shape[2]*out_shape[3], sizeof(float), outputFile_);
+        fclose(outputFile_);
+    }
+    return APP_ERR_OK;
+}
+
+
+APP_ERROR FastSCNN::Process(const std::string &inferPath, const std::string &fileName) {
+    std::vector<MxBase::TensorBase> inputs = {};
+    std::string inputIdsFile = inferPath + fileName;
+    APP_ERROR ret = ReadInputTensor(inputIdsFile, &inputs);
+    if (ret != APP_ERR_OK) {
+        LogError << "Read input ids failed, ret=" << ret << ".";
+        return ret;
+    }
+    std::vector<MxBase::TensorBase> outputs = {};
+    ret = Inference(inputs, &outputs);
+    if (ret != APP_ERR_OK) {
+        LogError << "Inference failed, ret=" << ret << ".";
+        return ret;
+    }
+
+    ret = WriteResult(fileName, outputs);
+    if (ret != APP_ERR_OK) {
+        LogError << "Write result failed, ret=" << ret << ".";
+        return ret;
+    }
+    return APP_ERR_OK;
+}
diff --git a/official/cv/fastscnn/infer/mxbase/src/FastSCNN.h b/official/cv/fastscnn/infer/mxbase/src/FastSCNN.h
new file mode 100644
index 0000000000000000000000000000000000000000..38b9d380550a8fb99c6a1871fb4567f9e554209b
--- /dev/null
+++ b/official/cv/fastscnn/infer/mxbase/src/FastSCNN.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2021 Huawei Technologies Co., Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MXBASE_FastSCNN_H
+#define MXBASE_FastSCNN_H
+
+#include <memory>
+#include <utility>
+#include <vector>
+#include <string>
+#include <map>
+#include "MxBase/ModelInfer/ModelInferenceProcessor.h"
+#include "MxBase/Tensor/TensorContext/TensorContext.h"
+
+extern std::vector<double> g_inferCost;
+
+struct InitParam {
+    uint32_t deviceId;
+    std::string modelPath;
+    std::string outputDataPath;
+};
+
+class FastSCNN {
+ public:
+    APP_ERROR Init(const InitParam &initParam);
+    APP_ERROR DeInit();
+    APP_ERROR Inference(const std::vector<MxBase::TensorBase> &inputs, std::vector<MxBase::TensorBase> *outputs);
+    APP_ERROR Process(const std::string &inferPath, const std::string &fileName);
+
+ protected:
+    APP_ERROR ReadTensorFromFile(const std::string &file, float *data);
+    APP_ERROR ReadInputTensor(const std::string &fileName, std::vector<MxBase::TensorBase> *inputs);
+    APP_ERROR WriteResult(const std::string &imageFile, std::vector<MxBase::TensorBase> outputs);
+
+ private:
+    std::shared_ptr<MxBase::ModelInferenceProcessor> model_;
+    MxBase::ModelDesc modelDesc_ = {};
+    uint32_t deviceId_ = 0;
+    std::string outputDataPath_ = "./result";
+    std::vector<uint32_t> inputDataShape_ = {1, 3, 768, 768};
+    uint32_t inputDataSize_ = 1769472;
+};
+
+#endif
diff --git a/official/cv/fastscnn/infer/mxbase/src/main.cpp b/official/cv/fastscnn/infer/mxbase/src/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..125d7f92491963faf573f294b35abca4b128f111
--- /dev/null
+++ b/official/cv/fastscnn/infer/mxbase/src/main.cpp
@@ -0,0 +1,105 @@
+/**
+ * Copyright 2021 Huawei Technologies Co., Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <unistd.h>
+#include <dirent.h>
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include "FastSCNN.h"
+#include "MxBase/Log/Log.h"
+
+std::vector<double> g_inferCost;
+
+void InitProtonetParam(InitParam* initParam, const std::string &model_path, const std::string &output_data_path) {
+    initParam->deviceId = 0;
+    initParam->modelPath = model_path;
+    initParam->outputDataPath = output_data_path;
+}
+
+APP_ERROR ReadFilesFromPath(const std::string &path, std::vector<std::string> *files) {
+    DIR *dir = NULL;
+    struct dirent *ptr = NULL;
+
+    if ((dir=opendir(path.c_str())) == NULL) {
+        LogError << "Open dir error: " << path;
+        return APP_ERR_COMM_OPEN_FAIL;
+    }
+
+    while ((ptr=readdir(dir)) != NULL) {
+        if (ptr->d_type == 8) {
+            files->push_back(ptr->d_name);
+        }
+    }
+    closedir(dir);
+    return APP_ERR_OK;
+}
+
+
+int main(int argc, char* argv[]) {
+    LogInfo << "=======================================  !!!Parameters setting!!! " << \
+               "========================================";
+    std::string model_path = argv[1];
+    LogInfo << "==========  loading model weights from: " << model_path;
+
+    std::string input_data_path = argv[2];
+    LogInfo << "==========  input data path = " << input_data_path;
+
+    std::string output_data_path = argv[3];
+    LogInfo << "==========  output data path = " << output_data_path << \
+               " WARNING: please make sure that this folder is created in advance!!!";
+
+    LogInfo << "========================================  !!!Parameters setting!!! " << \
+               "========================================";
+
+    InitParam initParam;
+    InitProtonetParam(&initParam, model_path, output_data_path);
+    auto fastscnn = std::make_shared<FastSCNN>();
+    APP_ERROR ret = fastscnn->Init(initParam);
+    if (ret != APP_ERR_OK) {
+        LogError << "FastSCNN init failed, ret=" << ret << ".";
+        return ret;
+    }
+    std::vector<std::string> files;
+    ret = ReadFilesFromPath(input_data_path, &files);
+    if (ret != APP_ERR_OK) {
+        LogError << "Read files from path failed, ret=" << ret << ".";
+        return ret;
+    }
+
+    // do infer
+    for (uint32_t i = 0; i < files.size(); i++) {
+        LogInfo << "Processing: " + std::to_string(i+1) + "/" + std::to_string(files.size()) + " ---> " + files[i];
+        ret = fastscnn->Process(input_data_path, files[i]);
+        if (ret != APP_ERR_OK) {
+            LogError << "FastSCNN process failed, ret=" << ret << ".";
+            fastscnn->DeInit();
+            return ret;
+        }
+    }
+
+    LogInfo << "infer succeed and write the result data with binary file !";
+
+    fastscnn->DeInit();
+    double costSum = 0;
+    for (uint32_t i = 0; i < g_inferCost.size(); i++) {
+        costSum += g_inferCost[i];
+    }
+    LogInfo << "Infer images sum " << g_inferCost.size() << ", cost total time: " << costSum << " ms.";
+    LogInfo << "The throughput: " << g_inferCost.size() * 1000 / costSum << " bin/sec.";
+    LogInfo << "==========  The infer result has been saved in ---> " << output_data_path;
+    return APP_ERR_OK;
+}
diff --git a/official/cv/fastscnn/infer/requirements.txt b/official/cv/fastscnn/infer/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..87f6e8b602e7bc48f954aeb512eb2e37ad18ef52
--- /dev/null
+++ b/official/cv/fastscnn/infer/requirements.txt
@@ -0,0 +1,3 @@
+pillow
+numpy
+tabulate
\ No newline at end of file
diff --git a/official/cv/fastscnn/infer/sdk/main.py b/official/cv/fastscnn/infer/sdk/main.py
new file mode 100644
index 0000000000000000000000000000000000000000..055dbd21f9914f317100d134cb4bb20c0c841ad9
--- /dev/null
+++ b/official/cv/fastscnn/infer/sdk/main.py
@@ -0,0 +1,374 @@
+'''
+The scripts to execute sdk infer
+'''
+# Copyright 2021 Huawei Technologies Co., Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============================================================================
+
+import argparse
+import os
+import time
+import numpy as np
+import PIL.Image as Image
+from tabulate import tabulate
+
+import MxpiDataType_pb2 as MxpiDataType
+from StreamManagerApi import StreamManagerApi, InProtobufVector, \
+    MxProtobufIn, StringVector
+
+def parse_args():
+    """set and check parameters."""
+    parser = argparse.ArgumentParser(description="FastSCNN process")
+    parser.add_argument("--pipeline", type=str, default=None, help="SDK infer pipeline")
+    parser.add_argument("--image_path", type=str, default=None, help="root path of image")
+    parser.add_argument('--image_width', default=768, type=int, help='image width')
+    parser.add_argument('--image_height', default=768, type=int, help='image height')
+    parser.add_argument('--save_mask', default=1, type=int, help='0 for False, 1 for True')
+    parser.add_argument('--mask_result_path', default='./mask_result', type=str,
+                        help='the folder to save the semantic mask images')
+    args_opt = parser.parse_args()
+    return args_opt
+
+def send_source_data(appsrc_id, tensor, stream_name, stream_manager):
+    """
+    Construct the input of the stream,
+    send inputs data to a specified stream based on streamName.
+
+    Returns:
+        bool: send data success or not
+    """
+    tensor_package_list = MxpiDataType.MxpiTensorPackageList()
+    tensor_package = tensor_package_list.tensorPackageVec.add()
+    array_bytes = tensor.tobytes()
+    tensor_vec = tensor_package.tensorVec.add()
+    tensor_vec.deviceId = 0
+    tensor_vec.memType = 0
+    for i in tensor.shape:
+        tensor_vec.tensorShape.append(i)
+    tensor_vec.dataStr = array_bytes
+    tensor_vec.tensorDataSize = len(array_bytes)
+    key = "appsrc{}".format(appsrc_id).encode('utf-8')
+    protobuf_vec = InProtobufVector()
+    protobuf = MxProtobufIn()
+    protobuf.key = key
+    protobuf.type = b'MxTools.MxpiTensorPackageList'
+    protobuf.protobuf = tensor_package_list.SerializeToString()
+    protobuf_vec.push_back(protobuf)
+
+    ret = stream_manager.SendProtobuf(stream_name, appsrc_id, protobuf_vec)
+    if ret < 0:
+        print("Failed to send data to stream.")
+        return False
+    return True
+
+cityspallete = [
+    128, 64, 128,
+    244, 35, 232,
+    70, 70, 70,
+    102, 102, 156,
+    190, 153, 153,
+    153, 153, 153,
+    250, 170, 30,
+    220, 220, 0,
+    107, 142, 35,
+    152, 251, 152,
+    0, 130, 180,
+    220, 20, 60,
+    255, 0, 0,
+    0, 0, 142,
+    0, 0, 70,
+    0, 60, 100,
+    0, 80, 100,
+    0, 0, 230,
+    119, 11, 32,
+]
+classes = ('road', 'sidewalk', 'building', 'wall', 'fence', 'pole', 'traffic light',
+           'traffic sign', 'vegetation', 'terrain', 'sky', 'person', 'rider', 'car',
+           'truck', 'bus', 'train', 'motorcycle', 'bicycle')
+
+valid_classes = [7, 8, 11, 12, 13, 17, 19, 20, 21, 22,
+                 23, 24, 25, 26, 27, 28, 31, 32, 33]
+
+_key = np.array([-1, -1, -1, -1, -1, -1,
+                 -1, -1, 0, 1, -1, -1,
+                 2, 3, 4, -1, -1, -1,
+                 5, -1, 6, 7, 8, 9,
+                 10, 11, 12, 13, 14, 15,
+                 -1, -1, 16, 17, 18])
+_mapping = np.array(range(-1, len(_key) - 1)).astype('int32')
+
+def _get_city_pairs(folder, split='train'):
+    '''_get_city_pairs'''
+    def get_path_pairs(img_folder, mask_folder):
+        img_paths = []
+        mask_paths = []
+        for root, _, files in os.walk(img_folder):
+            for filename in files:
+                if filename.startswith('._'):
+                    continue
+                if filename.endswith('.png'):
+                    imgpath = os.path.join(root, filename)
+                    foldername = os.path.basename(os.path.dirname(imgpath))
+                    maskname = filename.replace('leftImg8bit', 'gtFine_labelIds')
+                    maskpath = os.path.join(mask_folder, foldername, maskname)
+                    if os.path.isfile(imgpath) and os.path.isfile(maskpath):
+                        img_paths.append(imgpath)
+                        mask_paths.append(maskpath)
+                    else:
+                        print('cannot find the mask or image:', imgpath, maskpath)
+        print('Found {} images in the folder {}'.format(len(img_paths), img_folder))
+        return img_paths, mask_paths
+
+    if split in ('train', 'val'):
+        img_folder = os.path.join(folder, 'leftImg8bit' + os.sep + split)
+        mask_folder = os.path.join(folder, 'gtFine' + os.sep + split)
+        img_paths, mask_paths = get_path_pairs(img_folder, mask_folder)
+        return img_paths, mask_paths
+    assert split == 'trainval'
+    print('trainval set')
+    train_img_folder = os.path.join(folder, 'leftImg8bit' + os.sep + 'train')
+    train_mask_folder = os.path.join(folder, 'gtFine' + os.sep + 'train')
+    val_img_folder = os.path.join(folder, 'leftImg8bit' + os.sep + 'val')
+    val_mask_folder = os.path.join(folder, 'gtFine' + os.sep + 'val')
+    train_img_paths, train_mask_paths = get_path_pairs(train_img_folder, train_mask_folder)
+    val_img_paths, val_mask_paths = get_path_pairs(val_img_folder, val_mask_folder)
+    img_paths = train_img_paths + val_img_paths
+    mask_paths = train_mask_paths + val_mask_paths
+    return img_paths, mask_paths
+
+def _val_sync_transform(outsize, img, mask):
+    '''_val_sync_transform'''
+    short_size = min(outsize)
+    w, h = img.size
+    if w > h:
+        oh = short_size
+        ow = int(1.0 * w * oh / h)
+    else:
+        ow = short_size
+        oh = int(1.0 * h * ow / w)
+    img = img.resize((ow, oh), Image.BILINEAR)
+    mask = mask.resize((ow, oh), Image.NEAREST)
+    # center crop
+    w, h = img.size
+    x1 = int(round((w - outsize[1]) / 2.))
+    y1 = int(round((h - outsize[0]) / 2.))
+    img = img.crop((x1, y1, x1 + outsize[1], y1 + outsize[0]))
+    mask = mask.crop((x1, y1, x1 + outsize[1], y1 + outsize[0]))
+
+    # final transform
+    img, mask = np.array(img), _mask_transform(mask)
+    return img, mask
+
+def _class_to_index(mask):
+    # assert the value
+    values = np.unique(mask)
+    for value in values:
+        assert value in _mapping
+    index = np.digitize(mask.ravel(), _mapping, right=True)
+    return _key[index].reshape(mask.shape)
+
+def _mask_transform(mask):
+    target = _class_to_index(np.array(mask).astype('int32'))
+    return np.array(target).astype('int32')
+class SegmentationMetric():
+    """Computes pixAcc and mIoU metric scores
+    """
+
+    def __init__(self, nclass):
+        super(SegmentationMetric, self).__init__()
+        self.nclass = nclass
+        self.reset()
+
+    def update(self, preds, labels):
+        """Updates the internal evaluation result.
+
+        Parameters
+        ----------
+        labels : 'NumpyArray' or list of `NumpyArray`
+            The labels of the data.
+        preds : 'NumpyArray' or list of `NumpyArray`
+            Predicted values.
+        """
+        def evaluate_worker(self, pred, label):
+            correct, labeled = batch_pix_accuracy(pred, label)
+            inter, union = batch_intersection_union(pred, label, self.nclass)
+            self.total_correct += correct
+            self.total_label += labeled
+            self.total_inter += inter
+            self.total_union += union
+        evaluate_worker(self, preds, labels)
+
+    def get(self, return_category_iou=False):
+        """Gets the current evaluation result.
+
+        Returns
+        -------
+        metrics : tuple of float
+            pixAcc and mIoU
+        """
+        # remove np.spacing(1)
+        pixAcc = 1.0 * self.total_correct / (2.220446049250313e-16 + self.total_label)
+        IoU = 1.0 * self.total_inter / (2.220446049250313e-16 + self.total_union)
+        mIoU = IoU.mean().item()
+        if return_category_iou:
+            return pixAcc, mIoU, IoU
+        return pixAcc, mIoU
+
+    def reset(self):
+        """Resets the internal evaluation result to initial state."""
+        self.total_inter = np.zeros(self.nclass)
+        self.total_union = np.zeros(self.nclass)
+        self.total_correct = 0
+        self.total_label = 0
+
+def batch_pix_accuracy(output, target):
+    """PixAcc"""
+    # inputs are numpy array, output 4D NCHW where 'C' means label classes, target 3D NHW
+
+    predict = np.argmax(output.astype(np.int64), 1) + 1
+    target = target.astype(np.int64) + 1
+    pixel_labeled = (target > 0).sum()
+    pixel_correct = ((predict == target) * (target > 0)).sum()
+    assert pixel_correct <= pixel_labeled, "Correct area should be smaller than Labeled"
+    return pixel_correct, pixel_labeled
+
+def batch_intersection_union(output, target, nclass):
+    """mIoU"""
+    # inputs are numpy array, output 4D, target 3D
+    mini = 1
+    maxi = nclass
+    nbins = nclass
+    predict = np.argmax(output.astype(np.float32), 1) + 1
+    target = target.astype(np.float32) + 1
+
+    predict = predict.astype(np.float32) * (target > 0).astype(np.float32)
+    intersection = predict * (predict == target).astype(np.float32)
+    # areas of intersection and union
+    # element 0 in intersection occur the main difference from np.bincount. set boundary to -1 is necessary.
+    area_inter, _ = np.histogram(intersection, bins=nbins, range=(mini, maxi))
+    area_pred, _ = np.histogram(predict, bins=nbins, range=(mini, maxi))
+    area_lab, _ = np.histogram(target, bins=nbins, range=(mini, maxi))
+    area_union = area_pred + area_lab - area_inter
+    assert (area_inter > area_union).sum() == 0, "Intersection area should be smaller than Union area"
+    return area_inter.astype(np.float32), area_union.astype(np.float32)
+
+def main():
+    """
+    read pipeline and do infer
+    """
+
+    args = parse_args()
+
+    # init stream manager
+    stream_manager_api = StreamManagerApi()
+    ret = stream_manager_api.InitManager()
+    if ret != 0:
+        print("Failed to init Stream manager, ret=%s" % str(ret))
+        return
+
+    # create streams by pipeline config file
+    with open(os.path.realpath(args.pipeline), 'rb') as f:
+        pipeline_str = f.read()
+    ret = stream_manager_api.CreateMultipleStreams(pipeline_str)
+    if ret != 0:
+        print("Failed to create Stream, ret=%s" % str(ret))
+        return
+
+    stream_name = b'fastscnn'
+    infer_total_time = 0
+    assert os.path.exists(args.image_path), "Please put dataset in " + str(args.image_path)
+    images, mask_paths = _get_city_pairs(args.image_path, 'val')
+    assert len(images) == len(mask_paths)
+    if not images:
+        raise RuntimeError("Found 0 images in subfolders of:" + args.image_path + "\n")
+
+    if args.save_mask and not os.path.exists(args.mask_result_path):
+        os.makedirs(args.mask_result_path)
+    metric = SegmentationMetric(19)
+    metric.reset()
+    for index in range(len(images)):
+        image_name = images[index].split(os.sep)[-1].split(".")[0]  # get the name of image file
+        print("Processing ---> ", image_name)
+        img = Image.open(images[index]).convert('RGB')
+        mask = Image.open(mask_paths[index])
+        img, mask = _val_sync_transform((args.image_height, args.image_width), img, mask)
+
+        img = img.astype(np.float32)
+        mask = mask.astype(np.int32)
+        mean = [0.485, 0.456, 0.406]
+        std = [0.229, 0.224, 0.225]
+        img = img.transpose((2, 0, 1))#HWC->CHW
+        for channel, _ in enumerate(img):
+            # Normalization
+            img[channel] /= 255
+            img[channel] -= mean[channel]
+            img[channel] /= std[channel]
+
+        img = np.expand_dims(img, 0)#NCHW
+        mask = np.expand_dims(mask, 0)#NHW
+
+        if not send_source_data(0, img, stream_name, stream_manager_api):
+            return
+        # Obtain the inference result by specifying streamName and uniqueId.
+        key_vec = StringVector()
+        key_vec.push_back(b'modelInfer')
+        start_time = time.time()
+        infer_result = stream_manager_api.GetProtobuf(stream_name, 0, key_vec)
+        infer_total_time += time.time() - start_time
+        if infer_result.size() == 0:
+            print("inferResult is null")
+            return
+        if infer_result[0].errorCode != 0:
+            print("GetProtobuf error. errorCode=%d" % (infer_result[0].errorCode))
+            return
+        result = MxpiDataType.MxpiTensorPackageList()
+        result.ParseFromString(infer_result[0].messageBuf)
+        res = np.frombuffer(result.tensorPackageVec[0].tensorVec[0].dataStr, dtype='<f4')
+        mask_image = res.reshape(1, 19, args.image_height, args.image_width)
+
+        metric.update(mask_image, mask)
+        pixAcc, mIoU = metric.get()
+        print("[EVAL] Sample: {:d}, pixAcc: {:.3f}, mIoU: {:.3f}".format(index + 1, pixAcc * 100, mIoU * 100))
+        if args.save_mask:
+            output = np.argmax(mask_image[0], axis=0)
+            out_img = Image.fromarray(output.astype('uint8'))
+            out_img.putpalette(cityspallete)
+            outname = str(image_name) + '.png'
+            out_img.save(os.path.join(args.mask_result_path, outname))
+
+    pixAcc, mIoU, category_iou = metric.get(return_category_iou=True)
+    print('End validation pixAcc: {:.3f}, mIoU: {:.3f}'.format(pixAcc * 100, mIoU * 100))
+    txtName = os.path.join(args.mask_result_path, "eval_results.txt")
+    with open(txtName, "w") as f:
+        string = 'validation pixAcc:' + str(pixAcc * 100) + ', mIoU:' + str(mIoU * 100)
+        f.write(string)
+        f.write('\n')
+        headers = ['class id', 'class name', 'iou']
+        table = []
+        for i, cls_name in enumerate(classes):
+            table.append([cls_name, category_iou[i]])
+            string = 'class name: ' + cls_name + ' iou: ' + str(category_iou[i]) + '\n'
+            f.write(string)
+        print('Category iou: \n {}'.format(tabulate(table, headers, \
+                               tablefmt='grid', showindex="always", numalign='center', stralign='center')))
+    print("Testing finished....")
+    print("=======================================")
+    print("The total time of inference is {} s".format(infer_total_time))
+    print("=======================================")
+
+    # destroy streams
+    stream_manager_api.DestroyAllStreams()
+
+if __name__ == '__main__':
+    main()
diff --git a/official/cv/fastscnn/infer/sdk/run.sh b/official/cv/fastscnn/infer/sdk/run.sh
new file mode 100644
index 0000000000000000000000000000000000000000..2c73eefeb82c7b14036813bb2115a64435d288ff
--- /dev/null
+++ b/official/cv/fastscnn/infer/sdk/run.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+# Copyright 2021 Huawei Technologies Co., Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============================================================================
+
+image_width=768
+image_height=768
+save_mask=1
+mask_result_path=./mask_result
+# help message
+if [[ $1 == --help || $1 == -h ]];then
+    echo "usage:bash ./run.sh <args>"
+    echo "parameter explain:
+    --pipeline          set SDK infer pipeline, e.g. --pipeline=../data/config/fastscnn.pipeline
+    --image_path        root path of processed images, e.g. --image_path=../data/
+    --image_width       set the image width,  default: --image_width=768
+    --image_height      set the image height, default: --image_height=768
+    --save_mask         whether to save the semantic mask images, 0 for False, 1 for True, default: --save_mask=1
+    --mask_result_path  the folder to save the semantic mask images, default: --mask_result_path=./mask_result
+    -h/--help           show help message
+    "
+    exit 1
+fi
+
+for para in "$@"
+do
+    if [[ $para == --pipeline* ]];then
+        pipeline=`echo ${para#*=}`
+    elif [[ $para == --image_path* ]];then
+        image_path=`echo ${para#*=}`
+    elif [[ $para == --image_width* ]];then
+        image_width=`echo ${para#*=}`
+    elif [[ $para == --image_height* ]];then
+        image_height=`echo ${para#*=}`
+    elif [[ $para == --save_mask* ]];then
+        save_mask=`echo ${para#*=}`
+    elif [[ $para == --mask_result_path* ]];then
+        mask_result_path=`echo ${para#*=}`
+    fi
+done
+
+if [[ $pipeline  == "" ]];then
+   echo "[Error] para \"pipeline \" must be config"
+   exit 1
+fi
+if [[ $image_path  == "" ]];then
+   echo "[Error] para \"image_path \" must be config"
+   exit 1
+fi
+
+python3 main.py --pipeline=$pipeline \
+                  --image_path=$image_path \
+                  --image_width=$image_width \
+                  --image_height=$image_height \
+                  --save_mask=$save_mask \
+                  --mask_result_path=$mask_result_path
+
+exit 0
diff --git a/official/cv/fastscnn/modelarts/start_train.py b/official/cv/fastscnn/modelarts/start_train.py
new file mode 100644
index 0000000000000000000000000000000000000000..57efcf596cc4619de6b10df8b603938c99ee3089
--- /dev/null
+++ b/official/cv/fastscnn/modelarts/start_train.py
@@ -0,0 +1,239 @@
+# Copyright 2021 Huawei Technologies Co., Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# ============================================================================
+'''train scripts for modelarts'''
+import os
+import argparse
+import datetime
+import moxing as mox
+import numpy as np
+
+import mindspore
+import mindspore.nn as nn
+from mindspore import export
+from mindspore import context
+from mindspore.train import Model
+from mindspore.dataset import config
+from mindspore.common import set_seed
+from mindspore.common.tensor import Tensor
+from mindspore.context import ParallelMode
+from mindspore import FixedLossScaleManager
+from mindspore import load_checkpoint, load_param_into_net
+from mindspore.dataset.transforms.py_transforms import Compose
+from mindspore.dataset.vision.py_transforms import ToTensor, Normalize
+from mindspore.communication.management import init, get_rank, get_group_size
+from mindspore.train.callback import TimeMonitor, LossMonitor, CheckpointConfig, ModelCheckpoint
+
+from src.logger import get_logger
+from src.lr_scheduler import LRScheduler
+from src.dataloader import create_CitySegmentation
+from src.fast_scnn import FastSCNN, FastSCNNWithLossCell
+from src.util import SegmentationMetric, EvalCallBack, TempLoss
+
+def parse_args():
+    """Training Options for Segmentation Experiments"""
+    parser = argparse.ArgumentParser(description='Fast-SCNN on mindspore')
+    parser.add_argument('--dataset', type=str, default='/data/dataset/citys/',
+                        help='dataset name (default: /data/dataset/citys/)')
+    parser.add_argument('--base_size', type=int, default=1024, help='base image size')
+    parser.add_argument('--crop_size', type=int, default=(768, 768), help='crop image size')
+    parser.add_argument('--train_split', type=str, default='train',
+                        help='dataset train split (default: train)')
+    parser.add_argument('--aux', action='store_true', default=True, help='Auxiliary loss')
+    parser.add_argument('--aux_weight', type=float, default=0.4,
+                        help='auxiliary loss weight')
+    parser.add_argument('--epochs', type=int, default=1000, metavar='N',
+                        help='number of epochs to train (default: 1000)')
+    parser.add_argument('--save_every', type=int, default=1, metavar='N',
+                        help='save ckpt every N epoch')
+    parser.add_argument('--resume_path', type=str, default=None,
+                        help='put the path to resuming file if needed')
+    parser.add_argument('--resume_name', type=str, default=None,
+                        help='resuming file name')
+    parser.add_argument('--batch_size', type=int, default=2, metavar='N',
+                        help='input batch size for training (default: 2)')
+    parser.add_argument('--lr', type=float, default=0.001, metavar='LR',
+                        help='base learning rate (default: 0.045)')
+    parser.add_argument('--momentum', type=float, default=0.9, metavar='M',
+                        help='momentum (default: 0.9)')
+    parser.add_argument('--weight_decay', type=float, default=4e-5, metavar='M',
+                        help='w-decay (default: 4e-5)')
+
+    parser.add_argument('--eval_while_train', type=int, default=1, help='eval while training')
+    parser.add_argument('--eval_steps', type=int, default=10, help='each N epochs we eval')
+    parser.add_argument('--eval_start_epoch', type=int, default=850, help='eval_start_epoch')
+    parser.add_argument('--train_url', type=str, default='train_url/',
+                        help='needed by modelarts, but we donot use it because the name is ambiguous')
+    parser.add_argument('--data_url', type=str, default='data_url/',
+                        help='needed by modelarts, but we donot use it because the name is ambiguous')
+    parser.add_argument('--output_path', type=str, default='cache/output/',
+                        help='output_path, default is cache/output/')
+    parser.add_argument('--outer_path', type=str, default='s3://output/',
+                        help='obs path,to store e.g ckpt files ')
+    parser.add_argument("--file_format", type=str, choices=["AIR", "ONNX", "MINDIR"], \
+                        default="AIR", help="file format")
+
+    parser.add_argument('--device_target', type=str, default='Ascend',
+                        help='device where the code will be implemented. (Default: Ascend)')
+    parser.add_argument('--is_distributed', type=int, default=0, help='if multi device')
+    parser.add_argument('--rank', type=int, default=0, help='local rank of distributed')
+    parser.add_argument('--group_size', type=int, default=1, help='world size of distributed')
+    parser.add_argument('--is_save_on_master', type=int, default=1,
+                        help='save ckpt on master or all rank')
+    parser.add_argument('--ckpt_save_max', type=int, default=800,
+                        help='Maximum number of checkpoint files can be saved. Default: 800')
+    # the parser
+    args_ = parser.parse_args()
+    return args_
+
+args = parse_args()
+set_seed(1)
+device_id = int(os.getenv('DEVICE_ID', '0'))
+context.set_context(mode=context.GRAPH_MODE, device_target=args.device_target, save_graphs=False)
+save_dir = os.path.join(args.output_path, datetime.datetime.now().strftime('%Y-%m-%d_time_%H_%M_%S'))
+
+
+def copy_data_from_obs():
+    args.logger.info("copying dataset from obs to cache....")
+    mox.file.copy_parallel(args.dataset, 'cache/dataset')
+    args.logger.info("copying dataset finished....")
+    args.dataset = 'cache/dataset/'
+
+    # resume checkpoint if needed
+    if args.resume_path:
+        args.logger.info("copying resume checkpoint from obs to cache....")
+        mox.file.copy_parallel(args.resume_path, 'cache/resume_path')
+        args.logger.info("copying resume checkpoint finished....")
+        args.resume_path = 'cache/resume_path/'
+
+def copy_data_to_obs():
+    args.logger.info("copying files from cache to obs....")
+    mox.file.copy_parallel(save_dir, args.outer_path)
+    args.logger.info("copying finished....")
+
+def export_models():
+    args.logger.info("exporting model....")
+    net = FastSCNN(num_classes=19, aux=args.aux)
+    param_dict = load_checkpoint(os.path.join(save_dir, str(args.rank) + "_best_map.ckpt"))
+    load_param_into_net(net, param_dict)
+    input_arr = Tensor(np.zeros([1, 3, \
+                                args.crop_size[0], args.crop_size[1]]), mindspore.float32)
+    export(net, input_arr, file_name=os.path.join(save_dir, str(args.rank) + "_best_map"), \
+           file_format=args.file_format)
+    args.logger.info("export model finished....")
+
+def train():
+    '''train'''
+    # image transform
+    input_transform = Compose([
+        ToTensor(),
+        Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
+    ])
+
+    train_dataset, args.steps_per_epoch = create_CitySegmentation(args, data_path=args.dataset, \
+                        split=args.train_split, mode='train', transform=input_transform, \
+                        base_size=args.base_size, crop_size=args.crop_size, batch_size=args.batch_size, \
+                        device_num=args.group_size, rank=args.rank, shuffle=True)
+
+    # create network
+    f_model = FastSCNN(num_classes=19, aux=args.aux)
+
+    # resume checkpoint if needed
+    if args.resume_path:
+        args.resume_path = os.path.join(args.resume_path, args.resume_name)
+        args.logger.info('loading resume checkpoint {} into network'.format(args.resume_path))
+        load_param_into_net(f_model, load_checkpoint(args.resume_path))
+        args.logger.info('loaded resume checkpoint {} into network'.format(args.resume_path))
+
+    model = FastSCNNWithLossCell(f_model, args)
+    model.set_train()
+
+    # lr scheduling
+    lr_list = LRScheduler(mode='cosine', base_lr=args.lr, nepochs=args.epochs, \
+              iters_per_epoch=args.steps_per_epoch, power=0.9)(args.epochs*args.steps_per_epoch)
+
+    # optimizer
+    optimizer = nn.SGD(params=model.trainable_params(), momentum=args.momentum, \
+                       learning_rate=Tensor(lr_list, mindspore.float32), \
+                       weight_decay=args.weight_decay, loss_scale=1024)
+    loss_scale = FixedLossScaleManager(1024, drop_overflow_update=False)
+    model = Model(model, optimizer=optimizer, loss_scale_manager=loss_scale, amp_level="O0")
+
+    # define callbacks
+    if args.rank == 0:
+        time_cb = TimeMonitor(data_size=args.steps_per_epoch)
+        loss_cb = LossMonitor()
+        callbacks = [time_cb, loss_cb]
+    else:
+        callbacks = []
+
+    if args.rank_save_ckpt_flag:
+        ckpt_config = CheckpointConfig(save_checkpoint_steps=args.steps_per_epoch*args.save_every,
+                                       keep_checkpoint_max=args.ckpt_save_max)
+        save_ckpt_path = os.path.join(save_dir, 'ckpt_' + str(args.rank) + '/')
+        ckpt_cb = ModelCheckpoint(config=ckpt_config,
+                                  directory=save_ckpt_path,
+                                  prefix='rank_'+str(args.rank))
+        callbacks.append(ckpt_cb)
+
+    if args.eval_while_train:
+
+        val_dataset, _ = create_CitySegmentation(args, data_path=args.dataset, \
+                                       split='val', mode='val', transform=input_transform, \
+                                       base_size=args.base_size, crop_size=args.crop_size, \
+                                       batch_size=1, device_num=1, \
+                                       rank=args.rank, shuffle=False)
+        loss_f = TempLoss()
+        network_eval = Model(f_model, loss_fn=loss_f, metrics={"SegmentationMetric": SegmentationMetric(19)})
+
+        eval_cb = EvalCallBack(network_eval, val_dataset, interval=args.eval_steps,
+                               eval_start_epoch=args.eval_start_epoch, save_best_ckpt=True,
+                               ckpt_directory=save_dir, besk_ckpt_name=str(args.rank) + "_best_map.ckpt",
+                               metrics_name=("pixAcc", "mIou"))
+        callbacks.append(eval_cb)
+
+    model.train(args.epochs, train_dataset, callbacks=callbacks, dataset_sink_mode=True)
+    args.logger.info("training finished....")
+
+if __name__ == '__main__':
+    if args.is_distributed:
+        assert args.device_target == "Ascend"
+        context.set_context(device_id=device_id)
+        init()
+        args.rank = get_rank()
+        args.group_size = get_group_size()
+        device_num = args.group_size
+        context.reset_auto_parallel_context()
+        context.set_auto_parallel_context(device_num=device_num, parallel_mode=ParallelMode.DATA_PARALLEL)
+    else:
+        if args.device_target in ["Ascend", "GPU"]:
+            context.set_context(device_id=device_id)
+
+    # select for master rank save ckpt or all rank save, compatible for model parallel
+    args.rank_save_ckpt_flag = 0
+    if args.is_save_on_master:
+        if args.rank == 0:
+            args.rank_save_ckpt_flag = 1
+    else:
+        args.rank_save_ckpt_flag = 1
+
+    config.set_enable_shared_mem(False)
+    args.logger = get_logger(save_dir, "Fast_SCNN", args.rank)
+    args.logger.save_args(args)
+
+    print('Starting training, Total Epochs: %d' % (args.epochs))
+    copy_data_from_obs()
+    train()
+    export_models()
+    copy_data_to_obs()
diff --git a/official/cv/fastscnn/preprocess.py b/official/cv/fastscnn/preprocess.py
index 5a5ff78f0425871cf83cfddf5f1b0eda7ca9ae23..574b439c55fcf237e1b6011c4bb8424df2e45cc3 100644
--- a/official/cv/fastscnn/preprocess.py
+++ b/official/cv/fastscnn/preprocess.py
@@ -119,7 +119,7 @@ def crop_imageAndLabel(out_dir, image_path, image_height, image_width):
     if not os.path.exists(os.path.join(out_dir, "labels")):
         os.makedirs(os.path.join(out_dir, "labels"))
 
-    assert os.path.exists(image_path), "Please put dataset in {SEG_ROOT}/datasets/cityscapes"
+    assert os.path.exists(image_path), "Please put dataset in " + str(image_path)
     images, mask_paths = _get_city_pairs(image_path, 'val')
     assert len(images) == len(mask_paths)
     if not images:
diff --git a/official/cv/fastscnn/score.py b/official/cv/fastscnn/score.py
deleted file mode 100644
index ff820b377f2cea0fde40f8de9f8cf8ed007e1506..0000000000000000000000000000000000000000
--- a/official/cv/fastscnn/score.py
+++ /dev/null
@@ -1,160 +0,0 @@
-# Copyright 2021 Huawei Technologies Co., Ltd
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ============================================================================
-"""Evaluation Metrics for Semantic Segmentation"""
-import numpy as np
-
-__all__ = ['SegmentationMetric', 'batch_pix_accuracy', 'batch_intersection_union',
-           'pixelAccuracy', 'intersectionAndUnion', 'hist_info', 'compute_score']
-
-class SegmentationMetric():
-    """Computes pixAcc and mIoU metric scores
-    """
-
-    def __init__(self, nclass):
-        super(SegmentationMetric, self).__init__()
-        self.nclass = nclass
-        self.reset()
-
-    def update(self, preds, labels):
-        """Updates the internal evaluation result.
-
-        Parameters
-        ----------
-        labels : 'NumpyArray' or list of `NumpyArray`
-            The labels of the data.
-        preds : 'NumpyArray' or list of `NumpyArray`
-            Predicted values.
-        """
-        def evaluate_worker(self, pred, label):
-            correct, labeled = batch_pix_accuracy(pred, label)
-            inter, union = batch_intersection_union(pred, label, self.nclass)
-            self.total_correct += correct
-            self.total_label += labeled
-            self.total_inter += inter
-            self.total_union += union
-        evaluate_worker(self, preds, labels)
-
-    def get(self, return_category_iou=False):
-        """Gets the current evaluation result.
-
-        Returns
-        -------
-        metrics : tuple of float
-            pixAcc and mIoU
-        """
-        # remove np.spacing(1)
-        pixAcc = 1.0 * self.total_correct / (2.220446049250313e-16 + self.total_label)
-        IoU = 1.0 * self.total_inter / (2.220446049250313e-16 + self.total_union)
-        mIoU = IoU.mean().item()
-        if return_category_iou:
-            return pixAcc, mIoU, IoU
-        return pixAcc, mIoU
-
-    def reset(self):
-        """Resets the internal evaluation result to initial state."""
-        self.total_inter = np.zeros(self.nclass)
-        self.total_union = np.zeros(self.nclass)
-        self.total_correct = 0
-        self.total_label = 0
-
-def batch_pix_accuracy(output, target):
-    """PixAcc"""
-    # inputs are numpy array, output 4D NCHW where 'C' means label classes, target 3D NHW
-
-    predict = np.argmax(output.astype(np.int64), 1) + 1
-    target = target.astype(np.int64) + 1
-    pixel_labeled = (target > 0).sum()
-    pixel_correct = ((predict == target) * (target > 0)).sum()
-    assert pixel_correct <= pixel_labeled, "Correct area should be smaller than Labeled"
-    return pixel_correct, pixel_labeled
-
-def batch_intersection_union(output, target, nclass):
-    """mIoU"""
-    # inputs are numpy array, output 4D, target 3D
-    mini = 1
-    maxi = nclass
-    nbins = nclass
-    predict = np.argmax(output.astype(np.float32), 1) + 1
-    target = target.astype(np.float32) + 1
-
-    predict = predict.astype(np.float32) * (target > 0).astype(np.float32)
-    intersection = predict * (predict == target).astype(np.float32)
-    # areas of intersection and union
-    # element 0 in intersection occur the main difference from np.bincount. set boundary to -1 is necessary.
-    area_inter, _ = np.histogram(intersection, bins=nbins, range=(mini, maxi))
-    area_pred, _ = np.histogram(predict, bins=nbins, range=(mini, maxi))
-    area_lab, _ = np.histogram(target, bins=nbins, range=(mini, maxi))
-    area_union = area_pred + area_lab - area_inter
-    assert (area_inter > area_union).sum() == 0, "Intersection area should be smaller than Union area"
-    return area_inter.astype(np.float32), area_union.astype(np.float32)
-
-
-def pixelAccuracy(imPred, imLab):
-    """
-    This function takes the prediction and label of a single image, returns pixel-wise accuracy
-    To compute over many images do:
-    for i = range(Nimages):
-         (pixel_accuracy[i], pixel_correct[i], pixel_labeled[i]) = \
-            pixelAccuracy(imPred[i], imLab[i])
-    mean_pixel_accuracy = 1.0 * np.sum(pixel_correct) / (np.spacing(1) + np.sum(pixel_labeled))
-    """
-    # Remove classes from unlabeled pixels in gt image.
-    # We should not penalize detections in unlabeled portions of the image.
-    pixel_labeled = np.sum(imLab >= 0)
-    pixel_correct = np.sum((imPred == imLab) * (imLab >= 0))
-    pixel_accuracy = 1.0 * pixel_correct / pixel_labeled
-    return (pixel_accuracy, pixel_correct, pixel_labeled)
-
-
-def intersectionAndUnion(imPred, imLab, numClass):
-    """
-    This function takes the prediction and label of a single image,
-    returns intersection and union areas for each class
-    To compute over many images do:
-    for i in range(Nimages):
-        (area_intersection[:,i], area_union[:,i]) = intersectionAndUnion(imPred[i], imLab[i])
-    IoU = 1.0 * np.sum(area_intersection, axis=1) / np.sum(np.spacing(1)+area_union, axis=1)
-    """
-    # Remove classes from unlabeled pixels in gt image.
-    # We should not penalize detections in unlabeled portions of the image.
-    imPred = imPred * (imLab >= 0)
-
-    # Compute area intersection:
-    intersection = imPred * (imPred == imLab)
-    (area_intersection, _) = np.histogram(intersection, bins=numClass, range=(1, numClass))
-
-    # Compute area union:
-    (area_pred, _) = np.histogram(imPred, bins=numClass, range=(1, numClass))
-    (area_lab, _) = np.histogram(imLab, bins=numClass, range=(1, numClass))
-    area_union = area_pred + area_lab - area_intersection
-    return (area_intersection, area_union)
-
-
-def hist_info(pred, label, num_cls):
-    assert pred.shape == label.shape
-    k = (label >= 0) & (label < num_cls)
-    labeled = np.sum(k)
-    correct = np.sum((pred[k] == label[k]))
-
-    return np.bincount(num_cls * label[k].astype(int) + pred[k], \
-            minlength=num_cls ** 2).reshape(num_cls, num_cls), labeled, correct
-
-def compute_score(hist, correct, labeled):
-    iu = np.diag(hist) / (hist.sum(1) + hist.sum(0) - np.diag(hist))
-    mean_IU = np.nanmean(iu)
-    mean_IU_no_back = np.nanmean(iu[1:])
-    mean_pixel_acc = correct / labeled
-
-    return iu, mean_IU, mean_IU_no_back, mean_pixel_acc
diff --git a/official/cv/fastscnn/scripts/docker_start.sh b/official/cv/fastscnn/scripts/docker_start.sh
new file mode 100644
index 0000000000000000000000000000000000000000..e39553192b435f70dae6aa6b6adbfd6ffe901b40
--- /dev/null
+++ b/official/cv/fastscnn/scripts/docker_start.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# Copyright 2021 Huawei Technologies Co., Ltd
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.mitations under the License.
+
+docker_image=$1
+data_dir=$2
+model_dir=$3
+
+docker run -it --ipc=host \
+              --device=/dev/davinci0 \
+              --device=/dev/davinci1 \
+              --device=/dev/davinci2 \
+              --device=/dev/davinci3 \
+              --device=/dev/davinci4 \
+              --device=/dev/davinci5 \
+              --device=/dev/davinci6 \
+              --device=/dev/davinci7 \
+              --device=/dev/davinci_manager \
+              --device=/dev/devmm_svm --device=/dev/hisi_hdc \
+              -v /usr/local/Ascend/driver:/usr/local/Ascend/driver \
+              -v /usr/local/Ascend/add-ons/:/usr/local/Ascend/add-ons/ \
+              -v ${model_dir}:${model_dir} \
+              -v ${data_dir}:${data_dir}  \
+              -v /root/ascend/log:/root/ascend/log ${docker_image} /bin/bash
\ No newline at end of file
diff --git a/official/cv/fastscnn/scripts/run_distribute_train.sh b/official/cv/fastscnn/scripts/run_distribute_train.sh
index 499b4a621dff15539165f57e6ab1787201ecd3c5..dab1c97c3709cbb35af47c4175e3a037271267aa 100644
--- a/official/cv/fastscnn/scripts/run_distribute_train.sh
+++ b/official/cv/fastscnn/scripts/run_distribute_train.sh
@@ -14,9 +14,9 @@
 # limitations under the License.
 # ============================================================================
 
-if [ $# != 6 ]; then
+if [ $# != 7 ]; then
   echo "Usage: sh run_distribute_train.sh [train_code_path] [dataset]" \
-       "[epochs] [batch_size] [lr] [output_path]"
+       "[epochs] [batch_size] [lr] [output_path] [rank_table_file_path]"
   exit 1
 fi
 
@@ -50,11 +50,10 @@ fi
 
 ulimit -c unlimited
 export SLOG_PRINT_TO_STDOUT=0
-export RANK_TABLE_FILE=${train_code_path}scripts/hccl_8p_01234567_10.155.170.118.json
+export RANK_TABLE_FILE=${7}
 export RANK_SIZE=8
 export RANK_START_ID=0
 
-
 for((i=0;i<=$RANK_SIZE-1;i++));
 do
     export RANK_ID=${i}
@@ -65,7 +64,7 @@ do
     fi
     mkdir ${train_code_path}/device${DEVICE_ID}
     cd ${train_code_path}/device${DEVICE_ID} || exit
-    nohup python ${train_code_path}train.py --is_distributed=1 \
+    nohup python ${train_code_path}train.py --is_distributed=1 --device_target=Ascend \
     --dataset=${dataset} \
     --epochs=$3 \
     --batch_size=$4 \
diff --git a/official/cv/fastscnn/src/dataloader.py b/official/cv/fastscnn/src/dataloader.py
index 88d941af3692a5c10248d3e279561389a38afd07..6868b2baa8f091b4ba9b2669da770c1058a367d7 100644
--- a/official/cv/fastscnn/src/dataloader.py
+++ b/official/cv/fastscnn/src/dataloader.py
@@ -21,8 +21,6 @@ import mindspore.dataset as ds
 import mindspore.dataset.vision.c_transforms as CV
 
 from src.seg_data_base import SegmentationDataset
-from src.distributed_sampler import DistributedSampler
-
 
 __all__ = ['CitySegmentation']
 
@@ -162,20 +160,17 @@ def create_CitySegmentation(args, data_path='../dataset/', split='train', mode=N
     '''create_CitySegmentation'''
     dataset = CitySegmentation(args, root=data_path, split=split, mode=mode, \
                                base_size=base_size, crop_size=crop_size)
-    dataset_len = len(dataset)
-    distributed_sampler = DistributedSampler(dataset_len, device_num, rank, shuffle=shuffle)
-
     data_set = ds.GeneratorDataset(dataset, column_names=["image", "label"], num_parallel_workers=8, \
-                                   shuffle=shuffle, sampler=distributed_sampler)
+                                   shuffle=shuffle, num_shards=device_num, shard_id=rank)
     # general resize, normalize and toTensor
     if transform is not None:
         data_set = data_set.map(input_columns=["image"], operations=transform, num_parallel_workers=8)
     else:
         hwc_to_chw = CV.HWC2CHW()
         data_set = data_set.map(input_columns=["image"], operations=hwc_to_chw, num_parallel_workers=8)
-
     data_set = data_set.batch(batch_size, drop_remainder=True)
-    return data_set, dataset_len
+
+    return data_set, data_set.get_dataset_size()
 
 if __name__ == '__main__':
 
diff --git a/official/cv/fastscnn/src/distributed_sampler.py b/official/cv/fastscnn/src/distributed_sampler.py
deleted file mode 100644
index 11c4eff96fb1e8b3f3b6e702fd520874adf3183d..0000000000000000000000000000000000000000
--- a/official/cv/fastscnn/src/distributed_sampler.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright 2021 Huawei Technologies Co., Ltd
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# ============================================================================
-"""distributed sampler."""
-from __future__ import division
-import math
-import numpy as np
-
-
-class DistributedSampler:
-    """Distributed sampler."""
-    def __init__(self, dataset_size, num_replicas=None, rank=None, shuffle=True):
-        if num_replicas is None:
-            print("***********Setting world_size to 1 since it is not passed in ******************")
-            num_replicas = 1
-        if rank is None:
-            print("***********Setting rank to 0 since it is not passed in ******************")
-            rank = 0
-        self.dataset_size = dataset_size
-        self.num_replicas = num_replicas
-        self.rank = rank
-        self.epoch = 0
-        self.num_samples = int(math.ceil(dataset_size * 1.0 / self.num_replicas))
-        self.total_size = self.num_samples * self.num_replicas
-        self.shuffle = shuffle
-
-    def __iter__(self):
-        # deterministically shuffle based on epoch
-        if self.shuffle:
-            indices = np.random.RandomState(seed=self.epoch).permutation(self.dataset_size)
-            # np.array type. number from 0 to len(dataset_size)-1, used as index of dataset
-            indices = indices.tolist()
-            self.epoch += 1
-            # change to list type
-        else:
-            indices = list(range(self.dataset_size))
-
-        # add extra samples to make it evenly divisible
-        indices += indices[:(self.total_size - len(indices))]
-        assert len(indices) == self.total_size
-
-        # subsample
-        indices = indices[self.rank:self.total_size:self.num_replicas]
-        assert len(indices) == self.num_samples
-
-        return iter(indices)
-
-    def __len__(self):
-        return self.num_samples
diff --git a/official/cv/fastscnn/src/fast_scnn.py b/official/cv/fastscnn/src/fast_scnn.py
index 3f7accabd3376e35a4dc507169593f917a95cd57..d4cb4441d2c06dd6e78a4a4e1c8b69188050605a 100644
--- a/official/cv/fastscnn/src/fast_scnn.py
+++ b/official/cv/fastscnn/src/fast_scnn.py
@@ -256,7 +256,8 @@ class FastSCNNWithLossCell(nn.Cell):
         super(FastSCNNWithLossCell, self).__init__()
         self.network = network
         self.aux = args.aux
-        self.loss = MixSoftmaxCrossEntropyLoss(args, aux=args.aux, aux_weight=args.aux_weight)
+        self.loss = MixSoftmaxCrossEntropyLoss(args, aux=args.aux, aux_weight=args.aux_weight,
+                                               one_d_length=args.batch_size*args.crop_size[0]*args.crop_size[1])
     def construct(self, images, targets):
         outputs = self.network(images)
         if self.aux:
diff --git a/official/cv/fastscnn/src/score.py b/official/cv/fastscnn/src/score.py
index 275fcccff895045073d49b675d37097b09c4042e..465c41d6a0c506bbde91f3a5ac778352c410a2c9 100644
--- a/official/cv/fastscnn/src/score.py
+++ b/official/cv/fastscnn/src/score.py
@@ -16,8 +16,7 @@
 import numpy as np
 from mindspore.common.tensor import Tensor
 
-__all__ = ['SegmentationMetric', 'batch_pix_accuracy', 'batch_intersection_union',
-           'pixelAccuracy', 'intersectionAndUnion', 'hist_info', 'compute_score']
+__all__ = ['SegmentationMetric', 'batch_pix_accuracy', 'batch_intersection_union']
 
 class SegmentationMetric():
     """Computes pixAcc and mIoU metric scores
@@ -106,62 +105,3 @@ def batch_intersection_union(output, target, nclass):
     area_union = area_pred + area_lab - area_inter
     assert (area_inter > area_union).sum() == 0, "Intersection area should be smaller than Union area"
     return area_inter.astype(np.float32), area_union.astype(np.float32)
-
-
-def pixelAccuracy(imPred, imLab):
-    """
-    This function takes the prediction and label of a single image, returns pixel-wise accuracy
-    To compute over many images do:
-    for i = range(Nimages):
-         (pixel_accuracy[i], pixel_correct[i], pixel_labeled[i]) = \
-            pixelAccuracy(imPred[i], imLab[i])
-    mean_pixel_accuracy = 1.0 * np.sum(pixel_correct) / (np.spacing(1) + np.sum(pixel_labeled))
-    """
-    # Remove classes from unlabeled pixels in gt image.
-    # We should not penalize detections in unlabeled portions of the image.
-    pixel_labeled = np.sum(imLab >= 0)
-    pixel_correct = np.sum((imPred == imLab) * (imLab >= 0))
-    pixel_accuracy = 1.0 * pixel_correct / pixel_labeled
-    return (pixel_accuracy, pixel_correct, pixel_labeled)
-
-
-def intersectionAndUnion(imPred, imLab, numClass):
-    """
-    This function takes the prediction and label of a single image,
-    returns intersection and union areas for each class
-    To compute over many images do:
-    for i in range(Nimages):
-        (area_intersection[:,i], area_union[:,i]) = intersectionAndUnion(imPred[i], imLab[i])
-    IoU = 1.0 * np.sum(area_intersection, axis=1) / np.sum(np.spacing(1)+area_union, axis=1)
-    """
-    # Remove classes from unlabeled pixels in gt image.
-    # We should not penalize detections in unlabeled portions of the image.
-    imPred = imPred * (imLab >= 0)
-
-    # Compute area intersection:
-    intersection = imPred * (imPred == imLab)
-    (area_intersection, _) = np.histogram(intersection, bins=numClass, range=(1, numClass))
-
-    # Compute area union:
-    (area_pred, _) = np.histogram(imPred, bins=numClass, range=(1, numClass))
-    (area_lab, _) = np.histogram(imLab, bins=numClass, range=(1, numClass))
-    area_union = area_pred + area_lab - area_intersection
-    return (area_intersection, area_union)
-
-
-def hist_info(pred, label, num_cls):
-    assert pred.shape == label.shape
-    k = (label >= 0) & (label < num_cls)
-    labeled = np.sum(k)
-    correct = np.sum((pred[k] == label[k]))
-
-    return np.bincount(num_cls * label[k].astype(int) + pred[k], \
-            minlength=num_cls ** 2).reshape(num_cls, num_cls), labeled, correct
-
-def compute_score(hist, correct, labeled):
-    iu = np.diag(hist) / (hist.sum(1) + hist.sum(0) - np.diag(hist))
-    mean_IU = np.nanmean(iu)
-    mean_IU_no_back = np.nanmean(iu[1:])
-    mean_pixel_acc = correct / labeled
-
-    return iu, mean_IU, mean_IU_no_back, mean_pixel_acc
diff --git a/official/cv/fastscnn/src/util.py b/official/cv/fastscnn/src/util.py
index 36162888d5800c52742c6fe8bd8efee060a6357d..eb1ab7cdc01c54c949eb5c6cb1ee47d4748d8849 100644
--- a/official/cv/fastscnn/src/util.py
+++ b/official/cv/fastscnn/src/util.py
@@ -24,13 +24,7 @@ from mindspore import save_checkpoint
 from mindspore import log as logger
 from mindspore.train.callback import Callback
 from mindspore.common.tensor import Tensor
-
-def apply_eval(eval_param_dict):
-    """run Evaluation"""
-    model = eval_param_dict["model"]
-    dataset = eval_param_dict["dataset"]
-    eval_score = model.eval(dataset, dataset_sink_mode=False)["SegmentationMetric"]
-    return eval_score
+from src.score import batch_pix_accuracy, batch_intersection_union
 
 class TempLoss(nn.Cell):
     """A temp loss cell."""
@@ -63,8 +57,6 @@ class SegmentationMetric(nn.Metric):
         """
         preds, labels = inputs[0], inputs[-1]
         preds = preds[0]
-        #print("preds:",preds)
-        #print("labels:",labels)
         def evaluate_worker(self, pred, label):
             correct, labeled = batch_pix_accuracy(pred.asnumpy(), label.asnumpy())
             inter, union = batch_intersection_union(pred.asnumpy(), label.asnumpy(), self.nclass)
@@ -100,26 +92,26 @@ class EvalCallBack(Callback):
     Evaluation callback when training.
 
     Args:
-        eval_function (function): evaluation function.
-        eval_param_dict (dict): evaluation parameters' configure dict.
+        network (function): evaluation network.
+        dataloader (dict): evaluation dataloader.
         interval (int): run evaluation interval, default is 1.
         eval_start_epoch (int): evaluation start epoch, default is 1.
         save_best_ckpt (bool): Whether to save best checkpoint, default is True.
         besk_ckpt_name (str): bast checkpoint name, default is `best.ckpt`.
-        metrics_name (str): evaluation metrics name, default is `acc`.
+        metrics_name (str): evaluation metrics name, default is ("pixAcc", "mIou").
 
     Returns:
         None
 
     Examples:
-        >>> EvalCallBack(eval_function, eval_param_dict)
+        >>> EvalCallBack(network, dataloader)
     """
 
-    def __init__(self, eval_function, eval_param_dict, interval=1, eval_start_epoch=1, \
-        save_best_ckpt=True, ckpt_directory="./", besk_ckpt_name="best.ckpt", metrics_name="acc"):
+    def __init__(self, network, dataloader, interval=1, eval_start_epoch=1, \
+        save_best_ckpt=True, ckpt_directory="./", besk_ckpt_name="best.ckpt", metrics_name=("pixAcc", "mIou")):
         super(EvalCallBack, self).__init__()
-        self.eval_param_dict = eval_param_dict
-        self.eval_function = eval_function
+        self.network = network
+        self.dataloader = dataloader
         self.eval_start_epoch = eval_start_epoch
         if interval < 1:
             raise ValueError("interval should >= 1.")
@@ -147,7 +139,7 @@ class EvalCallBack(Callback):
         cb_params = run_context.original_args()
         cur_epoch = cb_params.cur_epoch_num
         if cur_epoch >= self.eval_start_epoch and (cur_epoch - self.eval_start_epoch) % self.interval == 0:
-            res = self.eval_function(self.eval_param_dict)
+            res = self.network.eval(self.dataloader, dataset_sink_mode=True)['SegmentationMetric']
             print(datetime.now().strftime('%Y-%m-%d %H:%M:%S,%f')[:-3],\
                   ":INFO: epoch: {}, {}: {}, {}: {}".format(cur_epoch, self.metrics_name[0], \
                   res[0]*100, self.metrics_name[1], res[1]*100), flush=True)
@@ -167,94 +159,3 @@ class EvalCallBack(Callback):
         print(datetime.now().strftime('%Y-%m-%d %H:%M:%S,%f')[:-3],\
         ":INFO: End training, the best {0} is: {1}, it's epoch is {2}".format(self.metrics_name[1],\
                         self.best_res*100, self.best_epoch), flush=True)
-
-def batch_pix_accuracy(output, target):
-    """PixAcc"""
-    # inputs are numpy array, output 4D NCHW where 'C' means label classes, target 3D NHW
-
-    predict = np.argmax(output.astype(np.int64), 1) + 1
-    target = target.astype(np.int64) + 1
-    pixel_labeled = (target > 0).sum()
-    pixel_correct = ((predict == target) * (target > 0)).sum()
-    assert pixel_correct <= pixel_labeled, "Correct area should be smaller than Labeled"
-    return pixel_correct, pixel_labeled
-
-def batch_intersection_union(output, target, nclass):
-    """mIoU"""
-    # inputs are numpy array, output 4D, target 3D
-    mini = 1
-    maxi = nclass
-    nbins = nclass
-    predict = np.argmax(output.astype(np.float32), 1) + 1
-    target = target.astype(np.float32) + 1
-
-    predict = predict.astype(np.float32) * (target > 0).astype(np.float32)
-    intersection = predict * (predict == target).astype(np.float32)
-    # areas of intersection and union
-    # element 0 in intersection occur the main difference from np.bincount. set boundary to -1 is necessary.
-    area_inter, _ = np.histogram(intersection, bins=nbins, range=(mini, maxi))
-    area_pred, _ = np.histogram(predict, bins=nbins, range=(mini, maxi))
-    area_lab, _ = np.histogram(target, bins=nbins, range=(mini, maxi))
-    area_union = area_pred + area_lab - area_inter
-    assert (area_inter > area_union).sum() == 0, "Intersection area should be smaller than Union area"
-    return area_inter.astype(np.float32), area_union.astype(np.float32)
-
-
-def pixelAccuracy(imPred, imLab):
-    """
-    This function takes the prediction and label of a single image, returns pixel-wise accuracy
-    To compute over many images do:
-    for i = range(Nimages):
-         (pixel_accuracy[i], pixel_correct[i], pixel_labeled[i]) = \
-            pixelAccuracy(imPred[i], imLab[i])
-    mean_pixel_accuracy = 1.0 * np.sum(pixel_correct) / (np.spacing(1) + np.sum(pixel_labeled))
-    """
-    # Remove classes from unlabeled pixels in gt image.
-    # We should not penalize detections in unlabeled portions of the image.
-    pixel_labeled = np.sum(imLab >= 0)
-    pixel_correct = np.sum((imPred == imLab) * (imLab >= 0))
-    pixel_accuracy = 1.0 * pixel_correct / pixel_labeled
-    return (pixel_accuracy, pixel_correct, pixel_labeled)
-
-def intersectionAndUnion(imPred, imLab, numClass):
-    """
-    This function takes the prediction and label of a single image,
-    returns intersection and union areas for each class
-    To compute over many images do:
-    for i in range(Nimages):
-        (area_intersection[:,i], area_union[:,i]) = intersectionAndUnion(imPred[i], imLab[i])
-    IoU = 1.0 * np.sum(area_intersection, axis=1) / np.sum(np.spacing(1)+area_union, axis=1)
-    """
-    # Remove classes from unlabeled pixels in gt image.
-    # We should not penalize detections in unlabeled portions of the image.
-    imPred = imPred * (imLab >= 0)
-
-    # Compute area intersection:
-    intersection = imPred * (imPred == imLab)
-    (area_intersection, _) = np.histogram(intersection, bins=numClass, range=(1, numClass))
-
-    # Compute area union:
-    (area_pred, _) = np.histogram(imPred, bins=numClass, range=(1, numClass))
-    (area_lab, _) = np.histogram(imLab, bins=numClass, range=(1, numClass))
-    area_union = area_pred + area_lab - area_intersection
-    return (area_intersection, area_union)
-
-
-def hist_info(pred, label, num_cls):
-    assert pred.shape == label.shape
-    k = (label >= 0) & (label < num_cls)
-    labeled = np.sum(k)
-    correct = np.sum((pred[k] == label[k]))
-
-    return np.bincount(num_cls * label[k].astype(int) + pred[k], minlength=num_cls ** 2).\
-                                   reshape(num_cls, num_cls), labeled, correct
-
-def compute_score(hist, correct, labeled):
-    iu = np.diag(hist) / (hist.sum(1) + hist.sum(0) - np.diag(hist))
-    mean_IU = np.nanmean(iu)
-    mean_IU_no_back = np.nanmean(iu[1:])
-    #freq = hist.sum(1) / hist.sum()
-    # freq_IU = (iu[freq > 0] * freq[freq > 0]).sum()
-    mean_pixel_acc = correct / labeled
-
-    return iu, mean_IU, mean_IU_no_back, mean_pixel_acc
diff --git a/official/cv/fastscnn/train.py b/official/cv/fastscnn/train.py
index a2bca20074422110a9f9f33079c5aab0931be730..125396df6cf5468e11c586b5ad3526778ba0fe41 100644
--- a/official/cv/fastscnn/train.py
+++ b/official/cv/fastscnn/train.py
@@ -14,7 +14,6 @@
 # ============================================================================
 '''train.py'''
 import os
-import math
 import argparse
 import datetime
 
@@ -22,6 +21,7 @@ import mindspore
 import mindspore.nn as nn
 from mindspore import context
 from mindspore.train import Model
+from mindspore.dataset import config
 from mindspore.common import set_seed
 from mindspore.common.tensor import Tensor
 from mindspore.context import ParallelMode
@@ -36,7 +36,7 @@ from src.logger import get_logger
 from src.lr_scheduler import LRScheduler
 from src.dataloader import create_CitySegmentation
 from src.fast_scnn import FastSCNN, FastSCNNWithLossCell
-from src.util import SegmentationMetric, EvalCallBack, apply_eval, TempLoss
+from src.util import SegmentationMetric, EvalCallBack, TempLoss
 
 
 def parse_args():
@@ -106,7 +106,7 @@ def train():
     if args.is_distributed:
         assert args.device_target == "Ascend"
         context.set_context(device_id=device_id)
-        init()
+        init("hccl")
         args.rank = get_rank()
         args.group_size = get_group_size()
         device_num = args.group_size
@@ -116,6 +116,7 @@ def train():
         if args.device_target in ["Ascend", "GPU"]:
             context.set_context(device_id=device_id)
 
+    config.set_enable_shared_mem(False) #we may get OOM when it set to 'True'
     # select for master rank save ckpt or all rank save, compatible for model parallel
     args.rank_save_ckpt_flag = 0
     if args.is_save_on_master:
@@ -140,17 +141,14 @@ def train():
         args.logger.info("copying dataset finished....")
         args.dataset = 'cache/dataset/'
 
-    train_dataset, train_dataset_len = create_CitySegmentation(args, data_path=args.dataset, \
+    train_dataset, args.steps_per_epoch = create_CitySegmentation(args, data_path=args.dataset, \
                         split=args.train_split, mode='train', transform=input_transform, \
                         base_size=args.base_size, crop_size=args.crop_size, batch_size=args.batch_size, \
                         device_num=args.group_size, rank=args.rank, shuffle=True)
 
-    args.steps_per_epoch = math.ceil(train_dataset_len / args.batch_size / args.group_size)
-
     # create network
     f_model = FastSCNN(num_classes=19, aux=args.aux)
 
-    # resume checkpoint if needed
     # resume checkpoint if needed
     if args.resume_path:
         if args.use_modelarts:
@@ -181,7 +179,7 @@ def train():
 
     # define callbacks
     if args.rank == 0:
-        time_cb = TimeMonitor(data_size=train_dataset_len)
+        time_cb = TimeMonitor(data_size=args.steps_per_epoch)
         loss_cb = LossMonitor()
         callbacks = [time_cb, loss_cb]
     else:
@@ -196,7 +194,7 @@ def train():
                                   prefix='rank_'+str(args.rank))
         callbacks.append(ckpt_cb)
 
-    if args.eval_while_train == 1 and args.rank == 0:
+    if args.eval_while_train:
 
         val_dataset, _ = create_CitySegmentation(args, data_path=args.dataset, \
                                        split='val', mode='val', transform=input_transform, \
@@ -206,8 +204,7 @@ def train():
         loss_f = TempLoss()
         network_eval = Model(f_model, loss_fn=loss_f, metrics={"SegmentationMetric": SegmentationMetric(19)})
 
-        eval_param_dict = {"model": network_eval, "dataset": val_dataset}
-        eval_cb = EvalCallBack(apply_eval, eval_param_dict, interval=args.eval_steps,
+        eval_cb = EvalCallBack(network_eval, val_dataset, interval=args.eval_steps,
                                eval_start_epoch=args.eval_start_epoch, save_best_ckpt=True,
                                ckpt_directory=save_dir, besk_ckpt_name="best_map.ckpt",
                                metrics_name=("pixAcc", "mIou"))