2 Star 0 Fork 0

spiger/modelzoo_utils

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
imk_init.hpp 5.98 KB
一键复制 编辑 原始数据 按行查看 历史
Fangorn Morn 提交于 2023-12-22 11:16 . 🎉 feat: init
#pragma once
#include <runtime.h>
#include <icraft-dev/device.h>
#include <icraft-ir/custom_op.h>
std::vector<std::string> split(std::string& str, const std::string& delim) {
std::string::size_type pos;
std::vector<std::string> result;
str += delim;
int size = str.size();
for (int i = 0; i < size; i++) {
pos = str.find(delim, i);
if (pos < size) {
std::string s = str.substr(i, pos - i);
result.push_back(s);
i = pos + delim.size() - 1;
}
}
return result;
}
void imk_init(const std::shared_ptr<icraft::dev::IcraftDevice>& device, const std::shared_ptr<icraft::ir::Operation>& operation,
const uint64_t& vm_base) {
//打印该runtime的虚拟地址
std::cout << "vm_base in runtimeInit: " << vm_base << std::endl;
// auto op_ptr = &const_cast<icraft::ir::Operation&>(operation);
auto custom_op = std::dynamic_pointer_cast<icraft::ir::CustomOp>(operation);
auto params = custom_op->params();
auto ofm = custom_op->outputFtmp()[0];
auto input_ = params["input"];
int reg_base = 0x10000400;
//根据配置的reg_base及input参数得到image_make的寄存器基地址
//当配置reg_base_不为空时,会优先将配置的基地址作为寄存器基地址
//当reg_base_为空时,会根据配置的input0~3确定各自的寄存器基地址,默认input0地址
//检查硬件的版本信息是否正确,不正确会抛出错误
if (device->readReg(reg_base + 0x234, true) != 0x20220623) {
throw std::runtime_error("ERROR :: No Image_Make HardWare");
}
//根据pad参数,得到上下左右pad的size
auto pad = params["pad"];
auto imgpad = split(pad, ",");
auto pad_r = std::atoi(imgpad[0].c_str());
auto pad_l = std::atoi(imgpad[1].c_str());
auto pad_b = std::atoi(imgpad[2].c_str());
auto pad_t = std::atoi(imgpad[3].c_str());
auto ifm = custom_op->inputFtmp()[0];
auto ifm_dims = ifm->dim();
//输入图片的通道数
auto ImageMakeChannel = ifm_dims[3];
//输入图片的宽度
auto ImageMakeWidth = ifm_dims[2];
//输入图片的高度
auto ImageMakeHeight = ifm_dims[1];
//根据输入ftmp的通道数,确定每次处理图片的通道数
//目前只支持1~4通道输入ftmp数据
auto ImageMakeChannel_each = 0;
if (ImageMakeChannel % 4 == 0) {
ImageMakeChannel_each = 4;
}
else if (ImageMakeChannel % 3 == 0) {
ImageMakeChannel_each = 3;
}
else if (ImageMakeChannel % 2 == 0) {
ImageMakeChannel_each = 2;
}
else {
ImageMakeChannel_each = 1;
}
//use input image
//计算批次,目前只支持计算批次为1
auto ImageMakeChannelTimes = ImageMakeChannel / ImageMakeChannel_each;
//得到每通道premean的值
auto premean = params["premean"];
auto premean_data = split(premean, ",");
std::vector<int> premean_data_(ImageMakeChannel);
for (int i = 0; i < ImageMakeChannel; i++) { // image_channel need software provide
premean_data_[i] = std::atoi(premean_data[i].c_str());
}
//得到每通道prescale的值
auto prescale = params["prescale"];
auto prescale_data = split(prescale, ",");
std::vector<float> prescale_data_1(ImageMakeChannel);
std::vector<int> prescale_data_(ImageMakeChannel);
//硬件中支持乘以prescale的倒数,并且会固定截位10位
for (int i = 0; i < ImageMakeChannel; i++) { // image_channel need software provide
prescale_data_1[i] = std::atof(prescale_data[i].c_str());
prescale_data_[i] = (int)((1.f / (float)prescale_data_1[i]) * pow(2, 10));
}
//将mean和scale的值拼接起来,其中precale为低16bit,prescale为高16bit
std::vector<uint32_t> ImageMakeMSC(ImageMakeChannel);
for (int i = 0; i < ImageMakeChannel; i++) {
ImageMakeMSC[i] = (int16_t)prescale_data_[i] | (int16_t)premean_data_[i] << 16;
}
//得到ImageMake写PL DDR的基地址,该地址加上了runtime vm_base偏移,用于多个runtime不同的地址空间
auto ImageMakeWddrBase_a = ofm->addr() + vm_base; //byte地址
//将上下左右的pad size拼接成一个32bit的数,该数用于写pad控制相关寄存器
auto ImageMakePadTop = pad_t;
auto ImageMakePadLeft = pad_l;
auto ImageMakePadBottom = pad_b;
auto ImageMakePadRight = pad_r;
auto ImageMakePadReg = ImageMakePadTop + (ImageMakePadBottom << 8) + (ImageMakePadLeft << 16) + (ImageMakePadRight << 24);
//每通道pad的值,目前为0
std::vector<int> prepad_data_(ImageMakeChannel);
for (int i = 0; i < ImageMakeChannel; i++) { // image_channel need software provide
prepad_data_[i] = 0;
}
//得到数据类型寄存器参数,当为8bit模式时为0,当为16bit模式时为1
int data_type_ = 0;
auto data_type = params["data_type"];
if (data_type == "FIXED8") {
data_type_ = 0;
}
else {
data_type_ = 1;
}
int ImageMakeDataArrange = data_type_;
//调用device的写寄存器的接口,配置硬件需要的寄存器,其中writeReg和readReg中最后一个参数为true,用于整体寄存器空间偏移配置
//各寄存器表示含义介绍,参照ImakeMake硬算子用户手册
//0x014~0x110
for (int i = 0; i < ImageMakeChannel; i++) {
device->writeReg(reg_base + (0x14 + i * 4), ImageMakeMSC[i], true);
}
device->writeReg(reg_base + 0x114, ImageMakeWddrBase_a, true);
device->writeReg(reg_base + 0x118, ImageMakeWidth, true);
device->writeReg(reg_base + 0x11C, ImageMakeHeight, true);
device->writeReg(reg_base + 0x124, ImageMakePadReg, true);
//0x128~0x224
for (int i = 0; i < ImageMakeChannel; i++) {
device->writeReg(reg_base + (0x128 + i * 4), prepad_data_[i], true);
}
device->writeReg(reg_base + 0x240, ImageMakeChannel_each, true);
device->writeReg(reg_base + 0x244, ImageMakeChannelTimes, true);
device->writeReg(reg_base + 0x254, ImageMakeDataArrange, true);
std::cout << "ImageMake loadParams end..." << std::endl;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/mxh-spiger/modelzoo_utils.git
git@gitee.com:mxh-spiger/modelzoo_utils.git
mxh-spiger
modelzoo_utils
modelzoo_utils
master

搜索帮助