From 1fa76228cab736012b2fc5bf3a09d7b36e7f5ad1 Mon Sep 17 00:00:00 2001 From: Duchstf Date: Fri, 11 Sep 2020 09:59:18 -0500 Subject: [PATCH 01/13] update conversion and templates --- hls4ml/model/hls_model.py | 49 ++++++++++++++++++++++++++--- hls4ml/templates/vivado_template.py | 23 +++++++++++--- hls4ml/writer/vivado_writer.py | 5 ++- 3 files changed, 67 insertions(+), 10 deletions(-) diff --git a/hls4ml/model/hls_model.py b/hls4ml/model/hls_model.py index d53c11589f..261540c07c 100644 --- a/hls4ml/model/hls_model.py +++ b/hls4ml/model/hls_model.py @@ -1227,13 +1227,31 @@ def print_tcl(self): class Pooling1D(Layer): def initialize(self): - shape = [self.attributes['n_out'], self.attributes['n_filt']] - dims = ['N_OUTPUTS_{}'.format(self.index), 'N_FILT_{}'.format(self.index)] - self.add_output_variable(shape, dims) + + #Consider different data format + cl=False + if self.get_attr('data_format') == 'channels_last': + shape = [self.attributes['n_out'], self.attributes['n_filt']] + dims = ['N_OUTPUTS_{}'.format(self.index), 'N_FILT_{}'.format(self.index)] + cl = True + else: + shape = [self.attributes['n_filt'], self.attributes['n_out']] + dims = ['N_FILT_{}'.format(self.index), 'N_OUTPUTS_{}'.format(self.index)] + + depth=(self.attributes['pad_right']+2) + print("adding :",shape,dims) + self.add_output_variable(shape, dims, cl = cl, depth=depth) self.set_attr('pool_op', self.get_attr('class_name').split('Pooling')[0]) + self.is1x1 = False + if (self.attributes['n_out'] == 1): + self.is1x1 = True def function_cpp(self,iFirst=False): params = self._default_function_params() + params['data_format'] = 'cf' if self.get_attr('data_format') == 'channels_first' else 'cl' + params['1x1'] = '' + if self.is1x1: + params['1x1'] = '_1x1' header='' if self.model.config.get_config_value('IOType') == 'io_serial': if iFirst: @@ -1244,15 +1262,36 @@ def function_cpp(self,iFirst=False): def config_cpp(self): params = self._default_config_params() + params['n_in'] = self.get_input_variable().size_cpp() params['n_out'] = self.get_output_variable().size_cpp() + if self.get_attr('data_format') == 'channels_last': + params['n_chan'] = self.get_input_variable().dim_names[1] + '-1' + params['n_chan_in'] = self.get_input_variable().dim_names[1] + params['n_filt'] = self.get_output_variable().dim_names[1] + '-1' + params['n_filt_in'] = self.get_output_variable().dim_names[1] + else: + params['n_chan'] = self.get_input_variable().dim_names[0] + '-1' + params['n_chan_in'] = self.get_input_variable().dim_names[0] + params['n_filt'] = self.get_output_variable().dim_names[0] + '-1' + params['n_filt_in'] = self.get_output_variable().dim_names[0] + return self._config_template.format(**params) def print_tcl(self): params = self._default_tcl_params() - params['n_chan_in'] = self.get_input_variable().dim_names[0] - params['n_filt_in'] = self.get_output_variable().dim_names[0] + if self.get_attr('data_format') == 'channels_last': + params['n_chan_in'] = self.get_input_variable().dim_names[1] + params['n_filt_in'] = self.get_output_variable().dim_names[1] + else: + params['n_chan_in'] = self.get_input_variable().dim_names[0] + params['n_filt_in'] = self.get_output_variable().dim_names[0] + + params['1x1'] = '' + if self.is1x1: + params['1x1'] = '_1x1' + return self._tcl_template.format(**params) class Pooling2D(Layer): diff --git a/hls4ml/templates/vivado_template.py b/hls4ml/templates/vivado_template.py index d30806fcf9..03317b4258 100644 --- a/hls4ml/templates/vivado_template.py +++ b/hls4ml/templates/vivado_template.py @@ -154,12 +154,18 @@ pooling1d_config_template = """struct config{index} : nnet::pooling1d_config {{ static const unsigned n_in = {n_in}; + static const unsigned n_filt = {n_filt}; + static const unsigned n_chan = {n_chan}; + static const unsigned n_filt_in = {n_filt_in}; + static const unsigned n_chan_in = {n_chan_in}; + static const unsigned stride = {stride}; static const unsigned pool_size = {pool_size}; + static const unsigned filt_size = {pool_size}; static const unsigned n_out = {n_out}; static const unsigned pad_left = {pad_left}; static const unsigned pad_right = {pad_right}; - static const unsigned stride = {stride}; static const nnet::Pool_Op pool_op = nnet::{pool_op}; + static const unsigned reuse = {reuse}; }};\n""" pooling2d_config_template = """struct config{index} : nnet::pooling2d_config {{ @@ -234,7 +240,7 @@ conv2dmerge_function_template = 'nnet::conv_2d_merge_{strategy}_{data_format}<{input_t}, {output_t}, {config}>({input}, {output}, {w}, {b});' activ_function_template = 'nnet::{activation}{strategy}<{input_t}, {output_t}, {config}>({input}, {output});' param_activ_function_template = 'nnet::{activation}{strategy}<{input_t}, {output_t}, {config}>({input}, {param}, {output});' -pooling1d_function_template = 'nnet::pooling1d<{input_t}, {config}>({input}, {output});' +pooling1d_function_template = 'nnet::pooling1d_{data_format}{1x1}<{input_t}, {output_t}, {config}>({input}, {output});' pooling2d_function_template = 'nnet::pooling2d_{data_format}{1x1}<{input_t}, {output_t}, {config}>({input}, {output});' merge_function_template = 'nnet::{merge}{strategy}<{input1_t}, {input2_t}, {output_t}, {config}>({input1}, {input2}, {output});' split_function_template = 'nnet::split{strategy}<{input_t}, {output_t}, {config}>({input}, {output1}, {output2});' @@ -306,6 +312,15 @@ source ../common/build.tcl \n""" +pooling1d_tcl_template = """set arg_0 "-I . -DN_INPUT={n_chan_in} -DN_OUTPUT={n_filt_in}" +set arg_1 "-DCONFIG={config}" +set arg_2 "-DINPUT_T={input_t} -DLAYER_T={output_t}" +set args "$arg_0 $arg_1 $arg_2" +set layer_type pooling1d_{data_format}{1x1} +\n +source ../common/build.tcl +\n""" + pooling2d_tcl_template = """set arg_0 "-I . -DN_INPUT={n_chan_in} -DN_OUTPUT={n_filt_in}" set arg_1 "-DCONFIG={config}" set arg_2 "-DINPUT_T={input_t} -DLAYER_T={output_t}" @@ -342,7 +357,7 @@ 'Conv2D' : conv2d_tcl_template, 'UpSampling2D' : upsampling2d_tcl_template, 'Activation' : activ_tcl_template, - 'Pooling1D' : pooling2d_tcl_template, + 'Pooling1D' : pooling1d_tcl_template, 'Pooling2D' : pooling2d_tcl_template, 'Merge' : merge_tcl_template, 'Concatenate' : merge_tcl_template, @@ -363,7 +378,7 @@ def __init__(self): self.register_templates('Activation' , activ_function_template, activ_config_template,activ_tcl_template) self.register_templates('ParametrizedActivation' , param_activ_function_template, activ_config_template,activ_tcl_template) self.register_templates('PReLU' , param_activ_function_template, activ_config_template,activ_tcl_template) - self.register_templates('Pooling1D' , pooling1d_function_template, pooling1d_config_template,pooling2d_tcl_template) + self.register_templates('Pooling1D' , pooling1d_function_template, pooling1d_config_template,pooling1d_tcl_template) self.register_templates('Pooling2D' , pooling2d_function_template, pooling2d_config_template,pooling2d_tcl_template) self.register_templates('Merge' , merge_function_template, merge_config_template,merge_tcl_template) self.register_templates('Concatenate' , merge_function_template, concat_config_template,merge_tcl_template) diff --git a/hls4ml/writer/vivado_writer.py b/hls4ml/writer/vivado_writer.py index e5ff8c2a5f..76e4f23f1a 100644 --- a/hls4ml/writer/vivado_writer.py +++ b/hls4ml/writer/vivado_writer.py @@ -200,7 +200,10 @@ def write_model_json(self, model): onexone = '_1x1' if(layer.get_attr('strategy') != None): strategy = "_" + layer.get_attr("strategy") - kernel_name = "pooling2d" + strategy + data_format + onexone + + #Kernel name depends on dimensions specify in layer's name + kernel_name = "pooling{}d".format(layer.__class__.__name__[-2]) + strategy + data_format + onexone + input_ports = [{"name":"input", "width": layer.get_input_variable().shape[0] +1}] if not(tensor_map[layer.get_output_variable().name]['input'] == []): From cb64150e9d43e257f932620b91ba88328552cf80 Mon Sep 17 00:00:00 2001 From: Duchstf Date: Fri, 11 Sep 2020 10:27:22 -0500 Subject: [PATCH 02/13] first adaptation for hls pool1d --- .../vivado/nnet_utils/nnet_pooling.h | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h index 26b03786d7..0dbabe8971 100644 --- a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h +++ b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h @@ -86,12 +86,17 @@ T pad_val(){ struct pooling1d_config{ // IO size static const unsigned n_in = 10; + static const unsigned n_filt = 4; + static const unsigned stride = 1; static const unsigned pool_size = 2; static const unsigned n_out = n_in / pool_size; static const unsigned pad_left = 0; static const unsigned pad_right = 0; + // Pooling function static const Pool_Op pool_op = Max; + // Reuse + static const unsigned reuse = 1; }; template @@ -105,6 +110,65 @@ void pooling1d(data_T data[CONFIG_T::n_in], data_T res[CONFIG_T::n_out]){ } } +template + void pooling1d_cl( + hls::stream data[CONFIG_T::n_filt_in], + hls::stream res [CONFIG_T::n_filt_in]) { + + const static int lShiftX = CONFIG_T::pool_width-CONFIG_T::pad_left-1; + const static int rowsize = (CONFIG_T::in_width+CONFIG_T::pad_left+CONFIG_T::pad_right); + + static ap_shift_reg layer_in_row[CONFIG_T::n_filt]; + #pragma HLS ARRAY_RESHAPE variable=layer_in_row complete dim=2 + + static data_T layer_in[CONFIG_T::pool_size*CONFIG_T::n_filt]; + #pragma HLS ARRAY_RESHAPE variable=layer_in complete dim=0 + + static unsigned pX=0; + + static data_T tmpdata[CONFIG_T::n_chan]; + #pragma HLS ARRAY_RESHAPE variable=tmpdata complete + + data_T iReset = data[0].read(); + for(int i0 = 0; i0 < CONFIG_T::n_chan; i0++) { + data_T pTmp = data[i0+1].read(); + tmpdata[i0] = pTmp; + } + static res_T pReset = 0; + if(iReset==0) { + pX = 0; + pReset = 0; + for(int i0 = 0; i0 < CONFIG_T::pad_left; i0++) nnet::cnnshiftzero(layer_in_row,layer_in); + } + nnet::cnnshift(tmpdata,layer_in_row,layer_in); + //Processs signal + unsigned pLoop = 1; + if(pX == CONFIG_T::n_in-1) pLoop = CONFIG_T::pad_right+1; + for(int i0 = 0; i0 < pLoop; i0++) { + if(i0 > 0) nnet::cnnshiftzero(layer_in_row,layer_in); + if((pX+1) % CONFIG_T::stride == 0 && pX > lShiftX-1) { + res_T pId = pReset; + if(pReset == 0) pReset = 1; + res[0].write(pId); + for(unsigned i1 = 0; i1 < CONFIG_T::n_filt; i1++) { + #pragma HLS UNROLL + data_T pool[CONFIG_T::pool_size]; + #pragma HLS ARRAY_RESHAPE variable=pool complete dim=0 + for(unsigned i2 = 0; i2 < CONFIG_T::pool_size; i2++) { + #pragma HLS UNROLL + pool[i2] = layer_in[i1*CONFIG_T::n_filt+i1]; + } + res[i1+1].write(pool_op(pool)); + } + } + pX = pX+1; + if(pX == CONFIG_T::in_width+CONFIG_T::pad_right) { + pX = 0; + for(int i1 = 0; i1 < CONFIG_T::pad_left; i1++) nnet::cnnshiftzero(layer_in_row,layer_in); + } + } +} + struct pooling2d_config{ // IO size static const unsigned in_height = 10; From 317e0ad7d3e0f446318d2a3ecfa0fcb12a0021e1 Mon Sep 17 00:00:00 2001 From: Duchstf Date: Fri, 11 Sep 2020 10:31:55 -0500 Subject: [PATCH 03/13] small fix --- hls4ml/templates/vivado/nnet_utils/nnet_pooling.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h index 0dbabe8971..1191c6f864 100644 --- a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h +++ b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h @@ -115,8 +115,8 @@ template hls::stream data[CONFIG_T::n_filt_in], hls::stream res [CONFIG_T::n_filt_in]) { - const static int lShiftX = CONFIG_T::pool_width-CONFIG_T::pad_left-1; - const static int rowsize = (CONFIG_T::in_width+CONFIG_T::pad_left+CONFIG_T::pad_right); + const static int lShiftX = CONFIG_T::pool_size-CONFIG_T::pad_left-1; + const static int rowsize = (CONFIG_T::n_in+CONFIG_T::pad_left+CONFIG_T::pad_right); static ap_shift_reg layer_in_row[CONFIG_T::n_filt]; #pragma HLS ARRAY_RESHAPE variable=layer_in_row complete dim=2 From 42f9fbc16757aace960c5bfb4046144f7587bae0 Mon Sep 17 00:00:00 2001 From: Duchstf Date: Fri, 11 Sep 2020 22:36:04 -0500 Subject: [PATCH 04/13] pool1d writer fix --- hls4ml/model/hls_model.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/hls4ml/model/hls_model.py b/hls4ml/model/hls_model.py index 261540c07c..20391cab7a 100644 --- a/hls4ml/model/hls_model.py +++ b/hls4ml/model/hls_model.py @@ -1238,7 +1238,7 @@ def initialize(self): shape = [self.attributes['n_filt'], self.attributes['n_out']] dims = ['N_FILT_{}'.format(self.index), 'N_OUTPUTS_{}'.format(self.index)] - depth=(self.attributes['pad_right']+2) + depth=1 print("adding :",shape,dims) self.add_output_variable(shape, dims, cl = cl, depth=depth) self.set_attr('pool_op', self.get_attr('class_name').split('Pooling')[0]) @@ -1262,20 +1262,20 @@ def function_cpp(self,iFirst=False): def config_cpp(self): params = self._default_config_params() - - params['n_in'] = self.get_input_variable().size_cpp() - params['n_out'] = self.get_output_variable().size_cpp() + input_dims = self.get_input_variable().dim_names if self.get_attr('data_format') == 'channels_last': - params['n_chan'] = self.get_input_variable().dim_names[1] + '-1' - params['n_chan_in'] = self.get_input_variable().dim_names[1] - params['n_filt'] = self.get_output_variable().dim_names[1] + '-1' - params['n_filt_in'] = self.get_output_variable().dim_names[1] + params['n_in'] = '*'.join([str(k) for k in input_dims[:-1]]) + params['n_chan'] = input_dims[1] + '-1' + params['n_chan_in'] = input_dims[1] else: - params['n_chan'] = self.get_input_variable().dim_names[0] + '-1' - params['n_chan_in'] = self.get_input_variable().dim_names[0] - params['n_filt'] = self.get_output_variable().dim_names[0] + '-1' - params['n_filt_in'] = self.get_output_variable().dim_names[0] + params['n_in'] = '*'.join([str(k) for k in input_dims[1:]]) + params['n_chan'] = sinput_dims[0] + '-1' + params['n_chan_in'] = input_dims[0] + + params['n_filt_in'] = 'N_FILT_{}'.format(self.index) + params['n_filt'] = 'N_FILT_{}-1'.format(self.index) + params['n_out'] = 'N_OUTPUTS_{}'.format(self.index) return self._config_template.format(**params) From fa298990136525aaeb02c65ba7fcd73785e21f07 Mon Sep 17 00:00:00 2001 From: Duchstf Date: Fri, 11 Sep 2020 22:37:37 -0500 Subject: [PATCH 05/13] typo fix --- hls4ml/model/hls_model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hls4ml/model/hls_model.py b/hls4ml/model/hls_model.py index 20391cab7a..65d8059887 100644 --- a/hls4ml/model/hls_model.py +++ b/hls4ml/model/hls_model.py @@ -1270,7 +1270,7 @@ def config_cpp(self): params['n_chan_in'] = input_dims[1] else: params['n_in'] = '*'.join([str(k) for k in input_dims[1:]]) - params['n_chan'] = sinput_dims[0] + '-1' + params['n_chan'] = input_dims[0] + '-1' params['n_chan_in'] = input_dims[0] params['n_filt_in'] = 'N_FILT_{}'.format(self.index) From 272cd24ea2ceb7c0683c9072aa4ac5513ce9d791 Mon Sep 17 00:00:00 2001 From: Duchstf Date: Fri, 11 Sep 2020 23:14:28 -0500 Subject: [PATCH 06/13] small fix to hls --- hls4ml/templates/vivado/nnet_utils/nnet_pooling.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h index 1191c6f864..3a9329cad0 100644 --- a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h +++ b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h @@ -118,7 +118,7 @@ template const static int lShiftX = CONFIG_T::pool_size-CONFIG_T::pad_left-1; const static int rowsize = (CONFIG_T::n_in+CONFIG_T::pad_left+CONFIG_T::pad_right); - static ap_shift_reg layer_in_row[CONFIG_T::n_filt]; + static ap_shift_reg layer_in_row[0][CONFIG_T::n_filt]; #pragma HLS ARRAY_RESHAPE variable=layer_in_row complete dim=2 static data_T layer_in[CONFIG_T::pool_size*CONFIG_T::n_filt]; @@ -162,7 +162,7 @@ template } } pX = pX+1; - if(pX == CONFIG_T::in_width+CONFIG_T::pad_right) { + if(pX == CONFIG_T::n_in+CONFIG_T::pad_right) { pX = 0; for(int i1 = 0; i1 < CONFIG_T::pad_left; i1++) nnet::cnnshiftzero(layer_in_row,layer_in); } From 20fbb540461f11547af4740cf0c9e440d06d3de4 Mon Sep 17 00:00:00 2001 From: Duchstf Date: Fri, 11 Sep 2020 23:29:07 -0500 Subject: [PATCH 07/13] further adaptation for pool1d --- hls4ml/templates/vivado/nnet_utils/nnet_pooling.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h index 3a9329cad0..cd22661144 100644 --- a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h +++ b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h @@ -118,7 +118,7 @@ template const static int lShiftX = CONFIG_T::pool_size-CONFIG_T::pad_left-1; const static int rowsize = (CONFIG_T::n_in+CONFIG_T::pad_left+CONFIG_T::pad_right); - static ap_shift_reg layer_in_row[0][CONFIG_T::n_filt]; + static ap_shift_reg layer_in_row[CONFIG_T::n_chan]; #pragma HLS ARRAY_RESHAPE variable=layer_in_row complete dim=2 static data_T layer_in[CONFIG_T::pool_size*CONFIG_T::n_filt]; @@ -134,13 +134,17 @@ template data_T pTmp = data[i0+1].read(); tmpdata[i0] = pTmp; } + static res_T pReset = 0; + if(iReset==0) { pX = 0; pReset = 0; for(int i0 = 0; i0 < CONFIG_T::pad_left; i0++) nnet::cnnshiftzero(layer_in_row,layer_in); } + nnet::cnnshift(tmpdata,layer_in_row,layer_in); + //Processs signal unsigned pLoop = 1; if(pX == CONFIG_T::n_in-1) pLoop = CONFIG_T::pad_right+1; From 18b2db691acc25706c976cf99377236173bcc02f Mon Sep 17 00:00:00 2001 From: Duchstf Date: Fri, 11 Sep 2020 23:34:45 -0500 Subject: [PATCH 08/13] fix bugs --- hls4ml/templates/vivado/nnet_utils/nnet_pooling.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h index cd22661144..d63b45daa9 100644 --- a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h +++ b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h @@ -118,7 +118,7 @@ template const static int lShiftX = CONFIG_T::pool_size-CONFIG_T::pad_left-1; const static int rowsize = (CONFIG_T::n_in+CONFIG_T::pad_left+CONFIG_T::pad_right); - static ap_shift_reg layer_in_row[CONFIG_T::n_chan]; + static ap_shift_reg layer_in_row[CONFIG_T::n_chan]; #pragma HLS ARRAY_RESHAPE variable=layer_in_row complete dim=2 static data_T layer_in[CONFIG_T::pool_size*CONFIG_T::n_filt]; From 08557910b412880276f6f8add3eea33f8954a03c Mon Sep 17 00:00:00 2001 From: Duchstf Date: Fri, 11 Sep 2020 23:38:54 -0500 Subject: [PATCH 09/13] more bug --- hls4ml/templates/vivado_template.py | 1 + 1 file changed, 1 insertion(+) diff --git a/hls4ml/templates/vivado_template.py b/hls4ml/templates/vivado_template.py index 03317b4258..64400dade9 100644 --- a/hls4ml/templates/vivado_template.py +++ b/hls4ml/templates/vivado_template.py @@ -154,6 +154,7 @@ pooling1d_config_template = """struct config{index} : nnet::pooling1d_config {{ static const unsigned n_in = {n_in}; + static const unsigned in_width = {n_in}; static const unsigned n_filt = {n_filt}; static const unsigned n_chan = {n_chan}; static const unsigned n_filt_in = {n_filt_in}; From 24fa026295170d8d152663f39338052460ba1da6 Mon Sep 17 00:00:00 2001 From: Duchstf Date: Sat, 12 Sep 2020 00:19:03 -0500 Subject: [PATCH 10/13] update shifting --- .../vivado/nnet_utils/nnet_pooling.h | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h index d63b45daa9..4eb7ea5643 100644 --- a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h +++ b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h @@ -140,16 +140,33 @@ template if(iReset==0) { pX = 0; pReset = 0; - for(int i0 = 0; i0 < CONFIG_T::pad_left; i0++) nnet::cnnshiftzero(layer_in_row,layer_in); + + for(int iX = 0; iX < CONFIG_T::pad_left; iX++) { + for(int i0 = 0; i0 < CONFIG_T::n_chan_in; i0++) { + data_T tmp = 0; + layer_in_row[i0].shift(0,tmp); + } + } } - nnet::cnnshift(tmpdata,layer_in_row,layer_in); + for(int i0 = 0; i0 < CONFIG_T::n_chan; i0++) { + #pragma HLS UNROLL + data_T tmp = data[i0+1].read(); + layer_in_row[i0].shift(0,tmp); + } //Processs signal unsigned pLoop = 1; if(pX == CONFIG_T::n_in-1) pLoop = CONFIG_T::pad_right+1; for(int i0 = 0; i0 < pLoop; i0++) { - if(i0 > 0) nnet::cnnshiftzero(layer_in_row,layer_in); + if(i0 > 0) { + for(int iX = 0; iX < CONFIG_T::pad_left; iX++) { + for(int i0 = 0; i0 < CONFIG_T::n_chan_in; i0++) { + data_T tmp = 0; + layer_in_row[i0].shift(0,tmp); + } + } + } if((pX+1) % CONFIG_T::stride == 0 && pX > lShiftX-1) { res_T pId = pReset; if(pReset == 0) pReset = 1; From 559d857c768092ddda5a4f57dae0d811a0049fb3 Mon Sep 17 00:00:00 2001 From: Duchstf Date: Sat, 12 Sep 2020 00:21:48 -0500 Subject: [PATCH 11/13] more shifting --- hls4ml/templates/vivado/nnet_utils/nnet_pooling.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h index 4eb7ea5643..2188f4832e 100644 --- a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h +++ b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h @@ -185,7 +185,14 @@ template pX = pX+1; if(pX == CONFIG_T::n_in+CONFIG_T::pad_right) { pX = 0; - for(int i1 = 0; i1 < CONFIG_T::pad_left; i1++) nnet::cnnshiftzero(layer_in_row,layer_in); + for(int i1 = 0; i1 < CONFIG_T::pad_left; i1++){ + for(int iX = 0; iX < CONFIG_T::pad_left; iX++) { + for(int i0 = 0; i0 < CONFIG_T::n_chan_in; i0++) { + data_T tmp = 0; + layer_in_row[i0].shift(0,tmp); + } + } + }; } } } From a58363f76d73bc5a3205e57b352f0388d61ce721 Mon Sep 17 00:00:00 2001 From: Duchstf Date: Sat, 12 Sep 2020 13:00:47 -0500 Subject: [PATCH 12/13] clean up codes --- .../vivado/nnet_utils/nnet_pooling.h | 60 ++++++++++--------- hls4ml/templates/vivado_template.py | 2 - 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h index 2188f4832e..24f96c8f1b 100644 --- a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h +++ b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h @@ -86,8 +86,8 @@ T pad_val(){ struct pooling1d_config{ // IO size static const unsigned n_in = 10; - static const unsigned n_filt = 4; - static const unsigned stride = 1; + static const unsigned n_filt = 2; + static const unsigned stride = 2; static const unsigned pool_size = 2; static const unsigned n_out = n_in / pool_size; static const unsigned pad_left = 0; @@ -145,14 +145,14 @@ template for(int i0 = 0; i0 < CONFIG_T::n_chan_in; i0++) { data_T tmp = 0; layer_in_row[i0].shift(0,tmp); - } } + } } for(int i0 = 0; i0 < CONFIG_T::n_chan; i0++) { - #pragma HLS UNROLL - data_T tmp = data[i0+1].read(); - layer_in_row[i0].shift(0,tmp); + #pragma HLS UNROLL + data_T tmp = data[i0+1].read(); + layer_in_row[i0].shift(0,tmp); } //Processs signal @@ -168,33 +168,35 @@ template } } if((pX+1) % CONFIG_T::stride == 0 && pX > lShiftX-1) { - res_T pId = pReset; - if(pReset == 0) pReset = 1; - res[0].write(pId); - for(unsigned i1 = 0; i1 < CONFIG_T::n_filt; i1++) { - #pragma HLS UNROLL - data_T pool[CONFIG_T::pool_size]; - #pragma HLS ARRAY_RESHAPE variable=pool complete dim=0 - for(unsigned i2 = 0; i2 < CONFIG_T::pool_size; i2++) { - #pragma HLS UNROLL - pool[i2] = layer_in[i1*CONFIG_T::n_filt+i1]; - } - res[i1+1].write(pool_op(pool)); - } + res_T pId = pReset; + if(pReset == 0) pReset = 1; + res[0].write(pId); + for(unsigned i1 = 0; i1 < CONFIG_T::n_filt; i1++) { + + #pragma HLS UNROLL + data_T pool[CONFIG_T::pool_size]; + #pragma HLS ARRAY_RESHAPE variable=pool complete dim=0 + + for(unsigned i2 = 0; i2 < CONFIG_T::pool_size; i2++) { + #pragma HLS UNROLL + pool[i2] = layer_in[i1*CONFIG_T::n_filt+i1]; + } + res[i1+1].write(pool_op(pool)); + } } pX = pX+1; if(pX == CONFIG_T::n_in+CONFIG_T::pad_right) { - pX = 0; - for(int i1 = 0; i1 < CONFIG_T::pad_left; i1++){ - for(int iX = 0; iX < CONFIG_T::pad_left; iX++) { - for(int i0 = 0; i0 < CONFIG_T::n_chan_in; i0++) { - data_T tmp = 0; - layer_in_row[i0].shift(0,tmp); - } - } - }; - } + pX = 0; + for(int i1 = 0; i1 < CONFIG_T::pad_left; i1++){ + for(int iX = 0; iX < CONFIG_T::pad_left; iX++) { + for(int i0 = 0; i0 < CONFIG_T::n_chan_in; i0++) { + data_T tmp = 0; + layer_in_row[i0].shift(0,tmp); + } + } + }; } + } } struct pooling2d_config{ diff --git a/hls4ml/templates/vivado_template.py b/hls4ml/templates/vivado_template.py index 64400dade9..0328957647 100644 --- a/hls4ml/templates/vivado_template.py +++ b/hls4ml/templates/vivado_template.py @@ -154,14 +154,12 @@ pooling1d_config_template = """struct config{index} : nnet::pooling1d_config {{ static const unsigned n_in = {n_in}; - static const unsigned in_width = {n_in}; static const unsigned n_filt = {n_filt}; static const unsigned n_chan = {n_chan}; static const unsigned n_filt_in = {n_filt_in}; static const unsigned n_chan_in = {n_chan_in}; static const unsigned stride = {stride}; static const unsigned pool_size = {pool_size}; - static const unsigned filt_size = {pool_size}; static const unsigned n_out = {n_out}; static const unsigned pad_left = {pad_left}; static const unsigned pad_right = {pad_right}; From 1633c0f4f0a012e42212c6b5f44c3018883f9f38 Mon Sep 17 00:00:00 2001 From: Duchstf Date: Sat, 12 Sep 2020 21:45:15 -0500 Subject: [PATCH 13/13] fix small bug --- .../vivado/nnet_utils/nnet_pooling.h | 44 +++++++++---------- 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h index 24f96c8f1b..c18169b544 100644 --- a/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h +++ b/hls4ml/templates/vivado/nnet_utils/nnet_pooling.h @@ -137,7 +137,7 @@ template static res_T pReset = 0; - if(iReset==0) { + if(iReset==0) { pX = 0; pReset = 0; @@ -160,41 +160,37 @@ template if(pX == CONFIG_T::n_in-1) pLoop = CONFIG_T::pad_right+1; for(int i0 = 0; i0 < pLoop; i0++) { if(i0 > 0) { - for(int iX = 0; iX < CONFIG_T::pad_left; iX++) { for(int i0 = 0; i0 < CONFIG_T::n_chan_in; i0++) { data_T tmp = 0; layer_in_row[i0].shift(0,tmp); } - } } if((pX+1) % CONFIG_T::stride == 0 && pX > lShiftX-1) { - res_T pId = pReset; - if(pReset == 0) pReset = 1; - res[0].write(pId); - for(unsigned i1 = 0; i1 < CONFIG_T::n_filt; i1++) { + res_T pId = pReset; + if(pReset == 0) pReset = 1; + res[0].write(pId); + for(unsigned i1 = 0; i1 < CONFIG_T::n_filt; i1++) { - #pragma HLS UNROLL - data_T pool[CONFIG_T::pool_size]; - #pragma HLS ARRAY_RESHAPE variable=pool complete dim=0 + #pragma HLS UNROLL + data_T pool[CONFIG_T::pool_size]; + #pragma HLS ARRAY_RESHAPE variable=pool complete dim=0 - for(unsigned i2 = 0; i2 < CONFIG_T::pool_size; i2++) { - #pragma HLS UNROLL - pool[i2] = layer_in[i1*CONFIG_T::n_filt+i1]; - } - res[i1+1].write(pool_op(pool)); - } + for(unsigned i2 = 0; i2 < CONFIG_T::pool_size; i2++) { + #pragma HLS UNROLL + pool[i2] = layer_in[i1*CONFIG_T::n_filt+i1]; + } + res[i1+1].write(pool_op(pool)); + } } pX = pX+1; - if(pX == CONFIG_T::n_in+CONFIG_T::pad_right) { + if(pX == CONFIG_T::n_in+CONFIG_T::pad_right) { pX = 0; - for(int i1 = 0; i1 < CONFIG_T::pad_left; i1++){ - for(int iX = 0; iX < CONFIG_T::pad_left; iX++) { - for(int i0 = 0; i0 < CONFIG_T::n_chan_in; i0++) { - data_T tmp = 0; - layer_in_row[i0].shift(0,tmp); - } + for(int i1 = 0; i1 < CONFIG_T::pad_left; i1++) { + for(int i0 = 0; i0 < CONFIG_T::n_chan_in; i0++) { + data_T tmp = 0; + layer_in_row[i0].shift(0,tmp); } - }; + } } } }