def posit_avg_pool(input_data, dsize, ochannel=1, posit_type="p8_1", use_quire=False): assert isinstance(input_data[0][0], list) output_data = [] divisor = dsize * dsize if posit_type == "p4_0": div = posit.PositN4E0(divisor) if use_quire: acc = quire.QuireN4E0C6() else: acc = posit.PositN4E0() elif posit_type == "p8_0": div = posit.PositN8E0(divisor) if use_quire: acc = quire.QuireN8E0C6() else: acc = posit.PositN8E0() elif posit_type == "p8_2": div = posit.PositN8E2(divisor) if use_quire: acc = quire.QuireN8E2C30() else: acc = posit.PositN8E2() else: div = posit.PositN8E1(divisor) if use_quire: acc = quire.QuireN8E1C14() else: acc = posit.PositN8E1() for oc in range(ochannel): for i in range(dsize): for j in range(dsize): acc += input_data[oc][i][j] if use_quire: if posit_type == "p4_0": tmp1 = acc.to_posit4_0() elif posit_type == "p8_0": tmp1 = acc.to_posit8_0() elif posit_type == "p8_2": tmp1 = acc.to_posit8_2() else: tmp1 = acc.to_posit8_1() else: tmp1 = acc tmp2 = [[tmp1 / div]] acc.reset() output_data.append(tmp2) return output_data
def read_param(wfile, bfile, ksize, ichannel=1, ochannel=1, posit_type="p8_1"): bias = bfile.readline() posit_bias = [] posit_weight = [] if posit_type == "p4_0": index_incre = 1 else: index_incre = 2 for oc in range(ochannel): if posit_type == "p4_0": tmp1 = posit.PositN4E0() elif posit_type == "p8_0": tmp1 = posit.PositN8E0() elif posit_type == "p8_2": tmp1 = posit.PositN8E2() else: tmp1 = posit.PositN8E1() index_base = index_incre * oc tmp1.set_from_bits(int(bias[index_base:index_base + index_incre], 16)) posit_bias.append(tmp1) tmp2 = [] for ic in range(ichannel): weight = wfile.readline() tmp3 = [] for i in range(ksize): tmp4 = [] row_base = i * index_incre * ksize for j in range(ksize): col_base = index_incre * j if posit_type == "p4_0": tmp5 = posit.PositN4E0() elif posit_type == "p8_0": tmp5 = posit.PositN8E0() elif posit_type == "p8_2": tmp5 = posit.PositN8E2() else: tmp5 = posit.PositN8E1() tmp5.set_from_bits( int( weight[row_base + col_base:row_base + col_base + index_incre], 16)) tmp4.append(tmp5) tmp3.append(tmp4) tmp2.append(tmp3) posit_weight.append(tmp2) return posit_weight, posit_bias
def param2posit(input_data, dsize, posit_type="p8_1", is_matrix=True): output_str = "" if posit_type == "p4_0": tmp = posit.PositN4E0() elif posit_type == "p8_0": tmp = posit.PositN8E0() elif posit_type == "p8_2": tmp = posit.PositN8E2() else: tmp = posit.PositN8E1() if is_matrix: for i in range(dsize): for j in range(dsize): tmp.assign(input_data[i][j].item()) tmp_str = tmp.raw_hex_string() output_str += tmp_str else: for i in range(dsize): tmp.assign(input_data[i]) tmp_str = tmp.raw_hex_string() output_str += tmp_str return output_str
def posit_pad(input_data, dsize, ichannel=1, pad_size=1, posit_type="p8_1"): assert isinstance(input_data[0][0], list) if posit_type == "p4_0": pad_num = posit.PositN4E0(0) elif posit_type == "p8_0": pad_num = posit.PositN8E0(0) elif posit_type == "p8_2": pad_num = posit.PositN8E2(0) else: pad_num = posit.PositN8E1(0) output_data = [] for ic in range(ichannel): first_line = [pad_num for _ in range(dsize + 2 * pad_size)] pad_head = [first_line for _ in range(pad_size)] for i in range(dsize): line_head = [pad_num for _ in range(pad_size)] line_head.extend(input_data[ic][i]) line_tail = [pad_num for _ in range(pad_size)] line_head.extend(line_tail) pad_head.append(line_head) last_line = [pad_num for _ in range(dsize + 2 * pad_size)] pad_tail = [last_line for _ in range(pad_size)] pad_head.extend(pad_tail) output_data.append(pad_head) return output_data
def InvertedResidual(input_data, conv_kernel, bn_weight, bn_bias, dsize, stride=1, ichannel=1, ochannel=1, expand_ratio=1, threshold=posit.PositN8E1(6), posit_type="p8_1", use_fma=False, use_quire=False): middle_oc = ichannel * expand_ratio osize = dsize // stride use_res_connect = stride == 1 and ichannel == ochannel if expand_ratio != 1: # pw pw_layers = ConvBNReLU(input_data, conv_kernel[0], bn_weight[0], bn_bias[0], dsize, 1, 1, ichannel, middle_oc, threshold, posit_type, use_fma, use_quire) # dw dw_layers = ConvBNReLU(pw_layers, conv_kernel[1], bn_weight[1], bn_bias[1], dsize, 3, stride, middle_oc, middle_oc, threshold, posit_type, use_fma, use_quire, False) # pw-linear pw_line_layers = func_v2.posit_conv2d_bn(dw_layers, conv_kernel[2], bn_weight[2], bn_bias[2], osize, 1, 1, middle_oc, ochannel, posit_type, use_fma, use_quire) else: # dw dw_layers = ConvBNReLU(input_data, conv_kernel[0], bn_weight[0], bn_bias[0], dsize, 3, stride, middle_oc, middle_oc, threshold, posit_type, use_fma, use_quire, False) # pw-linear pw_line_layers = func_v2.posit_conv2d_bn(dw_layers, conv_kernel[1], bn_weight[1], bn_bias[1], osize, 1, 1, middle_oc, ochannel, posit_type, use_fma, use_quire) if use_res_connect: for oc in range(ochannel): for i in range(osize): for j in range(osize): pw_line_layers[oc][i][j] += input_data[oc][i][j] return pw_line_layers
def posit_relu6_active(input_data, ochannel=1, threshold=posit.PositN8E1(6)): assert isinstance(input_data[0][0], list) dsize = len(input_data[0]) for oc in range(ochannel): for i in range(dsize): for j in range(dsize): if input_data[oc][i][j].isneg(): input_data[oc][i][j].reset() elif input_data[oc][i][j] > threshold: input_data[oc][i][j].assign(6) return input_data
def float2posit(input_data, dsize, posit_type="p8_1"): assert isinstance(dsize, int) output = [] if posit_type == "p4_0": for i in range(dsize): line_tmp = [] for j in range(dsize): p4 = posit.PositN4E0(input_data[i][j].item()) line_tmp.append(p4) output.append(line_tmp) elif posit_type == "p8_0": for i in range(dsize): line_tmp = [] for j in range(dsize): p8 = posit.PositN8E0(input_data[i][j].item()) line_tmp.append(p8) output.append(line_tmp) elif posit_type == "p8_2": for i in range(dsize): line_tmp = [] for j in range(dsize): p8 = posit.PositN8E2(input_data[i][j].item()) line_tmp.append(p8) output.append(line_tmp) else: for i in range(dsize): line_tmp = [] for j in range(dsize): p8 = posit.PositN8E1(input_data[i][j].item()) line_tmp.append(p8) output.append(line_tmp) return output
def ConvBNReLU(input_data, conv_kernel, bn_weight, bn_bias, dsize, ksize, stride=1, ichannel=1, ochannel=1, threshold=posit.PositN8E1(6), posit_type="p8_1", use_fma=False, use_quire=False, one_group=True): pad_size = (ksize - 1) // 2 if pad_size > 0: input_data = func.posit_pad(input_data, dsize, ichannel, pad_size, posit_type) dsize = dsize + pad_size * 2 if one_group: conv_bn = func_v2.posit_conv2d_bn(input_data, conv_kernel, bn_weight, bn_bias, dsize, ksize, stride, ichannel, ochannel, posit_type, use_fma, use_quire) else: assert ichannel == ochannel conv_bn = [] for i in range(ochannel): conv_bn_tmp = func_v2.posit_conv2d_bn([input_data[i]], [conv_kernel[i]], [bn_weight[i]], [bn_bias[i]], dsize, ksize, stride, 1, 1, posit_type, use_fma, use_quire) conv_bn.extend(conv_bn_tmp) output_data = func_v2.posit_relu6_active(conv_bn, ochannel, threshold) return output_data
def posit_conv2d_bn(input_data, conv_kernel, bn_weight, bn_bias, dsize, ksize, stride=1, ichannel=1, ochannel=1, posit_type="p8_1", use_fma=False, use_quire=False): assert not use_fma & use_quire assert isinstance(input_data[0][0], list) assert isinstance(conv_kernel[0][0][0], list) # assert isinstance(bn_bias[0], posit.PositN8E1) # assert isinstance(input_data[0][0][0], posit.PositN8E1) # assert isinstance(conv_kernel[0][0][0][0], posit.PositN8E1) output_data = [] osize = (dsize - ksize + 1) // stride if use_fma: for x in range(ochannel): if posit_type == "p4_0": acc = [[posit.PositN4E0() for _ in range(osize)] for _ in range(osize)] elif posit_type == "p8_0": acc = [[posit.PositN8E0() for _ in range(osize)] for _ in range(osize)] elif posit_type == "p8_2": acc = [[posit.PositN8E2() for _ in range(osize)] for _ in range(osize)] else: acc = [[posit.PositN8E1() for _ in range(osize)] for _ in range(osize)] for y in range(ichannel): for i in range(osize): d_base_row = i * stride for j in range(osize): d_base_col = j * stride for m in range(ksize): for n in range(ksize): acc[i][j] = input_data[y][d_base_row + m][ d_base_col + n].fma( conv_kernel[x][y][m][n], acc[i][j]) for i in range(osize): for j in range(osize): acc[i][j] = acc[i][j].fma(bn_weight[x], bn_bias[x]) output_data.append(acc) else: if use_quire: for x in range(ochannel): if posit_type == "p4_0": acc = [[quire.QuireN4E0C6() for _ in range(osize)] for _ in range(osize)] elif posit_type == "p8_0": acc = [[quire.QuireN8E0C6() for _ in range(osize)] for _ in range(osize)] elif posit_type == "p8_2": acc = [[quire.QuireN8E2C30() for _ in range(osize)] for _ in range(osize)] else: acc = [[quire.QuireN8E1C14() for _ in range(osize)] for _ in range(osize)] for y in range(ichannel): for i in range(osize): d_base_row = i * stride for j in range(osize): d_base_col = j * stride for m in range(ksize): for n in range(ksize): acc[i][j] += input_data[y][d_base_row + m][ d_base_col + n] * conv_kernel[x][y][m][n] out_tmp = [] if posit_type == "p4_0": for i in range(osize): line_tmp = [] for j in range(osize): p_tmp = acc[i][j].to_posit4_0() p_tmp = p_tmp.fma(bn_weight[x], bn_bias[x]) line_tmp.append(p_tmp) out_tmp.append(line_tmp) output_data.append(out_tmp) elif posit_type == "p8_0": for i in range(osize): line_tmp = [] for j in range(osize): p_tmp = acc[i][j].to_posit8_0() p_tmp = p_tmp.fma(bn_weight[x], bn_bias[x]) line_tmp.append(p_tmp) out_tmp.append(line_tmp) output_data.append(out_tmp) elif posit_type == "p8_2": for i in range(osize): line_tmp = [] for j in range(osize): p_tmp = acc[i][j].to_posit8_2() p_tmp = p_tmp.fma(bn_weight[x], bn_bias[x]) line_tmp.append(p_tmp) out_tmp.append(line_tmp) output_data.append(out_tmp) else: for i in range(osize): line_tmp = [] for j in range(osize): p_tmp = acc[i][j].to_posit8_1() p_tmp = p_tmp.fma(bn_weight[x], bn_bias[x]) line_tmp.append(p_tmp) out_tmp.append(line_tmp) output_data.append(out_tmp) else: for x in range(ochannel): if posit_type == "p4_0": acc = [[posit.PositN4E0() for _ in range(osize)] for _ in range(osize)] elif posit_type == "p8_0": acc = [[posit.PositN8E0() for _ in range(osize)] for _ in range(osize)] elif posit_type == "p8_2": acc = [[posit.PositN8E2() for _ in range(osize)] for _ in range(osize)] else: acc = [[posit.PositN8E1() for _ in range(osize)] for _ in range(osize)] for y in range(ichannel): for i in range(osize): d_base_row = i * stride for j in range(osize): d_base_col = j * stride for m in range(ksize): for n in range(ksize): acc[i][j] += input_data[y][d_base_row + m][ d_base_col + n] * conv_kernel[x][y][m][n] for i in range(osize): for j in range(osize): acc[i][j] = acc[i][j] * bn_weight[x] + bn_bias[x] output_data.append(acc) return output_data
def to_posit8_1(self): p8 = unum.Posit_8_1_t() q2v = unum.quire_to_value_8_1_14(self.__q8_1_14) unum.convert_q81_to_p81(q2v, p8) return posit.PositN8E1(p8)
def read_param_for_ir(wfile, bfile, ichannel=1, ochannel=1, expand_ratio=1, posit_type="p8_1"): middle_layers = ichannel * expand_ratio bias = bfile.readline() conv_weight = [] bn_bias = [] bn_weight = [] if posit_type == "p4_0": index_incre = 1 else: index_incre = 2 if expand_ratio != 1: for oc in range(ochannel): if posit_type == "p4_0": tmp1 = posit.PositN4E0() elif posit_type == "p8_0": tmp1 = posit.PositN8E0() elif posit_type == "p8_2": tmp1 = posit.PositN8E2() else: tmp1 = posit.PositN8E1() index_base = index_incre * oc tmp1.set_from_bits(int(bias[index_base:index_base + index_incre], 16)) bn_bias.append(tmp1) tmp2 = [] for ic in range(ichannel): weight = wfile.readline() tmp3 = [] for i in range(ksize): tmp4 = [] row_base = i * index_incre * ksize for j in range(ksize): col_base = index_incre * j if posit_type == "p4_0": tmp5 = posit.PositN4E0() elif posit_type == "p8_0": tmp5 = posit.PositN8E0() elif posit_type == "p8_2": tmp5 = posit.PositN8E2() else: tmp5 = posit.PositN8E1() tmp5.set_from_bits(int(weight[row_base + col_base:row_base + col_base + index_incre], 16)) tmp4.append(tmp5) tmp3.append(tmp4) tmp2.append(tmp3) conv_weight.append(tmp2) weight = wfile.readline() for oc in range(ochannel): if posit_type == "p4_0": tmp6 = posit.PositN4E0() elif posit_type == "p8_0": tmp6 = posit.PositN8E0() elif posit_type == "p8_2": tmp6 = posit.PositN8E2() else: tmp6 = posit.PositN8E1() index_base = index_incre * oc tmp6.set_from_bits(int(weight[index_base:index_base + index_incre], 16)) bn_weight.append(tmp6) return conv_weight, bn_weight, bn_bias