Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
return [self._function_template.format(**params)]
def config_cpp(self):
params = self._default_config_params()
params['in_height'] = self.get_input_variable().dim_names[0]
params['in_width'] = self.get_input_variable().dim_names[1]
params['n_chan'] = self.get_input_variable().dim_names[2]
params['out_height'] = self.get_output_variable().dim_names[0]
params['out_width'] = self.get_output_variable().dim_names[1]
params['n_filt'] = self.get_output_variable().dim_names[2]
params['nzeros'] = self.get_weights('weight').nzeros
return self._config_template.format(**params)
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)
self.set_attr('pool_op', self.get_attr('class_name').split('Pooling')[0])
def function_cpp(self):
params = self._default_function_params()
return [self._function_template.format(**params)]
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()
self.add_output_variable(shape, dims)
self.set_attr('pool_op', self.get_attr('class_name').split('Pooling')[0])
def function_cpp(self):
params = self._default_function_params()
return [self._function_template.format(**params)]
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()
return self._config_template.format(**params)
class Pooling2D(Layer):
def initialize(self):
shape = [self.attributes['out_height'], self.attributes['out_width'], self.attributes['n_filt']]
dims = ['OUT_HEIGHT_{}'.format(self.index), 'OUT_WIDTH_{}'.format(self.index), 'N_FILT_{}'.format(self.index)]
self.add_output_variable(shape, dims)
self.set_attr('pool_op', self.get_attr('class_name').split('Pooling')[0])
def function_cpp(self):
params = self._default_function_params()
return [self._function_template.format(**params)]
def config_cpp(self):
params = self._default_config_params()
params['n_in'] = self.get_input_variable().dim_names[0]
params['in_width'] = self.get_input_variable().dim_names[1]
params['out_height'] = self.get_output_variable().dim_names[0]
import numpy as np
import re
from ..optimizer import OptimizerPass
import hls4ml.model.hls_model as hls_model
import hls4ml.model.templates as templates
class BatchNormalizationQuantizedTanh(hls_model.Layer):
''' Merged Batch Normalization and quantized (binary or ternary) Tanh layer.
The mean, variance, beta, gamma parameters are folded into the threshold(s) at which the
sign of the input flips after the quantized (binary or ternary) Tanh activation.
'''
def initialize(self):
inp = self.get_input_variable()
shape = inp.shape
dims = inp.dim_names
precision_bits = re.search('.+<(.+?)>', inp.type.precision).group(1).split(',')
if 'ap_int' in inp.type.precision:
W = int(precision_bits[0])
I = W
F = 0
elif 'ap_fixed' in inp.type.precision:
W = int(precision_bits[0])
next = __next__
def update_precision(self, new_precision):
self.type.precision = new_precision
if 'int' in self.type.precision:
self.precision_fmt = '%d'
else:
precision_bits = re.search('.+<(.+?)>', self.type.precision).group(1).split(',')
decimal_bits = int(precision_bits[0]) - int(precision_bits[1])
decimal_spaces = int(np.floor(np.log10(2 ** decimal_bits - 1))) + 1
self.precision_fmt = '%.{}f'.format(decimal_spaces)
def definition_cpp(self):
return '{type} {name}[{size}]'.format(type=self.type.name, name=self.cppname, size=self.data_length)
class CompressedWeightVariable(WeightVariable):
def __init__(self, var_name, type_name, precision, data, reuse_factor, **kwargs):
super(CompressedWeightVariable, self).__init__(var_name, type_name, precision, data, **kwargs)
self.extra_zeros = 0
self.data_length = np.prod(data.shape) - self.nzeros
while self.data_length % reuse_factor != 0:
self.extra_zeros += 1
self.data_length += 1
self.nonzeros = np.prod(data.shape) - self.nzeros + self.extra_zeros
# Compress the array
weights = []
extra_nzero_cnt = self.extra_zeros
it = np.nditer(data, order='C', flags=['multi_index'])
max_idx = 0
while not it.finished:
val = it[0]
def pytorch_to_hls(yamlConfig):
######################
## Do translation
######################
print('Interpreting Model')
reader = PyTorchDataReader(yamlConfig)
core_layers = ['Linear']
skip_layers = ['Dropout', 'Flatten']
activation_layers = ['ReLU', 'Sigmoid', 'Tanh', 'SELU', 'LeakyReLU', 'Softmax', 'Softplus', 'Softsign']
supported_layers = core_layers + skip_layers + activation_layers
#This is a list of dictionaries to hold all the layer info we need to generate HLS
layer_list = []
#Loop through layers
print('Topology:')
modelstr = repr(reader.torch_model).split('\n')
for pytorch_layer in modelstr:
layer_match = re.match(r'\((\d)\): (\w+)\((.*)\)', pytorch_layer.strip())
if layer_match is None:
continue
self.add_weights_variable(name='bias', var_name='b{index}', data=bias)
def function_cpp(self):
params = self._default_function_params()
params['scale'] = self.get_weights('scale').name
params['bias'] = self.get_weights('bias').name
return [self._function_template.format(**params)]
def config_cpp(self):
params = self._default_config_params()
params['n_in'] = self.get_input_variable().size_cpp()
return self._config_template.format(**params)
class Merge(Layer):
def initialize(self):
assert(len(self.inputs) == 2)
inp1 = self.get_input_variable(self.inputs[0])
inp2 = self.get_input_variable(self.inputs[1])
shape = inp1.shape
assert(inp1.shape == inp2.shape)
dims = inp1.dim_names
self.add_output_variable(shape, dims)
def function_cpp(self):
params = {}
params['merge'] = self.get_attr('op').lower()
params['config'] = 'config{}'.format(self.index)
params['input1_t'] = self.get_input_variable(self.inputs[0]).type.name
params['input2_t'] = self.get_input_variable(self.inputs[1]).type.name
params['output_t'] = self.get_output_variable().type.name
def function_cpp(self):
params = self._default_function_params()
return [self._function_template.format(**params)]
def config_cpp(self):
params = self._default_config_params()
params['n_in'] = self.get_input_variable().dim_names[0]
params['in_width'] = self.get_input_variable().dim_names[1]
params['out_height'] = self.get_output_variable().dim_names[0]
params['out_width'] = self.get_output_variable().dim_names[1]
params['n_filt'] = self.get_output_variable().dim_names[2]
return self._config_template.format(**params)
class Activation(Layer):
def initialize(self):
inp = self.get_input_variable()
shape = inp.shape
dims = inp.dim_names
self.add_output_variable(shape, dims)
def function_cpp(self):
params = self._default_function_params()
params['activation'] = self.get_attr('activation')
params['config'] = '{}_config{}'.format(self.get_attr('activation'), self.index)
return [self._function_template.format(**params)]
def config_cpp(self):
params = self._default_config_params()
params['type'] = self.get_attr('activation')
# parameters.h
def config_cpp(self):
raise NotImplementedError
def get_numbers_cpp(self):
numbers = ''
for k, v in self.get_output_variable().get_shape():
numbers += '#define {} {}\n'.format(k,v)
return numbers
def precision_cpp(self):
return 'typedef {precision} layer{index}_t;'.format(precision=self.get_output_variable().precision, index=self.index)
class Input(Layer):
def initialize(self):
shape = self.attributes['input_shape']
if shape[0] is None:
shape = shape[1:]
dims = ['N_INPUT_{}_{}'.format(i, self.index) for i in range(1, len(shape) + 1)]
self.add_output_variable(shape, dims, var_name=self.name, type_name='input_t')
def function_cpp(self):
return None
def config_cpp(self):
return None
class Dense(Layer):
def initialize(self):
shape = [self.attributes['n_out']]
class Input(Layer):
def initialize(self):
shape = self.attributes['input_shape']
if shape[0] is None:
shape = shape[1:]
dims = ['N_INPUT_{}_{}'.format(i, self.index) for i in range(1, len(shape) + 1)]
self.add_output_variable(shape, dims, var_name=self.name, type_name='input_t')
def function_cpp(self):
return None
def config_cpp(self):
return None
class Dense(Layer):
def initialize(self):
shape = [self.attributes['n_out']]
dims = ['N_LAYER_{}'.format(self.index)]
quantize = self.get_attr('quantize', default=0)
compression = self.model.config.get_compression(self)
if self.model.config.is_resource_strategy(self):
if self.model.config.get_reuse_factor(self) == 1:
print('WARNING: Using ReuseFactor 1 with "Resource" strategy. This may not work.')
if compression:
self.set_attr('strategy', 'compressed')
else:
self.set_attr('strategy', 'large')
else:
self.set_attr('strategy', 'latency')
self.add_output_variable(shape, dims)
self.add_weights(quantize=quantize, compression=compression)
return act # ELU activation
class PReLU(Activation):
def initialize(self):
super(PReLU, self).initialize()
self.add_weights_variable(name='alpha', var_name='a{index}')
def function_cpp(self):
params = self._default_function_params()
params['activation'] = self.get_attr('activation').lower()
params['param'] = self.get_weights('alpha').name
params['config'] = '{}_config{}'.format(self.get_attr('activation'), self.index)
return [self._function_template.format(**params)]
class BatchNormalization(Layer):
def initialize(self):
inp = self.get_input_variable()
shape = inp.shape
dims = inp.dim_names
self.add_output_variable(shape, dims)
gamma = self.model.get_weights_data(self.name, 'gamma')
beta = self.model.get_weights_data(self.name, 'beta')
mean = self.model.get_weights_data(self.name, 'moving_mean')
var = self.model.get_weights_data(self.name, 'moving_variance')
scale = gamma / np.sqrt(var + self.get_attr('epsilon'))
bias = beta - gamma * mean / np.sqrt(var + self.get_attr('epsilon'))
self.add_weights_variable(name='scale', var_name='s{index}', data=scale)
self.add_weights_variable(name='bias', var_name='b{index}', data=bias)