独立编程说明¶
BMLang可以用来对指定的算法函数进行SOPHON TPU的加速实现。
BMLang独立编程时不同于我们常用的C/C++编程实现算法函数。 这里我们做个比对来让用户更好地了解BMLang。
C/C++编程实现
C/C++编程到最终运行,可以认为分为三个阶段。
C/C++程序实现。
gcc/g++编译。
Runtime执行。
BMLang编程实现
目前BMLang编程到最终运行在SOPHON TPU上,分为6个阶段:
BMLang程序实现。
g++编译生成可执行文件。
运行可执行文件生成BModel。
C/C++的业务程序实现,通过BMRuntime接口来调用之前生成的bmodel运行。
gcc/g++编译C/C++业务程序。
Runtime执行。
这里我们用BMLang实现GEMM的例子来具体说明。
第1步BMLang程序实现。BMLang程序源代码如下:
#include <vector>
#include "bmlang.h"
int main() {
// 首先要初始化bmlang
bmlang::init(bmlang::COMPILE_TPU, "BM1684", "./gemm");
// 接着声明要实现功能的输入和输出
// 声明输入时要指定输入Tensor的shape和data type
// Input shape and data type
std::vector<int> left_shape = {256, 1024};
std::vector<int> right_shape = {1024, 2048};
bmlang::DataType dtype = bmlang::FLOAT32;
// Declare left matrix
bmlang::Tensor left("left", dtype, left_shape);
bmlang::Tensor right("right", dtype, right_shape);
// 声明输出时需要不用指定shape
// 因为shape是根据bmlang操作和输入Tensor推导出来的
// Declare output tensors
bmlang::Tensor output("output", dtype);
// 然后调用bmlang的操作
// MatrixMul parameters
bmlang::MatrixMulParam param;
// MatrixMul param is mainly for quantized computation
// So float32 computation do not need it
// MatrixMul operator
std::vector<bmlang::Tensor*> inputs = {&left, &right};
bmlang::matrix_mul(inputs, output, param);
// 完成bmlang操作实现计算后,启动bmlang程序的编译优化
// Compile to optimize and CodeGen
bmlang::compile("GEMM");
// 最后反初始化bmlang
// Deinit bmlang
bmlang::deinit();
}
第2步g++编译上述程序。一个简单的CMake文件如下:
cmake_minimum_required(VERSION 2.8)
project(bmlang)
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR})
add_definitions(-DDEBUG --std=c++11 -fPIC -Wall -Werror)
set(CMAKE_BUILD_TYPE "Debug")
if(DEFINED ENV{REL_TOP})
include_directories($ENV{REL_TOP}/include/bmlang)
link_directories($ENV{REL_TOP}/lib/bmlang)
else()
message("source scripts first!")
endif()
add_executable(gemm_codegen gemm_codegen.cpp)
target_link_libraries(gemm_codegen bmlang)
第3步执行上述CMake编译后的gemm_codegen程序,生成bmodel在gemm文件夹中。
第4步编写C/C++业务程序调用gemm。这里和后面的步骤请参考nntoolchain文档中的BMRuntime的示例程序。