12. 附录

12.1. 应用输出协议

12.1.1. 网络传输格式

HBDK 使用 libzmq 进行网络传输。

每一帧数据包含2个 zmq 消息。网络传输中,将先发送当前帧的描述信息(见下一节),然后发送图像文件。详情参见网络协议相关示例代码。

12.1.1.1. 数据协议

HBDK 使用谷歌 Protobuf 协议 2.6.1 版本进行数据编序及序列还原。代码样例中的 Meta.proto 为数据协议的原始文件。

有关谷歌 Protobuf 协议相关参考,参见 Google Protobuf Tutorial

数据协议包含多个文件。本节逐一介绍数据协议定义内容及如何使用这些协议。相关使用信息,参见谷歌 Protobuf 协议及对应代码样例。

12.1.1.1.1. 基本数据结构(common.proto)

矩形帧

message Rect {
required float left = 1;
required float top = 2;
required float right = 3;
required float bottom = 4;
}

Rect 代表矩形区域。

图像

enum ImageFormat{
GRAY = 0;
  YV12 = 1;
  JPEG = 2;
  PNG = 3;
  CR12 = 4;
  BAD = 5;
  NV12 = 6;
  NV21 = 7;
}

message Image {
  required int32 width = 1;
  required int32 height = 2;
  required int32 channel = 3;
  optional int64 time_stamp = 4;
  optional int32 send_mode = 5;
  optional int32 format = 6;
  optional int32 index = 7;
  optional int32 count = 8;
  optional int32 depth = 9;
  optional int32 align = 10;
}

图像属性描述如下:

width

图像宽度

height

图像高度

channel

图像通道数

time_stamp

图像时间戳。单位:毫秒 (ms).

send_mode

指定图像数据发送模式。仅在Network Output模式下可用,其中:

  • 0:发送原始图像

  • 1:隔行取样

  • 2:隔行隔列取样

  • 3:隔行隔列隔帧取样

  • 4:不发送图像

format

图像格式。描述图象时,请使用 ImageFormat。

index

摄像头 ID

count

当前连接摄像头实际数量

depth

像素位深度

align

对齐

ObstacleRaw

enum VehProperty {
  VehProperty_Type = 0;    // 车辆类型,如SUV, Bus等
  VehProperty_Classification = 1;  // 车辆用途分类如救护车,警车等
  VehProperty_Light = 2;
}

enum TrafficLightProperty {
  TlProperty_Type = 0;
  TlProperty_Color = 1;
}

enum TrafficSignProperty {
  TsProperty_Type = 0;
}

enum ObstacleRawModelType {
  ObstacleRawModel_Car = 0;
  ObstacleRawModel_FullCar = 1;
  ObstacleRawModel_Ped = 2;
  ObstacleRawModel_Head = 3;
  ObstacleRawModel_Rare = 4;
  ObstacleRawModel_TrafficSign = 5;
  ObstacleRawModel_TrafficLight = 6;
  ObstacleRawModel_Lane = 7;
  ObstacleRawModel_RoadSign = 10;
}

message ObstacleRaw {
  required Rect rect = 1;
  required float conf = 2;
  required int32 model = 3;  // 应为ObstacleRawModelType之一
  optional int32 source = 4;  // 原始结果应始终为1
  repeated int32 property = 6;  // 输出通道索引
  repeated string property_name = 7;  // 描述属性的字符串
                                         // 例如,交通灯的红色,red
  repeated int32 property_type = 8;  // 描述属性,例如
                                        // 交通灯使用的TlProperty_Color
}

ObstacleRaw 用于描述障碍物的原始信息。例如,车辆,人的类型,置信度(0~100)以及原始检测信息(表示障碍物的长方体)。

每个障碍物包含了一些基本信息,例如 model、conf 等等。包含属性信息的对象,例如道路交通标志分类也会包含 pro:

  • 结构数据(meta_data.proto, meta.proto)

  • 感知结果定义

message StructurePerception {
    repeated CommonProto.ObstacleRaws obstacles_raws = 1;
}

enum DataType {
  DATA_IMG = 0;
}

message DataDescriptor {
  optional DataType type = 1;
}

message Data {
  required int32 version = 1;
  required int32 frame_id = 2;
  repeated CommonProto.Image image = 3;
  repeated DataDescriptor data_descriptor = 4;

  optional StructurePerception structure_perception = 30;
}

感知结果定义包含如下属性:

version

版本

frame_id

帧ID

image

图像

data_descriptor

数据描述。用于描述随着元数据在以太网中传输的数据

structure_perception

结构信息的感知

元数据定义如下:

message Meta {
  required int32 version = 1;
  required int32 frame_id = 2;
  optional MetaData.Data data = 7;
}

元数据涵盖每一帧图像中的所有描述信息。

12.2. 数据排布

X2/J2 硬件内部为了提高计算效率,其数据使用特殊的排布方式以使得卷积运算中同一批次乘加用到的 feature map 和 kernel 在内存中相邻排放。下面简要介绍 X2/J2 中数据排布(layout)的概念。

神经网络模型中的变量可以用一个4维的张量表示,每个数字是这个张量中的元素,我们称之为自然排布。 将不同维度的不同元素按一定规则紧密排列在一起,形成一个独立的小块(block),然后将这些小块看成新的元素,组成新的4维张量,我们称之为带有数据排布的张量。

X2/J2 的输入输出数据会用到不同的layout数据排布,用户可通过API获取layout描述信息,不同的layout数据不可以直接比较。 用户可自行选择用 X2/J2 编译工具提供的 API 进行数据排布的转换或根据实际场景自行编写高效的数据排布转换代码。 需要注意的是,在进行数据排布转换时,如果需要 padding,则 padding 的值必须为零。

Note

以下示例代码假设源数据已经按照layout的对齐要求进行对齐。例如,NHCW_8W4C排布的数据要求源数据宽度对齐到8,通道数对齐到4。

12.2.1. NHWC_NATIVE排布

另外还有NHCW_NATIVE和NCHW_NATIVE两种排列,他们和NHWC_NATIVE排布只是循环顺序不一样,就不再单独列出了。

下文中提到的native都特指该layout。

数据排布如下:

N0H0W0C0

N0H0W0C1

N0H0W1C0

N0H0W1C1

N0H1W0C0

N0H1W0C1

N1H0W0C0

N1H0W0C1

一个N*H*W*C大小的张量可用如下4重循环表示:

for (int n = 0; n < N; n++) {
  for (int h = 0; h < H; h++) {
    for (int w = 0; w < W; w++) {
      for (int c = 0; c < C; c++) {
        int native_offset = n*H*W*C + h*W*C + w*C + c;
      }
    }
  }
}

12.2.2. NHCW_8W4C排布

数据排布如下:

N0H0C*W*_w0c0~3

N0H0C*W*_w1c0~3

N0H0C*W*_w2c0~3

N0H0C*W*_w7c0~3

N0H0C*W*_w8c0~3

N0H0C*W*_w9c0~3

N0H0C*W*_w10c0~3

N0H0C*W*_w15c0~3

N0H0C*W*_w0c4~7

N0H0C*W*_w1c4~7

N0H0C*W*_w2c4~7

N0H0C*W*_w7c4~7

N0H0C*W*_w8c4~7

N0H0C*W*_w9c4~7

N0H0C*W*_w10c4~7

N0H0C*W*_w15c4~7

N0H1C*W*_w0c0~3

N0H0C*W*_w1c0~3

N0H1C*W*_w2c0~3

N0H1C*W*_w7c0~3

N1H0C*W*_w0c0~3

N1H0C*W*_w1c0~3

N1H0C*W*_w2c0~3

N1H0C*W*_w7c0~3

一个N*H*W*C大小的张量可用如下6重循环表示:

for (int n = 0; n < N; n++) {
  for (int h = 0; h < H; h++) {
    for (int c1 = 0; c1 < ceil(C/4); c1++) {
      for (int w1 = 0; w1 < ceil(W/8); w1++) {
        // in the block
        for (int w2 = 0; w2 < 8; w2++) {
          for (int c2 = 0; c2 < 4; c2++) {
            int native_offset = n*H*W*C + h*W*C + (w1*8 + w2)*C + c1*4 + c2;
            int layout_offset = n*H*W*C + h*W*C + c1*W*4 + w1*8*4 + w2*4 + c2;
            // layout_data[layout_offset] = native_data[native_offset];
            // native_data[native_offset] = layout_data[layout_offset];
          }
        }
      }
    }
  }
}

12.2.3. NHCW_8W4C_S2D排布

数据排布如下:

N0H0C*W*_w0c0~3

N0H0C*W*_w2c0~3

N0H0C*W*_w4c0~3

N0H0C*W*_w14c0~3

N0H0C*W*_w1c0~3

N0H0C*W*_w3c0~3

N0H0C*W*_w5c0~3

N0H0C*W*_w15c0~3

N0H0C*W*_w16c0~3

N0H0C*W*_w18c0~3

N0H0C*W*_w20c0~3

N0H0C*W*_w30c0~3

N0H0C*W*_w17c0~3

N0H0C*W*_w19c0~3

N0H0C*W*_w21c0~3

N0H0C*W*_w31c0~3

N0H0C*W*_w0c4~7

N0H0C*W*_w2c4~7

N0H0C*W*_w4c4~7

N0H0C*W*_w14c4~7

N0H0C*W*_w1c4~7

N0H0C*W*_w3c4~7

N0H0C*W*_w5c4~7

N0H0C*W*_w15c4~7

N0H1C*W*_w0c0~3

N0H1C*W*_w2c0~3

N0H1C*W*_w4c0~3

N0H1C*W*_w14c0~3

N1H0C*W*_w0c0~3

N1H0C*W*_w2c0~3

N1H0C*W*_w4c0~3

N1H0C*W*_w14c0~3

一个N*H*W*C大小的张量可用如下6重循环表示:

for (int n = 0; n < N; n++) {
  for (int h = 0; h < H; h++) {
    for (int c1 = 0; c1 < ceil(C/4); c1++) {
      for (int w1 = 0; w1 < ceil(W/16); w1++) {
        // in the block
        for (int w2 = 0; w2 < 16; w2++) {
          for (int c2 = 0; c2 < 4; c2++) {
            int native_offset = n*H*W*C + h*W*C + (w1*16 + w2)*C + c1*4 + c2;
            int layout_offset = n*H*W*C + h*W*C + c1*W*4 + w1*16*4 + ((w2%2)*8 + (w2/2))*4 + c2;
            // layout_data[layout_offset] = native_data[native_offset];
            // native_data[native_offset] = layout_data[layout_offset];
          }
        }
      }
    }
  }
}

12.2.4. NHCW_16W16C排布

数据排布如下:

N0H0C*W*_w0c0~15

N0H0C*W*_w1c0~15

N0H0C*W*_w2c0~15

N0H0C*W*_w15c0~15

N0H0C*W*_w16c0~15

N0H0C*W*_w17c0~15

N0H0C*W*_w18c0~15

N0H0C*W*_w31c0~15

N0H0C*W*_w0c16~31

N0H0C*W*_w1c16~31

N0H0C*W*_w2c16~31

N0H0C*W*_w15c16~31

N0H0C*W*_w16c16~31

N0H0C*W*_w17c16~31

N0H0C*W*_w18c16~31

N0H0C*W*_w31c16~31

N0H1C*W*_w0c0~15

N0H1C*W*_w1c0~15

N0H1C*W*_w2c0~15

N0H1C*W*_w15c0~15

N1H0C*W*_w0c0~15

N1H0C*W*_w1c0~15

N1H0C*W*_w2c0~15

N1H0C*W*_w15c0~15

一个N*H*W*C大小的张量可用如下6重循环表示:

for (int n = 0; n < N; n++) {
  for (int h = 0; h < H; h++) {
    for (int c1 = 0; c1 < ceil(C/16); c1++) {
      for (int w1 = 0; w1 < ceil(W/16); w1++) {
        // in the block
        for (int w2 = 0; w2 < 16; w2++) {
          for (int c2 = 0; c2 < 16; c2++) {
            int native_offset = n*H*W*C + h*W*C + (w1*16 + w2)*C + c1*16 + c2;
            int layout_offset = n*H*W*C + h*W*C + c1*W*16 + w1*16*16 + w2*16 + c2;
            // layout_data[layout_offset] = native_data[native_offset];
            // native_data[native_offset] = layout_data[layout_offset];
          }
        }
      }
    }
  }
}

12.2.5. NHCW_16W16C_S2D排布

数据排布如下:

N0H0C*W*_w0c0~15

N0H0C*W*_w2c0~15

N0H0C*W*_w4c0~15

N0H0C*W*_w30c0~15

N0H0C*W*_w1c0~15

N0H0C*W*_w3c0~15

N0H0C*W*_w5c0~15

N0H0C*W*_w31c0~15

N0H0C*W*_w32c0~15

N0H0C*W*_w34c0~15

N0H0C*W*_w36c0~15

N0H0C*W*_w62c0~15

N0H0C*W*_w33c0~15

N0H0C*W*_w35c0~15

N0H0C*W*_w37c0~15

N0H0C*W*_w63c0~15

N0H0C*W*_w0c16~31

N0H0C*W*_w2c16~31

N0H0C*W*_w4c16~31

N0H0C*W*_w30c16~31

N0H0C*W*_w1c16~31

N0H0C*W*_w3c16~31

N0H0C*W*_w5c16~31

N0H0C*W*_w31c16~31

N0H1C*W*_w0c0~15

N0H1C*W*_w2c0~15

N0H1C*W*_w4c0~15

N0H1C*W*_w30c0~15

N1H0C*W*_w0c0~15

N1H0C*W*_w2c0~15

N1H0C*W*_w4c0~15

N1H0C*W*_w30c0~15

一个N*H*W*C大小的张量可用如下6重循环表示:

for (int n = 0; n < N; n++) {
  for (int h = 0; h < H; h++) {
    for (int c1 = 0; c1 < ceil(C/16); c1++) {
      for (int w1 = 0; w1 < ceil(W/32); w1++) {
        // in the block
        for (int w2 = 0; w2 < 32; w2++) {
          for (int c2 = 0; c2 < 16; c2++) {
            int native_offset = n*H*W*C + h*W*C + (w1*32 + w2)*C + c1*16 + c2;
            int layout_offset = n*H*W*C + h*W*C + c1*W*16 + w1*32*16 + ((w2%2)*16 + (w2/2))*16 + c2;
            // layout_data[layout_offset] = native_data[native_offset];
            // native_data[native_offset] = layout_data[layout_offset];
          }
        }
      }
    }
  }
}

12.2.6. NHCW_32C排布

数据排布如下:

N0H0C*W0_c0~31

N0H0C*W1_c0~31

N0H0C*W2_c0~31

N0H0C*W0_c32~63

N0H0C*W1_c32~63

N0H0C*W2_c32~63

N0H1C*W0_c0~31

N0H1C*W1_c0~31

N0H1C*W2_c0~31

N1H0C*W0_c0~31

N1H0C*W1_c0~31

N1H0C*W2_c0~31

一个N*H*W*C大小的张量可用如下5重循环表示:

for (int n = 0; n < N; n++) {
  for (int h = 0; h < H; h++) {
    for (int c1 = 0; c1 < ceil(C/32); c1++) {
      for (int w = 0; w < W; w++) {
        // in the block
        for (int c2 = 0; c2 < 32; ++c2) {
            int native_offset = n*H*W*C + h*W*C + w*C + c1*32 + c2;
            int layout_offset = n*H*W*C + h*W*C + c1*W*32 + w*32 + c2;
            // layout_data[layout_offset] = native_data[native_offset];
            // native_data[native_offset] = layout_data[layout_offset];
        }
      }
    }
  }
}

12.2.7. NCHW_8C排布

该排布只用于高精度输出32bit的大尾端数据。

数据排布如下:

N0C*H0W0_c0~7

N0C*H0W1_c0~7

N0C*H0W2_c0~7

N0C*H1W0_c0~7

N0C*H1W1_c0~7

N0C*H1W2_c0~7

N0C*H0W0_c8~15

N0C*H0W1_c8~15

N0C*H0W2_c8~15

N0C*H1W0_c8~15

N0C*H1W1_c8~15

N0C*H2W2_c8~15

N1C*H0W0_c0~7

N1C*H0W1_c0~7

N1C*H0W2_c0~7

一个N*H*W*C大小的张量可用如下5重循环表示:

for (int n = 0; n < N; ++n) {
  for (int c1 = 0; c1 < ceil(C/8); ++c1) {
    for (int h = 0; h < H; ++h) {
      for (int w = 0; w < W; ++w) {
        // in the block
        for (int c2 = 0; c2 < 8; ++c2) {
          int native_offset = n*H*W*C + h*W*C + w*C + c1*8 + c2;
          int layout_offset = n*H*W*C + c1*H*W*8 + h*W*8 + w*8 + c2;
          // layout_data[layout_offset] = native_data[native_offset];
          // native_data[native_offset] = layout_data[layout_offset];
        }
      }
    }
  }
}

12.3. HBDK3 改变及新功能

本小节简要总结 HBDK3 中的变化,新功能及一些问题修复。

12.3.1. hbdk-cc 变化

注意事项

  • -i,--input-source 选项变为可选项。如未设置,默认模型输入类型为 DDR。

  • --enable-dbg-dump_input_td 选项从 HBDK3 中移除,替换为功能更加强大的 --dump-layer-output 选项, 后者可以输出网络中任意一层的结果。

总体改进

  • 新添 -n,--name 选项,用于指定编译的模型名字。

  • 新添 --dump-layer-output 选项,用于输出网络中任意一层的结果。

  • 新添 --description 选项,用于指定模型描述文件名。

  • 新添 --core-num 选项,用于指定 BPU 核数 (默认值:1)。

  • 新添 --advice 选项,当某一层执行时间大于指定时间(单位:毫秒)时,打印建议信息。

  • 新添 --fast 优化选项,指定优化目标为每帧执行时间最短。

  • 新添 --ddr 优化选项,指定优化目标为 DDR 访存带宽最小。

HBDK2 到 HBDK3 移植示例

这里会给出 HBDK2 的 MXNet 和 TensorFlow 示例,并且会在下面给出等价的 HBDK3 命令行写法。

  • 对于 HBDK2 中的 -i 选项:

    hbdk-cc --march bernoulli -m model_0.json -p real_0.params -s 1x540x960x3 -i ddr --O3 -o YOLOV3.hbm
    hbdk-cc --march bernoulli -f tf -m model_0.pb -s 1x540x960x3 -i pyramid --O3 -o YOLOV3.hbm
    

    等价的 HBDK3 命令行如下:在第一个命令行中, -i 选项被省略,此处使用默认值。但由于第二个命令行中的模型输入来源并非 DDR,所以不能省略,需要显式指定。

    hbdk-cc --march bernoulli -m model_0.json -p real_0.params -s 1x540x960x3 --O3 -o YOLOV3.hbm
    hbdk-cc --march bernoulli -f tf -m model_0.pb -s 1x540x960x3 -i pyramid --O3 -o YOLOV3.hbm
    
  • 对于 HBDK2 中的 --enable-dbg-dump_input_td 选项:

    hbdk-cc --march bernoulli -m model_0.json -p real_0.params -s 1x540x960x3 -i ddr --O3 -o YOLOV3.hbm --enable-dbg-dump_input_td
    hbdk-cc --march bernoulli -f tf -m model_0.pb -s 1x540x960x3 -i pyramid --O3 -o YOLOV3.hbm --enable-dbg-dump_input_td
    

    等价的 HBDK3 命令如下,原命令行中的 --enable-dbg-dump_input_td 会将模型输入存储到 DDR 中,因为模型的输入为 quantiinput0 层的输出,所以这里使用 --dump-layer-output 选项指定存储 quantiinput0 层的输出到 DDR 中,是等价的。

    hbdk-cc --march bernoulli -m model_0.json -p real_0.params -s 1x540x960x3 -i ddr --O3 -o YOLOV3.hbm --dump-layer-output quantiinput0
    hbdk-cc --march bernoulli -f tf -m model_0.pb -s 1x540x960x3 -i pyramid --O3 -o YOLOV3.hbm --dump-layer-output quantiinput0
    
  • 对于 HBDK3 中新增的选项:

    hbdk-cc --march bernoulli -m model_0.json -p real_0.params -s 1x540x960x3 -i ddr --O3 -o YOLOV3.hbm --dump-layer-output quantiinput0 -n MyYoLo --core-num 2 --ddr --advice 100
    hbdk-cc --march bernoulli -f tf -m model_0.pb -s 1x540x960x3 -i pyramid --O3 -o YOLOV3.hbm --dump-layer-output quantiinput0 -n MyYoLo --core-num 2 --ddr --advice 100
    

    上例中,我们使用 -n 选项指定编译得到的模型名字为 “MyYoLo”;使用 --core-num 选项指定使用 2 个 BPU 核;使用 --ddr 选项指定优化目标为 DDR 的使用带宽;使用 --advice 选项指定当某一层执行时间慢于 100 毫秒时,编译器会打印出建议信息。

12.3.2. hbdk-pack 变化

注意事项

  • -o, --output 选项变为可选项,如未指定,默认输出文件名为 packed_x_models.hbm,其中 x 代表该 hbm 文件中包含的模型数量。

总体改进

  • 新添 --tag 选项,用于为打包后的 HBM 文件打标签。

HBDK2 到 HBDK3 移植示例

  • 对于 HBDK2 中的 -o 选项:

    hbdk-cc --march bernoulli -m model_0.json -p real_0.params -s 1x540x960x3 -i ddr --O3 -o YOLOV3.hbm
    hbdk-cc --march bernoulli -m model_1.json -p real_1.params -s 1x128x128x3 -i ddr --O3 -o ResNet18.hbm
    hbdk-pack YOLOV3.hbm ResNet18.hbm -o packed_2_models.hbm
    

    HBDK3 中等价的命令行如下:

    hbdk-cc --march bernoulli -m model_0.json -p real_0.params -s 1x540x960x3 --O3 -o YOLOV3.hbm
    hbdk-cc --march bernoulli -m model_1.json -p real_1.params -s 1x128x128x3 --O3 -o ResNet18.hbm
    hbdk-pack YOLOV3.hbm ResNet18.hbm
    

    上例 HBDK3 的等价命令行中,省略了 -o 选项,hbdk-pack 工具会生成一个名为 packed_2_models.hbm 的文件,因为这个文件中包含 2 个模型。

  • 对于 HBDK3 中的 –tag 选项:

    hbdk-cc --march bernoulli -m model_0.json -p real_0.params -s 1x540x960x3 -i ddr --O3 -o YOLOV3.hbm
    hbdk-cc --march bernoulli -m model_1.json -p real_1.params -s 1x128x128x3 -i ddr --O3 -o ResNet18.hbm
    hbdk-pack YOLOV3.hbm ResNet18.hbm -o packed_2_models.hbm --tag V1.0.0
    

    packed_2_model.hbm 的 tag 为 V1.0.0,可以通过 hbdk-disas 工具查看。

12.3.3. hbdk-sim 变化

注意事项

  • -F,--input-feature-Y,--input-uv-C,--input-y 选项被合并进 -i,--input-binary。 对于 pyramid 和 resizer 输入, 应使用一个YUV文件,而不再是分开的 Y 文件和 UV 文件。

  • resizer 配置文件被移除(--resizer-config)。resizer 的 roi/stride 等信息需在命令行中指定。

  • hbdk-sim 现总是使用二进制输入文件, 不再支持文本输入

  • 对于来自 ddr 的输入,hbdk-sim 的输入文件应为 NHWC 数据排布,不再使用硬件的数据排布。

总体改进

  • 新添 -o,--output 选项指定输出目录。

  • 极大减少了运行时间。

HBDK2 到 HBDK3 移植示例

  • HBDK2 示例

    hbdk-sim --modelso YOLOV3.hbm --model-name YOLOV3 --march bernoulli --resizer-config resizer_config.txt -Y input.y -C input.uv
    # resizer_config 文件存储了resizer yuv大小/间隔/Roi坐标/Roi大小
    
  • HBDK3 中等价命令如下:

    hbdk-sim -f YOLOV3.hbm -n YOLOV3 -i YOLOV3_input.yuv --input-source pyramid --yuv-size 704x1280 --yuv-stride 1280 --yuv-roi-coord 10x20 --yuv-roi-size 540x960
    

12.3.4. hbdk-model-check 变化

注意事项

总体改进

  • 新添选项 --display-limitation,用于打印所有的限制。

示例

hbdk-model-check --display-limitation bernoulli

12.4. 词汇表

AP

Application Processor。

BIF

Bus Interface,BIF 用于 AP 和 CP 间的数据交互,以及访问 DDR 和寄存器。

BPU

Brain Processing Unit,X2/J2 上的卷积神经网络加速引擎。

CP

Co-processor。

HBDK

Horizon BPU Development Kit,包括模型编译器,linker以及性能分析器。

Horizon OpenExplorer

地平线天工开物开发工具链。

Hobot Framework

运行于 X2/J2 平台的系统框架。以有向图的形式提供可将基础功能组件组成更复杂的功能模块的机制。

IPU

Image Processing Unit,图像处理单元。

NHWC

Batch, Height, Width, Channel。用于描述张量的4维数据,最右侧为最内维。

PYM

Pyramid。

SIF

Sensor Interface,SIF 用于接收摄像头模组输出的图像数据,将图像数据(可为视频帧回灌输入或 Camera 输入)从外部传入X2/J2 芯片内。

SoC

System on Chip。

SoM

System on Module。

VIO

Video In/Out。

X2/J2

芯片版本名称。J2 用于汽车行业,X2 用于其他领域。BPU架构为 Bernoulli V1。X2/J2 编译器工具对应的 march 为 bernoulli。