Skip to content

Commit 1ad1ad9

Browse files
jicamposjmitrevs
andauthored
added check for conv implementation (fastmachinelearning#1155)
* added check for conv implementation * Updated node attr key and made case insensitive * Updated Conv1D and Conv2d optimizer match and default linebuffer values * format * Add check for io_parallel and update tests * Update optimizer match and default values for linebuffer impl. * format * Refactor: Replace casefold with lower and use setdefault * Minor refactor --------- Co-authored-by: Jovan Mitrevski <[email protected]>
1 parent c408145 commit 1ad1ad9

File tree

6 files changed

+74
-62
lines changed

6 files changed

+74
-62
lines changed

hls4ml/backends/catapult/passes/conv_stream.py

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ class GenerateConvStreamingInstructions(OptimizerPass):
66
'''Generates the instructions for streaming implementation of CNNs'''
77

88
def match(self, node):
9-
return isinstance(node, (Conv1D, SeparableConv1D, Conv2D, SeparableConv2D))
9+
is_match = (
10+
isinstance(node, (Conv1D, SeparableConv1D, Conv2D, SeparableConv2D))
11+
and node.model.config.get_config_value('IOType').lower() == 'io_stream'
12+
and node.get_attr('implementation').lower() == 'encoded'
13+
)
14+
return is_match
1015

1116
def transform(self, model, node):
1217
node_class = node.__class__.__name__
@@ -18,35 +23,25 @@ def transform(self, model, node):
1823
raise Exception(f'Cannot generate instructions for node {node.name} ({node_class})')
1924

2025
def _generate_1d_instructions(self, node):
21-
if node.model.config.get_config_value('IOType') == 'io_stream':
22-
min_w, instructions = node.model.config.backend.compute_conv1d_instructions(
23-
node.get_input_variable().shape[0],
24-
node.get_input_variable().shape[1],
25-
node.get_attr('filt_width'),
26-
node.get_attr('stride_width'),
27-
)
28-
instructions_str = ','.join(str(i) for i in instructions)
29-
node.set_attr('min_width', min_w)
30-
node.set_attr('instructions', instructions_str)
31-
else:
32-
# these are unused; just put dummy values
33-
node.set_attr('min_width', node.get_attr('in_width'))
34-
node.set_attr('instructions', '0')
26+
min_w, instructions = node.model.config.backend.compute_conv1d_instructions(
27+
node.get_input_variable().shape[0],
28+
node.get_input_variable().shape[1],
29+
node.get_attr('filt_width'),
30+
node.get_attr('stride_width'),
31+
)
32+
instructions_str = ','.join(str(i) for i in instructions)
33+
node.set_attr('min_width', min_w)
34+
node.set_attr('instructions', instructions_str)
3535

3636
def _generate_2d_instructions(self, node):
37-
if node.model.config.get_config_value('IOType') == 'io_stream':
38-
min_h, min_w, instructions = node.model.config.backend.compute_conv2d_instructions(
39-
node.get_input_variable().shape[0],
40-
node.get_input_variable().shape[1],
41-
node.get_input_variable().shape[2],
42-
node.get_attr('filt_height'),
43-
node.get_attr('stride_height'),
44-
)
45-
instructions_str = ','.join(str(i) for i in instructions)
46-
node.set_attr('min_height', min_h)
47-
node.set_attr('min_width', min_w)
48-
node.set_attr('instructions', instructions_str)
49-
else:
50-
node.set_attr('min_height', node.get_attr('in_height'))
51-
node.set_attr('min_width', node.get_attr('in_width'))
52-
node.set_attr('instructions', '0')
37+
min_h, min_w, instructions = node.model.config.backend.compute_conv2d_instructions(
38+
node.get_input_variable().shape[0],
39+
node.get_input_variable().shape[1],
40+
node.get_input_variable().shape[2],
41+
node.get_attr('filt_height'),
42+
node.get_attr('stride_height'),
43+
)
44+
instructions_str = ','.join(str(i) for i in instructions)
45+
node.set_attr('min_height', min_h)
46+
node.set_attr('min_width', min_w)
47+
node.set_attr('instructions', instructions_str)

hls4ml/backends/catapult/passes/convolution_templates.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ def format(self, node):
9494
else:
9595
params['fill_fn'] = 'FillConv1DBuffer'
9696

97+
params['min_width'] = node.get_attr('min_width', node.get_attr('in_width'))
98+
params['instructions'] = node.get_attr('instructions', '0')
99+
97100
conv_config = self.template.format(**params)
98101

99102
mult_params = self._default_config_params(node)
@@ -210,6 +213,10 @@ def format(self, node):
210213
else:
211214
params['fill_fn'] = 'FillConv2DBuffer'
212215

216+
params['min_height'] = node.get_attr('min_height', node.get_attr('in_height'))
217+
params['min_width'] = node.get_attr('min_width', node.get_attr('in_width'))
218+
params['instructions'] = node.get_attr('instructions', '0')
219+
213220
conv_config = self.template.format(**params)
214221

215222
mult_params = self._default_config_params(node)

hls4ml/backends/vivado/passes/conv_stream.py

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ class GenerateConvStreamingInstructions(OptimizerPass):
66
'''Generates the instructions for streaming implementation of CNNs'''
77

88
def match(self, node):
9-
return isinstance(node, (Conv1D, SeparableConv1D, Conv2D, SeparableConv2D))
9+
is_match = (
10+
isinstance(node, (Conv1D, SeparableConv1D, Conv2D, SeparableConv2D))
11+
and node.model.config.get_config_value('IOType').lower() == 'io_stream'
12+
and node.get_attr('implementation').lower() == 'encoded'
13+
)
14+
return is_match
1015

1116
def transform(self, model, node):
1217
node_class = node.__class__.__name__
@@ -18,35 +23,25 @@ def transform(self, model, node):
1823
raise Exception(f'Cannot generate instructions for node {node.name} ({node_class})')
1924

2025
def _generate_1d_instructions(self, node):
21-
if node.model.config.get_config_value('IOType') == 'io_stream':
22-
min_w, instructions = node.model.config.backend.compute_conv1d_instructions(
23-
node.get_input_variable().shape[0],
24-
node.get_input_variable().shape[1],
25-
node.get_attr('filt_width'),
26-
node.get_attr('stride_width'),
27-
)
28-
instructions_str = ','.join(str(i) for i in instructions)
29-
node.set_attr('min_width', min_w)
30-
node.set_attr('instructions', instructions_str)
31-
else:
32-
# these are unused; just put dummy values
33-
node.set_attr('min_width', node.get_attr('in_width'))
34-
node.set_attr('instructions', '0')
26+
min_w, instructions = node.model.config.backend.compute_conv1d_instructions(
27+
node.get_input_variable().shape[0],
28+
node.get_input_variable().shape[1],
29+
node.get_attr('filt_width'),
30+
node.get_attr('stride_width'),
31+
)
32+
instructions_str = ','.join(str(i) for i in instructions)
33+
node.set_attr('min_width', min_w)
34+
node.set_attr('instructions', instructions_str)
3535

3636
def _generate_2d_instructions(self, node):
37-
if node.model.config.get_config_value('IOType') == 'io_stream':
38-
min_h, min_w, instructions = node.model.config.backend.compute_conv2d_instructions(
39-
node.get_input_variable().shape[0],
40-
node.get_input_variable().shape[1],
41-
node.get_input_variable().shape[2],
42-
node.get_attr('filt_height'),
43-
node.get_attr('stride_height'),
44-
)
45-
instructions_str = ','.join(str(i) for i in instructions)
46-
node.set_attr('min_height', min_h)
47-
node.set_attr('min_width', min_w)
48-
node.set_attr('instructions', instructions_str)
49-
else:
50-
node.set_attr('min_height', node.get_attr('in_height'))
51-
node.set_attr('min_width', node.get_attr('in_width'))
52-
node.set_attr('instructions', '0')
37+
min_h, min_w, instructions = node.model.config.backend.compute_conv2d_instructions(
38+
node.get_input_variable().shape[0],
39+
node.get_input_variable().shape[1],
40+
node.get_input_variable().shape[2],
41+
node.get_attr('filt_height'),
42+
node.get_attr('stride_height'),
43+
)
44+
instructions_str = ','.join(str(i) for i in instructions)
45+
node.set_attr('min_height', min_h)
46+
node.set_attr('min_width', min_w)
47+
node.set_attr('instructions', instructions_str)

hls4ml/backends/vivado/passes/convolution_templates.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ def format(self, node):
108108
else:
109109
params['conv_fn'] = 'Conv1DResource'
110110

111+
params['min_width'] = node.get_attr('min_width', node.get_attr('in_width'))
112+
params['instructions'] = node.get_attr('instructions', '0')
113+
111114
conv_config = self.template.format(**params)
112115

113116
mult_params = self._default_config_params(node)
@@ -239,6 +242,10 @@ def format(self, node):
239242
else:
240243
params['fill_fn'] = 'FillConv2DBuffer'
241244

245+
params['min_height'] = node.get_attr('min_height', node.get_attr('in_height'))
246+
params['min_width'] = node.get_attr('min_width', node.get_attr('in_width'))
247+
params['instructions'] = node.get_attr('instructions', '0')
248+
242249
conv_config = self.template.format(**params)
243250

244251
mult_params = self._default_config_params(node)

test/pytest/test_conv1d_narrow.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ def model():
3131
('io_stream', 'resource', 'Encoded'),
3232
('io_stream', 'latency', 'LineBuffer'),
3333
('io_stream', 'resource', 'LineBuffer'),
34+
('io_parallel', 'resource', 'Encoded'),
35+
('io_parallel', 'latency', 'Encoded'),
36+
('io_parallel', 'resource', 'LineBuffer'),
37+
('io_parallel', 'latency', 'LineBuffer'),
3438
],
3539
)
3640
@pytest.mark.filterwarnings("error")

test/pytest/test_conv2d_narrow.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ def model():
3131
('io_stream', 'resource', 'Encoded'),
3232
('io_stream', 'latency', 'LineBuffer'),
3333
('io_stream', 'resource', 'LineBuffer'),
34+
('io_parallel', 'resource', 'Encoded'),
35+
('io_parallel', 'latency', 'Encoded'),
36+
('io_parallel', 'resource', 'LineBuffer'),
37+
('io_parallel', 'latency', 'LineBuffer'),
3438
],
3539
)
3640
@pytest.mark.filterwarnings("error")

0 commit comments

Comments
 (0)