def gen_layer_struct(klayer: k210_layer.K210Layer, idx: int): reserved = 0 set_to_zero = 0 img_ram_size = 2 * 1024 * 1024 conv_arg = klayer.conv and klayer.conv.to_k210() or default_conv_arg bn_arg = klayer.bn and klayer.bn.to_k210(conv_arg['swsx']) or default_bn_arg act_arg = klayer.act and klayer.act.to_k210(bn_arg['post_scale']) or default_act_arg pool_arg = klayer.pool and klayer.pool.to_k210() or default_pool_arg io_arg = klayer.to_k210() mino, maxo = klayer.act.min_y, klayer.act.max_y output_scale, output_bias = tools.min_max_to_scale_bias(mino, maxo) img_input_size = int(math.ceil(io_arg['i_ch_num'] / conv_arg['coef_group']) * 64 * conv_arg['channel_switch_addr']) img_output_size = int(math.ceil(io_arg['o_ch_num'] / io_arg['wb_group']) * 64 * io_arg['wb_channel_switch_addr']) assert (img_input_size + img_output_size <= img_ram_size) interrupt_enabe = { 'int_en': set_to_zero, 'ram_flag': reserved, 'full_add': set_to_zero, 'depth_wise_layer': conv_arg['depth_wise_layer'] } image_addr = { 'image_src_addr': '(uint64_t)' + hex(int((0 if not idx & 1 else (img_ram_size - img_input_size)) / 64)), 'image_dst_addr': '(uint64_t)' + hex(int((0 if idx & 1 else (img_ram_size - img_output_size)) / 64)) } image_channel_num = { 'i_ch_num': hex(io_arg['i_ch_num'] - 1), 'o_ch_num': hex(io_arg['o_ch_num'] - 1), 'o_ch_num_coef': hex(conv_arg['o_ch_num_coef'] - 1), } image_size = { 'i_row_wid': hex(conv_arg['i_row_wid'] - 1), 'i_col_high': hex(conv_arg['i_col_high'] - 1), 'o_row_wid': hex(io_arg['o_row_wid'] - 1), 'o_col_high': hex(io_arg['o_col_high'] - 1), } kernel_pool_type_cfg = { 'kernel_type': conv_arg['kernel_type'], 'pad_type': conv_arg['pad_type'], 'pool_type': pool_arg['pool_type'], 'first_stride': conv_arg['first_stride'], 'bypass_conv': 0 if klayer.conv else 1, 'load_para': bn_arg['load_para'], 'dma_burst_size': io_arg['dma_burst_size'], 'pad_value': tools.signed_to_hex(conv_arg['pad_value'], 8), 'bwsx_base_addr': bn_arg['bwsx_base_addr'], } kernel_load_cfg = { 'load_coor': conv_arg['load_coor'], 'load_time': conv_arg['load_time'] - 1, 'para_size': conv_arg['para_size'], 'para_start_addr': conv_arg['para_start_addr'], } kernel_offset = { 'coef_column_offset': set_to_zero, 'coef_row_offset': set_to_zero, } kernel_calc_type_cfg = { 'channel_switch_addr': hex(conv_arg['channel_switch_addr']), 'row_switch_addr': hex(conv_arg['row_switch_addr']), 'coef_size': reserved, 'coef_group': conv_arg['coef_group'], 'load_act': 1 if klayer.act else 0, 'active_addr': act_arg['active_addr'] } write_back_cfg = { 'wb_channel_switch_addr': hex(io_arg['wb_channel_switch_addr']), 'wb_row_switch_addr': hex(io_arg['wb_row_switch_addr']), 'wb_group': io_arg['wb_group'] } conv_value = { 'shr_w': conv_arg['shr_w'], 'shr_x': conv_arg['shr_x'], 'arg_w': tools.signed_to_hex(conv_arg['arg_w'], 24), 'arg_x': tools.signed_to_hex(conv_arg['arg_x'], 24), } conv_value2 = { 'arg_add': int(round(conv_arg['arg_add'])), } dma_parameter = { 'send_data_out': io_arg['send_data_out'], 'channel_byte_num': io_arg['channel_byte_num'] - 1, 'dma_total_byte': io_arg['dma_total_byte'] - 1, } return { 'interrupt_enabe': interrupt_enabe, 'image_addr': image_addr, 'image_channel_num': image_channel_num, 'image_size': image_size, 'kernel_pool_type_cfg': kernel_pool_type_cfg, 'kernel_load_cfg': kernel_load_cfg, 'kernel_offset': kernel_offset, 'kernel_calc_type_cfg': kernel_calc_type_cfg, 'write_back_cfg': write_back_cfg, 'conv_value': conv_value, 'conv_value2': conv_value2, 'dma_parameter': dma_parameter }, (output_scale, output_bias)
def __init__(self, iwo_minmax, ico_shapes, conv_weights_isdw, bn_mean_var_gamma_beta_epsilon, act_type, pool_type_size_stride, eight_bit_mode=False, cbap_tensor_info=None, idx=-1): input_min, input_max, weights_min, weights_max, output_min, output_max = iwo_minmax input_shape, conv_shape, output_shape = ico_shapes conv_weights, conv_isdw = conv_weights_isdw conv_tensor_info, bn_tensor_info, act_tensor_info, pool_tensor_info, *_ = [ *list(cbap_tensor_info or []), dict(), dict(), dict(), dict() ] output_name = pool_tensor_info.get('name') or act_tensor_info.get( 'name', 'noname') input_scale, input_bias = tools.min_max_to_scale_bias( input_min, input_max) output_scale, output_bias = tools.min_max_to_scale_bias( output_min, output_max) layer_shape_trans = [ int(input_shape[1]), int(input_shape[2]), int(input_shape[3]), int(output_shape[1]), int(output_shape[2]), int(output_shape[3]) ] print('[layer {}]: {}'.format(idx, output_name), ' shape(HWC): {}x{}x{} ==> {}x{}x{}'.format( *layer_shape_trans), ' scale,bias: ({},{}) ==> ({},{})'.format( input_scale, input_bias, output_scale, output_bias), sep='\n') self.conv = K210Conv(conv_weights, conv_isdw, eight_bit_mode, [input_shape, conv_shape], [input_min, input_max, weights_min, weights_max], tensor_info=conv_tensor_info) bn_mean, bn_var, bn_gamma, bn_beta, bn_epsilon = bn_mean_var_gamma_beta_epsilon self.bn = K210BN(bn_mean, bn_var, bn_gamma, bn_beta, bn_epsilon, eight_bit_mode, tensor_info=bn_tensor_info) self.act = K210Act(output_min, output_max, act_type, eight_bit_mode=eight_bit_mode, tensor_info=act_tensor_info) if pool_type_size_stride is not None: pool_type, pool_size, pool_stride = pool_type_size_stride if pool_size == 2 and conv_shape[3] % 2 != 0: raise ValueError( "at {} unsupport padding mode SAME of pooling" \ .format(pool_tensor_info.get('name', 'noname')) ) if conv_isdw and pool_size != 1: raise ValueError( 'not supported DepthwiseConv2d({}) followed by pooling witch pool_size is not 1.' \ .format(pool_tensor_info.get('name', 'noname')) ) self.pool = K210Pool(pool_type, pool_size, pool_stride, pool_tensor_info) else: self.pool = None